Csci 490 / Engr 596 Csci 490 / Engr 596 Special Topics / Special Special Topics / Special Projects Projects Software Design and Scala Software Design and Scala Programming Programming Spring Semester 2010 Spring Semester 2010 Lecture Notes Lecture Notes
51
Embed
Csci 490 / Engr 596 Special Topics / Special Projects Software Design and Scala Programming Spring Semester 2010 Lecture Notes.
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Csci 490 / Engr 596Csci 490 / Engr 596Special Topics / Special ProjectsSpecial Topics / Special Projects
Software Design and Scala ProgrammingSoftware Design and Scala Programming
Spring Semester 2010Spring Semester 2010Lecture NotesLecture Notes
Designing with PatternsDesigning with Patterns
This is a set of slides to accompany chapter 2 of This is a set of slides to accompany chapter 2 of John Vlissides’s book John Vlissides’s book
Common interface for key elementsCommon interface for key elements2
/
bin/ user/ tmp/
is tom/ harry/dick/ junk
Class Hierarchy for File Structure Class Hierarchy for File Structure class Node class Node {{ public: // declare common interface herepublic: // declare common interface here
Makeup of Common InterfaceMakeup of Common Interface
4
Operations should apply equally to Operations should apply equally to files files and and directoriesdirectories
Common interestsCommon interests name, size, protection, …
Operations that have clear meaning for both files and directories are easy to treat uniformly
Makeup of Common Interface (cont.)Makeup of Common Interface (cont.)
5
Operations that do not have clear meaning for both files and directories are difficult to treat uniformlyExampleExample
virtual Node* getChild (int n); Return the nth child Return value Node *
define getChild in both Directory class and Node classcall getChild without casting
Let us define Directory operations recursivelylong Directory :: size(){ long total = 0;
Node * child;for (int I = 0; child = getChild(i); ++i){ total += child -> size(); }return total;
}
Composite PatternComposite Pattern
6
Compose objects into tree structure to represent Compose objects into tree structure to represent part-whole hierarchiespart-whole hierarchiesGive clients uniform way to deal with these objects Give clients uniform way to deal with these objects whether internal nodes or leaveswhether internal nodes or leaves
Component
operation() getChild(int)
Leaf
operation()
Composite
operation() getChild(int)
In File structure
Component – Node Leaf– File Composite – Directory
Composite Pattern (cont.)Composite Pattern (cont.)Use Use CompositeComposite when whenRepresent part-whole hierarchies of objectsRepresent part-whole hierarchies of objectsIgnore difference between compositions of objects Ignore difference between compositions of objects
and individual objectsand individual objectsclients treat all objects uniformlyclients treat all objects uniformly
ConsequencesConsequencesPositivePositive
Supports tree structures of arbitrary complexitySupports tree structures of arbitrary complexity
NegativeNegativeLeads to system in which classes of all objects look like each other
7
Design Status CheckDesign Status Check
8
Used Composite pattern to generate Used Composite pattern to generate backbone of application backbone of application
Treated files and directories uniformlyTreated files and directories uniformly
Now look at where children come fromNow look at where children come from
AdoptionAdoption
Node created independently from directory
Directory adopts child nodevirtual void adopt (Node * child);Child’s responsibility is handed over to directory
when directory gets deleted, so does child
9
Node
operation() getChild(int)
File
operation()
Directory
operation() getChild(int)
Aggregation
OrphansOrphans
Directory no longer child’s parent
virtual void orphan (Node * child);
10
NonuniformityNonuniformity
Consider command mkdir to create subdiecrtorymkdir newsubdir
mkdir subdirA/subdirB/newsubdir
Examine consequences of not treating files and directories uniformly
11
Nonuniformity (cont.)Nonuniformity (cont.)What happens without uniformity?
2. Scan Intent sections for something that sounds right
3. Study how patterns interrelate
4. Look at patterns whose purpose corresponds to what to do
5. Examine a relevant cause of redesign, apply patterns that help to avoid it
6. Consider what should be variable in design15
Choose Pattern for Symbolic LinksChoose Pattern for Symbolic LinksApply approach No. 6
16
AdapterAdapter Vary interface to objectVary interface to object
BridgeBridge Vary implementation of objectVary implementation of object
CompositeComposite Vary object’s structure and compositionVary object’s structure and composition
DecoratorDecorator Vary responsibilities without subclassingVary responsibilities without subclassing
FacadeFacade Vary interface to subsystemVary interface to subsystem
FlyweightFlyweight Vary storage costs of objectsVary storage costs of objects
ProxyProxy Vary how object is accessed and/or its Vary how object is accessed and/or its locationlocation
Proxy PatternProxy Pattern
17
Subject
request() …
RealSubject
request()
Proxy
request() …
realSubject… realSubject -> request(); …
Apply Proxy PatternApply Proxy Pattern
class Link : public Node
{ public :
Link (Node *);
// redeclare common Node interface here
private:
Node * _subject;
}
18
Node
…
RealSubject
…
Link
…
realSubject… realSubject -> request(); …
// Link implements Node interface
Node * Link :: getChild (int n)
{
return _subject-> getChild(n);
} RealSubject
Design Status CheckDesign Status Check
19
Applied Composite pattern structure the file Applied Composite pattern structure the file system system
Applied Proxy pattern to support symbolic Applied Proxy pattern to support symbolic linkslinks
Class Class NodeNode is intersection of the two patterns is intersection of the two patternsComponent in CompositeComponent in CompositeSubject in ProxySubject in Proxy
Visitor PatternVisitor PatternConsider operations that work differently on Consider operations that work differently on different kinds of nodesdifferent kinds of nodes UnixUnix cat cat commandcommand
solution1: change existing classessolution1: change existing classessolution2: use downcastssolution2: use downcasts
void Client :: cat (Node * node)void Client :: cat (Node * node){{ Link *l; Link *l;
else if (else if (dynamic_castdynamic_cast <Directory*> (node)) <Directory*> (node))cerr << “can’t cat a directory.” cerr << “can’t cat a directory.”
<<endl<<endlelse if (l = else if (l = dynamic_castdynamic_cast <Link *> (node)) <Link *> (node))
cat(l -> getSubject());cat(l -> getSubject());}} How to avoid How to avoid downcastsdowncasts?? 21
Visitor Pattern (cont.)Visitor Pattern (cont.)
Represent operation to be performed on Represent operation to be performed on elements of object structureelements of object structure
Define new operation without changing Define new operation without changing classes of elements on which it operatesclasses of elements on which it operatesExampleExample
Compiler supports open-ended set of analyses without Compiler supports open-ended set of analyses without changing classes that implements abstract syntax treechanging classes that implements abstract syntax tree
22
Visitor Pattern (cont.)Visitor Pattern (cont.)
23
client
Visitor
visitConcreteElemA(concrElemA a) visitConcreteElemB(concrElemB b)
Concrete Visitor1
visitConcreteElemA(concrElemA a) visitConcreteElemB(concrElemB b)
Concrete Visitor2
visitConcreteElemA(concrElemA a) visitConcreteElemB(concrElemB b)
When default behavior common to two or more types, put common functionality into visitNode operation for default callvoid Visitor :: visitNode (Node * n)
{ // common default behavior }
void Visitor :: visitFile (File * f)
{ Visitor :: visitNode (f); }
void Visitor :: visitDirectory (Directory * d)
{ Visitor :: visitNode (d); }
void Visitor :: visitLink (Link * l)
{ Visitor :: visitNode (l); }
Visitor CaveatsVisitor Caveats
31
Is class hierarchy stable? Adding a new kind of Node may cause all classes in
Visitor hierarchy to change
Visitor creates a circular dependency between Visitor and Node class hierarchies Change to either base class interface is likely to prompt
recompilation of both hierarchies class NewVisitor : public Visitor{ public:
using Visitor :: visit;virtual void visit (Node *);
};
Design Status CheckDesign Status Check
32
Applied Composite and Proxy patterns to define file system
Applied Visitor pattern to allow introduction of new capabilities noninvasively By adding instead of changing code
Now look at how to address security issues
Single-User ProtectionSingle-User Protection
33
Protect file system objects from accidental change or deletion A node be readable or unreadable, writable or unwritable
This work was supported by a grant from This work was supported by a grant from Acxiom Corporation titled “The Acxiom Acxiom Corporation titled “The Acxiom Laboratory for Software Architecture and Laboratory for Software Architecture and Component Engineering (ALSACE).”Component Engineering (ALSACE).”