panas-pattern-hatchingnullDesign PatternsDesign PatternsThomas Panas
September 20th, 2001Design PatternsDesign PatternsJava Design PatternsJava Design PatternsDesign Pattern Book (GoF) in Java
Creational Patterns
Structural Patterns
Behavioral Patterns
Design Patterns and the Java ...
nullDesign PatternsDesign PatternsThomas Panas
September 20th, 2001Design PatternsDesign PatternsJava Design PatternsJava Design PatternsDesign Pattern Book (GoF) in Java
Creational Patterns
Structural Patterns
Behavioral Patterns
Design Patterns and the Java Foundation Classes
Case StudiesJava Design PatternsJava Design PatternsCreational Patterns (6)
(The Factory Pattern)
The Factory Method
The Abstract Factory Method
The Singleton Pattern
The Builder Pattern
The Prototype PatternJava Design PatternsJava Design PatternsStructural Patterns (7)
The Adapter Pattern
The Bridge Pattern
The Composite Pattern
The Decorator Pattern
The Façade Pattern
The Flyweight Pattern
The Proxy PatternJava Design PatternsJava Design PatternsBehavioral Patterns (11)
Chain of Responsibility Pattern
The Command Pattern
The Interpreter Pattern
The Iterator Pattern
The Mediator Pattern
The Momento PatternThe Observer Pattern
The State Pattern
The Strategy Pattern
The Template Pattern
The Visitor PatternPatterns in JavaPatterns in JavaSummerized Design Pattern Catalog
21 Patterns from the GoF
20 other Patterns
Pattern Partition Structure
Fundamental Design Patterns
Creational Patterns
Partitioning Patterns
Structural PatternsBehavioral Patterns
Concurrency PatternsPatterns in JavaPatterns in JavaFundamental Design Patterns (5)
Delegation
Interface
Immutable
Marker Interface
ProxyPatterns in JavaPatterns in JavaCreational Patterns (5)
Factory Method
Abstract Factory
Builder
Prototype
Object PoolPatterns in JavaPatterns in JavaPartitioning Patterns (3)
Layered Initialization
Filter
CompositePatterns in JavaPatterns in JavaStructural Patterns (9)
Adapter
Iterator
Bridge
Façade
Flyweight
Dynamic Linkage
Virtual Proxy
Decorator
Cache ManagementPatterns in JavaPatterns in JavaBehavioral Patterns (11)
Chain of Responsibility
Command
Little Language
Mediator
Snapshot
Observer
StateNull Object
Strategy
Template Method
VisitorPatterns in JavaPatterns in JavaConcurrency Patterns (7)
Single Threaded Execution
Guarded Suspension
Balking
Scheduler
Read/Write Lock
Producer-Consumer
Two-Phase TerminationPattern HatchingPattern HatchingWritten by John Vlissides (GoF)
Tips&Tricks Book
Entwerfen mit Mustern
Themen und Variationen (Ein Singleton umbringen)
Die Gemeinschaft der Liebe (Events)
Sieben Angewohnheiten erfolgreicher MusterautorenEntwerfen mit MusternEntwerfen mit MusternMission: Creating a File-system
Arbitrary size, depth and complexity
Easy use and easy extendable
/bin/user/temp/lsdick/tom/harry/junkPattern HatchingPattern HatchingRequirements
Treat files and directories similar, when requesting their names. This makes code easier to write and maintain.
To treat files and directories similar we need to implement the same interface. We get a common (abstract) basis-class, that we call Node.
Furthermore, we know that directories contain files.Pattern HatchingPattern HatchingBasic C++/UML StructureClass Node {
protected:
Node();
Node(const Node&);
virtual Node* getChild(int n);
};Class File : public Node {
public:
File();
// Content
};Class Directory : public Node {
public:
Directory();
Node* getChild(int n);
// Content
private:
list _nodes;
};Pattern HatchingPattern HatchingSearching for a Pattern …
This pattern allows you to build complex objects by recursively composing similar objects in a treelike manner.
It also allows the objects in the tree to be manipulated in a consistent manner, by requiring all of the objects in the tree to have a common super-class or interface.
Who am I? Pattern HatchingPattern HatchingComposite PatternComponent
operation()
getChild(int)Leaf
operation()Composite
operation()
getChild(int)childrenPattern HatchingPattern HatchingWhere does the children come from?
Instead of creating files, which is done by the user, the file-system must “adopt” files to directories.
Virtual void adopt(Node *child)
Virtual void orphan(Node *child)
Where do we implement adopt and orphan? In directory or node?
Pattern HatchingPattern HatchingBasic C++/UML StructureClass Node {
protected:
Node();
Node(const Node&);
virtual Node* getChild(int n);
};Class File : public Node {
public:
File();
// Content
};Class Directory : public Node {
public:
Directory();
Node* getChild(int n);
void adopt(Node* child);
private:
list _nodes;
};Pattern HatchingPattern HatchingExample: mkdirVoid Client::mkdir (Directory* current, const string& path) {
string subpath = subpath(path);
if (subpath.empty()) {
current->adopt(new Directory(path));
} else {
string name = head(path);
Node* child = find(name, current);
if (child) {
mkdir(child, subpath);
} else {
cerr << name << “ doesn’t exit.” << endl;
}}}
Pattern HatchingPattern HatchingExample: mkdir - DowncastVoid Client::mkdir (Directory* current, const string& path) {
string subpath = subpath(path);
if (subpath.empty()) {
current->adopt(new Directory(path));
} else {
string name = head(path);
Node* node = find(name, current);
if (node) {
Directory* child = dynamic_cast(node);
if (child) {
mkdir(child, subpath);
} else {
cerr << getName() << “ is no Directory”;
}}}}
Pattern HatchingPattern HatchingBasic C++/UML StructureClass Node {
protected:
Node();
Node(const Node&);
virtual Node* getChild(int n);
virtual void adopt(Node* child);
};Class File : public Node {
public:
File();
// Content
};Class Directory : public Node {
public:
Directory();
Node* getChild(int n);
void adopt(Node *child);
private:
list _nodes;
};Pattern HatchingPattern HatchingExample: mkdirVoid Client::mkdir (Node* current, const string& path) {
string subpath = subpath(path);
if (subpath.empty()) {
current->adopt(new Directory(path));
} else {
string name = head(path);
Node* child = find(name, current);
if (child) {
mkdir(child, subpath);
} else {
cerr << name << “ doesn’t exit.” << endl;
}}}
Pattern HatchingPattern HatchingSymbolic Links
Reference to a Node in our File-System
File Link: enable to edit and save the linked file as same as a usual file
Directory Link: enable to add/delete nodes to a directory that the link shows to
Is there a pattern that helps to implement symbolic links?Pattern HatchingPattern HatchingFinding the right structual pattern…
Adapter helps to vary the interface of an object
Bridge helps to vary the implementation of an object
Composite helps to vary the structure and composite
Façade helps us to vary the interface to a subsystem
Proxy helps us to vary how to access an object and where to find it
Bingo
Control the access to an object with the help of a preliminary proxy object = Proxy PatternPattern HatchingPattern HatchingProxy PatternSubject
request()
…RealSubject
request()
…Proxy
request()
…realSubjectrealSubject->request();Pattern HatchingPattern HatchingProxy Pattern
We need to find a common structure for the proxy pattern with our composite pattern
As we recognize, our common interface that we still want to use for the file-system is Node
And because the Composite structure uses a common interface already, we can combine the Proxy “Subject” Interface into our Node InterfacePattern HatchingPattern HatchingProxy
PatternNode
getName()
streamIn(istream)
streamOut(ostream)
getChild(int)
adopt(Node)
orphan(Node)Link
streamIn(istream)
streamOut(ostream)
getSubject()File
streamIn(istream)
streamOut(ostream)Directory
streamIn(istream)
streamOut(ostream)
getChild(int)
adopt(Node)
orphan(Node)childrensubjectComposite PatternPattern HatchingPattern HatchingEnhancing the code with “cat”
We want to print out files
We do not want to change existing code
“cat” should be abstract and work for files, directories and links. But only files will be printed out, directories give an error message
To be abstract we would need to implement cat in the Node class, but this would change our existing code
One solution: extracting cat out into another classPattern HatchingPattern HatchingClient::catVoid Client::cat (Node* node) {
Link* l;
if (dynamic_cast(node)) {
node->streamOut(cout);
} else if (dynamic_cast(node)) {
cerr << “ cat do not work on Directories”;
} else if (l = dynamic_cast(node)) {
cat(l->getSubject());
}
}
- dynamic casting!Pattern HatchingPattern HatchingSearching for a Pattern…
Pattern X enables you to define a new operation in your existing classes without changing those classes.
This pattern creates an external class to act on data in other classes.
Guess again! Pattern HatchingPattern HatchingVisitor patternVisitorVisited
instancevisited.accept(this);v.visit(this);Pattern HatchingPattern HatchingVisitor PatternClass Visitor {
public:
Visitor();
void visit(File*);
void visit(Directory*);
void visit (Link*);
}; void Visitor::visit (File* f)
{f->streamOut(cout);}
void Visitor::visit (Directory* d)
{cerr << “no printout for a directory”;}
void Visitor::visit (Link* l)
{l->getSubject()->accept(*this);}Visitor cat;
node->accept(cat); void File::accept (Visitor& v) {v.visit(this);}
void Directory::accept (Visitor& v) {v.visit(this);}
void Link::accept (Visitor& v) {v.visit(this);}
Pattern HatchingPattern HatchingProxy
PatternNode
getName()
streamIn(istream)
streamOut(ostream)
getChild(int)
adopt(Node)
orphan(Node)
accept(Visitor)Link
streamIn(istream)
streamOut(ostream)
getSubject()
accept(Visitor)File
streamIn(istream)
streamOut(ostream)
accept(Visitor)
Directory
streamIn(istream)
streamOut(ostream)
getChild(int)
adopt(Node)
orphan(Node)
accept(Visitor)
childrensubjectComposite PatternVisitor PatternDesign PatternsDesign Patterns?