Presentation is loading. Please wait.

Presentation is loading. Please wait.

Jason Smith The Software Revolution, Inc. based on UNC PhD work, and “Elemental Design Patterns”, Addison-Wesley, 2012.

Similar presentations


Presentation on theme: "Jason Smith The Software Revolution, Inc. based on UNC PhD work, and “Elemental Design Patterns”, Addison-Wesley, 2012."— Presentation transcript:

1 Jason Smith The Software Revolution, Inc. based on UNC PhD work, and “Elemental Design Patterns”, Addison-Wesley, 2012

2

3  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

4 Zimmer, 1995

5  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

6 Woolf, 1998

7  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

8  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?

9  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?

10  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

11  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 decorato r object recursion objectifier

12 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

13  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

14  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?

15  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

16  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

17  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

18  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)

19 Fields, Methods, Objects, Types OO entities we characterize relationships among ObjectMethodFieldType ObjectDefines Defines or Is of type MethodN/ADefines or Method call Defines or Field use Defines or Returns of type FieldN/AState change CohesionIs of type TypeDefines Defines or subtyping

20 Fields, Methods, Objects, Types Defines is a scope relationship ObjectMethodFieldType ObjectDefines Defines or Is of type MethodN/ADefines or Method call Defines or Field use Defines or Returns of type FieldN/AState change CohesionIs of type TypeDefines Defines or subtyping

21 ObjectMethodFieldType Object Is of type Method Method callField useReturns of type FieldState change CohesionIs of type Type subtyping

22 o. f( ) calls p. g( ) enclosing object enclosing object Calling method Called method

23 A B b: B f() g() h() b.g()

24 class A { B b; f ( ) { b.g(); } } class B { g ( ) { } h ( ) { } } main ( ) { A a; a.f(); }

25

26

27 dissimilar Conglomeration Recursion Delegation Redirection similar dissimilar similar method similarity object similarity

28   -calculus ◦ Abadi and Cardelli, “A Theory of Objects”, 1998 ◦ Computation model for OO programs ◦ Object form of -calculus   -calculus ◦ Modification and extension for patterns ◦ Operators for reliances ◦ J. Smith, 2004

29

30  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)

31  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.

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72 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?

73 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”

74 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

75 “Composite”

76

77 // 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 ); } }

78 // Purpose. Composite // Strategy. Use recursive composition // to create a heterogeneous aggregate #include // that can be treated homogeneously. enum NodeType { FileT, DirT }; // int g_indent = 0; // Benefit. No more type checking and // type casting (coupling between Dir class File { // and File is gone, Dir is only public: // 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 ) { 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(); }

79 (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

80 All non-trivial designs involve many cross-mixed patterns Same class might be a component in 4 or 5 patterns

81 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

82 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

83

84

85 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…

86 Source code gcc parse tree gcc object XML gcc2poml poml2otter Source-code- specific otter clauses Rho calculus compos rules EDP catalog Otter theorem prover Found patterns report python Otter proofs

87 Object element EDPs CreateObj AbsInterface Retrieve Type Relation EDPs Inheritance Method Invocation EDPs Recursion RedirectedRecursion Redirect RedirectInFamily RedirectInLimitedFamily Delegate DelegateInFamily DelegateInLimitedFamily Conglomeration DelegatedConglomeration ExtendMethod RevertMethod

88

89 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 23 rd GoF pattern is Iterator … Really a language construct, not a pattern Is an operation for a data type

90 Begin with  -calculus ( OO analog to -calculus ) Add ability to encode relationships between constructs with reliance operators … gives  -calculus Describe relationships between objects, methods, and fields Transitive A< { "@context": "http://schema.org", "@type": "ImageObject", "contentUrl": "http://images.slideplayer.com/8/2319125/slides/slide_90.jpg", "name": "Begin with  -calculus ( OO analog to -calculus ) Add ability to encode relationships between constructs with reliance operators … gives  -calculus Describe relationships between objects, methods, and fields Transitive A<

91 Source code gcc parse tree gcc object XML gcc2oml oml2otter Source-code- specific otter clauses Rho calculus compos rules EDP catalog Otter theorem prover Found patterns report python Otter proofs

92 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

93

94

95 Code trials Problem from Evans and Sutherland C++ standard library analysis for EDPs Working code from previous projects (OvalTine)

96

97

98

99

100

101

102

103 Hundreds of patterns are named and in use How do we get these into the formal dictionary? Must a programmer be a  -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 )

104 SPQR tools will extract the facts into  -calculus Hand tune the definition and test

105 Vary by type… inheritance Get the photo of whiteboard MDL explains patterns existence

106 Why are patterns the way they are? MDL explains it… GoF are minimal in several measures that make sense for software complexity Software Architecture

107 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 +  -calculus + transitivity (isotopes) gives searching over infinite design space using finite number of definitions New way to teach OO concepts and design

108

109

110

111

112

113 Method similarity fixed at “similar”

114 Method similarity fixed at “dissimilar”

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139


Download ppt "Jason Smith The Software Revolution, Inc. based on UNC PhD work, and “Elemental Design Patterns”, Addison-Wesley, 2012."

Similar presentations


Ads by Google