Jason Smith The Software Revolution, Inc. based on UNC PhD work, and “Elemental Design...
-
Upload
khalid-norsworthy -
Category
Documents
-
view
212 -
download
0
Transcript of Jason Smith The Software Revolution, Inc. based on UNC PhD work, and “Elemental Design...
Elemental Design Patterns
Jason SmithThe Software Revolution, Inc.
based on UNC PhD work, and “Elemental Design Patterns”, Addison-Wesley, 2012
Decorator (GOF)
Used to extend behavior dynamically, at run time
Like an internal plug-in system as found in a web browser
Alternative to using inheritance to provide all possible combinations of behaviors
Decorator informally
Decompose DecoratorObjectifier
Zimmer, 1995
Allows a single object interface to represent multiple concrete implementations
Client requests a method to be invoked via the objectifier interface
Client cannot know which of the concrete method bodies will execute and provide the service
Objectifier
Decompose DecoratorObject Recursion
Woolf, 1998
Chains two objects with related types
Object recursion uses Objectifier as the backbone of its form…
Adds a link between one of the concrete implementations and the interface
Uses the link to invoke the same method --to “recurse” in a sense, but on a different (related) object
Object Recursion
So Decorator can be described in
terms of composing smaller pieces
Are these pieces as small as they can
be?
Perhaps there is more “downward” to
go
Where is the bottom of this abstraction
pile?
Turtles all the way down
Turtles all the way down
So Decorator can be described in
terms of composing smaller pieces
Are these pieces as small as they can
be?
Perhaps there is more “downward” to
go
Where is the bottom of this abstraction
pile?
Turtles all the way down
So Decorator can be described in
terms of composing smaller pieces
Are these pieces as small as they can
be?
Perhaps there is more “downward” to
go
Where is the bottom of this abstraction
pile?
EDP
Turtles all the way down
So Decorator can be described in
terms of composing smaller pieces
Are these pieces as small as they can
be?
Perhaps there is more “downward” to
go
Where is the bottom of this abstraction
pile?
EDP
Elemental design patterns
decorator
object recursio
n
objectifier
Pattern Descriptions
Solution
• structure• implementation• sample code
Problem
• intent• motivation• known uses
Context
• applicability• consequences• related patterns
Hard to fit: participants, collaborations
Design Pattern A common solution to a common problem within a particular context
Participants, Collaborations are parts and relationships
Relationships form the core of design
Design of a car is more than a piles of pieces… engine, tires, transmission, seats
Design shows how the parts relate… connect, interact, work of one affects function of another
Parts list gives components
Relationships tell how parts function in concert to win over the entropy of the pile
Relationships
What is smallest relationship we can define?
A single concept connection between two things
Look for such among the entities in OO programming
Means we have to decide…
what are the conceptual entities in OO programs?
Relationships
Goal: detect elemental relationships automatically, if we can
Goal: compose elemental patterns to get higher patterns (automatically, if we can)
Higher pattern means more complex, harder to find patterns
Pause… for directions
Different relationships, different purposes
Scoping relationships give context
Scope is how an element is made unique among all other elements in the system
class Menu in package GUI_Elements is not the same thing as
class Menu in package Restaurant_Items
Scope: an enclosing something that has a name, in which you define something new
Contextual Relationships
Class: scope for methods and fields it defines
Package/namespace: scope for all in it
Method/function: scope for local variables
Access an element: specify the scopes from outer level in
◦ Implicit notation: No scope for locals in a method, or another method in same class
◦ Differing notation:
GUI_Element::Menu vs. aMenu.anItem
Context: Scope
We now have scope relationships… what else can we form relationships between?
Classes, their fields and methods…. not much else
What about objects? Different from classes?
Classes do two things
◦ Type information… member methods and fields that will exists separately in each object created
◦ Global shared fields… “static” class methods and fields
Class is really a type with an object (for global)
Relationships… what else?
Fields, Methods, Objects, Types OO entities we characterize relationships among
FMOT
Object Method Field Type
Object Defines Defines Defines Defines or Is of type
Method N/A Defines orMethod call
Defines orField use
Defines orReturns of type
Field N/A State change
Cohesion Is of type
Type Defines Defines Defines Defines orsubtyping
Fields, Methods, Objects, Types Defines is a scope relationship
FMOT
Object Method Field Type
Object Defines Defines Defines Defines or Is of type
Method N/A Defines orMethod call
Defines orField use
Defines orReturns of type
Field N/A State change
Cohesion Is of type
Type Defines Defines Defines Defines orsubtyping
OO Entity InteractionsFMOT Non-scoping
Object Method Field Type
ObjectIs of type
MethodMethod call Field use Returns of
type
Field State change
Cohesion Is of type
Typesubtyping
Terminologymethod call
o . f( ) calls p . g( )enclosingobject
enclosingobject
Callingmethod
Calledmethod
EDP Basicsin UML
A B
b: B
f()
g()h()
b.g()
class A { B b; f ( ) { b.g(); }}class B { g ( ) { } h ( ) { }}main ( ) { A a; a.f();}
EDP Basicsin Code
More EDPsDeputized Redirection
More EDPsRecursion
First Four EDPs
dissimilar
Conglomeration
Recursion
Delegation
Redirection
similar
dissimilar
similar
methodsimilarity
object similarit
y
s-calculus ◦ Abadi and Cardelli, “A Theory of Objects”, 1998◦ Computation model for OO programs◦ Object form of l-calculus
r-calculus◦ Modification and extension for patterns◦ Operators for reliances◦ J. Smith, 2004
Theoretical Foundations
Another Example
Focus on OO programming concepts, not OO language constructs
a.f() calls b.g(), then b.g() calls c.h() We can see that a.f() does not call c.h() (a
structural relationship)
However a.f() relies on c.h() to execute correctly in order for f to complete its work
So there is a reliance between a.f() and c.h() (conceptual, not structural)
Reliances
Zimmer, W. Relationships between design patterns. In J.O. Coplien and D.C. Schmidt, eds., Pattern Languages of Program Design. Addison-Wesley, Voston, 1995, pp. 345-364.
Woolf, B. The object recursion pattern. In N. Harrison, B. Foote, and H. Rohnert, eds., Pattern Languages of Program Design 4. Addison-Wesley, Boston, 1998, pp. 41-52.
References
Decorator (GOF)
Decorator in PIN
Abstract Factory
Factory Method
Decorator
Proxy
Chain of Responsibility
Template Method
Create Object
Retrieve
Inheritance
Abstract Interface
Delegation
Redirection
Conglomeration
Recursion
Revert Method
Extend Method
Delegated Conglomeration
Redirected Recursion
Trusted Delegation
Trusted Redirection
Deputized Delegation
Deputized Redirection
Fulfill Method
Retrieve New
Retrieve Shared
Objectifier
Object Recursion
Similarity Space A1
Similarity Space A2
Standard PINbox
Expanded PIN Instance
SPQR Flow
Analysis of Design Pattern Structure in OO Source
Code
Jason SmithIBM Watson Research
Our Goals
• Provide tools to software engineers to aid in the efficient comprehension of existing code bases (maintenance, new design with re-use)
• Provide support for development of new code that adheres to best-practices architecture
• Create metrics to compare relative comprehensibility and relative quality of system designs for analysis prior to implementation
• Why find patterns?
Design Patterns
• Abstractions of lessons learned
• GoF 1995
• Culling code down to the language-independent ideas, not implementation specifics …
• Community agreement on what gains “pattern” status
• Common vocabulary for software engineers to discuss and compare design issues, best practices, architecture and organization
“Common (agreed good) solutions to common problems”
Atop the Abstraction Stack
• Assembly mnemonics
• Procedural programming -- locality of code
• Object-oriented programming -- encapsulation of data with code
• Idioms
best language practices
• Design patterns
best design practices, language independent
Example Pattern“Composite”
Example Pattern“Composite”
In reality, they look like this …
// Composite pattern -- Structural example using System;using System.Text;using System.Collections;
// "Component"abstract class Component{ // Fields protected string name; // Constructors public Component( string name ) { this.name = name; } // Methods abstract public void Add(Component c); abstract public void Remove( Component c ); abstract public void Display( int depth );}
// "Composite"Class Composite : Component{ // Fields private ArrayList children = new ArrayList(); // Constructors public Composite( string name ) : base( name ) {} // Methods public override void Add( Component component ) { children.Add( component ); } public override void Remove( Component component ) { children.Remove( component );} public override void Display( int depth ) { Console.WriteLine( new String( '-', depth ) + name ); // Display each of the node's children foreach( Component component in children ) component.Display( depth + 2 ); }}
// "Leaf"class Leaf : Component{ // Constructors public Leaf( string name ) : base( name ) {} // Methods public override void Add( Component c ) { Console.WriteLine("Cannot add to a leaf"); }
public override void Remove( Component c ) { Console.WriteLine("Cannot remove from a leaf"); }
public override void Display( int depth ) { Console.WriteLine( new String( '-', depth ) + name ); }}
public class Client{ public static void Main( string[] args ) { // Create a tree structure Composite root = new Composite( "root" ); root.Add( new Leaf( "Leaf A" )); root.Add( new Leaf( "Leaf B" )); Composite comp = new Composite( "Composite X" );
comp.Add( new Leaf( "Leaf XA" ) ); comp.Add( new Leaf( "Leaf XB" ) ); root.Add( comp );
root.Add( new Leaf( "Leaf C" ));
// Add and remove a leaf Leaf l = new Leaf( "Leaf D" ); root.Add( l ); root.Remove( l );
// Recursively display nodes root.Display( 1 ); }}
// Purpose. Composite // Strategy. Use recursive composition // to create a heterogeneous aggregate#include <string.h> // that can be treated homogeneously.enum NodeType { FileT, DirT }; //int g_indent = 0; // Benefit. No more type checking and // type casting (coupling between Dirclass File { // and File is gone, Dir is onlypublic: // coupled to abstract base class) File( char* n ) { type_ = FileT; strcpy( name_, n ); } class AbsFile { NodeType getType() { return type_; } public: void ls() { virtual void ls() = 0; for (int i=0; i < g_indent; i++) protected: cout << ' '; char name_[20]; cout << name_ << endl; } static int indent_;private: }; NodeType type_; int AbsFile::indent_ = 0; char name_[20];}; class File: public AbsFile { public:class Dir { File( char* n ) {public: strcpy( name_, n ); } Dir( char* n ) { type_ = DirT; void ls() { strcpy( name_, n ); total_ = 0; } for (int i=0; i < indent_; i++) NodeType getType() { return type_; } cout << ' '; void add( File* f ) { cout << name_ << endl; } files_[total_++] = f; }; } void ls() { class Dir : public AbsFile { for (int i=0; i < g_indent; i++) public: cout << ' '; Dir( char* n ) { cout << name_ << ":" << endl; strcpy( name_, n ); total_ = 0; } g_indent += 3; void add( AbsFile* f ) { for (int i=0; i < total_; i++) files_[total_++] = f; } if (files_[i]->getType() void ls() { == DirT) for (int i=0; i < indent_; i++) ((Dir*) files_[i])->ls(); cout << ' '; else cout << name_ << ":" << endl; files_[i]->ls(); indent_ += 3; g_indent -= 3; } for (int i=0; i < total_; i++)private: files_[i]->ls(); NodeType type_; indent_ -= 3; } char name_[20]; private: File* files_[10]; AbsFile* files_[10]; int total_; int total_;}; };
void main( void ) void main( void ){ { Dir one("1"), two("2"), thr("3"); Dir one("1"), two("2"), thr("3"); File a("a"), b("b"), c("c"), File a("a"), b("b"), c("c"), d("d"), e("e"); d("d"), e("e"); one.add( &a ); one.add( &a ); one.add( (File*) &two ); one.add( &two ); one.add( &b ); one.add( &b ); two.add( &c ); two.add( &c ); two.add( &d ); two.add( &d ); two.add( (File*) &thr ); two.add( &thr ); thr.add( &e ); thr.add( &e ); one.ls(); one.ls();} }
Or this…
Or this…
(defgeneric add-dependent (dm dependent &optional recursivep) ;; see below for the optional args (:documentation "Add DEPENDENT as a dependent of DM. Return DM"))
(defgeneric delete-dependent (dm dependent &optional recursivep) (:documentation "Remove DEPENDENT from DM. Return DM"))
;;; No DELETE-DEPENDENT-IF
(defgeneric map-dependents (f dm) (:documentation "Map F over the dependents of DM. Return DM"))
;;; No cursors.
(defgeneric make-collection-for-dependent-mixin (dm))
(defclass dependent-mixin () ;; something that has dependents. We expose the DEPENDENTS slot. ((dependents :reader dependents-of)))
(defmethod make-collection-for-dependent-mixin ((dm dependent-mixin)) (make-instance 'simple-childed-mixin))
(defmethod initialize-instance :after ((dm dependent-mixin) &key) (setf (slot-value dm 'dependents)
(make-collection-for-dependent-mixin dm)))
(defmethod add-dependent ((dm dependent-mixin) dependee &optional recursivep)
(declare (ignorable recursivep)) (add-child (dependents-of dm) dependee) dm)
(defmethod delete-dependent ((dm dependent-mixin) dependee &optional recursivep)
(declare (ignorable recursivep)) (delete-child (dependents-of dm) dependee) dm)
(defmethod map-dependents (f (dm dependent-mixin)) (map-over f (dependents-of dm)) dm)
A solution must be language independent
Patterns “Intertwingled”
All non-trivial designs involve many cross-mixed patterns
Same class might be a component in 4 or 5 patterns
Prior Approaches
• GoF patterns are too large to formalize flexibly
• “Mini-patterns” have been tried but still at too large a graularity
• Cannot handle implementation variances, due to static definitions of patterns… no inference capabilities
Elemental Design Patterns
• GoF patterns are too large to formalize flexibly
• Divide and conquer… define “bricks” and “wall construction procedures”
• Call them Elemental Design Patterns ( EDP )
• Idea is for EDPs to be easy to find in code
• Use resolution theorem prover to do the “wall assembly”
• Add to the assembly methods rules that allow flexible variations on basic definitions
Mini-Pattern: Objectifier
Mini-Pattern: Object Recursion
Relationships
Relationships are the key
Method calls: relationships between functions
Field access: relationships between objects
Inheritance: relationships between types
Objects, Types, Methods, Fields…
What else is there in OO? That’s it…
SPQR System
Source code
gcc parse treegcc
object XML
gcc2poml
poml2otter
Source-code-specific otter clauses
Rho calculus compos rules EDP catalog
Otter theorem prover
Found patterns report
python
Otter proofs
EDP Catalog
Object element EDPsCreateObj AbsInterface Retrieve
Type Relation EDPsInheritance
Method Invocation EDPsRecursion RedirectedRecursion Redirect RedirectInFamily RedirectInLimitedFamilyDelegate DelegateInFamily DelegateInLimitedFamilyConglomeration DelegatedConglomerationExtendMethod RevertMethod
Redirect In Family
Composing EDPs
• Successful in composing the EDPs to define 22 of the 23 GoF patterns
• Can produce many other described patterns as well from the literature
and mini’s… Objectifier, ObjRecursion
• 23rd GoF pattern is Iterator …Really a language construct, not a pattern
Is an operation for a data type
Formalization
• Begin with s-calculus ( OO analog to l-calculus )
• Add ability to encode relationships between constructs with reliance operators … gives r-calculus
Describe relationships between objects, methods, and fieldsTransitive
A<<B, B<<C : A<<C
• Define EDPs directly in r-calculus
• Express more complex patterns as compositions and assemblies of EDPs
• Encode it all as Otter clauses
SPQR System
Source code
gcc parse treegcc
object XML
gcc2oml
oml2otter
Source-code-specific otter clauses
Rho calculus compos rules EDP catalog
Otter theorem prover
Found patterns report
python
Otter proofs
“Isotopes”
• Flexibility requires capturing variations on a basic pattern
• Static definition/specification cannot capture the many different detailed forms code may take and still be judged a “pattern instance”
• Implementation may differ, clutter may be more or less, extra objects may be imposed, but
the base roles appear,
their relationships stay the same
Redirect In Family
Redirect In Family Isotope
Evaluation
• Code trials
• Problem from Evans and Sutherland
• C++ standard library analysis for EDPs
• Working code from previous projects (OvalTine)
E&S Industrial Code
Rho Calculus Definitions
Found Patterns
Object Recursion - Annotated
Decorator Pattern
Decorator - Annotated
SPQR Tool Sequence
Extension via Training
• Hundreds of patterns are named and in use
• How do we get these into the formal dictionary? Must a programmer be a r-calculus expert?
• New patterns can be added via “training”
• Write a canonical program that contains the necessary and sufficient code components comprising the pattern ( and little else )
SPQR tools will extract the facts into r-calculusHand tune the definition and test
Other forms of Variance
• Vary by type… inheritance
• Get the photo of whiteboard
• MDL explains patterns existence
Are Patterns Arbitrary?
• Why are patterns the way they are?
• MDL explains it… GoF are minimal in several measures that make sense for software complexity
• Software Architecture
Advantages of SPQR
• Near zero learning curve
• Adding to existing tool chain, not replacing it
• Not adding to workload of engineer
• Analogous to a spelling checker or execution profiler
• Theorem prover + r-calculus + transitivity (isotopes) gives searching over infinite design space using finite number
of definitions• New way to teach OO concepts and design
Design Space 2.6
Design Space 2.7
Design Space 2.8
Design Space 3D
2D Projection of 3D SpaceMethod similarity fixed at
“similar”
2D Projection of 3D SpaceMethod similarity fixed at
“dissimilar”
Recursion
Deputized Recursion
DecoratorUML collaboration diagram
Strategyrole-annotated class diagram
Big Class Diagram
Decorator towards PIN
Decoratortowards PIN
Fulfill Method
Fulfill Method
Decorator (reprise)
Decorator base
Up a level…
4.13.a
4.13.b
4.14
4.15
4.16
4.17
4.18
4.19
4.20
4.21
4.22
4.23
Pattern