CSE3009: (Software Architecture and Design) Yann-Gal - - PowerPoint PPT Presentation

cse3009
SMART_READER_LITE
LIVE PREVIEW

CSE3009: (Software Architecture and Design) Yann-Gal - - PowerPoint PPT Presentation

CSE3009: (Software Architecture and Design) Yann-Gal Guhneuc Patterns in Practice This work is licensed under a Creative Commons Attribution-NonCommercial- ShareAlike 3.0 Unported License Patterns


slide-1
SLIDE 1

Yann-Gaël Guéhéneuc

This work is licensed under a Creative Commons Attribution-NonCommercial- ShareAlike 3.0 Unported License

CSE3009: 소프트웨어 구조및설계

(Software Architecture and Design)

Patterns in Practice

slide-2
SLIDE 2

2/162

Patterns

 Patterns document reusable solutions to

recurring problems

– Architecture

  • Architectural styles

– Design

  • Design patterns
  • Design anti-patterns

– Implementation

  • Idioms
slide-3
SLIDE 3

3/162

Examples

 Do you know

– C++? – Java? – Lisp? – Prolog? – Smalltalk?

slide-4
SLIDE 4

4/162

C++

class Dog { string name; Dog(const Dog* dog) : name(dogname) {}} class Kennel { Dog* dog; string name; } if (&kennel != this) { thisdog = new Dog(kennel.dog); thisname = kennel.name; } return *this;

Bruce Eckel ; Thinking in C++ ; Volume 2, pages 551–553, Planet PDF, 2nd Edition, 2000.

?

Overriding of

  • perator =
slide-5
SLIDE 5

5/162

Java

final Object oldListOfEntities = this.listOfEntities(); this.fireVetoableChange( "RemoveEntity",

  • ldListOfEntities,

anEntity); this.removeEntity(anEntity); this.firePropertyChange( "RemoveEntity",

  • ldListOfEntities,

anEntity);

?

Veto protocol

  • f JavaBeans
slide-6
SLIDE 6

6/162

(define (square ls) (if (null? ls) '() (cons ((lambda(x) (* x x)) (car ls)) (square (cdr ls)))))

Lisp

?

Map

slide-7
SLIDE 7

7/162

Prolog

checkLt0(LA, LT, LD, NNLA, NNLT, NNLD) :- nextEvent( [], E), interpretEvent(E, IE), checkLt1(IE, LA, LT, LD, NLA, NLT, NLD), !, ( (IE = programEnd, NNLA = NLA, NNLT = NLT, NNLD = NLD) ; checkLt0(NLA, NLT, NLD, NNLA, NNLT, NNLD) ).

?

Conditional

slide-8
SLIDE 8

8/162

Smalltalk

Integer>>+ aNumber ^aNumber addInteger: self Float>>+ aNumber ^aNumber addFloat: self Integer>>addInteger: anInteger <primitive: 1> Float>>addFloat: aFloat <primitive: 2> Integer>>addFloat: aFloat ^self asFloat addFloat: aFloat Float>>addInteger: anInteger ^self addFloat: anInteger asFloat

Kent Beck ; Smalltalk – Best practice patterns ; Pages 55–57, Prentice Hall, 1997, ISBN 0-13-476904-X.

?

Double dispatch

slide-9
SLIDE 9

9/162

Conclusion on the Examples

 The examples showed idioms in the given

pieces of source code

– These idioms are recurring motifs in a program source code – These motifs connote a recognized, acknowledge style of programming

slide-10
SLIDE 10

10/162

Outline

 Definition  Quality  Form  Example  Catalogue  Practice  Conclusion

slide-11
SLIDE 11

11/162

Outline

 Definition  Quality  Form  Example  Catalogue  Practice  Conclusion

slide-12
SLIDE 12

12/162

Definition

 Context

– 1977 et 1979: architecture

  • Christopher Alexander
  • A Pattern Language: Towns, Buildings,

Construction and the idea of generative patterns

  • The Timeless Way of Building and the idea of

perfection in architecture

– 1990: object-oriented design

  • Erich Gamma, Richard Helm, Ralph Johnson,

and John Vlissides†

  • Design Patterns drawn from experience
slide-13
SLIDE 13

13/162

Definition

 A Pattern Language:

Towns, Buildings, Construction

– 253 patterns – Generative grammar – “At the core... is the idea that people should design for themselves their own houses, streets and communities. This idea... comes simply from the observation that most of the wonderful places of the world were not made by architects but by the people.”

slide-14
SLIDE 14

14/162

Definition

“Each pattern describes a problem which occurs over and

  • ver again in our environment, and then describes the core
  • f the solution to that problem, in such way that you can

use this solution a million times over, without ever doing it the same way twice.”

—Christopher Alexander, 1977

“Each pattern is a three part rule, which express a relation between a context, a problem, and a solution.”

—Christopher Alexander, 1977

slide-15
SLIDE 15

15/162

盈進学園 東野高等学校 http://eishin.ac/

slide-16
SLIDE 16

16/162

Definition

 Design Patterns:

Elements of Reusable OO Software

– 23 patterns – Not a language? – “Dynamic, highly parameterized software is harder to understand and build than more static software.”

slide-17
SLIDE 17

17/162

Definition

“The strict modeling of the real world leads to reflect today’s realities but not necessarily tomorrow’s. The abstractions that emerge during design are key to making a design flexible.” —Erich Gamma, 1994

slide-18
SLIDE 18

18/162

JHotDraw

http://www.jhotdraw.org/ http://www.javaworld.com/article/2074997/swing-gui-programming/ become-a-programming-picasso-with-jhotdraw.html

slide-19
SLIDE 19

19/162

Definition

 A pattern is a general reusable solution to a

commonly occurring problem within a given context in software development, operation, and maintenance

slide-20
SLIDE 20

20/162

Definition

 A pattern is a general reusable solution to a

commonly occurring problem within a given context in software development,

  • peration, and maintenance

– Patterns have been identified for

  • Different phases of software development
  • Different levels of abstraction
  • Different technologies
slide-21
SLIDE 21

21/162

Definition

 A pattern is a general reusable solution to a

commonly occurring problem within a given context in software development,

  • peration, and maintenance
slide-22
SLIDE 22

22/162

Definition

 A pattern is a general reusable solution to a

commonly occurring problem within a given context in software development,

  • peration, and maintenance

– Problem faced by three people at three different times in a similar context – Particular problems are not included, except if they occur more than three times…

slide-23
SLIDE 23

23/162

Definition

 A pattern is a general reusable solution to a

commonly occurring problem within a given context in software development, operation, and maintenance

slide-24
SLIDE 24

24/162

Definition

 A pattern is a general reusable solution to a

commonly occurring problem within a given context in software development, operation, and maintenance

– Essentially, a solution must describe steps to solve the problem

  • Architecture
  • Design
  • Implementation
slide-25
SLIDE 25

25/162

Definition

 A pattern is a general reusable solution to a

commonly occurring problem within a given context in software development, operation, and maintenance

slide-26
SLIDE 26

26/162

Definition

 A pattern is a general reusable solution to a

commonly occurring problem within a given context in software development, operation, and maintenance

– The solution must not be particular – The solution can be adapted – The solution must be adapted

slide-27
SLIDE 27

27/162

Definition

 A pattern is a general reusable solution to a

commonly occurring problem within a given context in software development, operation, and maintenance

– The solution must not be particular – The solution can be adapted – The solution must be adapted

  • Forces
  • Variants
slide-28
SLIDE 28

28/162

Recall the C++ Example

class Dog { string name; Dog(const Dog* dog) : name(dogname) {}} class Kennel { Dog* dog; string name; } if (&kennel != this) { thisdog = new Dog(kennel.dog); thisname = kennel.name; } return *this;

Bruce Eckel ; Thinking in C++ ; Volume 2, pages 551–553, Planet PDF, 2nd Edition, 2000.

Development, operation, and maintenance Commonly occurring problem within a given context General reusable solution

slide-29
SLIDE 29

29/162

Outline

 Definition  Quality  Form  Example  Catalogue  Practice  Conclusion

slide-30
SLIDE 30

30/162

Quality

 A means to enhance the reusability

– Of the code written using the pattern + Its flexibility – Of the problem and its solution

 A means to encapsulate design experience  A common vocabulary among designers  A means to have that

“quality without a name”

slide-31
SLIDE 31

31/162

Quality Without a Name

“There is a point you reach in tightening a nut, where you know that to tighten just a little more might strip the thread, but to leave it slightly looser would risk having the hut coming off from vibration. If you've worked with your hands a lot, you know what this means, but the advice itself is meaningless.”

—Robert Pirsig, circa. 1972

“[T]oo often software developers spend their days grinding away for pay at programs they neither need nor love. But not in the Linux world - which may explain why the average quality of software originated in the Linux community is so high.”

—Eric Raymond, 1998

slide-32
SLIDE 32

32/162

Quality Without a Name

slide-33
SLIDE 33

33/162

Quality Without a Name

ニワトリのヒナの雌雄鑑別 (chick sexing) “The master would stand over the apprentice and watch. The student would pick up a chick, examine its rear, and toss it into one bin or the

  • ther. The master would give

feedback: yes or no.” —Eagleman, 2011

http://discovermagazine.com/2011/sep/18-your-brain-knows-lot-more-than-you-realize

slide-34
SLIDE 34

34/162

Practice, practice and practice more

slide-35
SLIDE 35

35/162

slide-36
SLIDE 36

36/162

Quality

 Rationale

– “Software design is widely recognised as being a “wicked” or “ill-structured” problem, characterised by ambiguous specifications, no true/false solutions (only ones that are “better” or “worse” from a particular perspective), the lack

  • f any “stopping rule” to determine when a

solution has been reached, and no ultimate test

  • f whether a solution meets the requirements.”

—Zhang and Budgen, 2012

slide-37
SLIDE 37

37/162

Quality

“Important assumptions

– That patterns can be codified in such a way that they can be shared between different designers – That reuse will lead to “better” designs. There is an obvious question here of what constitutes “better”, but a key measure is maintainability”

—Zhang and Budgen, 2012

(With minor adaptations)

slide-38
SLIDE 38

38/162

Quality

“Advantages:

– Using patterns improves programmer productivity and program quality – Novices can increase their design skills significantly by studying and applying patterns – Patterns encourage best practices, even for experiences designers – Design patterns improve communication, both among developers and from developers to maintainers”

—Zhang and Budgen, 2012

(With minor adaptations)

slide-39
SLIDE 39

39/162

Outline

 Definition  Quality  Form  Example  Catalogue  Practice  Conclusion

slide-40
SLIDE 40

40/162

Form

 Several books, articles

– “Theoretical” – With examples – Among others…

slide-41
SLIDE 41

41/162

Form

 Several books, articles

– Amazon.com

  • Books › Computers & Technology › Programming ›

Software Design, Testing & Engineering › Object- Oriented Design › "patterns"

  • 224 results on May 31, 2013
slide-42
SLIDE 42

42/162

Form

 Several books, articles

– Amazon.com

  • Exclusion

– Unreleased books – Specific to a technology or frameworks » e.g., MVVM Unleashed by Michael Brown – Process oriented, user-interface, programming languages » e.g., Process Patterns: Building Large-Scale Systems Using Object Technology by Scott W. Ambler and Barbara Hanscome – Proceedings of conferences – Unrelated to software engineering

slide-43
SLIDE 43

43/162

Form

1. Pattern-Oriented Software Architecture, Patterns for Concurrent and Networked Objects: Volume 2 (Wiley Software... by Douglas C. Schmidt, Michael Stal, Hans Rohnert and Frank Buschmann 2. Pattern-Oriented Software Architecture, Patterns for Resource Management: Volume 3 (Wiley Software Patterns Series... by Michael Kircher and Prashant Jain 3. Pattern-Oriented Software Architecture, A System of Patterns: Volume 1 (Wiley Software Patterns Series) by Frank Buschmann, Regine Meunier, Hans Rohnert and Peter Sommerlad 4. Pattern-Oriented Software Architecture For Dummies (For Dummies (Computers)) by Robert Hanmer 5. Web Security Patterns by Ramesh Nagappan and Christopher Steel 6. Safe C++ by Vladimir Kushnir 7. Programming in the Large with Design Patterns by Eddie Burris 8. Elemental Design Patterns by Jason McC. Smith 9. Java Application Architecture: Modularity Patterns with Examples Using OSGi (Robert C. Martin Series) by Kirk Knoernschild 10. Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions (Addison-Wesley Signature... by Gregor Hohpe and Bobby Woolf 11. Patterns of Enterprise Application Architecture (Addison-Wesley Signature Series (Fowler)) by Martin Fowler 12. Cognitive Patterns: Problem-Solving Frameworks for Object Technology by Robert K Konitzer, Bobbin Teegarden, Alexander Rush and Karen M Gardner 13. Service Design Patterns: Fundamental Design Solutions for SOAP/WSDL and RESTful Web Services by Robert Daigneau 14. The ACE Programmer's Guide: Practical Design Patterns for Network and Systems Programming by Stephen D. Huston, James CE Johnson and Umar Syyid 15. Patterns for Parallel Software Design (Wiley Software Patterns Series) by Jorge Luis Ortega-Arjona 16. Design Patterns in Object-oriented ABAP by Igor Barbaric 17. Object-Oriented Reengineering Patterns by Oscar Nierstrasz, Stéphane Ducasse and Serge Demeyer 18. Dependency Injection by Dhanji R. Prasanna 19. Object-Oriented Software Engineering Using UML, Patterns, and Java (3rd Edition) by Bernd Bruegge and Allen H. Dutoit 20. J2EE Design Patterns by William Crawford and Jonathan Kaplan 21. Applying UML and Patterns: An Introduction to Object-oriented Analysis and Design and Iterative Development by Craig Larman 22. Object-oriented Analysis and Design Using Umlan Introduction to Unified Process and Design Patterns by Mahesh P. Matha 23. C++ Design Patterns and Derivatives Pricing (Mathematics, Finance and Risk) by M. S. Joshi 24. Effective Java (2nd Edition) by Joshua Bloch 25. Patterns for Fault Tolerant Software (Wiley Software Patterns Series) by Robert Hanmer 26. Implementation Patterns by Kent Beck 27. Patterns for Computer-Mediated Interaction (Wiley Software Patterns Series) by Till Schummer and Stephan Lukosch 28. Pattern Oriented Software Architecture Volume 5: On Patterns and Pattern Languages by Frank Buschmann, Kevlin Henney and Douglas C. Schmidt 29. Object-Oriented Analysis and Design with Applications (3rd Edition) by Grady Booch, Robert A. Maksimchuk, Michael
  • W. Engle and Bobbi J. Young
30. Head First Object-Oriented Analysis and Design by Brett D. McLaughlin, Gary Pollice and Dave West 31. Agile Principles, Patterns, and Practices in C# by Robert C. Martin and Micah Martin 32. Design Patterns For Dummies by Steve Holzner 33. Pattern Languages of Program Design 5 by Dragos Manolescu, Markus Voelter and James Noble 34. Design Patterns in Java(TM) (Software Patterns Series) by Steven John Metsker and William C. Wake 35. Object-Oriented Design and Patterns by Cay S. Horstmann 37. Object-Oriented Modeling and Design with UML (2nd Edition) by Michael R. Blaha and James R Rumbaugh 38. Remoting Patterns: Foundations of Enterprise, Internet and Realtime Distributed Object Middleware (Wiley Software... by Markus Völter, Michael Kircher and Uwe Zdun 39. Software Factories: Assembling Applications with Patterns, Models, Frameworks, and Tools (Wiley Application Development... by Jack Greenfield, Keith Short, Steve Cook and Stuart Kent 40. Refactoring to Patterns by Joshua Kerievsky 41. Architecting Enterprise Solutions: Patterns for High-Capability Internet-based Systems (Wiley Software Patterns... by Paul Dyson and Andrew Longshaw 42. Enterprise Patterns and MDA: Building Better Software with Archetype Patterns and UML by Jim Arlow and Ila Neustadt 43. Data Access Patterns: Database Interactions in Object-Oriented Applications by Clifton Nock 44. Domain-Driven Design: Tackling Complexity in the Heart of Software by Eric Evans 45. Pattern-Oriented Analysis and Design: Composing Patterns to Design Software Systems by Sherif M. Yacoub, Hany H. Ammar, Sherif Yacoub and Hany Ammar 46. Java Extreme Programming Cookbook by Eric M. Burke and Brian M. Coyner 47. J2EE Best Practices: Java Design Patterns, Automation, and Performance (Wiley Application Development Series) by Darren Broemmer 48. Real-Time Design Patterns: Robust Scalable Architecture for Real-Time Systems by Bruce Powel Douglass 49. Design Patterns Java¿ Workbook by Steven John Metsker 50. EJB Design Patterns: Advanced Patterns, Processes, and Idioms by Floyd Marinescu 51. Streamlined Object Modeling: Patterns, Rules, and Implementation by Jill Nicola, Mark Mayfield and Mike Abney 52. Design Patterns Explained: A New Perspective on Object-Oriented Design by Alan Shalloway and James Trott 53. Small Memory Software: Patterns for systems with limited memory (Software Patterns Series) by James Noble and Charles Weir 54. AntiPatterns in Project Management by William J. Brown, Hays W. "Skip" McCormick III and Scott W. Thomas 55. Pattern Languages of Program Design 4 (Software Patterns Series) by Brian Foote, Neil Harrison and Hans Rohnert 56. Testing Object-Oriented Systems: Models, Patterns, and Tools by Robert V. Binder 57. Design Patterns and Contracts by Jean-Marc Jezequel, Michel Train and Christine Mingins 58. Object-Oriented Software Development Using Java: Principles, Patterns, and Frameworks (1/e) by Xiaoping Jia 59. Refactoring: Improving the Design of Existing Code by Martin Fowler, Kent Beck, John Brant and William Opdyke 60. More Process Patterns: Delivering Large-Scale Systems Using Object Technology (SIGS: Managing Object Technology... by Scott W. Ambler 61. Pattern Hatching: Design Patterns Applied by John Vlissides 62. AntiPatterns: Refactoring Software, Architectures, and Projects in Crisis by William J. Brown, Raphael C. Malveau, Hays W. "Skip" McCormick and Thomas J. Mowbray 63. A Little Java, A Few Patterns (Language, Speech, & Communication) by Matthias Felleisen, Daniel P. Friedman and Ralph E. Johnson 64. Pattern Languages of Program Design 3 (v. 3) by Robert C. Martin, Dirk Riehle and Frank Buschmann 65. Object Models: Strategies, Patterns, and Applications (2nd Edition) by Peter Coad, David North and Mark Mayfield 66. Analysis Patterns: Reusable Object Models by Martin Fowler 67. Patterns of Software: Tales from the Software Community by Richard P. Gabriel 68. Pattern Languages of Program Design 2 (v. 2) by John Vlissides, James O. Coplien and Norman L. Kerth 69. Software Patterns by James Coplien 70. Software Architecture: Perspectives on an Emerging Discipline by Mary Shaw and David Garlan 71. Adaptive Object-Oriented Software: The Demeter Method with Propagation Patterns: The Demeter Method with Propagation... by Karl Lieberherr 72. Pattern Languages of Program Design by James O. Coplien and Douglas C. Schmidt
slide-44
SLIDE 44

44/162

Form

“Each pattern is a three part rule, which express a relation between a context, a problem, and a solution.” —Christopher Alexander, 1977

slide-45
SLIDE 45

45/162

Form

 General form as for the GoF

also inspired by Coplien’s form

– Name – Problem(s) – Solution – Consequences

slide-46
SLIDE 46

46/162

Form (Extended)

 General form as for the GoF

also inspired by Coplien’s form

– Name – Problem(s) – Example(s) – Solution – Example(s) – Consequences – (Follow-up)

slide-47
SLIDE 47

47/162

Form

 General form as for the GoF

also inspired by Coplien’s form

– Not formal – Room for interpretation – But…

  • UML-like class diagrams
  • UML-like sequence diagrams
  • Smalltalk / C++ example code
slide-48
SLIDE 48

48/162

Outline

 Definition  Quality  Form  Example  Catalogue  Practice  Conclusion

slide-49
SLIDE 49

49/162

Example (1/5)

 Simplified compiler

– Parse files to build an AST – Iterate over the AST

  • Build DefaultMutableTreeNodes

javax.swing.tree.DefaultMutableTreeNode for a graphical representation of the AST

  • Bind types
  • Generate code
slide-50
SLIDE 50

50/162

Example (1/5)

 Simplified compiler

– Parse files to build an AST – Iterate over the AST

  • Build DefaultMutableTreeNodes

javax.swing.tree.DefaultMutableTreeNode for a graphical representation of the AST

  • Bind types
  • Generate code
slide-51
SLIDE 51

51/162

Example (2/5)

 AST

Field generateCode() Statement generateCode() Method generateCode() Class generateCode() CompilationUnit generateCode() Main

slide-52
SLIDE 52

52/162

Example (3/5)

package compiler; import java.util.Set; public class Method { private Set statements; public void addStatement(final Statement aStatement) { this.statements.add(aStatement); } public void removeStatement(final Statement aStatement) { this.statements.remove(aStatement); } } package compiler; public class Field { /* To be implemented. */ } package compiler; public class Statement { /* To be implemented. */ }

slide-53
SLIDE 53

53/162

Example (4/5)

package compiler; import java.util.Set; public class Class { private String name; private Set methods; private Set fields; public String getName() { return this.name; } public void addMethod(final Method aMethod) { this.methods.add(aMethod); } public void removeMethod(final Method aMethod) { this.methods.remove(aMethod); } public void addField(final Method aField) { this.fields.add(aField); } public void removeField(final Field aField) { this.fields.remove(aField); } }

slide-54
SLIDE 54

54/162

Example (5/5)

package compiler; import java.util.Iterator; import java.util.Set; public class CompilationUnit { private Set classes; public void addClass(final Class aClass) { this.classes.add(aClass); } public void removeClass(final Class aClass) { this.classes.remove(aClass); } public Class getClass(final String aName) { final Iterator iterator = this.classes.iterator(); while (iterator.hasNext()) { final Class aClass = (Class) iterator.next(); if (aClass.getName().equals(aName)) { return aClass; } } return null; } }

slide-55
SLIDE 55

55/162

Naïve Implementation (1/7)

 How to generate microcode for

– Microsoft Windows operating system – Intel Pentium processor

Add a generateCode() method in each class

slide-56
SLIDE 56

56/162

Naïve Implementation (2/7)

public class Method { … public String generateCode() { String generatedCode = ""; /* Do something at the beginning. */ final Iterator iterator = this.statements.iterator(); while (iterator.hasNext()) { final Statement aStatement = (Statement) iterator.next(); generatedCode += aStatement.generateCode(); } /* Do something at the end. */ return generatedCode; } } public class Field { … public String generateCode() { String generatedCode = ""; /* Do something. */ return generatedCode; } } public class Statement { … public String generateCode() { String generatedCode = ""; /* Do something. */ return generatedCode; } }

slide-57
SLIDE 57

57/162

Naïve Implementation (3/7)

public class Class { … public String generateCode() { String generatedCode = ""; /* Do something at the beginning. */ final Iterator iteratorOnFields = this.fields.iterator(); while (iteratorOnFields.hasNext()) { final Field aField = (Field) iteratorOnFields.next(); generatedCode += aField.generateCode(); } final Iterator iteratorOnMethods = this.methods.iterator(); while (iteratorOnMethods.hasNext()) { final Method aMethod = (Method) iteratorOnMethods.next(); generatedCode += aMethod.generateCode(); } /* Do something at the end. */ return generatedCode; } }

slide-58
SLIDE 58

58/162

Naïve Implementation (4/7)

public class CompilationUnit { … public String generateCode() { String generatedCode = ""; /* Do something at the beginning. */ final Iterator iterator = this.classes.iterator(); while (iterator.hasNext()) { final Class aClass = (Class) iterator.next(); generatedCode += aClass.generateCode(); } /* Do something at the end. */ return generatedCode; } }

slide-59
SLIDE 59

59/162

Naïve Implementation (5/7)

cu : CompilationUnit c : Class m : Method s : Statement m : Main generateCode( ) generateCode( ) generateCode( ) generateCode( )

slide-60
SLIDE 60

60/162

Naïve Implementation (6/7)

 Limitations of the naïve implementation

– What about generating code for

  • Linux on PowerPC?
  • Linux on Motorola 68060?
  • OS/400 on AS/400?

Combinatorial explosion of generateCodeForXXX() methods in each class

slide-61
SLIDE 61

61/162

Naïve Implementation (7/7)

 Requirements

– Decouple the data structure

  • The AST

– From algorithms on the data structure

  • The generateCodeForXXX() method
  • And others, including type binding!

The Visitor design pattern guides you to do that!

slide-62
SLIDE 62

62/162

Visitor (2/13)

 Name: Visitor  Intent: “Represent an operation to be

performed on the elements of an object

  • structure. Visitor lets you define a new
  • peration without changing the classes of

the elements on which it operates.”

slide-63
SLIDE 63

63/162

Visitor (3/13)

 Motivation: “Consider a compiler that

represents programs as abstract syntax

  • trees. It will need to perform operations on

abstract syntax trees for "static semantic" analyses like checking that all variables are

  • defined. It will also need to generate code.”
slide-64
SLIDE 64

64/162

Visitor (4/13)

 Motivation (cont’d): “[…] It will be confusing

to have type-checking code mixed with pretty-printing code or flow analysis code. […] It would be better if each new operation could be added separately, and the node classes were independent of the operations that apply to them.”

slide-65
SLIDE 65

65/162

Visitor (5/13)

 Motivation (cont’d): “We can have both by

packaging related operations from each class in a separate object, called a visitor, and passing it to elements of the abstract syntax tree as it's traversed.”

slide-66
SLIDE 66

66/162

Visitor (6/13)

 Motivation (cont’d): “When an element

accepts the visitor, it sends a request to the visitor that encodes the element's class. It also includes the element as an argument. The visitor will then execute the operation for that element—the operation that used to be in the class of the element.”

slide-67
SLIDE 67

67/162

Visitor (8/13)

 Applicability

– An object structure contains many classes of

  • bjects with differing interfaces…

– Many distinct and unrelated operations need to be performed on objects in an object structure… – The classes defining the object structure rarely change, but you often want to define new

  • perations over the structure…
slide-68
SLIDE 68

68/162

Visitor (9/13)

 Structure

slide-69
SLIDE 69

69/162

Visitor (10/13)

 Participants

– Visitor (NodeVisitor)

  • Declares a Visit operation for

each class…

– ConcreteVisitor (TypeCheckingVisitor)

  • Implements each Visit…

– Element (Node)

  • Defines an Accept operation…

– ConcreteElement (AssignmentNode)

  • Implements Accept …

– ObjectStructure (Program)

  • Can enumerate its elements
  • May provide a high-level

interface to allow the visitor to visit its elements

  • May either be a composite

(see Composite) or a collection

slide-70
SLIDE 70

70/162

Visitor (11/13)

 Collaborations

slide-71
SLIDE 71

71/162

Visitor (13/13)

 Consequences: …  Implementation: …  Sample code: …  Known uses

– ASTs – Meta-models – …

 Related patterns: Composite

slide-72
SLIDE 72

72/162

Better Implementation (1/6)

package compiler.visitor; import compiler.Class; import compiler.CompilationUnit; import compiler.Field; import compiler.Method; import compiler.Statement; public interface Visitor { void open(final Class aClass); void open(final CompilationUnit aCompilationUnit); void open(final Method aMethod); void close(final Class aClass); void close(final CompilationUnit aCompilationUnit); void close(final Method aMethod); void visit(final Field aField); void visit(final Statement aStatement); }

slide-73
SLIDE 73

73/162

Better Implementation (2/6)

public class Method { … public void accept(final Visitor aVisitor) { aVisitor.open(this); final Iterator iterator = this.statements.iterator(); while (iterator.hasNext()) { final Statement aStatement = (Statement) iterator.next(); aStatement.accept(aVisitor); } aVisitor.close(this); } } public class Field { … public void accept(final Visitor aVisitor) { aVisitor.visit(this); } } public class Statement { … public void accept(final Visitor aVisitor) { aVisitor.visit(this); } }

slide-74
SLIDE 74

74/162

Better Implementation (3/6)

public class Class { … public void accept(final Visitor aVisitor) { aVisitor.open(this); final Iterator iteratorOnFields = this.fields.iterator(); while (iteratorOnFields.hasNext()) { final Field aField = (Field) iteratorOnFields.next(); aField.accept(aVisitor); } final Iterator iteratorOnMethods = this.methods.iterator(); while (iteratorOnMethods.hasNext()) { final Method aMethod = (Method) iteratorOnMethods.next(); aMethod.accept(aVisitor); } aVisitor.close(this); } }

slide-75
SLIDE 75

75/162

Better Implementation (4/6)

public class CompilationUnit { … public void accept(final Visitor aVisitor) { aVisitor.open(this); final Iterator iterator = this.classes.iterator(); while (iterator.hasNext()) { final Class aClass = (Class) iterator.next(); aClass.accept(aVisitor); } aVisitor.close(this); } }

slide-76
SLIDE 76

76/162

Better implementation (5/6)

m : Main cu : CompilationUnit c : Class m : Method s : Statement v : IVisitor accept(IVisitor) accept(IVisitor) accept(IVis itor) accept(IVisitor)
  • pen(CompilationUnit)
  • pen(Clas s)
  • pen(Method)
visit(Statement) close(Method) close(Class) close(CompilationUnit)

cu : CompilationUnit c : Class m : Method s : Statement m : Main generateCode( ) generateCode( ) generateCode( ) generateCode( )

slide-77
SLIDE 77

77/162

Better implementation (5/6)

cu : CompilationUnit c : Class m : Method s : Statement m : Main generateCode( ) generateCode( ) generateCode( ) generateCode( )

m : Main cu : CompilationUnit c : Class m : Method s : Statement v : IVisitor accept(IVisitor) accept(IVisitor) accept(IVis itor) accept(IVisitor)
  • pen(CompilationUnit)
  • pen(Clas s)
  • pen(Method)
visit(Statement) close(Method) close(Class) close(CompilationUnit)
slide-78
SLIDE 78

78/162

Better Implementation (6/6)

 By using the visitor design pattern

– Decouple data structure and algorithms – Put the traversal in only one place, in the AST – Allow the addition of new algorithms without changing the data structure

Much better, clearer implementation!

slide-79
SLIDE 79

79/162

Conclusion on the Example

 The Visitor design pattern is useful

anywhere you have

– A data (stable) structure – Algorithms (infinite) on that data structure

 Design patterns provided good solution to

recurrent problems!

slide-80
SLIDE 80

80/162

Outline

 Definition  Quality  Form  Example  Catalogue  Practice  Conclusion

slide-81
SLIDE 81

81/162

Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides ; Design Patterns: Elements of Reusable Object-Oriented Software ; Addison-Wesley, 1995

slide-82
SLIDE 82

82/162

Catalogue

 Design patterns

– Development and maintenance – Design/implementation levels – Examples in C++ and Smalltalk

 Divided in three categories

– Behavioural – Creational – Structural

slide-83
SLIDE 83

83/162

Catalogue

slide-84
SLIDE 84

84/162

Catalogue

 Abstract Factory (87)

– Provide an interface for creating families of related or dependent objects without specifying their concrete classes

 Adapter (139)

– Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces

slide-85
SLIDE 85

85/162

Catalogue

 Bridge (151)

– Decouple an abstraction from its implementation so that the two can vary independently

 Builder (97)

– Separate the construction of a complex object from its representation so that the same construction process can create different representations

slide-86
SLIDE 86

86/162

Catalogue

 Chain of Responsibility (223)

– Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it

slide-87
SLIDE 87

87/162

Catalogue

 Command (233)

– Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations

 Composite (163)

– Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions

  • f objects uniformly
slide-88
SLIDE 88

88/162

Catalogue

 Decorator (175)

– Attach additional responsibilities to an object

  • dynamically. Decorators provide a flexible

alternative to subclassing for extending functionality

 Facade (185)

– Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use

slide-89
SLIDE 89

89/162

Catalogue

 Factory Method (107)

– Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses

 Flyweight (195)

– Use sharing to support large numbers of fine- grained objects efficiently

slide-90
SLIDE 90

90/162

Catalogue

 Interpreter (243)

– Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language

 Iterator (257)

– Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation

slide-91
SLIDE 91

91/162

Catalogue

 Mediator (273)

– Define an object that encapsulates how a set of

  • bjects interacts. Mediator promotes loose

coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently

 Memento (283)

– Without violating encapsulation, capture and externalize an object's internal state so that the

  • bject can be restored to this state later
slide-92
SLIDE 92

92/162

Catalogue

 Observer (293)

– Define a one-to-many dependency between

  • bjects so that when one object changes state,

all its dependents are notified and updated automatically

 Prototype (117)

– Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype

slide-93
SLIDE 93

93/162

Catalogue

 Proxy (207)

– Provide a surrogate or placeholder for another

  • bject to control access to it.

 Singleton (127)

– Ensure a class only has one instance, and provide a global point of access to it

slide-94
SLIDE 94

94/162

Catalogue

 State (305)

– Allow an object to alter its behaviour when its internal state changes. The object will appear to change its class

 Strategy (315)

– Define a family of algorithms, encapsulate each

  • ne, and make them interchangeable. Strategy

lets the algorithm vary independently from clients that use it

slide-95
SLIDE 95

95/162

Catalogue

 Template Method (325)

– Define the skeleton of an algorithm in an

  • peration, deferring some steps to subclasses.

Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure

slide-96
SLIDE 96

96/162

Catalogue

 Visitor (331)

– 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

slide-97
SLIDE 97

97/162

Outline

 Definition  Quality  Form  Example  Catalogue  Practice  Conclusion

slide-98
SLIDE 98

98/162

Practice

“The strict modeling of the real world leads to reflect today’s realities but not necessarily tomorrow’s. The abstractions that emerge during design are key to making a design flexible.” —Erich Gamma, 1994

slide-99
SLIDE 99

99/162

Practice

“The description of communicating objects and classes customized to solve general design problem in a particular context.” —Erich Gamma, 1994

slide-100
SLIDE 100

100/162

Practice

“Each design pattern lets some aspect of system structure vary independently of other aspects, thereby making a system more robust to a particular kind of change.” —Erich Gamma, 1994

slide-101
SLIDE 101

101/162

The following is only complementary to reading books and practicing

slide-102
SLIDE 102

102/162

Practice

 Scattered information

– Informal text

 A suggested example rather than a

general rule

Interpreting them all...

slide-103
SLIDE 103

103/162

Practice

 When encountering complex problems?

– Numerous design patterns (is there any complete list out there?) – Granularity

  • Requirements, analysis, architecture
  • Design, implementation (idioms)
  • Refactoring, testing

Knowing them all...

slide-104
SLIDE 104

104/162

Practice

 Iterative induction process

– From an example to an abstraction to an application to the abstraction to an application… – Validation process?

Applying them all...

slide-105
SLIDE 105

105/162

Practice

 Use known categories

– Behavioural – Creational – Structural

 Use the Internet  Read and discuss others’ code

slide-106
SLIDE 106

106/162

Practice

 Use known categories

– Behavioural – Creational – Structural

 Use the Internet  Read and discuss others’ code

slide-107
SLIDE 107

107/162

Practice

 Use known categories

– Behavioural – Creational – Structural

 Use the Internet  Read and discuss others’ code

slide-108
SLIDE 108

108/162

Practice

 Assess the trade-offs

– Flexibility – Complexity

slide-109
SLIDE 109

109/162

Practice

 Assess the trade-offs

– Flexibility – Complexity

slide-110
SLIDE 110

110/162

Practice

 Assess the trade-offs

– Flexibility – Complexity

 Sometimes it is necessary to remove the

solution of a DP used in the code

slide-111
SLIDE 111

111/162

Practice

 Sometimes it is necessary to remove the

solution of a DP used in the code

slide-112
SLIDE 112

112/162

Practice

“There is a natural relation between patterns and refactorings. “Patterns are where you want to be; refactorings are ways to get there from somewhere else” —Josuha Kerievsky citing Martin Fowler, 2004

slide-113
SLIDE 113

113/162

slide-114
SLIDE 114

114/162

Practice

 Refactoring to a Visitor

– Previous example of code generation from a common AST

 Implementing a variant of the Visitor

– padl.kernel.impl.Constituent.accept(IVisitor) – padl.kernel.impl.Constituent.accept(IVisitor, String) – padl.kernel.impl.Constituent.accept(Class, IVisitor, String, boolean)

 Refactoring away from the Visitor

– ptidej.statement.creator.classfiles.loc.BCELLOCFinder

slide-115
SLIDE 115

115/162

Practice

 Refactoring to a Visitor

– Previous example of code generation from a common AST

 Implementing a variant of the Visitor

– padl.kernel.impl.Constituent.accept(IVisitor) – padl.kernel.impl.Constituent.accept(IVisitor, String) – padl.kernel.impl.Constituent.accept(Class, IVisitor, String, boolean)

 Refactoring away from the Visitor

– ptidej.statement.creator.classfiles.loc.BCELLOCFinder

slide-116
SLIDE 116

116/162

Practice

 Refactoring to a Visitor

– Previous example of code generation from a common AST

 Implementing a variant of the Visitor

– padl.kernel.impl.Constituent.accept(IVisitor) – padl.kernel.impl.Constituent.accept(IVisitor, String) – padl.kernel.impl.Constituent.accept(Class, IVisitor, String, boolean)

 Refactoring away from the Visitor

– ptidej.statement.creator.classfiles.loc.BCELLOCFinder

slide-117
SLIDE 117

117/162

Practice

 Implementing a variant of the Visitor

– Problem when implementing the solution of the Visitor design pattern

  • Too many duplicated accept(…) methods
  • Two cases for visit(…) and open(…)+close(…)
slide-118
SLIDE 118

118/162

Practice

 Implementing a variant of the Visitor

– Problem when implementing the solution of the Visitor design pattern

  • Too many duplicated accept(…) methods
  • What if the data structure changes?
  • Two cases for visit(…) and open(…)+close(…)
slide-119
SLIDE 119

119/162

Practice

 Implementing a variant of the Visitor

– Problem when implementing the solution of the Visitor design pattern

  • Too many duplicated accept(…) methods
  • What if the data structure changes?
  • Two cases for visit(…) and open(…)+close(…)
slide-120
SLIDE 120

120/162

Practice

 Implementing a variant of the Visitor

– Problem when implementing the solution of the Visitor design pattern

  • Too many duplicated accept(…) methods
  • What if the data structure changes?
  • Two cases for visit(…) and open(…)+close(…)

– Solution

  • Use the introspection mechanism of Java
slide-121
SLIDE 121

121/162

Practice

 Implementing a variant of the Visitor

– Problem when implementing the solution of the Visitor design pattern

  • Too many duplicated accept(…) methods
  • What if the data structure changes?
  • Two cases for visit(…) and open(…)+close(…)

– Solution

  • Use the introspection mechanism of Java
slide-122
SLIDE 122

122/162

Practice

 Use the introspection

mechanism of Java

private boolean accept( final java.lang.Class currentReceiver, final IVisitor visitor, final String methodName, final boolean shouldRecurse) { acceptClassName = currentReceiver.getName(); java.lang.Class argument = null; try { argument = visitor.getClass().getClassLoader().loadClass(acceptClassName); } catch (final ClassNotFoundException e) { visitor.unknownConstituentHandler(methodName, this); return false; } try { final Method method = visitor.getClass().getMethod( methodName, new java.lang.Class[] { argument }); method.invoke(visitor, new Object[] { this }); return true; } catch (final Exception e) { if (e instanceof NoSuchMethodException) { visitor.unknownConstituentHandler(methodName + '(‘ + argument.getName() + ')', this); } else { throw new RuntimeException(e); } } return false; }

slide-123
SLIDE 123

123/162

Practice

 Use the introspection

mechanism of Java

private boolean accept( final java.lang.Class currentReceiver, final IVisitor visitor, final String methodName, final boolean shouldRecurse) { acceptClassName = currentReceiver.getName(); java.lang.Class argument = null; try { argument = visitor.getClass().getClassLoader().loadClass(acceptClassName); } catch (final ClassNotFoundException e) { visitor.unknownConstituentHandler(methodName, this); return false; } try { final Method method = visitor.getClass().getMethod( methodName, new java.lang.Class[] { argument }); method.invoke(visitor, new Object[] { this }); return true; } catch (final Exception e) { if (e instanceof NoSuchMethodException) { visitor.unknownConstituentHandler(methodName + '(‘ + argument.getName() + ')', this); } else { throw new RuntimeException(e); } } return false; }

final Method method = visitor.getClass().getMethod( methodName, new java.lang.Class[] { argument }); method.invoke(visitor, new Object[] { this });

slide-124
SLIDE 124

124/162

Practice

 Use the introspection

mechanism of Java

private boolean accept( final java.lang.Class currentReceiver, final IVisitor visitor, final String methodName, final boolean shouldRecurse) { acceptClassName = currentReceiver.getName(); java.lang.Class argument = null; try { argument = visitor.getClass().getClassLoader().loadClass(acceptClassName); } catch (final ClassNotFoundException e) { visitor.unknownConstituentHandler(methodName, this); return false; } try { final Method method = visitor.getClass().getMethod( methodName, new java.lang.Class[] { argument }); method.invoke(visitor, new Object[] { this }); return true; } catch (final Exception e) { if (e instanceof NoSuchMethodException) { visitor.unknownConstituentHandler(methodName + '(‘ + argument.getName() + ')', this); } else { throw new RuntimeException(e); } } return false; }

slide-125
SLIDE 125

125/162

Practice

 Use the introspection

mechanism of Java

private boolean accept( final java.lang.Class currentReceiver, final IVisitor visitor, final String methodName, final boolean shouldRecurse) { acceptClassName = currentReceiver.getName(); java.lang.Class argument = null; try { argument = visitor.getClass().getClassLoader().loadClass(acceptClassName); } catch (final ClassNotFoundException e) { visitor.unknownConstituentHandler(methodName, this); return false; } try { final Method method = visitor.getClass().getMethod( methodName, new java.lang.Class[] { argument }); method.invoke(visitor, new Object[] { this }); return true; } catch (final Exception e) { if (e instanceof NoSuchMethodException) { visitor.unknownConstituentHandler(methodName + '(‘ + argument.getName() + ')', this); } else { throw new RuntimeException(e); } } return false; }

acceptClassName = currentReceiver.getName(); java.lang.Class argument = null; try { argument = visitor.getClass().getClassLoader().loadClass(acceptClassName); } catch (final ClassNotFoundException e) { visitor.unknownConstituentHandler(methodName, this); return false; }

slide-126
SLIDE 126

126/162

Practice

 Use the introspection

mechanism of Java

private boolean accept( final java.lang.Class currentReceiver, final IVisitor visitor, final String methodName, final boolean shouldRecurse) { acceptClassName = currentReceiver.getName(); java.lang.Class argument = null; try { argument = visitor.getClass().getClassLoader().loadClass(acceptClassName); } catch (final ClassNotFoundException e) { visitor.unknownConstituentHandler(methodName, this); return false; } try { final Method method = visitor.getClass().getMethod( methodName, new java.lang.Class[] { argument }); method.invoke(visitor, new Object[] { this }); return true; } catch (final Exception e) { if (e instanceof NoSuchMethodException) { visitor.unknownConstituentHandler(methodName + '(‘ + argument.getName() + ')', this); } else { throw new RuntimeException(e); } } return false; }

slide-127
SLIDE 127

127/162

Practice

 Use the introspection

mechanism of Java

private boolean accept( final java.lang.Class currentReceiver, final IVisitor visitor, final String methodName, final boolean shouldRecurse) { acceptClassName = currentReceiver.getName(); java.lang.Class argument = null; try { argument = visitor.getClass().getClassLoader().loadClass(acceptClassName); } catch (final ClassNotFoundException e) { visitor.unknownConstituentHandler(methodName, this); return false; } try { final Method method = visitor.getClass().getMethod( methodName, new java.lang.Class[] { argument }); method.invoke(visitor, new Object[] { this }); return true; } catch (final Exception e) { if (e instanceof NoSuchMethodException) { visitor.unknownConstituentHandler(methodName + '(‘ + argument.getName() + ')', this); } else { throw new RuntimeException(e); } } return false; }

catch (final Exception e) { if (e instanceof NoSuchMethodException) { visitor.unknownConstituentHandler(methodName + '(‘ + argument.get...; } else { throw new RuntimeException(e); } }

slide-128
SLIDE 128

128/162

Practice

 Use the introspection mechanism of Java

– No more duplicated accept(…) methods – Handles cases for visit(…) and

  • pen(…)+close(…)

– Plus, allows extensions to the data structure without changing all existing Visitors

slide-129
SLIDE 129

129/162

Practice

 Use the introspection mechanism of Java

– No more duplicated accept(…) methods – Handles cases for visit(…) and

  • pen(…)+close(…)

– Plus, allows extensions to the data structure without changing all existing Visitors

slide-130
SLIDE 130

130/162

Practice

 Refactoring to a Visitor

– Previous example of code generation from a common AST

 Implementing a variant of the Visitor

– padl.kernel.impl.Constituent.accept(IVisitor) – padl.kernel.impl.Constituent.accept(IVisitor, String) – padl.kernel.impl.Constituent.accept(Class, IVisitor, String, boolean)

 Refactoring away from the Visitor

– ptidej.statement.creator.classfiles.loc.BCELLOCFinder

slide-131
SLIDE 131

131/162

Practice

 Refactoring away from the Visitor

final FileInputStream fis = new FileInputStream(path); final ClassParser parser = new ClassParser(fis, path); final JavaClass clazz = parser.parse(); clazz.accept(this.instFinder); fis.close(); public class BCELLOCFinder implements Visitor { private JavaClass currentClass; public void visitCode(final Code aCode) { } public void visitCodeException(final CodeException aCodeException) { } // 18 other empty “visit” methods public void visitJavaClass(final JavaClass aClass) { this.currentClass = aClass; final Method[] methods = aClass.getMethods(); for (int i = 0; i < methods.length; i++) { this.visitMethod(methods[i]); } } // 4 more empty “visit” methods public void visitMethod(final Method aMethod) { Integer count = null; final String ckey = this.adaptor.adapt(this.currentClass); final String mkey = this.adaptor.adapt(this.currentClass, aMethod); final Map methodMap = this.methodMap(ckey); count = this.getLOC(code); methodMap.put(mkey, count); } // 6 more empty “visit” methods }

slide-132
SLIDE 132

132/162

Practice

 Refactoring away from the Visitor

final FileInputStream fis = new FileInputStream(path); final ClassParser parser = new ClassParser(fis, path); final JavaClass clazz = parser.parse(); clazz.accept(this.instFinder); fis.close(); public class BCELLOCFinder implements Visitor { private JavaClass currentClass; public void visitCode(final Code aCode) { } public void visitCodeException(final CodeException aCodeException) { } // 18 other empty “visit” methods public void visitJavaClass(final JavaClass aClass) { this.currentClass = aClass; final Method[] methods = aClass.getMethods(); for (int i = 0; i < methods.length; i++) { this.visitMethod(methods[i]); } } // 4 more empty “visit” methods public void visitMethod(final Method aMethod) { Integer count = null; final String ckey = this.adaptor.adapt(this.currentClass); final String mkey = this.adaptor.adapt(this.currentClass, aMethod); final Map methodMap = this.methodMap(ckey); count = this.getLOC(code); methodMap.put(mkey, count); } // 6 more empty “visit” methods }

final FileInputStream fis = new FileInputStream(path); final ClassParser parser = new ClassParser(fis, path); final JavaClass clazz = parser.parse(); clazz.accept(this.instFinder); fis.close();

slide-133
SLIDE 133

133/162

Practice

 Refactoring away from the Visitor

final FileInputStream fis = new FileInputStream(path); final ClassParser parser = new ClassParser(fis, path); final JavaClass clazz = parser.parse(); clazz.accept(this.instFinder); fis.close(); public class BCELLOCFinder implements Visitor { private JavaClass currentClass; public void visitCode(final Code aCode) { } public void visitCodeException(final CodeException aCodeException) { } // 18 other empty “visit” methods public void visitJavaClass(final JavaClass aClass) { this.currentClass = aClass; final Method[] methods = aClass.getMethods(); for (int i = 0; i < methods.length; i++) { this.visitMethod(methods[i]); } } // 4 more empty “visit” methods public void visitMethod(final Method aMethod) { Integer count = null; final String ckey = this.adaptor.adapt(this.currentClass); final String mkey = this.adaptor.adapt(this.currentClass, aMethod); final Map methodMap = this.methodMap(ckey); count = this.getLOC(code); methodMap.put(mkey, count); } // 6 more empty “visit” methods }

slide-134
SLIDE 134

134/162

Practice

 Refactoring away from the Visitor

final FileInputStream fis = new FileInputStream(path); final ClassParser parser = new ClassParser(fis, path); final JavaClass clazz = parser.parse(); clazz.accept(this.instFinder); fis.close(); public class BCELLOCFinder implements Visitor { private JavaClass currentClass; public void visitCode(final Code aCode) { } public void visitCodeException(final CodeException aCodeException) { } // 18 other empty “visit” methods public void visitJavaClass(final JavaClass aClass) { this.currentClass = aClass; final Method[] methods = aClass.getMethods(); for (int i = 0; i < methods.length; i++) { this.visitMethod(methods[i]); } } // 4 more empty “visit” methods public void visitMethod(final Method aMethod) { Integer count = null; final String ckey = this.adaptor.adapt(this.currentClass); final String mkey = this.adaptor.adapt(this.currentClass, aMethod); final Map methodMap = this.methodMap(ckey); count = this.getLOC(code); methodMap.put(mkey, count); } // 6 more empty “visit” methods }

public void visitJavaClass(final JavaClass aClass) { this.currentClass = aClass; final Method[] methods = aClass.getMethods(); for (int i = 0; i < methods.length; i++) { this.visitMethod(methods[i]); } }

slide-135
SLIDE 135

135/162

Practice

 Refactoring away from the Visitor

– 28 empty methods – Hard-coded call the visitMethod(…)

  • See this.visitMethod(methods[i]);

– JavaClasses do not contain other similar

  • bjects, they are not a Composite object

– Unnecessary code, complexity

slide-136
SLIDE 136

136/162

Practice

 Refactoring away from the Visitor

– 28 empty methods – Hard-coded call the visitMethod(…)

  • See this.visitMethod(methods[i]);

– JavaClasses do not contain other similar

  • bjects, they are not a Composite object

– Unnecessary code, complexity

slide-137
SLIDE 137

137/162

Practice

 Unnecessary code, complexity

– Trade-offs of (most of) design patterns

Flexibility Complexity

slide-138
SLIDE 138

138/162

Practice

 Trade-offs of (most of) design patterns

– Flexibility

  • Favouring composition over inheritance

– Complexity

  • More objects interacting
  • More messages exchanged
slide-139
SLIDE 139

139/162

Practice

 Trade-offs of (most of) design patterns

– Flexibility

  • Favouring composition over inheritance

– Complexity

  • More objects interacting
  • More messages exchanged
slide-140
SLIDE 140

140/162

cu : CompilationUnit c : Class m : Method s : Statement m : Main generateCode( ) generateCode( ) generateCode( ) generateCode( )

m : Main cu : CompilationUnit c : Class m : Method s : Statement v : IVisitor accept(IVisitor) accept(IVisitor) accept(IVis itor) accept(IVisitor)
  • pen(CompilationUnit)
  • pen(Clas s)
  • pen(Method)
visit(Statement) close(Method) close(Class) close(CompilationUnit)

Plus the use of reflection!

slide-141
SLIDE 141

141/162

Practice

 Trade-offs of (most of) design patterns

– Flexibility

  • Favouring composition over inheritance

– Complexity

  • More objects interacting
  • More messages exchanged
slide-142
SLIDE 142

142/162

Practice

 Trade-offs of (most of) design patterns

– Flexibility

  • Favouring composition over inheritance

– Complexity

  • More objects interacting
  • More messages exchanged
slide-143
SLIDE 143

143/162

Practice

 Flexibility

– Favour composition over inheritance

  • Allow changing implementation
  • Allow safe inheritance

Add one level of indirection

and (possibly)

Use double-dispatch

slide-144
SLIDE 144

144/162

Practice

 Add one level of indirection

“Rather than giving you a lengthy explanation, let me just point you to the Strategy pattern. It is my prototypical example for the flexibility of composition over inheritance.” Erich Gamma, 2005

slide-145
SLIDE 145

145/162

Practice

 Add one level of indirection

http://itewbm.tistory.com/29

slide-146
SLIDE 146

146/162

Practice

 Add one level of indirection

http://programmers.stackexchange.com/questions/203210/ is-context-inheritance-as-shown-by-head-first-design-patterns-duck-example-ir

slide-147
SLIDE 147

147/162

slide-148
SLIDE 148

148/162

Practice

 Add one level of indirection

http://programmers.stackexchange.com/questions/203210/ is-context-inheritance-as-shown-by-head-first-design-patterns-duck-example-ir

N

  • s

p e c i a l c

  • d

e f

  • r

“ n

  • b

e h a v i

  • u

r ” w i t h t h e N u l l O b j e c t d e s i g n p a t t e r n E n c a p s u l a t e w h a t v a r i e s

slide-149
SLIDE 149

149/162

Practice

 Add one level of indirection

“You have a container, and you plug in some smaller objects. These smaller objects configure the container and customize the behaviour of the container. This is possible since the container delegates some behaviour to the smaller thing. In the end you get customization by configuration. ” Erich Gamma, 2005

(With minor adaptations)

slide-150
SLIDE 150

150/162

Practice

 Add one level of indirection

“You have a container, and you plug in some smaller objects. These smaller objects configure the container and customize the behaviour of the container. This is possible since the container delegates some behaviour to the smaller thing. In the end you get customization by configuration. ” Erich Gamma, 2005

(With minor adaptations)

slide-151
SLIDE 151

151/162

Practice

 Use double-dispatch

– Object receives a message – Object sends a message back with itself as parameter

slide-152
SLIDE 152

152/162

Practice

 Use double-dispatch

– Object receives a message – Object sends a message back with itself as parameter

print(CtxWriter aCTXWriter, Rect aRectangle) { ... } ... print(StringWriter aStringWriter, Triangle aTriangle) { ... } ... PrinterWriter printer = new SystemWriter(); IShape shape = new Square(); print(printer, shape);

slide-153
SLIDE 153

153/162

http://c2.com/cgi-bin/wiki?DoubleDispatchExample http://www.patentstorm.us/patents/6721807/description.html

public class SystemWriter implements PrinterWriter { @Override public void print(final Rect rect) { System.out.print("Printed the rectangle: "); System.out.println(this); } @Override public void print(final Square aSquare) { System.out.print("Printed the square: "); System.out.println(this); } } public class Rect implements IShape { @Override public void printOn(final PrinterWriter aWriter) { aWriter.print(this); } } public class Square implements IShape { @Override public void printOn(final PrinterWriter aWriter) { aWriter.print(this); } } public class Main { public static void main(final String[] args) { final PrinterWriter writer = new SystemWriter(); IShape shape; shape = new Rect(); shape.printOn(writer); shape = new Square(); shape.printOn(writer); } } public interface PrinterWriter { void print(final Rect aRect); void print(final Square aSquare); ... } public interface IShape { void printOn(final PrinterWriter aWriter); }

slide-154
SLIDE 154

154/162

Practice

 Unnecessary code, complexity

– Trade-offs of (most of) design patterns

Flexibility Complexity

slide-155
SLIDE 155

155/162

Practice

 Beware also of “bad” solutions to recurring

design problems

http://www.jot.fm/issues/issue_2006_07/column4/

slide-156
SLIDE 156

156/162

Practice

 Anti-patterns (also antipatterns)

– A common response to a recurring problem that is usually ineffective and may be counterproductive – Code smells are symptoms of “bad” programming

slide-157
SLIDE 157

157/162

Practice

 Two examples of anti-patterns

– Visitor design and JavaClasses

ptidej.statement.creator.classfiles.loc.BCELLOCFinder

– Blob (aka God Class)

slide-158
SLIDE 158

158/162

Outline

 Definition  Quality  Form  Example  Catalogue  Practice  Conclusion

slide-159
SLIDE 159

159/162

Conclusion

 Patterns ease communication  Patterns improve regularity

and quality… even without a name…

 Patterns avoid surprises

i.e., reinventing the wheel differently each time

 Patterns generate architectures

slide-160
SLIDE 160

160/162

Conclusion

 Identify a recurring design problem  Identify a design pattern that potentially

solve the problem

 Assess the costs and benefits of

implementing the proposed solution

– Quality and quality without a name

slide-161
SLIDE 161

161/162

Conclusion

 Identify a recurring design problem  Identify that the solution brings

– Unneeded flexibility – Unnecessary complexity

 Assess the costs and benefits of removing

the proposed solution

slide-162
SLIDE 162

162/162

Conclusion

 Tools supporting design patterns

– “GoF” book

  • Lists, classifications, relationships [Gamma et al., 1996]

– CASE Tools

  • Fragments [Florijn et al., 1997]
  • PatternsBox and Ptidej [Albin et al., 2001]
  • Refactoring tools…

– Navigation

  • Tutor [Motelet, 2000]