Tải bản đầy đủ (.pptx) (25 trang)

Visitor (THIẾT kế đối TƯỢNG SLIDE)

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (421.31 KB, 25 trang )

The Visitor Pattern

1


The Problem

2


The Problem
Show me everything in a consistent manner …
… and send it to my friend via email
oh, and send it to her phone as well
and print it …

3


Some analysis music please...
AmazoneNote
title
author
isbn
price

GoogleNote
heading
excerpt
url


NewsNote
heading
byLine
excerpt

RssNote
heading
text
date

4


Commonality is in the eye of the beholder
Note

AmazoneNote

GoogleNote

title
author
isbn
price

heading
excerpt
url

NewsNote

heading
byLine
excerpt

RssNote
heading
text
date

5


Need do operations in Note structure
• With a little casual application of polymorphism...
Note
printHeading()
printDetails()
asPrintable()
asEmailContent()
asSMS()

Does this look bad to you?



AmazoneNote

GoogleNote

NewsNote


RssNote

6


The solution
Visitor Pattern
• "Represent an operation to be performed on the
elements of an object structure. Visitor lets you
define a new operation without changing the
classes of the elements on which it operates"
GOF

7


Structure
Visitor
Client
visitConcreteElement1(e : ConcreteElement1)
visitConcreteElement2(e : ConcreteElement2)

ConcreteVisistor1

ConcreteVisistor2

visitConcreteElement1(e : ConcreteElement1)
visitConcreteElement2(e : ConcreteElement2)


visitConcreteElement1(e : ConcreteElement1)
visitConcreteElement2(e : ConcreteElement2)

ObjectStructure

Element
accept(v : Visitor)

visitor.visitConcreteElement1(this);

ConcreteElement1

ConcreteElement2

accept(visitor : Visitor)

accept(visitor : Visitor)
8


A solution to a problem in a context
Note
accept(v : NodeVisitor)

AmazoneNote

GoogleNote

NewsNote


RssNote

<<Interface>>

NoteVisitor

+ visitAmazoneNote()
+ visitGoogleNote()
+ visitNewsNote()
+ visitRssNote()

NoteHeadingPrinter

NoteDetailsPrinter
9


Let’s show it in code!
public interface Note {
void accept(NoteVisitor v);
}

public interface NoteVisitor {
void visitAmazoneNote(AmazoneNote note);
void visitGoogleNote(GoogleNote note);
void visitNewsNote(NewsNote note);
void visitRssNote(RssNote note);
}

10



AmazoneNote
public class AmazoneNote implements Note {
String title;
String author;
String isbn;
double price;
public AmazoneNote(String title, String author,
String isbn, double price) {
this.title = title;
this.author = author;
this.isbn = isbn;
this.price = price;
}
public void accept(NoteVisitor visitor) {
visitor.visitAmazoneNote(this);
}
}
11


GoogleNote
public class GoogleNote implements Note {
String heading;
String excerpt;
String url;
public GoogleNote(String heading, String excerpt,
String url) {
this.heading = heading;

this.excerpt = excerpt;
this.url = url;
}
public void accept(NoteVisitor visitor) {
visitor.visitGoogleNote(this);
}
}

12


NewsNote
public class NewsNote implements Note {
String heading;
String byLine;
String excerpt;
public NewsNote(String heading, String byLine,
String excerpt) {
this.heading = heading;
this.byLine = byLine;
this.excerpt = excerpt;
}
public void accept(NoteVisitor visitor) {
visitor.visitNewsNote(this);
}
}

13



RssNote
public class RssNote implements Note {
String heading;
String text;
Date date;
public RssNote(String heading, String text) {
this.heading = heading;
this.text = text;
this.date = new Date(System.currentTimeMillis());
}
public void accept(NoteVisitor visitor) {
visitor.visitRssNote(this);
}
}

14


NoteHeadingPrinter visitor
public class NoteHeadingPrinter implements NoteVisitor {
public void visitAmazoneNote(AmazoneNote note) {
System.out.println(note.title);
}
public void visitGoogleNote(GoogleNote note) {
System.out.println(note.heading);
}
public void visitNewsNote(NewsNote note) {
System.out.println(note.heading);
}
public void visitRssNote(RssNote note) {

System.out.println(note.heading);
}
}
15


NoteDetailsPrinter visitor
public class NoteDetailsPrinter implements NoteVisitor {
public void visitAmazoneNote(AmazoneNote note) {
System.out.println(note.title);
System.out.println(note.price);
}
public void visitGoogleNote(GoogleNote note) {
System.out.println(note.heading);
System.out.println(note.excerpt);
}
public void visitNewsNote(NewsNote note) {
System.out.println(note.heading);
System.out.println(note.byLine);
System.out.println(note.excerpt);
}

}

public void visitRssNote(RssNote note) {
System.out.println(note.heading);
System.out.println(note.text);
}
16



NoteDetailsPrinter visitor
public class NoteDetailsPrinter implements NoteVisitor {
public void visitAmazoneNote(AmazoneNote note) {
System.out.println(note.title);
System.out.println(note.price);
}
public void visitGoogleNote(GoogleNote note) {
System.out.println(note.heading);
System.out.println(note.excerpt);
}
public void visitNewsNote(NewsNote note) {
System.out.println(note.heading);
System.out.println(note.byLine);
System.out.println(note.excerpt);
}

}

public void visitRssNote(RssNote note) {
System.out.println(note.heading);
System.out.println(note.text);
}
17


NoteIterator
public class NoteIterator {
private List<Note> sampleNotes() {
List<Note> notes = new ArrayList<Note>();

notes.add(new NewsNote("Melbourne Pushes Boundaries", "Tim
Colebatch",
"Melbourne is experiencing its biggest growth surge since
1960's"));
notes.add(new GoogleNote(
"Redhill Consulting Pty Ltd - Ruby on Rails plugins",
"Here are some Ruby on Rails plugins we're
developed ...",
" />notes.add(new AmazoneNote("The Wolves in the Wall", "Nail
Gaiman",
"ISBN XXX-XXXX-XXXXX", 12.06));
notes.add(new RssNote("let's talk about tests, baby...",
"Some long babbling about test naming heuristics"));
return notes;
}
public void visitAllUsing(NoteVisitor visitor) {
for (Note note : sampleNotes()) {
note.accept(visitor);

18


Test Drive
public class NoteTestDrive {
public static void main(String[] args) {
NoteIterator iterator = new NoteIterator();
iterator.visitAllUsing(new NoteHeadingPrinter());

}


}

iterator.visitAllUsing(new NoteDetailsPrinter());

19


Output
Melbourne Pushes Boundaries
The Wolves in the Wall
Redhill Consulting Pty Ltd - Ruby on Rails Plugins

Output of
NoteHeadingPrinter

Let's talk about tests, baby...

Melbourne Pushes Boundaries
Tim Colebatch
Melbourne is experiencing its biggest growth surge since the 1960's
The Wolves in the Wall
12.06

Output of NoteDetailsPrinter

Redhill Consulting Pty Ltd - Ruby on Rails Plugins
Here are some Ruby on Rails plugins we've developed...
Let's talk about tests, baby...
Some long babbling about test naming heuristics
20



When?
• “An object structure contains many classes of objects
with differing interfaces, and you want to perform
operations on these objects that depend on their
concrete classes”
• “Many distinct and unrelated operations need to be
performed on objects in an object structure, and you
want to avoid ‘polluting’ their classes with these
operations. Visitor lets you keep unrelated operations
together by defining them in one class. When the object
structure is shared by many applications, use Visitor to
put operations in just those applications that need them”

21


When?
• “The classes defining the object structure rarely
change, but you often want to define new
operations over the structure. Changing the
object structure classes requires redefining the
interface to all visitors, which is potentially costly.
If the object structure classes change often, then
it’s probably better to define the operations in
those classes”

22



Consequences
• Visitor makes adding new operations easy
• A visitor gathers related operations and
separates unrelated ones
• Adding new ConcreteElement classes is hard
• Visitors can cross object hierarchies
• Visitors can accumulate state
• Visitors may compromise encapsulation

23


File Folder Examples
FileSystemElement
name : String
getName()
getElement(name)
createIterator()
accept(v : Vistor)

File
size : int

Folder
children : ArrayList

getElement()
createIterator()
accept()


addElement(FileSystemElement)
removeElement(FileSystemElement)
getElement(name)
createIterator()
accept(v : Visitor)

Visitor
visitFile(file : File)
visitFolder(folder : Folder)

PrintVisitor

CountFileVisitor

visitFile(file : File)
visitFolder(folder : Folder)

visitFile(file : File)
visitFolder(folder : Folder)

24


Shape Example
Shape
Client

location : CartesianPoint
accept()


Dot

Circle

Square

radius : int

size : int

Rectangle
heigth : int
width : int

<<Interface>>

ShapeVisitor
forDot()
forCircle()
forSquare()
forRectanle()

Area

IsContain
point : CartesianPoint

BoundingBox


25


×