0% found this document useful (0 votes)
17 views29 pages

12-Visitor Baitap

The document describes the visitor pattern, which is a way to separate an object structure from the operations performed on it. It allows adding new operations without changing the structure's classes. The visitor pattern is demonstrated through a Notes structure with different note types (AmazonNote, GoogleNote, etc). Visitors like NoteHeadingPrinter and NoteDetailsPrinter are defined to operate on the note structure. The visitor pattern solves the problem of performing multiple operations on the note structure in an extensible way.

Uploaded by

daoduynhat12a2
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
17 views29 pages

12-Visitor Baitap

The document describes the visitor pattern, which is a way to separate an object structure from the operations performed on it. It allows adding new operations without changing the structure's classes. The visitor pattern is demonstrated through a Notes structure with different note types (AmazonNote, GoogleNote, etc). Visitors like NoteHeadingPrinter and NoteDetailsPrinter are defined to operate on the note structure. The visitor pattern solves the problem of performing multiple operations on the note structure in an extensible way.

Uploaded by

daoduynhat12a2
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 29

The Visitor Pattern

08/05/2023 1
The Problem

08/05/2023 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 …

08/05/2023 3
Some analysis music please...

AmazoneNote GoogleNote NewsNote RssNote


title heading heading heading
author excerpt byLine text
isbn url excerpt date
price

08/05/2023 4
Commonality is in the eye of the beholder
Note

AmazoneNote GoogleNote NewsNote RssNote


title heading heading heading
author excerpt byLine text
isbn url excerpt date
price

08/05/2023 5
Need do operations in Note structure
• With a little casual application of polymorphism...
Note

printHeading()
printDetails()
asPrintable() Does this look bad to you?
asEmailContent()
asSMS()

AmazoneNote GoogleNote NewsNote RssNote

08/05/2023 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

08/05/2023 7
Structure
Visitor
Client
visitConcreteElement1(e : ConcreteElement1)
visitConcreteElement2(e : ConcreteElement2)

ConcreteVisistor1 ConcreteVisistor2

visitConcreteElement1(e : ConcreteElement1) visitConcreteElement1(e : ConcreteElement1)


visitConcreteElement2(e : ConcreteElement2) visitConcreteElement2(e : ConcreteElement2)

Element
ObjectStructure
accept(v : Visitor)

ConcreteElement1 ConcreteElement2

visitor.visitConcreteElement1(this); accept(visitor : Visitor) accept(visitor : Visitor)

08/05/2023 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

08/05/2023 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);
}

08/05/2023 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);
}
}
08/05/2023 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);
}
}

08/05/2023 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);
}
}

08/05/2023 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);
}
}

08/05/2023 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);
}
}

08/05/2023 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);
}
}
08/05/2023 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);
}
}
08/05/2023 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 ...",
"http://www.redhillconsulting.com.au/rails_plugins.html"));
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);
System.out.println();
}
}
}08/05/2023 18
Test Drive
public class NoteTestDrive {
public static void main(String[] args) {
NoteIterator iterator = new NoteIterator();

iterator.visitAllUsing(new NoteHeadingPrinter());

iterator.visitAllUsing(new NoteDetailsPrinter());
}
}

08/05/2023 19
Output
Melbourne Pushes Boundaries

The Wolves in the Wall Output of NoteHeadingPrinter

Redhill Consulting Pty Ltd - Ruby on Rails Plugins

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

08/05/2023 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”

08/05/2023 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”

08/05/2023 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

08/05/2023 23
File Folder Examples
FileSystemElement
name : String Visitor

getName() visitFile(file : File)


getElement(name) visitFolder(folder : Folder)
createIterator()
accept(v : Vistor)

PrintVisitor CountFileVisitor

visitFile(file : File) visitFile(file : File)


visitFolder(folder : Folder) visitFolder(folder : Folder)
File Folder
size : int children : ArrayList

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

08/05/2023 24
Shape Example

08/05/2023 25
We are going to build a Car!
• The car is a class that comprises car elements
of 3 different types :
– Engine (name, price)
– Wheel (name, price)
– Body (name, price)
• Tasks: calculate car fabrication cost, time and
print the list of required parts
• In order to perform those tasks, we need to
implement the following operations for each one
of the parts:
– 1. Fabrication cost calculation
– 2. Fabrication time calculation
– 3. Print information about the part
08/05/2023 26
Design without the Visitor

08/05/2023 27
Shopping cart
• For example, think of a Shopping cart where we
can add different type of items (Elements as
Book (price and isbnNumbers) and Fruit (price,
weight and name). When we click on checkout
button, it calculates the total amount to be paid.
• Now we calculate the total amount to be paid
and print the list of buy elements
• In order to perform those tasks, we need to
implement the following operations for each one
of the Elements:
– 1. Fabrication cost calculation
– 2. Print information about the list of buy element
08/05/2023 29
Graph
• Cho một đồ thị vô hướng G, gồm n đỉnh,
• Để thăm tất cả các đỉnh của đồ thị ta thực hiện
theo 2 phương pháp:
– Thăm theo chiều rộng
– Thăm theo chiều sâu
• Yêu cầu: Thực hiện các thao tác in các đỉnh đã
duyệt và lưu các đỉnh đã duyệt
• Yêu cầu: áp dụng mẫu thiết kế Visitor để vẽ sơ
đồ UML giải quyết bài toán về Đồ thị.

08/05/2023 31

You might also like