Software Design Patterns in Practice

213
Yann-Gaël Guéhéneuc This work is licensed under a Creative Commons Attribution-NonCommercial- ShareAlike 3.0 Unported License Some Theory and Practice on Patterns – In Practice NII, Tokyo, Japan 12/02/14

description

Following the lecture on quality models and the importance of taking into account good practices, we focus on patterns by providing examples of well-known idioms, design patterns, and architectural patterns. We then go on presenting their history, forms, as well as concrete examples of their uses. We also discuss approaches to identify their occurrences in the source code of OO systems under maintenance.

Transcript of Software Design Patterns in Practice

Page 1: Software Design Patterns in Practice

Yann-Gaël Guéhéneuc

This work is licensed under a Creative Commons Attribution-NonCommercial-

ShareAlike 3.0 Unported License

Some Theory and Practice on Patterns – In Practice

NII, Tokyo, Japan12/02/14

Page 2: Software Design Patterns in Practice

2/213

Patterns

Patterns document reusable solutions to recurring problems– Architecture

• Architectural styles– Design

• Design patterns• Design anti-patterns

– Implementation• Idioms

Page 3: Software Design Patterns in Practice

3/213

Examples

Do you know– C++?– Java?– Lisp?– Prolog?– Smalltalk?

Page 4: Software Design Patterns in Practice

4/213

C++

class Dog {string name;

Dog(const Dog* dog) : name(dogname) {}}class Kennel { Dog* dog; string name; }

if (&kennel != this) {

thisdog =new Dog(kennel.dog);thisname = kennel.name;

}return *this;

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

Page 5: Software Design Patterns in Practice

5/213

C++

class Dog {string name;

Dog(const Dog* dog) : name(dogname) {}}class Kennel { Dog* dog; string name; }

if (&kennel != this) {

thisdog =new Dog(kennel.dog);thisname = kennel.name;

}return *this;

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

?

Page 6: Software Design Patterns in Practice

6/213

C++

class Dog {string name;

Dog(const Dog* dog) : name(dogname) {}}class Kennel { Dog* dog; string name; }

if (&kennel != this) {

thisdog =new Dog(kennel.dog);thisname = kennel.name;

}return *this;

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

?Overriding of operator =

Page 7: Software Design Patterns in Practice

7/213

Java

final Object oldListOfEntities =this.listOfEntities();

this.fireVetoableChange("RemoveEntity",oldListOfEntities,anEntity);

this.removeEntity(anEntity);this.firePropertyChange(

"RemoveEntity",oldListOfEntities,anEntity);

Page 8: Software Design Patterns in Practice

8/213

Java

final Object oldListOfEntities =this.listOfEntities();

this.fireVetoableChange("RemoveEntity",oldListOfEntities,anEntity);

this.removeEntity(anEntity);this.firePropertyChange(

"RemoveEntity",oldListOfEntities,anEntity);

?

Page 9: Software Design Patterns in Practice

9/213

Java

final Object oldListOfEntities =this.listOfEntities();

this.fireVetoableChange("RemoveEntity",oldListOfEntities,anEntity);

this.removeEntity(anEntity);this.firePropertyChange(

"RemoveEntity",oldListOfEntities,anEntity);

?Veto protocol of JavaBeans

Page 10: Software Design Patterns in Practice

10/213

(define (square ls)(if (null? ls)

'()(cons ((lambda(x) (* x x))

(car ls))(square (cdr ls)))))

Lisp

Page 11: Software Design Patterns in Practice

11/213

(define (square ls)(if (null? ls)

'()(cons ((lambda(x) (* x x))

(car ls))(square (cdr ls)))))

Lisp

?

Page 12: Software Design Patterns in Practice

12/213

(define (square ls)(if (null? ls)

'()(cons ((lambda(x) (* x x))

(car ls))(square (cdr ls)))))

Lisp

?Map

Page 13: Software Design Patterns in Practice

13/213

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)).

Page 14: Software Design Patterns in Practice

14/213

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)).

?

Page 15: Software Design Patterns in Practice

15/213

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

Page 16: Software Design Patterns in Practice

16/213

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.

Page 17: Software Design Patterns in Practice

17/213

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.

?

Page 18: Software Design Patterns in Practice

18/213

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

Page 19: Software Design Patterns in Practice

19/213

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

Page 20: Software Design Patterns in Practice

20/213

Outline

Definition Quality Form Example Catalogue Practice Conclusion

Page 21: Software Design Patterns in Practice

21/213

Outline

Definition Quality Form Example Catalogue Practice Conclusion

Page 22: Software Design Patterns in Practice

22/213

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

Page 23: Software Design Patterns in Practice

23/213

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

Page 24: Software Design Patterns in Practice

24/213

Definition

“Each pattern describes a problem which occurs over and over again in our environment, and then describes the core of 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

Page 25: Software Design Patterns in Practice

25/213

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

Page 26: Software Design Patterns in Practice

26/213

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

Page 27: Software Design Patterns in Practice

27/213

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

Page 28: Software Design Patterns in Practice

28/213

JHotDrawhttp://www.jhotdraw.org/

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

Page 29: Software Design Patterns in Practice

29/213

Definition

A pattern is a general reusable solution to a commonly occurring problem within a given context in software development, operation, and maintenance

Page 30: Software Design Patterns in Practice

30/213

Definition

A pattern is a general reusable solution to a commonly occurring problem within a given context in software development, operation, and maintenance– Patterns have been identified for

• Different phases of software development• Different levels of abstraction• Different technologies• …

Page 31: Software Design Patterns in Practice

31/213

Definition

A pattern is a general reusable solution to a commonly occurring problem within a given context in software development, operation, and maintenance

Page 32: Software Design Patterns in Practice

32/213

Definition

A pattern is a general reusable solution to a commonly occurring problem within a given context in software development, operation, 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…

Page 33: Software Design Patterns in Practice

33/213

Definition

A pattern is a general reusable solution to a commonly occurring problem within a given context in software development, operation, and maintenance

Page 34: Software Design Patterns in Practice

34/213

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

Page 35: Software Design Patterns in Practice

35/213

Definition

A pattern is a general reusable solution to a commonly occurring problem within a given context in software development, operation, and maintenance

Page 36: Software Design Patterns in Practice

36/213

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

Page 37: Software Design Patterns in Practice

37/213

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

Page 38: Software Design Patterns in Practice

38/213

Recall the C++ Example

class Dog {string name;

Dog(const Dog* dog) : name(dogname) {}}class Kennel { Dog* dog; string name; }

if (&kennel != this) {

thisdog =new Dog(kennel.dog);thisname = kennel.name;

}return *this;

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

Page 39: Software Design Patterns in Practice

39/213

Recall the C++ Example

class Dog {string name;

Dog(const Dog* dog) : name(dogname) {}}class Kennel { Dog* dog; string name; }

if (&kennel != this) {

thisdog =new Dog(kennel.dog);thisname = kennel.name;

}return *this;

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

Page 40: Software Design Patterns in Practice

40/213

Recall the C++ Example

class Dog {string name;

Dog(const Dog* dog) : name(dogname) {}}class Kennel { Dog* dog; string name; }

if (&kennel != this) {

thisdog =new Dog(kennel.dog);thisname = kennel.name;

}return *this;

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

Development, operation, and maintenance

Page 41: Software Design Patterns in Practice

41/213

Recall the C++ Example

class Dog {string name;

Dog(const Dog* dog) : name(dogname) {}}class Kennel { Dog* dog; string name; }

if (&kennel != this) {

thisdog =new Dog(kennel.dog);thisname = 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

Page 42: Software Design Patterns in Practice

42/213

Recall the C++ Example

class Dog {string name;

Dog(const Dog* dog) : name(dogname) {}}class Kennel { Dog* dog; string name; }

if (&kennel != this) {

thisdog =new Dog(kennel.dog);thisname = 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

Page 43: Software Design Patterns in Practice

43/213

Outline

Definition Quality Form Example Catalogue Practice Conclusion

Page 44: Software Design Patterns in Practice

44/213

Quality

A means to enhance the reusability– Of the code written using the pattern

+ Its flexibility– Of the problem and its solution

Page 45: Software Design Patterns in Practice

45/213

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

Page 46: Software Design Patterns in Practice

46/213

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

Page 47: Software Design Patterns in Practice

47/213

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”

Page 48: Software Design Patterns in Practice

48/213

Quality Without a Name

Page 49: Software Design Patterns in Practice

49/213

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

Page 50: Software Design Patterns in Practice

50/213

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

Page 51: Software Design Patterns in Practice

51/213

Quality Without a Name

Page 52: Software Design Patterns in Practice

52/213

Quality Without a Name

ニワトリのヒナの雌雄鑑別

(chick sexing)

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

Page 53: Software Design Patterns in Practice

53/213

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 other. The master would give feedback: yes or no.”

—Eagleman, 2011

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

Page 54: Software Design Patterns in Practice

54/213

Page 55: Software Design Patterns in Practice

55/213

Practice, practiceand practice more

Page 56: Software Design Patterns in Practice

56/213

Page 57: Software Design Patterns in Practice

57/213

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 of any “stopping rule” to determine when a solution has been reached, and no ultimate test of whether a solution meets the requirements.”

—Zhang and Budgen, 2012

Page 58: Software Design Patterns in Practice

58/213

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)

Page 59: Software Design Patterns in Practice

59/213

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)

Page 60: Software Design Patterns in Practice

60/213

Outline

Definition Quality Form Example Catalogue Practice Conclusion

Page 61: Software Design Patterns in Practice

61/213

Form

Several books, articles– “Theoretical”– With examples

– Among others…

Page 62: Software Design Patterns in Practice

62/213

Form

Several books, articles– “Theoretical”– With examples

– Among others…

Page 63: Software Design Patterns in Practice

63/213

Form

Several books, articles– “Theoretical”– With examples

– Among others…

Page 64: Software Design Patterns in Practice

64/213

Form

Several books, articles– “Theoretical”– With examples

– Among others…

Page 65: Software Design Patterns in Practice

65/213

Form

Several books, articles– “Theoretical”– With examples

– Among others…

Page 66: Software Design Patterns in Practice

66/213

Form

Several books, articles– “Theoretical”– With examples

– Among others…

Page 67: Software Design Patterns in Practice

67/213

Form

Several books, articles– Amazon.com

• Books › Computers & Technology › Programming ›Software Design, Testing & Engineering › Object-Oriented Design › "patterns"

• 224 results on May 31, 2013

Page 68: Software Design Patterns in Practice

68/213

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

Page 69: Software Design Patterns in Practice

69/213

Form1. Pattern-Oriented Software Architecture, Patterns for Concurrent and Networked Objects: Volume 2 (Wiley Software...

by Douglas C. Schmidt, Michael Stal, Hans Rohnert and Frank Buschmann2. Pattern-Oriented Software Architecture, Patterns for Resource Management: Volume 3 (Wiley Software Patterns

Series... by Michael Kircher and Prashant Jain3. Pattern-Oriented Software Architecture, A System of Patterns: Volume 1 (Wiley Software Patterns Series) by Frank

Buschmann, Regine Meunier, Hans Rohnert and Peter Sommerlad4. Pattern-Oriented Software Architecture For Dummies (For Dummies (Computers)) by Robert Hanmer5. Web Security Patterns by Ramesh Nagappan and Christopher Steel6. Safe C++ by Vladimir Kushnir7. Programming in the Large with Design Patterns by Eddie Burris8. Elemental Design Patterns by Jason McC. Smith9. Java Application Architecture: Modularity Patterns with Examples Using OSGi (Robert C. Martin Series) by Kirk

Knoernschild10. Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions (Addison-Wesley

Signature... by Gregor Hohpe and Bobby Woolf11. Patterns of Enterprise Application Architecture (Addison-Wesley Signature Series (Fowler)) by Martin Fowler12. Cognitive Patterns: Problem-Solving Frameworks for Object Technology by Robert K Konitzer, Bobbin Teegarden,

Alexander Rush and Karen M Gardner13. Service Design Patterns: Fundamental Design Solutions for SOAP/WSDL and RESTful Web Services by Robert

Daigneau14. The ACE Programmer's Guide: Practical Design Patterns for Network and Systems Programming by Stephen D.

Huston, James CE Johnson and Umar Syyid15. Patterns for Parallel Software Design (Wiley Software Patterns Series) by Jorge Luis Ortega-Arjona16. Design Patterns in Object-oriented ABAP by Igor Barbaric17. Object-Oriented Reengineering Patterns by Oscar Nierstrasz, Stéphane Ducasse and Serge Demeyer18. Dependency Injection by Dhanji R. Prasanna19. Object-Oriented Software Engineering Using UML, Patterns, and Java (3rd Edition) by Bernd Bruegge and Allen H.

Dutoit20. J2EE Design Patterns by William Crawford and Jonathan Kaplan21. Applying UML and Patterns: An Introduction to Object-oriented Analysis and Design and Iterative Development by

Craig Larman22. Object-oriented Analysis and Design Using Umlan Introduction to Unified Process and Design Patterns by Mahesh P.

Matha23. C++ Design Patterns and Derivatives Pricing (Mathematics, Finance and Risk) by M. S. Joshi24. Effective Java (2nd Edition) by Joshua Bloch25. Patterns for Fault Tolerant Software (Wiley Software Patterns Series) by Robert Hanmer26. Implementation Patterns by Kent Beck27. Patterns for Computer-Mediated Interaction (Wiley Software Patterns Series) by Till Schummer and Stephan Lukosch28. Pattern Oriented Software Architecture Volume 5: On Patterns and Pattern Languages by Frank Buschmann, Kevlin

Henney and Douglas C. Schmidt29. Object-Oriented Analysis and Design with Applications (3rd Edition) by Grady Booch, Robert A. Maksimchuk, Michael

W. Engle and Bobbi J. Young30. 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 Martin32. Design Patterns For Dummies by Steve Holzner33. Pattern Languages of Program Design 5 by Dragos Manolescu, Markus Voelter and James Noble34. Design Patterns in Java(TM) (Software Patterns Series) by Steven John Metsker and William C. Wake35. 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 Rumbaugh38. Remoting Patterns: Foundations of Enterprise, Internet and Realtime Distributed Object Middleware (Wiley

Software... by Markus Völter, Michael Kircher and Uwe Zdun39. Software Factories: Assembling Applications with Patterns, Models, Frameworks, and Tools (Wiley Application

Development... by Jack Greenfield, Keith Short, Steve Cook and Stuart Kent40. Refactoring to Patterns by Joshua Kerievsky41. Architecting Enterprise Solutions: Patterns for High-Capability Internet-based Systems (Wiley Software Patterns...

by Paul Dyson and Andrew Longshaw42. Enterprise Patterns and MDA: Building Better Software with Archetype Patterns and UML by Jim Arlow and Ila

Neustadt43. Data Access Patterns: Database Interactions in Object-Oriented Applications by Clifton Nock44. Domain-Driven Design: Tackling Complexity in the Heart of Software by Eric Evans45. Pattern-Oriented Analysis and Design: Composing Patterns to Design Software Systems by Sherif M. Yacoub,

Hany H. Ammar, Sherif Yacoub and Hany Ammar46. Java Extreme Programming Cookbook by Eric M. Burke and Brian M. Coyner47. J2EE Best Practices: Java Design Patterns, Automation, and Performance (Wiley Application Development

Series) by Darren Broemmer48. Real-Time Design Patterns: Robust Scalable Architecture for Real-Time Systems by Bruce Powel Douglass49. Design Patterns Java¿ Workbook by Steven John Metsker50. EJB Design Patterns: Advanced Patterns, Processes, and Idioms by Floyd Marinescu51. Streamlined Object Modeling: Patterns, Rules, and Implementation by Jill Nicola, Mark Mayfield and Mike Abney52. Design Patterns Explained: A New Perspective on Object-Oriented Design by Alan Shalloway and James Trott53. Small Memory Software: Patterns for systems with limited memory (Software Patterns Series) by James Noble

and Charles Weir54. AntiPatterns in Project Management by William J. Brown, Hays W. "Skip" McCormick III and Scott W. Thomas55. Pattern Languages of Program Design 4 (Software Patterns Series) by Brian Foote, Neil Harrison and Hans

Rohnert56. Testing Object-Oriented Systems: Models, Patterns, and Tools by Robert V. Binder57. Design Patterns and Contracts by Jean-Marc Jezequel, Michel Train and Christine Mingins58. Object-Oriented Software Development Using Java: Principles, Patterns, and Frameworks (1/e) by Xiaoping Jia59. Refactoring: Improving the Design of Existing Code by Martin Fowler, Kent Beck, John Brant and William Opdyke60. More Process Patterns: Delivering Large-Scale Systems Using Object Technology (SIGS: Managing Object

Technology... by Scott W. Ambler61. Pattern Hatching: Design Patterns Applied by John Vlissides62. AntiPatterns: Refactoring Software, Architectures, and Projects in Crisis by William J. Brown, Raphael C. Malveau,

Hays W. "Skip" McCormick and Thomas J. Mowbray63. A Little Java, A Few Patterns (Language, Speech, & Communication) by Matthias Felleisen, Daniel P. Friedman

and Ralph E. Johnson64. Pattern Languages of Program Design 3 (v. 3) by Robert C. Martin, Dirk Riehle and Frank Buschmann65. Object Models: Strategies, Patterns, and Applications (2nd Edition) by Peter Coad, David North and Mark Mayfield66. Analysis Patterns: Reusable Object Models by Martin Fowler67. Patterns of Software: Tales from the Software Community by Richard P. Gabriel68. Pattern Languages of Program Design 2 (v. 2) by John Vlissides, James O. Coplien and Norman L. Kerth69. Software Patterns by James Coplien70. Software Architecture: Perspectives on an Emerging Discipline by Mary Shaw and David Garlan71. Adaptive Object-Oriented Software: The Demeter Method with Propagation Patterns: The Demeter Method with

Propagation... by Karl Lieberherr72. Pattern Languages of Program Design by James O. Coplien and Douglas C. Schmidt

Page 70: Software Design Patterns in Practice

70/213

Form

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

—Christopher Alexander, 1977

Page 71: Software Design Patterns in Practice

71/213

Form

General form as for the GoFalso inspired by Coplien’s form– Name– Problem(s)– Solution– Consequences

Page 72: Software Design Patterns in Practice

72/213

Form (Extended)

General form as for the GoFalso inspired by Coplien’s form– Name– Problem(s)– Example(s)– Solution– Example(s)– Consequences– (Follow-up)

Page 73: Software Design Patterns in Practice

73/213

Form

General form as for the GoFalso inspired by Coplien’s form– Not formal– Room for interpretation

– But…• UML-like class diagrams• UML-like sequence diagrams• Smalltalk / C++ example code

Page 74: Software Design Patterns in Practice

74/213

Outline

Definition Quality Form Example Catalogue Practice Conclusion

Page 75: Software Design Patterns in Practice

75/213

Example (1/5)

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

• Build DefaultMutableTreeNodesjavax.swing.tree.DefaultMutableTreeNode

for a graphical representation of the AST

• Bind types• Generate code• …

Page 76: Software Design Patterns in Practice

76/213

Example (1/5)

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

• Build DefaultMutableTreeNodesjavax.swing.tree.DefaultMutableTreeNode

for a graphical representation of the AST

• Bind types• Generate code• …

Page 77: Software Design Patterns in Practice

77/213

Example (2/5)

AST

Field

generateCode()

Statement

generateCode()

Method

generateCode()

Class

generateCode()

CompilationUnit

generateCode()

Main

Page 78: Software Design Patterns in Practice

78/213

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. */

}

Page 79: Software Design Patterns in Practice

79/213

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

}

Page 80: Software Design Patterns in Practice

80/213

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;

}}

Page 81: Software Design Patterns in Practice

81/213

Naïve Implementation (1/7)

How to generate microcode for– Microsoft Windows operating system– Intel Pentium processor

Page 82: Software Design Patterns in Practice

82/213

Naïve Implementation (1/7)

How to generate microcode for– Microsoft Windows operating system– Intel Pentium processor

Add a generateCode()method in each class

Page 83: Software Design Patterns in Practice

83/213

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;

}}

Page 84: Software Design Patterns in Practice

84/213

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;

}}

Page 85: Software Design Patterns in Practice

85/213

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;

}}

Page 86: Software Design Patterns in Practice

86/213

Naïve Implementation (5/7)

cu : CompilationUnit

c : Class m : Method s : Statementm : Main

generateCode( )

generateCode( )

generateCode( )

generateCode( )

Page 87: Software Design Patterns in Practice

87/213

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?

Page 88: Software Design Patterns in Practice

88/213

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

Page 89: Software Design Patterns in Practice

89/213

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!

Page 90: Software Design Patterns in Practice

90/213

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!

Page 91: Software Design Patterns in Practice

91/213

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 operation without changing the classes of the elements on which it operates.”

Page 92: Software Design Patterns in Practice

92/213

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

Page 93: Software Design Patterns in Practice

93/213

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

Page 94: Software Design Patterns in Practice

94/213

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

Page 95: Software Design Patterns in Practice

95/213

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

Page 96: Software Design Patterns in Practice

96/213

Visitor (8/13)

Applicability– An object structure contains many classes of

objects 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 operations over the structure…

Page 97: Software Design Patterns in Practice

97/213

Visitor (9/13)

Structure

Page 98: Software Design Patterns in Practice

98/213

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

Page 99: Software Design Patterns in Practice

99/213

Visitor (11/13)

Collaborations

Page 100: Software Design Patterns in Practice

100/213

Visitor (13/13)

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

– ASTs– Meta-models– …

Related patterns: Composite

Page 101: Software Design Patterns in Practice

101/213

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);

}

Page 102: Software Design Patterns in Practice

102/213

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);

}}

Page 103: Software Design Patterns in Practice

103/213

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);

}}

Page 104: Software Design Patterns in Practice

104/213

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);

}}

Page 105: Software Design Patterns in Practice

105/213

Bet

ter i

mpl

emen

tatio

n

(5/6

)

Page 106: Software Design Patterns in Practice

106/213

Bet

ter i

mpl

emen

tatio

n

(5/6

)cu :

CompilationUnitc : Class m : Method s : Statementm : Main

generateCode( )

generateCode( )

generateCode( )

generateCode( )

Page 107: Software Design Patterns in Practice

107/213

Bet

ter i

mpl

emen

tatio

n

(5/6

) m : Main cu : CompilationUnit

c : Class m : Method s : Statement v : IVisitor

accept(IVisitor)

accept(IVisitor)

accept(IVis itor)

accept(IVisitor)open(CompilationUnit)

open(Clas s)

open(Method)

visit(Statement)

close(Method)

close(Class)

close(CompilationUnit)

Page 108: Software Design Patterns in Practice

108/213

cu : CompilationUnit

c : Class m : Method s : Statementm : 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)open(CompilationUnit)

open(Clas s)

open(Method)

visit(Statement)

close(Method)

close(Class)

close(CompilationUnit)

Page 109: Software Design Patterns in Practice

109/213

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

Page 110: Software Design Patterns in Practice

110/213

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!

Page 111: Software Design Patterns in Practice

111/213

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!

Page 112: Software Design Patterns in Practice

112/213

Outline

Definition Quality Form Example Catalogue Practice Conclusion

Page 113: Software Design Patterns in Practice

113/213

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

Page 114: Software Design Patterns in Practice

114/213

Catalogue

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

Divided in three categories– Behavioural– Creational– Structural

Page 115: Software Design Patterns in Practice

115/213

Catalogue

Page 116: Software Design Patterns in Practice

116/213

Catalogue

Page 117: Software Design Patterns in Practice

117/213

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

Page 118: Software Design Patterns in Practice

118/213

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

Page 119: Software Design Patterns in Practice

119/213

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

Page 120: Software Design Patterns in Practice

120/213

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 of objects uniformly

Page 121: Software Design Patterns in Practice

121/213

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

Page 122: Software Design Patterns in Practice

122/213

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

Page 123: Software Design Patterns in Practice

123/213

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

Page 124: Software Design Patterns in Practice

124/213

Catalogue

Mediator (273) – Define an object that encapsulates how a set of

objects 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 object can be restored to this state later

Page 125: Software Design Patterns in Practice

125/213

Catalogue

Observer (293) – Define a one-to-many dependency between

objects 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

Page 126: Software Design Patterns in Practice

126/213

Catalogue

Proxy (207) – Provide a surrogate or placeholder for another

object to control access to it. Singleton (127)

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

Page 127: Software Design Patterns in Practice

127/213

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

one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it

Page 128: Software Design Patterns in Practice

128/213

Catalogue

Template Method (325) – Define the skeleton of an algorithm in an

operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure

Page 129: Software Design Patterns in Practice

129/213

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

Page 130: Software Design Patterns in Practice

130/213

Outline

Definition Quality Form Example Catalogue Practice Conclusion

Page 131: Software Design Patterns in Practice

131/213

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

Page 132: Software Design Patterns in Practice

132/213

Practice

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

—Erich Gamma, 1994

Page 133: Software Design Patterns in Practice

133/213

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

Page 134: Software Design Patterns in Practice

134/213

The following is only complementaryto reading books and practicing

Page 135: Software Design Patterns in Practice

135/213

Practice

Scattered information– Informal text

A suggested example rather than a general rule

Interpreting them all...

Page 136: Software Design Patterns in Practice

136/213

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

Page 137: Software Design Patterns in Practice

137/213

Practice

Iterative induction process – From an example to an abstraction to an

application to the abstraction to an application…

– Validation process?

Applying them all...

Page 138: Software Design Patterns in Practice

138/213

Practice

Use known categories– Behavioural – Creational – Structural

Use the Internet

Read and discuss others’ code

Page 139: Software Design Patterns in Practice

139/213

Practice

Use known categories– Behavioural – Creational – Structural

Use the Internet

Read and discuss others’ code

Page 140: Software Design Patterns in Practice

140/213

Read and discuss others’ code

Page 141: Software Design Patterns in Practice

141/213

Practice

Assess the trade-offs– Flexibility– Complexity

Page 142: Software Design Patterns in Practice

142/213

Practice

Assess the trade-offs– Flexibility– Complexity

Page 143: Software Design Patterns in Practice

143/213

Practice

Assess the trade-offs– Flexibility– Complexity

Sometimes it is necessary to remove the solution of a DP used in the code

Page 144: Software Design Patterns in Practice

144/213

Practice

Sometimes it is necessary to remove the solution of a DP used in the code

Page 145: Software Design Patterns in Practice

145/213

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 citingMartin Fowler, 2004

Page 146: Software Design Patterns in Practice

146/213

Page 147: Software Design Patterns in Practice

147/213

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

Page 148: Software Design Patterns in Practice

148/213

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

Page 149: Software Design Patterns in Practice

149/213

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

Page 150: Software Design Patterns in Practice

150/213

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(…)

Page 151: Software Design Patterns in Practice

151/213

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(…)

• What if the data structure changes?

Page 152: Software Design Patterns in Practice

152/213

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(…)

• What if the data structure changes?

Page 153: Software Design Patterns in Practice

153/213

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(…)

• What if the data structure changes?

– Solution• Use the introspection mechanism of Java

Page 154: Software Design Patterns in Practice

154/213

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(…)

• What if the data structure changes?

– Solution• Use the introspection mechanism of Java

Page 155: Software Design Patterns in Practice

155/213

Prac

tice

U

se th

e in

trosp

ectio

n m

echa

nism

of J

ava

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;

}

Page 156: Software Design Patterns in Practice

156/213

Prac

tice

U

se th

e in

trosp

ectio

n m

echa

nism

of J

ava

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

Page 157: Software Design Patterns in Practice

157/213

Prac

tice

U

se th

e in

trosp

ectio

n m

echa

nism

of J

ava

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;

}

Page 158: Software Design Patterns in Practice

158/213

Prac

tice

U

se th

e in

trosp

ectio

n m

echa

nism

of J

ava

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;

}

Page 159: Software Design Patterns in Practice

159/213

Prac

tice

U

se th

e in

trosp

ectio

n m

echa

nism

of J

ava

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;

}

Page 160: Software Design Patterns in Practice

160/213

Prac

tice

U

se th

e in

trosp

ectio

n m

echa

nism

of J

ava

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);

}

}

Page 161: Software Design Patterns in Practice

161/213

Practice

Use the introspection mechanism of Java– No more duplicated accept(…) methods– Handles cases for visit(…) and open(…)+close(…)

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

Page 162: Software Design Patterns in Practice

162/213

Practice

Use the introspection mechanism of Java– No more duplicated accept(…) methods– Handles cases for visit(…) and open(…)+close(…)

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

Page 163: Software Design Patterns in Practice

163/213

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

Page 164: Software Design Patterns in Practice

164/213

Prac

tice

R

efac

torin

g aw

ay fr

om th

e Vi

sito

r

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

}

Page 165: Software Design Patterns in Practice

165/213

Prac

tice

R

efac

torin

g aw

ay fr

om th

e Vi

sito

r

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();

Page 166: Software Design Patterns in Practice

166/213

Prac

tice

R

efac

torin

g aw

ay fr

om th

e Vi

sito

r

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

}

Page 167: Software Design Patterns in Practice

167/213

Prac

tice

R

efac

torin

g aw

ay fr

om th

e Vi

sito

r

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]);

}

}

Page 168: Software Design Patterns in Practice

168/213

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

objects, they are not a Composite object

– Unnecessary code, complexity

Page 169: Software Design Patterns in Practice

169/213

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

objects, they are not a Composite object

– Unnecessary code, complexity

Page 170: Software Design Patterns in Practice

170/213

Practice

Unnecessary code, complexity– Trade-offs of (most of) design patterns

Page 171: Software Design Patterns in Practice

171/213

Practice

Unnecessary code, complexity– Trade-offs of (most of) design patterns

Flexibility

Page 172: Software Design Patterns in Practice

172/213

Practice

Unnecessary code, complexity– Trade-offs of (most of) design patterns

Flexibility Complexity

Page 173: Software Design Patterns in Practice

173/213

Practice

Trade-offs of (most of) design patterns– Flexibility

• Favouring composition over inheritance

– Complexity• More objects interacting • More messages exchanged

Page 174: Software Design Patterns in Practice

174/213

Practice

Trade-offs of (most of) design patterns– Flexibility

• Favouring composition over inheritance

– Complexity• More objects interacting • More messages exchanged

Page 175: Software Design Patterns in Practice

175/213

cu : CompilationUnit

c : Class m : Method s : Statementm : 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)open(CompilationUnit)

open(Clas s)

open(Method)

visit(Statement)

close(Method)

close(Class)

close(CompilationUnit)

Page 176: Software Design Patterns in Practice

176/213

cu : CompilationUnit

c : Class m : Method s : Statementm : 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)open(CompilationUnit)

open(Clas s)

open(Method)

visit(Statement)

close(Method)

close(Class)

close(CompilationUnit)

Plus the use of reflection!

Page 177: Software Design Patterns in Practice

177/213

Practice

Trade-offs of (most of) design patterns– Flexibility

• Favouring composition over inheritance

– Complexity• More objects interacting • More messages exchanged

Page 178: Software Design Patterns in Practice

178/213

Practice

Trade-offs of (most of) design patterns– Flexibility

• Favouring composition over inheritance

– Complexity• More objects interacting • More messages exchanged

Page 179: Software Design Patterns in Practice

179/213

Practice

Flexibility– Favour composition over inheritance

• Allow changing implementation• Allow safe inheritance

Page 180: Software Design Patterns in Practice

180/213

Practice

Flexibility– Favour composition over inheritance

• Allow changing implementation• Allow safe inheritance

Add one level of indirection

Page 181: Software Design Patterns in Practice

181/213

Practice

Flexibility– Favour composition over inheritance

• Allow changing implementation• Allow safe inheritance

Add one level of indirectionand (possibly)

Use double-dispatch

Page 182: Software Design Patterns in Practice

182/213

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

Page 183: Software Design Patterns in Practice

183/213

Practice

Add one level of indirection

http://itewbm.tistory.com/29

Page 184: Software Design Patterns in Practice

184/213

Practice

Add one level of indirection

http://itewbm.tistory.com/29

Page 185: Software Design Patterns in Practice

185/213

Practice

Add one level of indirection

http://itewbm.tistory.com/29

Page 186: Software Design Patterns in Practice

186/213

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

Page 187: Software Design Patterns in Practice

187/213

Page 188: Software Design Patterns in Practice

188/213

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

Page 189: Software Design Patterns in Practice

189/213

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

No special code for “no behaviour”

with the NullObject design pattern

Page 190: Software Design Patterns in Practice

190/213

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

Encapsulate what varies

Page 191: Software Design Patterns in Practice

191/213

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)

Page 192: Software Design Patterns in Practice

192/213

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)

Page 193: Software Design Patterns in Practice

193/213

Practice

Use double-dispatch– Object receives a message– Object sends a message back

with itself as parameter

Page 194: Software Design Patterns in Practice

194/213

Practice

Use double-dispatch– Object receives a message– Object sends a message back

with itself as parameter

Page 195: Software Design Patterns in Practice

195/213

Practice

print(CtxWriter aCTXWriter, Rect aRectangle) { ... }...print(StringWriter aStringWriter, Triangle aTriangle) { ... }...

PrinterWriter printer = new SystemWriter();IShape shape = new Square();print(printer, shape);

Page 196: Software Design Patterns in Practice

196/213

Practice

print(CtxWriter aCTXWriter, Rect aRectangle) { ... }...print(StringWriter aStringWriter, Triangle aTriangle) { ... }...

PrinterWriter printer = new SystemWriter();IShape shape = new Square();print(printer, shape);

Page 197: Software Design Patterns in Practice

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

public class SystemWriter implements PrinterWriter {@Overridepublic void print(final Rect rect) {

System.out.print("Printed the rectangle: ");System.out.println(this);

}@Overridepublic void print(final Square aSquare) {

System.out.print("Printed the square: ");System.out.println(this);

}}

public class Rect implements IShape {@Overridepublic void printOn(final PrinterWriter aWriter) {

aWriter.print(this);}

}

public class Square implements IShape {@Overridepublic 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);

}

Page 198: Software Design Patterns in Practice

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

public class SystemWriter implements PrinterWriter {@Overridepublic void print(final Rect rect) {

System.out.print("Printed the rectangle: ");System.out.println(this);

}@Overridepublic void print(final Square aSquare) {

System.out.print("Printed the square: ");System.out.println(this);

}}

public class Rect implements IShape {@Overridepublic void printOn(final PrinterWriter aWriter) {

aWriter.print(this);}

}

public class Square implements IShape {@Overridepublic 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);

}

Page 199: Software Design Patterns in Practice

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

public class SystemWriter implements PrinterWriter {@Overridepublic void print(final Rect rect) {

System.out.print("Printed the rectangle: ");System.out.println(this);

}@Overridepublic void print(final Square aSquare) {

System.out.print("Printed the square: ");System.out.println(this);

}}

public class Rect implements IShape {@Overridepublic void printOn(final PrinterWriter aWriter) {

aWriter.print(this);}

}

public class Square implements IShape {@Overridepublic 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);

}

Page 200: Software Design Patterns in Practice

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

public class SystemWriter implements PrinterWriter {@Overridepublic void print(final Rect rect) {

System.out.print("Printed the rectangle: ");System.out.println(this);

}@Overridepublic void print(final Square aSquare) {

System.out.print("Printed the square: ");System.out.println(this);

}}

public class Rect implements IShape {@Overridepublic void printOn(final PrinterWriter aWriter) {

aWriter.print(this);}

}

public class Square implements IShape {@Overridepublic 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);

}

Page 201: Software Design Patterns in Practice

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

public class SystemWriter implements PrinterWriter {@Overridepublic void print(final Rect rect) {

System.out.print("Printed the rectangle: ");System.out.println(this);

}@Overridepublic void print(final Square aSquare) {

System.out.print("Printed the square: ");System.out.println(this);

}}

public class Rect implements IShape {@Overridepublic void printOn(final PrinterWriter aWriter) {

aWriter.print(this);}

}

public class Square implements IShape {@Overridepublic 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);

}

Page 202: Software Design Patterns in Practice

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

public class SystemWriter implements PrinterWriter {@Overridepublic void print(final Rect rect) {

System.out.print("Printed the rectangle: ");System.out.println(this);

}@Overridepublic void print(final Square aSquare) {

System.out.print("Printed the square: ");System.out.println(this);

}}

public class Rect implements IShape {@Overridepublic void printOn(final PrinterWriter aWriter) {

aWriter.print(this);}

}

public class Square implements IShape {@Overridepublic 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);

}

Page 203: Software Design Patterns in Practice

203/213

Practice

Unnecessary code, complexity– Trade-offs of (most of) design patterns

Page 204: Software Design Patterns in Practice

204/213

Practice

Unnecessary code, complexity– Trade-offs of (most of) design patterns

Flexibility

Page 205: Software Design Patterns in Practice

205/213

Practice

Unnecessary code, complexity– Trade-offs of (most of) design patterns

Flexibility Complexity

Page 206: Software Design Patterns in Practice

206/213

Practice

Beware also of “bad” solutions to recurring design problems

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

Page 207: Software Design Patterns in Practice

207/213

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

Page 208: Software Design Patterns in Practice

208/213

Practice

Two examples of anti-patterns– Visitor design and JavaClasses

ptidej.statement.creator.classfiles.loc.BCELLOCFinder

– Blob (aka God Class)

Page 209: Software Design Patterns in Practice

209/213

Outline

Definition Quality Form Example Catalogue Practice Conclusion

Page 210: Software Design Patterns in Practice

210/213

Conclusion

Patterns ease communication

Patterns improve regularityand quality… even without a name…

Patterns avoid surprisesi.e., reinventing the wheel differently each time

Patterns generate architectures

Page 211: Software Design Patterns in Practice

211/213

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

Page 212: Software Design Patterns in Practice

212/213

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

Page 213: Software Design Patterns in Practice

213/213

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]