re factoring and design patterns

783
REFACTORING, SOFTWARE DEVELOPMENT AND DESIGN PATTERNS A book-sized thesis on software design

Upload: evans-krypton-sowah

Post on 03-Dec-2015

59 views

Category:

Documents


6 download

DESCRIPTION

Re Factoring and Design Patterns

TRANSCRIPT

Page 1: Re Factoring and Design Patterns

REFACTORING,

SOFTWARE

DEVELOPMENT

AND

DESIGN PATTERNS

A book-sized thesis on software design

Page 2: Re Factoring and Design Patterns

2 Peter Kaptein

HTMLMeta:: The tags in this HTML Meta block are used by DocumentShare to publish the pages to HTML, make decisions on what to publish when and add all the metadata on each page. ::Publish info} Published to HTML and ePub with DocumentShare ::Bookname} Refactoring and Design Patterns ::Filename} Refactoring-and-Design-Patterns ::Versions} 001,002 ::Current} 003 Versions

The version numbers will be used to create links to the previous versions of the presented numbers. If a previous version of that chapter does not exist or is added incorrectly, the resulting link will be a dead link. No corrections or checks on dead links are made in the publishing process

::Authors} Peter Kaptein ::ePubauthor} Kaptien, Peter ::Creation date} Created: December 17, 2011 ::Publication date} Last update: April 22, 2012 ::Content width} 700 pixels ::Print width} 700 pixels ::Copyright} © 2012 ::Publish settings} 1;Text;SubTOC|2;Text;SubTOC|3;Text;Subchapters

HTML Publish settings The text from the chapter is followed by the Table of Content of subchapters, for chapters of depth 1 and depth 2. The content of chapters of depth 3 will be published without TOC and will include the text from all subchapters. The subchapters from level 4 and deeper will not be published as separate HTML content.

::Tag link text} See: ::HTMLMeta

Page 3: Re Factoring and Design Patterns

Refactoring and Design Patterns 3

::Links} Refactoring and Design Patterns Peter Kaptein Last update: April 22, 2012 Status Chapters and Patterns marked with: ** are in revision Patterns marked with a: * are not addressed yet Downloads Downloads include: presentations and cheat sheets on Refactoring, OOP and Design Patterns. You are allowed to freely use this content to teach to classes and use within your company. Sites and blogs My Professional blog Beyond the Keyboard Blog posts on hardware hacking and tinkering HotForestGreen Internet of Things Framework © 2011, 2012 ::Links;

::footer} ::footer;

Page 4: Re Factoring and Design Patterns

4 Peter Kaptein

PART 1: INTRODUCTION 14

A brief oversight of the contents 15 About this book 20 Downloadable Content ** 30

PART 2: SCOPE AND PERSPECTIVE IN SOFTWARE DEVELOPMENT 33

Basics on scoping and perspective 34 What is beneficial and what is not? 66

PART 3: BASICS OF OBJECT ORIENTED PROGRAMMING 69

Introduction to OOP 70 OOP principles 79

PART 4: SOFTWARE ARCHITECTURE 115

PART 5: REFACTORING 116

Basics 117 Refactoring step by step 129 Elements of Refactoring ** 136

BOOK 2: DESIGN PATTERNS 176

PART 6: INTRODUCTION TO DESIGN PATTERNS AND DESIGN PRINCIPLES 177

Introduction to Design Patterns 178 Anti-patterns 196

PART 7: MACRO-PATTERNS AND DESIGN PRINCIPLES 197

Basics 198 Model, View, Controller 201 3-Tier 240 Manager, Handler, Operator, Parser, Utility, Data Object 244 Extended MVC and Separation of Responsibilities 276 Inversion of Control 290 Simulation, Actor, Rule, Behavior 300

PART 8: CLASSIFICATIONS OF DESIGN PATTERNS 301

The “Gang of Four” Design Patterns 302 Patterns ordered by type and use 304 Patterns mapped to context and environment ** 406

PART 9: DESIGN PATTERNS 427

Adapter 428

Page 5: Re Factoring and Design Patterns

Refactoring and Design Patterns 5

Bridge 443 Builder 468 Chain of Responsibility * 489 Command 490 Composite ** 502 Data Access Object * 512 Decorator 513 Delegate 532 Façade 550 Factory Method 567 Factory, Abstract 579 Factory, Simple 597 Flyweight * 610 Injector * 611 Interpreter ** 612 Manager 620 Mediator 635 Multiton * 651 Object Map ** 652 Object Pool * 660 Observer 661 Parser 682 Prototype * 707 Proxy 708 Reflection * 729 Singleton * 730 State 731 Strategy 748 Template Method * 764 Visitor 765

Page 6: Re Factoring and Design Patterns

6 Peter Kaptein

PART 1: INTRODUCTION 14

A brief oversight of the contents 15 Overview of the chapters 16 Scope and perspective in Software Design 16 Object Oriented Programming and Refactoring 16 Refactoring and Design Patterns 17 Software Design, Design Principles and Design Patterns 18 Understanding Design Patterns 18 Basic principles that will help you write better code 19

About this book 20 Forms in which this book is published 21 Why I wrote this book 21 Why I made it public 21 What I did 22 Books I read (and need to read) 24 The five assumptions I started from 26 What I thought this book would be 26 Who I am and where I come from 26 Intended audience and entry level 27 Code examples, or: the lack of 27 Some backgrounds 27 Licence 27 What made me do it 28

Downloadable Content ** 30 Download and share 31 eBooks 31 OOP Principles 31 The refactoring process 31 Design Patterns 32 presentations 32

PART 2: SCOPE AND PERSPECTIVE IN SOFTWARE DEVELOPMENT 33

Basics on scoping and perspective 34 What fits where? 35 A summary on Cycles of software realization ** 39 What approaches can you use? 48 Phases, approaches and relevance when building software 55

What is beneficial and what is not? 66 Choosing Design Patterns during Realization instead of in Design Phase 67 Refactor, refactor, refactor 67 Good is better than Perfect 68

PART 3: BASICS OF OBJECT ORIENTED PROGRAMMING 69

Introduction to OOP 70 Learning curve 71

Page 7: Re Factoring and Design Patterns

Refactoring and Design Patterns 7

Productivity curves 72 Why do we use it? 76 What is it? 78

OOP principles 79 A visual summary 80 Classes and objects 83 Strong Typing 85 Scoping methods and variables: static, local, private, protected, public, and final 87 Extraction, Encapsulation and Abstraction 91 Base classes 95 Specialization 96 Interfaces 106 Using Composition 111 Overloading and overriding Methods 114

PART 4: SOFTWARE ARCHITECTURE 115

PART 5: REFACTORING 116

Basics 117 What is it? 118 To refactor or not at all? 120 When will you Refactor? 124 When will you not Refactor? 124 Why is Refactoring beneficial? 125 Why is it relevant? 125 Why will Refactoring become one of your most valued assets? 126 Refactoring and Design Patterns 127

Refactoring step by step 129 The steps in a refactoring process 130 When is the refactoring process done? 134 Refactoring Pitfalls and dangers 135

Elements of Refactoring ** 136 Three main types of refactoring 137 Maintaining a stable project structure 155 Creating an Design Pattern agnostic Code Base 155 Promoting and Demoting your code 156 Using MVC and separation of responsibilities 159 Constants and remarks 172

BOOK 2: DESIGN PATTERNS 176

PART 6: INTRODUCTION TO DESIGN PATTERNS AND DESIGN PRINCIPLES 177

Introduction to Design Patterns 178 What are Design Patterns? 179 What are they not? 181 What are the main elements? 182 Where and how do they fit in your process? 187 Why are Design Patterns awesome? 189

Page 8: Re Factoring and Design Patterns

8 Peter Kaptein

How do you recognize Design Patterns in your own code? 191 When and how do you apply them? 191 What can go wrong? 192 How do you improve your use and implementation of Design Patterns? 194 How do you keep control? 194 Design Patterns and Game Development 195

Anti-patterns 196

PART 7: MACRO-PATTERNS AND DESIGN PRINCIPLES 197

Basics 198 Macro and Macro Patterns 199 Design Principles 199 Design Principles and Macro Patterns 199 Overview of Macro-Patterns and Design Principles 199

Model, View, Controller 201 A summary of the content in this chapter and the next chapters 202 The MVC Pattern 203 Different perspectives on the MVC Pattern 207 MCV and 3-Tier Development 215 Model, View, Hub, Interface: a deconstruction of MVC 221 Use and abuse of MVC 237

3-Tier 240 Diagrams 241

Manager, Handler, Operator, Parser, Utility, Data Object 244 Origins 245 Diagrams 245 Using MHOPUDO in Refactoring 247 The Manager and Manager Classes 250 The Handler and Handler Classes 255 The Operator and Operator Classes 260 The Utiliy and Utility Class 267 The Parser and Parser Class 269 Data Objects 273

Extended MVC and Separation of Responsibilities 276 Introduction 277 A visual summary of the Extended MVC Pattern 278 Overview of the type of objects we use within the Extended MVC Pattern 284

Inversion of Control 290 Diagrams 291 Basic definition 293 See also 293 Benefits of Dependency Injection 293 Inversion of Control and Design Patterns 294 Bonus material 298

Page 9: Re Factoring and Design Patterns

Refactoring and Design Patterns 9

Simulation, Actor, Rule, Behavior 300

PART 8: CLASSIFICATIONS OF DESIGN PATTERNS 301

The “Gang of Four” Design Patterns 302 Creational patterns 303 Structural Patterns 303 Behavioral Patterns 303

Patterns ordered by type and use 304 Patterns and their use 306 Wrapping, interfacing and abstraction 309 Delegation of actions 328 Creation of dynamic classes 342 Creation of objects and complex structures 356 Sharing and re-using objects 379 Events, instructions and communication 384 Data and data-transfer 399

Patterns mapped to context and environment ** 406 Overview 407 Client / Server 409 Synchronous / Asynchronous systems 410 Push / Pull mechanisms 412 Thin Clients 413 Rich Clients 415 Desktop Applications 417 Game Development 420

PART 9: DESIGN PATTERNS 427

Adapter 428 Intent (GoF) 429 Adapter basics 429 Diagrams 430 Comparisons and differences 437 Summary 440 See also 441 Aspects from “Design Patterns” 442

Bridge 443 Intent (GoF) 444 Bridge basics 444 Diagrams 446 When do you use Bridge? 454 Comparisons and differences 455 Summary 458 See also 459 Bonus material 460 Aspects from “Design Patterns” 467

Page 10: Re Factoring and Design Patterns

10 Peter Kaptein

Builder 468 Intent (GoF) 469 Builder basics 469 Diagrams 471 Summary 477 See also 478 Comparisons and differences 479 Bonus Material 482 Aspects from Design Patterns 488

Chain of Responsibility * 489 Command 490

Intent (GoF) 491 Command basics 491 Diagrams 493 When do you use the Command Pattern 498 Comparisons and differences 499 Summary 500 See also 500

Composite ** 502 Intent (GoF) 503 Diagrams 504 Comparisons and differences 508 Summary 509 See also 509 Aspects from Design Patterns 511

Data Access Object * 512 Decorator 513

Intent (GoF) 514 Decorator basics 514 Diagrams 515 When do you use it? 524 Comparisons and differences 525 Bonus material 528 Summary 529 See also 529 Aspects from “Design Patterns” 530

Delegate 532 Intent 533 Delegate basics 533 Diagrams 534 When do you use the Delegate Pattern? 543 Comparisons and differences 544 Summary 546 See also 547 Bonus material 548

Façade 550 Intent (GoF) 551 Façade basics 551

Page 11: Re Factoring and Design Patterns

Refactoring and Design Patterns 11

Diagrams 553 Simple diagram of the Façade 555 When do you use the Façade? 561 Comparisons and differences 561 Summary 564 See also 565 Aspects from “Design Patterns” 566

Factory Method 567 Intent(GoF) 568 Factory Method basics 568 Diagrams 569 Why would you use the Factory Method? 575 Comparisons and differences 575 Summary 577 See also 578 Aspects from Design Patterns 578

Factory, Abstract 579 Intent (GoF) 580 Abstract Factory basics 580 Diagrams 582 Why would you use an Abstract Factory? 590 Comparisons and differences 590 Summary 592 See also 593 Bonus material 594

Factory, Simple 597 Intent 598 Simple Factory basics 598 Diagrams 600 Why would you use the Simple Factory? 605 Comparisons and differences 606 Summary 608 See also 608 Bonus material 609

Flyweight * 610 Injector * 611 Interpreter ** 612

Intent (GoF) 613 Diagrams 614 Comparisons and differences 617 Summary 618 See also 618 Aspects from Design Patterns 619

Manager 620 Intent 621 Manager basics 621 Diagrams 623 When do you use the Manager? 630

Page 12: Re Factoring and Design Patterns

12 Peter Kaptein

Comparisons and differences 630 Summary 632 See also 633 Aspects from “Design Patterns” highlighted in this chapter 634

Mediator 635 Intent (GoF) 636 Mediator basics 636 Diagrams 638 When do you use the Mediator? 645 Comparisons and differences 646 Summary 648 See also 649 Aspects from “Design Patterns” 650

Multiton * 651 Object Map ** 652

Intent 653 The basis of the Object Map 653 Diagrams 654 Comparisons and differences 656 Summary 659 See also 659

Object Pool * 660 Observer 661

Intent (GoF) 662 The basis of the Observer Pattern 662 Diagrams 663 When do you use the Observer Pattern? 675 Comparisons and differences 676 Summary 679 See also 681

Parser 682 Intent 683 Parser basics 683 Diagrams 684 When do you use the Parser? 693 Comparisons and differences 694 Bonus material 696 Summary 705 See also 706

Prototype * 707 Proxy 708

Intent (GoF) 709 Proxy basics 709 Diagrams 711 When do you use which Proxy? 717 Comparisons and differences 718 Bonus material 720 Summary 725

Page 13: Re Factoring and Design Patterns

Refactoring and Design Patterns 13

See also 726 Aspects from “Design Patterns” 727

Reflection * 729 Singleton * 730 State 731

Intent (GoF) 732 State basics 732 Diagrams 733 When would you use State Pattern? 740 Comparisons and differences 741 Bonus material 743 Summary 744 See also 745 Aspects from Design Patterns 747

Strategy 748 Intent (GoF) 749 Strategy basics 749 Diagrams 750 When would you use the Strategy Pattern? 757 Comparisons and differences 758 Summary 760 See also 761 Aspects from Design Patterns 762

Template Method * 764 Visitor 765

Intent (GoF) 766 Visitor basics 766 Diagrams 768 When do you use the Visitor? 777 Comparisons and differences 778 Summary 780 See also 781 Aspects from Design Patterns 782

Page 14: Re Factoring and Design Patterns

14 Peter Kaptein

PART 1: INTRODUCTION ::Tag:Part1

Page 15: Re Factoring and Design Patterns

Refactoring and Design Patterns 15

A BRIEF OVERSIGHT OF THE CONTENTS ::includesubchapters ::Tag:BROF

Page 16: Re Factoring and Design Patterns

16 Peter Kaptein

OVERVIEW OF THE CHAPTERS

::Tag:BROF-CHPT Part 2: Scope and perspective What fits where? When does what becomes relevant in designing and building software? What approaches can you use? What is beneficial and what is not? Part 3: Basics of Object Oriented Programming Why do we use it? What is it? What are the base principles? Part 4: Software Architecture What are the basic principles? How do you setup your skeleton project? How do you stay agile, even when the requirements in your projects change several times? How do you make sure you do not get stuck in a dead end? Part 5: Factoring and Refactoring What is it? Why is it beneficial? Why is it relevant? Why will it become one of your most valued assets, your best friend ever when building software? Part 6 and 7: Design Patterns What are they? Where do they fit in your design and building process? Why are they awesome? How do you recognize them? How do build them? How do you become their master instead of their slave?

SCOPE AND PERSPECTIVE IN SOFTWARE DESIGN

::Tag:BROF-SCPR You need to start somewhere when you create software. Scope and Perspective is an attempt to summarize the process that makes a software project. Cycles Each process has a cycle through different stadia of development and progression. ::Link:SCOPE-CYCL Approaches ::Link:SCOPE-REL-001 Phases and relevance of specific elements ::Link:SCOPE-PH-001

OBJECT ORIENTED PROGRAMMING AND REFACTORING

::Tag:BROF-003 As stated before, giving you Design Patterns without the basics on OOP (Object Oriented Programming) and Refactoring is like giving you the parts of a machine without the manual on how to put them together.

Page 17: Re Factoring and Design Patterns

Refactoring and Design Patterns 17

Because of this basic principle I included sections on the very basics of OOP and Refactoring to help you grasp these concepts if you did not have the fortune yet to find and learn them form another source. These OOP and Refactoring principles include: Extraction, Encapsulation and Abstraction Extraction, Encapsulation and Abstraction is a three step process leading to code that is more Agile and more ready to re-use. ::Link:OOP-PRNC-EEA|OOP-PRNC-SPC Interfaces, Abstract classes and Base classes Interfaces, Abstract classes and Base classes allow you to make interchangeable classes and Objects and re-use specific functionalities ::Link:OOP-PRNC-INTF|OOP-PRNC-BCL Inheritance Inheritance includes the concepts of Extending classes, Specialization, Polymorphism, Constructors and Super- and Subclasses ::Link:OOP-PRNC-SPC

REFACTORING AND DESIGN PATTERNS

::Tag:BROF-001 I believe Design Patterns are a result of a process called Refactoring. Even though the word “design” is part of Design Patterns, they are seldomly created before coding started. In many cases they emerge from the code by reworking that code until it becomes more and more simple and more and more structured. To start the design process of software by: “What design Patterns shall we use in our project?” is like choosing and buying the building materials before you created the blueprint of the house. Design Patterns, according to this book, are: Repeating patterns emerging from your code This means that during the ongoing process of creation, certain choices and directions become more and more prevalent than others Concrete implementations of your working tools and your working materials Design Patterns are like the concrete building blocks for a kitchen and the hammers and drills you use to install it A result of refactoring When you refactor your code, the goal in general is to clean that code from rubbish and to put repeating patterns into separate classes. The moment you start to ::Link:RFCT-DPT

Page 18: Re Factoring and Design Patterns

18 Peter Kaptein

SOFTWARE DESIGN, DESIGN PRINCIPLES AND DESIGN

PATTERNS

::Tag:BROF-001a When architecting: what do you use instead? If Design Patterns are like building blocks, what Patterns can you use to Design or Architect your Software? And more concretely: what patterns can you use to structure and organize your Code? ::Link:INTRDP-MCRDP Using the Model, View, Controller Pattern MVC is a “Design Pattern” that is actually a way to structure your project. A philosophy to extract code from one place and put it somewhere else. ::Link: MVC Deconstructing the MVC Pattern The MVC Pattern has been used in many different ways. But whe you go back to the original definition, what do the different parts of the MVC Pattern actually do? To find out, I started to explore the variations and deconstruct and refactor the MVC pattern. ::Link: MVC-PATT-VAR|MVC-PATT-MVHI Using Manager, Handler, Operator, Parser, Utility and Data-object to separate responsibilities MHOPUDO is based on Organizational principles and emerged in 2008 / 2009 as a more solid way to quickly organize my classes. MHOPUDO focuses mainly on the Model in the MVC Pattern. It pretends that your code and your project is a company with different people and players in different and explicit roles. MHOPUDO takes distribution of Responsibilities as its main starting point. ::Link:MHOPUDO Design Principles: when Patterns are more generic Looking at Patterns like MVC and principles like Inversion of Control, a new chapter grew, focusing mainly on the Patterns which are too generic and non-specific to be Design Patterns. As they focus on principles, I decided to label them “Design Principles” instead. As said, MVC is part of that chapter, as are Inversion of Control, the Extended MVC Pattern and the aforementioned MHOPUDO. ::Link:INTRDP-MCRDP

UNDERSTANDING DESIGN PATTERNS

::Tag:BROF-002 If you are like me, your attempt to read “Design Patterns” by the Gang of Four, and any other book based on “Design Patterns” might have left you with a feeling of desperation and even less understanding what you thought it might have been about. Design Patterns in every day practice While the theory and principles behind the patterns is quite sound, the way these Patterns are described is usually very hard to translate to your everyday practice: When do you apply what design pattern? Where do they fit in your overall design? Which design pattern is most fit for what purpose? Part 8 tries to cover these questions by offering several classifications of Design Patterns, including the one from “Design Patterns” itself. ::Tag:CLSDP|PAT-TYPC Design Patterns and their scope

Page 19: Re Factoring and Design Patterns

Refactoring and Design Patterns 19

When you start using Design Patterns, one of the main questions might be: when do I start involving them in my process? What is the scope of Design Patterns? Do you take them as a starting point for your software design, or are they a consequence of the building process? My introduction to Design Patterns tries to give you a genral picture of the design process and where Desing Patterns might kick in. ::Link:INTRDP|INTRDP-CONT

BASIC PRINCIPLES THAT WILL HELP YOU WRITE BETTER

CODE

::Tag:BROF-004 To help you even further I introduce you to some basic concepts that are applicable in any situation and in whatever design process you are in. Those base principles are: Separation of Responsibilities Who does what where, when and why? More than anything in your design and organization of your code and your classes: “who does what, when and why” should be crystal clear. It is the number one Design Rule. Regardless of how many Design Patterns you have used, if the distribution of Responsibilities is unclear, you have failed in organizing your classes and your code ::Link:RFCT-ELM-SRSP The use of Abstraction and Encapsulation To write Agile Code – which will not break even if your project changes course many times – you need to understand how to apply Abstraction of code and Encapsulation. ::Link: OOP-PRNC-SPC Model Driven / Model Centered Design A concept in which the Model is the center of everything that happens. Whatever you do, display or hide, the Model is the one doing it 3-Tier Even though seemingly “overshadowed” by MVC ad a design principle, you will find that 3-Tier is a very valuable and more complete reference point to build your architecture and something that automatically will emerge once your start building Data Driven Applications ::Link:INTRDP-MCRDP-3TR|MVC-3TIER

Page 20: Re Factoring and Design Patterns

20 Peter Kaptein

ABOUT THIS BOOK ::Tag:ABOUT ::includesubchapters

Page 21: Re Factoring and Design Patterns

Refactoring and Design Patterns 21

FORMS IN WHICH THIS BOOK IS PUBLISHED

::Tag:ABOUT-006 To make the book easy to read, easy to use and easy to distribute this book is published as PDF, ePub, HTML website and on paper via a Print on Demand service. For all forms, the Word document in which it is typed is used as the source. The HTML site Using the Word-file and some software I wrote myself, the book is published to HTML, cleaned up and put into separate pages. I use the chapters, some hidden to generate the hyperlinks to chapters and between HTML pages and to create a clickable table of contents. As PDF and ePub Using Calibre and an HTML version of the book I create the ePub. The PDF is created by saving it as PDF from Word. The ePub makes it easy to read it as text on an e-reader, while the PDF handles the illustrations better: allowing you the best quality your e-reader can offer you. As a hardcopy The Print on Demand version is more an experiment. The idea is that in some cases you might rather have and use a hardcopy. Again the Word-document is used as the source, published to PDF and printed when a book is ordered.

WHY I WROTE THIS BOOK

::Tag:ABOUT-001 This book is my dissertation on Design Patterns and Refactoring. It is not written for a university or to gain any doctorate title, but simply to deepen my own understanding of Design Patterns and ground my understanding of Refactoring. The reason I started this project is the work I did in 2010 and 2011 as a Lead Developer on a project for a big publishing house, with a team of 10 programmers working with my code and my designs. I noticed that my lack of a good knowledge of Design Patterns was something I could not get away with anymore. And so I decided to do something about it.

WHY I MADE IT PUBLIC

::Tag:ABOUT-002 First of all: I blog. So anything I write about my trade is made public the moment I feel it is done. Usually this is 4 hours after I start writing. I write because I think I have something to add. And this is also the case with this dissertation. I feel I have something of value to add to the already existing list of books on Design Patterns. And I feel that this dissertation (or book) can help others like me to get a better and deeper understanding on Design Patterns.

Page 22: Re Factoring and Design Patterns

22 Peter Kaptein

WHAT I DID

::Tag:ABOUT-003 I did several things. First I started reading any and all books I could find about Design Patterns, which are not that many. I made notes and assumptions and connections. Then I took what I thought I knew about Design Patterns and started writing about it. During the writing process I regularly grabbed back on the source: “Design Patterns” by the Gang of Four, to check and double-check if my assumptions were right, or I was simply making things up. Where I was making things up and making the wrong assumptions, I corrected. In all other places I simply double checked and left what was there for the next round of reading. For Refactoring and Design Patterns I took my own experience as a starting point. Next I read back ”Refactoring” and “Clean Code” to follow a similar pattern as with the Design Patterns. During the writing process I made several diagrams to clarify the workings of each Pattern as I understood it and then went back to the class diagrams as presented in “Design Patterns”. What was there I took and clarified where needed by adding comments with each relationship and making variables explicit in each Class in the Class diagrams, so that you do not have to be an UML expert to understand what is going on. As the last step I added a “Visual Summary” of each Pattern that describes the very basics either in what they do or how you get there. The class diagrams I created can differ a bit from what you will find in “Design Patterns”, mostly in how I name the different parts and by adding the type of Class (Interfaces, Base Classes). Anything that is a Base Class I named “Base Something” and in most cases (as you can have many variations) I added the letter “A”, making a Base Class: “Something” : “Base Something A”. While adding some things I tried to stay as true as possible to the original diagrams, not wanting to add even more confusion to an already complex topic. You will find examples of this in the diagrams I added below. Methods and variables with a “+” are public. Methods and variables with a “-“ are private.

Page 23: Re Factoring and Design Patterns

Refactoring and Design Patterns 23

Example of a clarified class diagram: the Decorator Pattern

«interface / base class»Base Component A

+ someMethod()+ anotherMethod()

Concrete Component A

Override / implement:+ someMethod()+ anotherMethod()

Base Decorator A

+ setComponent( component )Override / implement:+ someMethod()+ anotherMethod()

1: «implements / extends»

«component.someMethod()»

Concrete Decorator B Concrete Decorator C

- yourAddedMethodC()- yourAddedMethodD()Override:+ someMethod()+ anotherMethod()

- component

2: «is of type»

- yourAddedMethodB()Override:+ anotherMethod()

Concrete Decorator A

- yourAddedMethodA()

3: «extends»

Example of a visual summer: the Decorator Pattern

Decorator A

+ yourMethodA: extended add extra functionalities execute: yourClass.yourMethodA()+ yourMethodB: extended do something extra execute: yourClass.yourMethodA()

Decorator B

1: «can be wrapped by»

2: «can be wrapped by»

+ yourMethodA(): extended+ yourMethodB(): extended

Main Interface / Base Class

3: «share the same»

Your Class

+ yourMethodA(): do something+ yourMethodB() do something else

variables

procedures

+ yourMethodA():+ yourMethodB()

::Link: PAT-DEC

Page 24: Re Factoring and Design Patterns

24 Peter Kaptein

BOOKS I READ (AND NEED TO READ)

::Tag:ABOUT-003a Before I started writing: “Design Patterns and refactoring” and during the writing process I read several books to get a better grip on Design Patterns and to buff up my knowledge on refactoring and general principles on coding. Books without comments are still on my need-to-read list. Recommended reads Books market with a star are considered by me as recommended reads.

BOOKS ABOUT- AND RELATED TO DESIGN PATTERNS ::Tag:ABOUT-003aa * Design Patterns – elements of re-usable Object-Oriented software Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides Addison-Wesley Professional This book is your main source and main reference for all the 23 Design Patterns described in “Design Patterns”. Published in 1995 it is one of the most important and influential books on Design Patterns. Many works, including this book, are derivates of: “Design Patterns”. As a consequence information present in “Design Patterns” is lost in other books while information made explicit in other books is hidden in “Design Patterns”. Head First Design Patterns Elisabeth Freeman, Eric Freeman, Bert Bates, Kathy Sierra, Elisabeth Robson O'Reilly Media Head First.. is a book I added to my read-list to double-check my own assumptions against what other writers wrote and thought about “Desing Patterns”. Having tried this book before, I found the original “Design Patterns” book by the Gang of Four more clear and more useable. C# 3.0 Design Patterns Judith Bishop O'Reilly Media I found C# Design Patterns to be a book that added less than: “Design Patterns for Dummies”. The examples only highlight specific parts of the Design Patterns and in general the writing did not really help me to understand the Patterns that well. * Design Patterns For Dummies Steve Holzner For Dummies Even though the tone of voice can be sometimes annoying in the introductions, where: “chief Head Honcho of company Awesomeness is asking your advice to solve a Big Problem”, the book offers a relatively low entry level to get a grip on Design Patterns. Reading “Design Patterns for Dummies” helped me understanding and decoding the sometimes Effective Java (2nd edition) Joshua Bloch; Addison-Wesley

Page 25: Re Factoring and Design Patterns

Refactoring and Design Patterns 25

BOOKS RELATED TO CODING AND REFACTORING ::Tag:ABOUT-003ab Code Complete: A Practical Handbook of Software Construction (2nd edition) Steve McConnel Microsoft Press Agile Software Development, Principles, Patterns, and Practices Robert C. Martin Prentice Hall Clean Code: A Handbook of Agile Software Craftsmanship Robert C. Martin Prentice Hall Refactoring: Improving the Design of Existing Code Martin Fowler, Kent Beck, John Brant, William Opdyke, Don Roberts, Addison-Wesley Professional Refactoring to Patterns Joshua Kerievsky Addison-Wesley Professional Beautiful Code: Leading Programmers Explain How They Think Andy Oram, Greg Wilson (editors) O'Reilly The Pragmatic Programmer: From Journeyman to Master Andrew Hunt, David Thomas Addison-Wesley Professional

Page 26: Re Factoring and Design Patterns

26 Peter Kaptein

THE FIVE ASSUMPTIONS I STARTED FROM

::Tag:ABOUT-004 1: There are logical groups in Desing Patterns Design Patterns do stuff. So based on what they do, how can you group them? I decided to look at the problems they solve and the things they facilitate. For instance: wrapping things. Or helping you to create complex structures. Or offering you choice in how a process will be done, or which objects will be instantiated when a specific context occurs. 2: There are many explicit and unmentioned relationships between Design Patterns I also assumed Design Patterns have relationships with each other. In the way they are similar, different, can be replaced by another Design Pattern or solve the same problem in a different way because there is a different need. 3: The best way to crack the code is to focus on the groups and relationships I assumed that the best way to crack the code of Design Patterns is to create these groups and find and describe these relationships. 4: Refactoring your code is the best way to learn Design Patterns I learned most about Design Patterns by simply refactoring my code. By centralizing logic, restructuring code, making things more generic, making more things possible with less and less “copy & paste” coding and more and more use of OOP principles. 5: Design Patterns emerge Design Patterns are not invented up-front. They emerge from refactoring. They emerge from improvement after improvement of your code and your approach to a specific situation. They emerge from the use and need of re-usable code and re-usable solutions.

WHAT I THOUGHT THIS BOOK WOULD BE

::Tag:ABOUT-005 I thought this dissertation would be around 60 to 120 pages. Short and simple. Instead it grew to be over 500 700 pages. One of the culprits are the diagrams. We have 23 GoF Design patterns, around 7 additional Patterns and an average of 10 pages per Pattern for the diagrams alone, already adding up to roughly 300 pages of text and diagrams. The rest is mapping the similarities and differences between the Patterns and describing the relationships to similar Patterns.

WHO I AM AND WHERE I COME FROM

::Tag:ABOUT-007 I have been developing software for my living since 1997, after many different pursuits in other directions before that. In another life I would have been an Engineer in the field of Informatics, but I never finished my study. Instead I published a fanzine, tried to make my living as a print-broker and graphic designer until I entered the field of Informatics by chance: writing solutions in MS Access 2 (part of MS Office 95) and building database driven solutions for an Intranet for an advertisement company called Wieden & Kennedy in Amsterdam.

Page 27: Re Factoring and Design Patterns

Refactoring and Design Patterns 27

I moved from Visual Basic to VB Script in Active Server Pages to JavaScript and ActionScript 1 and 2 (very similar to JavaScript) to ActionScript 3 (based on ECMAscript 5 and very similar to Java, including most OOP principles). The projects I worked on and products I created have always been very ambitious, from creating custom Content Management Systems to Intranet systems for companies, to webshops and frameworks to generate code from Database Structures. The need to dive deeply into OOP principles came when I started to do problem fixing for projects abandoned by others due to re-organizations and people leaving or dropping the project. The need to dive deeply into Design Patterns is when I became the technical lead on a big project for Reed Elsevier in 2010 / 2011: where a team of over 10 people was working with- and building their stuff on top of the structures and the code I produced. I felt I could no longer get away with my home-brew solutions without the knowledge of at least the very basic patterns described in “Design Patterns – elements of re-usable Object-Oriented software”.

INTENDED AUDIENCE AND ENTRY LEVEL

::Tag:ABOUT-008 Design Patterns and Refactoring is intended for anyone who wants- or needs to know more about the Design Patterns we should all know. I tried to keep it as clean and simple as possible, avoiding the common pitfalls like code-samples you have to decipher to understand the deeper meanings of the Design Patterns. Instead I focused on visualizations and dependencies. There is still a level of abstraction and, as a consequence, some “WTF!??!! What does he mean by this?” deciphering work to do for you. Give me feedback online when you encounter such parts. I cannot promise I will incorporate all feedback into the book, but it will certainly trigger me to review that text and see if the text can be cleared up a bit.

CODE EXAMPLES, OR: THE LACK OF

::Tag:ABOUT-009 I deliberately left out code examples. I found with each book I read on Design Patterns that they created more confusion and additional noise than really helping me understanding the Patterns. Instead I focused my energy on the diagrams and the Dependencies and Notes I use to describe them. These are intended to give you all the information to understand and apply the Design Patterns.

SOME BACKGROUNDS

::Tag:ABOUT-010 Initially I planned to write this dissertation in a sabbatical period I had planned for the second half of 2011. But the ongoing economic crisis made me decide otherwise and accept a new assignment. And instead I planned the writing for December 2011 and the first quarter of 2012. The first form in which I intended to write about Design Patterns and Refactoring was via blog posts. But somewhere along the lines this became a book, written offline.

LICENCE

::Tag:ABOUT-012

Page 28: Re Factoring and Design Patterns

28 Peter Kaptein

This book is licensed under Creative Commons, instead of being offered to a publisher and being put under Copyright, meaning that I WANT it to be spread and copied and copied and copied for free and no costs, again and again until kingdom comes. It means that I WANT it to pop up on any possible download list, in any possible collection of books on Software Engineering, Software Architecture and Design Patterns.

WHAT MADE ME DO IT

::Tag:ABOUT-013 It took me six years, from the first introduction to Design Patterns in 2004 to my first serious endeavors in 2010 to “get” Object Oriented Programming and Design Patterns. Before that time, my time, the lack of peer-programmers and the lack of understandable documentation held me back and kept me in the dark. Learning to play the guitar, but no time As far as I knew then, Design Patterns were not helping. To get to know them was a lot of work and in most cases that was time I did not have to spend. It was like learning to play the guitar where you had got away before with humming a tune. Frustrating, a lot of work and very little rewards. Blocking my creative flow Another reason not to use Design Patters was that I felt they were blocking my flow. I was able to do fine without them and smart enough to build solid software based on simple rules I invented myself. I had already designing and building software for 8 years, using Microsoft Access, Visual Basic, HTML, JavaScript and Macromedia Flash with ActionScript 1 and 2. And never needed anything. Mr. Fixit, cleaning up the hat others had left behind When entered the wonderful world of contracting, I became: “Mr. Fixit” in 2007, helping out several abandoned projects (due to teams leaving the company or projects no longer supported by the original contractors) I was introduced to how other people perceived software design and how they perceived the application of Design Patterns. In most cases it was a complete mess of code that did things in many ways I would never have allowed it to: round pegs in square holes. What this told me was three things:

1. I was not doing so bad myself 2. I was not the only one being clueless: being paid to do this work 3. Something was not working when people tried to apply Design Patterns

Enter the big projects with other people It took me another year from 2010 to 2011 as lead developer and software architect on a big project (including a team in India) to make a major leap into a better general understanding of Design Patterns and Refactoring. Rules that emerged from within my teams Working on a project with a team, with different levels of experience, involved a different set of rules. I could no longer get away with messy code, as other would suffer from that even more than I would. And so I defined the following rules for myself:

Your code shall be clean

Page 29: Re Factoring and Design Patterns

Refactoring and Design Patterns 29

Meaning that there should be no mess, no unclarities, no dead stuff Your code shall be clear Meaning that reading the code itself should be enough in most cases to understand how things work and how they relate to each other Your implementations shall be consistent, clear and simple Meaning that: when things work one way here, they should work the same way somewhere else and when you cannot explain something to your peers using a maximum of three diagrams and three pages of paper, you still have a lot of work to do You shall use the shortest route possible Meaning that the more simplified your code and your project is, the better

Refactoring Refactoring became my weapon of choice, above anything else. The better I was able to clean up “my” project, the better the result would be. The more I was able to simplify and Abstract the processes, the less chance there was for the horror of Copy & Paste coding. Design Patterns revisited I could no longer get away with not understanding Desing Patterns. Halfway 2011, when my contract ended, I decided I wanted to increase my expertise and improve understanding in Design Patterns. I also felt, for all the reasons mentioned in this introduction, that it would be good to make the result of my study and research into a book that would include OOP principles and Refactoring as writing about Design Patterns without either is like offering you the parts of a machine without the manual to put it all together. This book / site This book, site, or whatever you are reading is the result. I hope you like it. Peter Amsterdam, Arnhem, Gran Canaria, Florence , December 2011 – May 2012

Page 30: Re Factoring and Design Patterns

30 Peter Kaptein

DOWNLOADABLE CONTENT ** ::Tag:DWNLD ::includesubchapters

Page 31: Re Factoring and Design Patterns

Refactoring and Design Patterns 31

DOWNLOAD AND SHARE

::Tag:DWNLD-DSH Share and copy All content you can download here is meant to be shared and copied by you and others. Teach and study You can use the material freely to teach and study Design Patterns, Refactoring and everything that comes with it. Fair use Yu are not allowed to copy material from these sources unless explitly stated in the documents.

EBOOKS

::Tag:DWNLD-EBKS

REFACTORING AND DESIGN PATTERNS ::Tag:DWNLD-EBKS-001 “Refactoring and Desing Patterns” is this book you are reading either online or in PDF or ePub format. You can download two versions: PDF and ePub which are both DRM free. You are free to copy and share these books for professional and private use. ePub format Handy and created primarily for e-book readers. Illustrations are optimized as best as possible for e-book format and converted to PNG format. Depending on your reader, the (limited) resolution of the images and the size and resolution of the screen, the illustrations might lose some of their readability. Download: ePub format PDF format The PDF version offers the best I can do on styling and readability. Illustrations maintain their format as vector images and are without quality loss. The same goes for fonts and design. You can use and read PDF documents on both PC and eBook reader. Download: PDF format

OOP PRINCIPLES

::Tag:DWNLD-OOP

THE REFACTORING PROCESS

::Tag:DWNLD-REF : Download links related to the Refactoring Process

REFACTORING SUMMARY ::Tag:DWNLD-REF-001 English version

Page 32: Re Factoring and Design Patterns

32 Peter Kaptein

The Refactoring summary gives you a simple and quick overview of all the main aspects of refactoring as mentioned in this book. It is a quick guide and “cheat sheet” for if you want to skip all the theory. Download PDF: Refactoring Summary, EN version

DESIGN PATTERNS

::Tag:DWNLD-DESP : Download links related to Design Patterns

PRESENTATIONS

::Tag:DWNLD-PRES

DUTCH PRESENTATIONS ::Tag:DWNLD-PRES-NL As I have been teaching some courses in Dutch, I created these presentations in Dutch first. Refactoring and Design Patterns This presentation is a summary of the book, made into presentation form. Download PDF: Refactoring, OOP and Design Patterns, NL version Design Patterns and game development This presentation shows a set of the most relevant patterns for game development. As example two games are taken: Tower Defense and a Platform game. Dowload PDF: Tower Defence and Design Patterns, NL version

Page 33: Re Factoring and Design Patterns

Refactoring and Design Patterns 33

PART 2: SCOPE AND

PERSPECTIVE IN

SOFTWARE

DEVELOPMENT ::Tag:PART2

Page 34: Re Factoring and Design Patterns

34 Peter Kaptein

BASICS ON SCOPING AND PERSPECTIVE ::Tag:SCOPE

Page 35: Re Factoring and Design Patterns

Refactoring and Design Patterns 35

WHAT FITS WHERE?

::Tag:SCOPE-001

DESIGN PATTERNS AND SOFTWARE DESIGN ::Tag:SCOPE-002 Design Patterns are concrete implementations Regardless of what the use of “Design” might seem to indicate in “Design Patterns”, Design Patterns are usually not a part of the overall design of Software itself. Design Patterns are concrete implementations and – if put into a design document – belong mostly in the Technical- or Concrete Design. More about that in this chapter I will elaborate on this quite straight forward premise in this chapter.

PATTERNS IN SOFTWARE ARCHITECTURE ::Tag:SCOPE-003 High level design The Architecture of your software is in most cases what is called a “High level Design”. It describes what comes where and what follows what and how something is connected to something else. It gives you terminologies to share and refer to, so that when you build “A”, you can refer to it with a specific term or description everyone can relate to if and when they read the Architecture Documents. Represent processes Patterns in Software Architecture describe mostly the processes of the things that happen and the processes of things that can go wrong. More global and stable structures Terms and Patterns in Architecture Documents tend to be relatively stable. Even after many refactorings, and re-shufflings of elements and what processes happen where and when, the main structures and architectural starting points usually remains the same. Architectural players in my code The patterns I use in my architecture are based on organizational principles and some names like Managers and Operators are derived from that world. To give you an example, my architectures include:

1. Managers – To manage things 2. Handlers – To handle things 3. Parsers – To parse things 4. Objects – To do things 5. Services – To connect to other applications and send and retrieve data 6. Value Objects – To contain and keep values 7. Base Classes – To do the basic things

Specialized players in my code Apart from that you will find concrete variations on these themes, like:

1. Data Managers 2. Application Managers 3. Data Handlers

Page 36: Re Factoring and Design Patterns

36 Peter Kaptein

4. Data Parsers Architecture? Conceptual mostly, no concrete technical processes Nowhere here you will find concrete technical processes telling you how exactly data will be parsed, or which Design Patterns will be used to do things. As all that might, can and will change as the project continues and insights and requirements and the understanding of requirements change.

PATTERNS IN FUNCTIONAL, INTERACTIVE AND USER EXPERIENCE DESIGN ::Tag:SCOPE-004 Functional implementation of requirements Functional Designs usually describe the functional implementation of the Requirements. By hacking them up in screens/dialogs and by organizing the data and data-requirements in logical blocks that make sense for the user Interaction design Closely related to the Functional Design is the Interaction Design. Where the Functional Design focuses mainly on “what goes where, when?”, the Interaction Design adds “how will the user interact with this?” to it. Functional and Interaction Design have a lot of overlaps and usually are merged due to this. Focus The patterns used in Interaction and Functional Design are usually based on:

Human behavior What is the first thing a person will do ant try? What is the break-off point? How do you keep a user motivated? What is frustrating? Human perspective In what way will the user look at this? What is clear and what will fail when the user sees and tries to use this? Communication of required actions How can you make clear what actions are required in what specific cases? How can you communicate this? What words will you use? What symbols? What colors? What layout?

Functional design? No concrete code Functional design focuses – s stated above – on the human factor. How does a person look at a Page? Where does she expects buttons? What action should be next according to his or her perception? No concrete is designed here yet. Processes however will be more concrete specifically for interactions and the order of specific actions.

PATTERNS IN SOFTWARE IMPLEMENTATION AND TECHNICAL DESIGN ::Tag:SCOPE-005 Recurring patterns in implementation When you implement functionality, there are some basic patterns that will always recur, like:

Opening and closing files and databases

Editing, removing, adding and creating files and data records

Page 37: Re Factoring and Design Patterns

Refactoring and Design Patterns 37

Navigating from screen/panel A to B and back

Showing feedback to users via popups, notifications in the screen and related to input items

Filtering data

Creating and destroying objects

Validating data and input Focus: concrete realization Each of these patterns focus on the concrete realization of the system requirements. They intend to offer solutions for problems you need to solve to make things work. Patterns can vary and change The Concrete Patterns used in the Realization process can vary even when the project progresses. For instance, where requirements for navigation at first seemed to cover only a linear process, moving from Step A to Step B, to Step C and so on, “suddenly” the application also should allow for side-steps into other parts, where updates can also affect the main line. Parallel processes Even worse, it might even be required to have several parallel processes happening at the same time, where – for instance – you can have information on multiple people visible on screen and for each person state and location in the process (Step A, B, C and D) should be maintained, so that when you switch from “Person 1” to “Person 2” and back, “Person 1” is where you left it: at Step C. Solutions that were perfect for situation A might fail in situation B Even though your first solution might have been awesome for one single person, it might fail in its current implementation when you are asked to show many people at the same time, where each Person maintains its state. Disposable? You will find later on in the Design Patterns section the statement:

“Design Patterns are disposable”

Meaning that whatever Design Pattern you have chosen in the start, should be implemented in such a way that you can replace the implementation for “Design Pattern A” for the implementation of “Design Pattern B” OOP Principles There are two principles in OOP that help you do that:

Abstraction Where you decouple the implementation of things from the place or places you use that implementation Encapsulation Where you encapsule functionalities into either a method call, or extract that functionality entirely into a new Class

We will get deeper into these principles in the Refactoring chapter

Page 38: Re Factoring and Design Patterns

38 Peter Kaptein

Page 39: Re Factoring and Design Patterns

Refactoring and Design Patterns 39

A SUMMARY ON CYCLES OF SOFTWARE REALIZATION **

::Tag:SCOPE-CYCL

STEPS THAT LEAD TO A PROJECT AND ITS RESULT ::Tag:SCOPE-CYCL-003 Before you start building, usually something along the line of the following steps has been taken place:

2 41 3 5

Discovery ApprovalIntentionScoping, Budget

Design

6 7 8 9

Reali- zation

Test / Debug

ReleaseAccep-tation

The most generic (Waterfall) phases for software development Phase 1: Intention Where the Client formalizes the intention to have something built. Phase 2: Discovery In which you and your Client will formalize what is needed why and how much. Phase 3: Scoping and Budget In which all requirements are set against hours and costs to actually build stuff. In this phase, the results from the discovery phase are used as the basis for estimations on hours required to build the solution(s) and the cost for the infrastructure to run that solution once it is released. Phase 4: Further scoping and approval In this phase, the offer is reviewed with the Client and revised where needed, to meet the balance of Client Budgets (rarely enough for everything) and Client Requirements (usually more than can be paid for or can be built in the given time). Phase 5: Design stage In which the requirements are translated into functional and interactive designs. Phase 6: Realization Where designs are translated into coding.

Page 40: Re Factoring and Design Patterns

40 Peter Kaptein

Phase 7: Testing / debugging Where the result is tested and debugged until all agreed Requirements are met and the application passes all tests agreed upon. Phase 8: Acceptation Before the application can be launched, it has to be accepted by the client. This phase is the acceptation or “Client Acceptation” phase in which the Client will test the application and decide whether it applies to the current needs or the requirements. Applications can be rejected in this phase by the cliend due to several reasons including relevance against current needs and failure to pass the tests due to remaining errors. Phase9: Release / Launch In which the application is launched, shipped, put online or whatever the destination is. Waterfall and RAD / Agile Depending on your development process, each Phase will have a distinct beginning and end (Waterfall Method) or will cross and overlap and done with short cuts due to better development tools, rendering specific and more detailed parts of the classic development cycle more as overhead than helpful in the process (RAD, Agile, Prototyping, Extreme Programming). More info in next chapter We will go briefly into each phase later on. ::Link:SCOPE-REL

Page 41: Re Factoring and Design Patterns

Refactoring and Design Patterns 41

BASIC STAGES IN SOFTWARE DEVELOPMENT ::Tag:SCOPE-CYCL-001

THE BASIC PROCESS ::Tag:SCOPE-CYCL-001-BAS

2 3 4

Build Test ReleaseDesign

1

Basic stages in software development The basic process consists of four stages: Design, Build, Test and Release. To avoid repetition, we will go into a description of each phase in the next parts.

ADDING REFACTORING AND FIXING TO THE PROCESS ::Tag:SCOPE-CYCL-001-RF

2 4 61 3 5

Build Test DeliverDesign Refactor Fix

Adding refactoring and fixing to the process Stages When you are going to write the actual code, you will go through several stages in your process. These stages are: 1: Design This phase includes the following questions: How will you implement the requirements? What Patterns will you use? Where will you put what? 2: Build / Realization This is the coding and visual design process. 3: Refactoring / Cleaning up Every so now and then, you should stop and review what you have done. When things become messy and when you start losing oversight it is time to refactor. Build and refactoring can be an ongoing process, where the code is refactored from time to time and then building is continued. Also see the Refactoring section.

Page 42: Re Factoring and Design Patterns

42 Peter Kaptein

4: Test /Testing Each cycle in your development process involves testing. Does it work? Can we break it? At first your building will be aimed at making it work and your testing will be focused on the general functionality: “loading a file, inserting values, storing values in a database”. In general the exceptions are tested by you once most general cases are implemented, as “making it work” is already a lot of work. The result is a bug list or issue list. 5: Fix / Debugging Each issue you will find will need to be solved. Either by correcting faulty code, or by rewriting and re-designing your code. It is possible that part of the fixing process is another round of revision or refactoring of your code, to clear and clean things up or to directly support the debugging process itself. 6: Deliver /Release Once all the functionalities you are aware of are implemented, tested and working in good order, you release. This can be one of many intermediate releases.

2 4 61 3 5

Build Test Deliver

Test, Register

bugs

Build,Test

Working proof of concept

Bug list, issue list

Design Refactor

Revise, Rename, Repair,

Test

Improved POC

Fix

Revise, Repair,

Test

Release version

Paper prototype

Showing the full actions and the results per phase.

Page 43: Re Factoring and Design Patterns

Refactoring and Design Patterns 43

MORE AGILE/REALISTIC CYCLES ::Tag:SCOPE-CYCL-001-AG In most contemporary development processes, these six steps overlap and cross each other. In our development process we can have two main “Agile” cycles. For instance:

2

1

Build

Test Release

Design Refactor

Fix

Test / Debug

Refactor

A less linear and more “Agile” approach

Cycle 1: Design, Build, Test/Debug, Refactor In this cycle, we design the basics of what we think our end client needs. Once we have a feeling that we have the basics thought out, we start building and testing. Based on the results we refactor our code, test again, maybe build new functionalities and go back to the design phase and then repeat the processes until we think we are ready for the next cycle: Design, Realization, Test, Refactoring. Cycle 2: Test, Debug (Fix), Refactor, Release In this cycle, all basic functionalities are built and the main goal is to meet all requirements. The first three in this cycle: Testing, Debugging, Refactoring are repeated until satisfaction, after which follows the Release. The Release can be an Intermediate Release, followed by Testing by another group and then a repetition of this cycle until all bug reports are closed

Page 44: Re Factoring and Design Patterns

44 Peter Kaptein

MOVING FROM DESIGN TO RELEASE ::Tag:SCOPE-CYCL-001-BP When you look at the bigger picture in a more Agile process, the development process might look something like the image below.

Define Focus

DesignMake it

workMake it better

Make it awesome

1 2 3 4 5

Release

6

Moving step by step to a working application Step 1: Define the focus In this step the team defines what the focus is. What needs to be built? What are the requirements? What are the goals that need to be achieved? Using a prioritization method like MoSCoW (Using Must have, Should have, Could have, Would have) priorities are defined in what has to and could be built. Additional approaches like the SMART principle (Specific, Measurable, Attainable, Relevant, Timely) and methods like Timeboxing can be used to define deadlines and clear targets and results. Step 2: Design Based on the results from the first step, a design is made. In most cases this will be a “Paper prototype” describing the broader lines, the different (technical) parts and how the application should function, without going too much into details. Step 3: Make it work As soon as the design is done to satisfaction the rough first version is created. This first version does not have to look good, but show that what is wanted and needed is possible. The result is a working proof of concept that shows all main elements (Must haves) and that can be demoed to other people. Step 4: Make it better Once the Proof of concept is done, the result is refined in one or more successive steps. Must haves are done and Should haves incorporated. From a working proof of concept, the application (or game or site) grows into something that resembles more and more the ideal end result. The end result can still hold minor bugs, but is good enough (“Beta”) to be released and used. Step 5: Make it awesome In this step, all effort is in making the application, site or game awesome. All bugs are killed, all flaws removed. Things like performance and design are scrutinized. In this stage, the application (or game or site) is tested and improved over and over until there is nothing more to improve. Step 6: Release In this last step, the result is released onto the web, into market places and wherever it should be found.

Page 45: Re Factoring and Design Patterns

Refactoring and Design Patterns 45

Define Focus

DesignMake it

workMake it better

Make it awesome

1 2

Build,Test,

Revise,Deliver

3 4 5

Build,Test,

Revise,Deliver

Working proof of concept

Beta-version

Release version

Build,Test,

Revise,Deliver

Release

6

Paper prototype

Basic require-ments

Showing a more detailed step by step process to a working application

Page 46: Re Factoring and Design Patterns

46 Peter Kaptein

ANOTHER VIEW: PROTOTYPING, TESTING & BUG FIXING, REFACTORING, REVIEW ::Tag:SCOPE-CYCL-002 But what about your clients? When you look at your process from the point of view of your Clientsm, one thing is missing: the Review. Where and when will you show your results? How did you get there? Prototyping, Testing/bug fixing, Refactoring and Review assume that each cycle starts with prototyping and ends with a review of the result you created before you release it. It assumes the designs are already made, or made in a different phase. We again put refactoring (and fixing) in as a major step.

2 41 3 5

Test / Fix ReviewPrototype

Refactor Release

The five steps in this process Step 1: Prototyping Where the design, or the idea is realized into mockups, click-through models, Working Proof of Concepts, Beta-versions and whatever more suits the current phase and fits your way of working. Step 2: Testing & Bug fixing During the Prototyping process and once the Prototype has reached some level of maturity, you test. Test to see if the basic functionalities are as intended and to finalize the prototype/Working proof of Concept for the next stage. Step 3: Refactoring (and re-testing) As a result of Testing and bug Fixing, specific code, specific structures and specific parts in the organization of your project might need revision, cleaning up: Refactoring. By making Refactoring a major phase, you acknowledge that cleaning up the code is an explicit part of your development and delivery cycle before you deliver. Step 4: Review Once done with the cycle of Prototyping, Testing/Bug fixing and Refactoring, the application is reviewed by you, your team and (a representative of) the Client. Step 5: Release In this step, the result is released, either to a next phase, or to the world.

Page 47: Re Factoring and Design Patterns

Refactoring and Design Patterns 47

2 41 3 5

Test / Fix Review

Show/demo to others/ client

Revise, Repair,

Test

Improved POC

Go / no go

Prototype

Refactor

Revise, Rename, Repair,

Test

Clean POC

Release

Working proof of concept

Build,Test

A full overview of the different steps and their parts

Page 48: Re Factoring and Design Patterns

48 Peter Kaptein

WHAT APPROACHES CAN YOU USE?

::Tag:SCOPE-APPR

ALL DESIGN FIRST, REALIZATION SECOND ::Tag:SCOPE-APPR-001 As discussed many times before, Waterfall Method is one of the approaches to software development where design comes first and realization comes second. In Waterfall Method you do not mix design and realization.

ADVANTAGES Legal: design documents are like Contracts, waiver of responsibility The advantages of Waterfall Method at this point in time are mainly legal. Your design documents are like contracts. If you follow them, your Client will have to accept whatever is delivered according to these contracts. If the system does not add up to the Clients needs, it is not your fault Sense of control As long as everything is documented, you – as the Client – feel that you have some control over what will come out at the end of the process.

DISADVANTAGES Long time before delivery Waterfall Method has a very long period of time passing between the first conversation with the Client and the first Release to Staging and Live Systems. The Requirements and Design Phase itself can take from 3 to 6 months alone, and no Code has been written in the mean time. Not Agile to changes in the meantime Once the process is started and the documents are delivered and taken into Realization, there is hardly any room for change. Hardly any contact with- and Process Involvement from the Client In most cases, Design and Realization takes place behind closed doors and on locations isolated from the Client. Feedback moments mainly exists of Documents being delivered and Reviewed.

Page 49: Re Factoring and Design Patterns

Refactoring and Design Patterns 49

DESIGN UNTIL FUNCTIONAL DESIGN, REALIZATION SHORTLY AFTER ::Tag:SCOPE-APPR-002 This is not yet the mixed approach I will discuss later. Still a part of Waterfall Method is used, where as much as possible is designed on paper until the point where all involved parties (usually the client and the software design team) are satisfied that all requirements are met. Instead of going into yet another design phase after the Functional (and Interactive / User Experience) design is done, realization is started.

ADVANTAGES See Waterfall Method The legal value of design up front and value of the “Sense of Control” remains. Shorter time to market Realization shortly after has a shorter (faster) time to market than Waterfall Method, as the last design stage of Waterfall Method (the Technical Design) is skipped in most cases

DISADVANTAGES See Waterfall Method Even if the design process is cut short, the client still has little involvement in general and months are spent designing a system on paper.

Page 50: Re Factoring and Design Patterns

50 Peter Kaptein

THE MIXED DESIGN/REALIZATION APPROACH ::Tag:SCOPE-APPR-003 RAD, Agile, Prototyping, Extreme Programming This is RAD, Agile, Prototyping, Extreme Programming. As soon as the first requirements are known, realization is started and building of the software is commenced. Short Design cycles, focused on Design Principles To avoid Design at all, however, is a bad way to go. In most cases, RAD, Agile and Extreme Programming applies very short design cycles in which the design principles of the system and subsystems are defined. From that point on, the Implementation takes over as it is usually faster to build and test assumptions in code than working them out on paper. Application is the Detail Design The Application itself is both the detail design and proof of concept that will be shown to the client in successive stages. Documentation afterwards The detailed design documents are usually created afterwards, using tools to reverse-engineer class diagrams and extract documentation as it is written in the code. Next phases If the system is still under development, the system documentation might include steps for the next phase.

ADVANTAGES More involvement of the Client during the process The client is part of the design and realization process from day one. Depending on the chosen method (RAD, Prototyping, Agile, Extreme Programming) the client is part of daily sprints or regular demo and feedback sessions as new intermediate versions are delivered and made available for review. More Agile when requirements change, the software will be adjusted as well. Based on the programming skills of the team and proper cleaning-up sessions and “Strategic Architecture”, these changes can be implemented either quite easily or with great pain. Shorter time to market Where Waterfall Method can take 3 to 6 months and more before any line of code is written, the Mixed Design and Realization approach starts delivering results as soon as possible, which can be days if it involves systems with known type of interfaces, or within several weeks and months if the technology and environment is a bit less mature and needs more manual labor.

Page 51: Re Factoring and Design Patterns

Refactoring and Design Patterns 51

DISADVANTAGES Reduced sense of Control Where Waterfall Method and all derivations are clear on the end result long before realization is started, RAD and the likes are not. Things grow organically and can grow out of control: delivering something else than initially intended. RAD, Agile and Extreme Programming all have tools to avoid scope creep, but if they are not applied, the project can become a mess. Bad documentation when Documentation is not a deliverable As realization has more priority than documentation, documentation might – and usually is – the last thing to happen, if it happens at all. This means that in maintenance and for future changes, the system becomes a risk of increased costs.

Page 52: Re Factoring and Design Patterns

52 Peter Kaptein

THE USE OF DESIGN PATTERNS IN THESE APPROACHES ::Tag:SCOPE-USEDP

WATERFALL METHOD: DESIGN ON PAPER FIRST ::Tag:SCOPE-USEDP-001 If you follow Waterfall Method to the end, the design documents will include some form of technical design and this technical design will include an overview of which design patterns will be used.

THE ABBREVIATED WATERFALL METHOD: GLOBAL DESIGN ON PAPER, ACTUAL CHOICE WHILE BUILDING ::Tag:SCOPE-USEDP-002 Global guidelines In the Abbreviated Waterfall Method you will have some global guide-lines on which Design Patterns might be used and which not. The real implementation is done as the project progresses. Levels of freedom are usually defined by the organization It is very dependent on the organization (in which you work) itself how much freedom you will have and how much change and Refactorings your code will see before you reach the end of the project. In some cases, the first decision made is also the solution you will work on and work around as the project progresses. Waterfall legacy One possible reason I found when working in such an environment is the still present legacy of Waterfall Method, where big changes during the realization process are preferably avoided as much as possible, so instead of throwing out something that does not work as intended, it is bent in such a way that it kind of does. Design Patterns? On paper first? The use and the design of Design Patterns might be done on paper first. the detail of that paper design, regardless if it is conceptual or concrete, depends on the team and software designers.

AGILE, RAD, PROTOTYPING, EXTREME PROGRAMMING ::Tag:SCOPE-USEDP-003 No warranty of agile code Neither of these approaches to coding are a warranty that the code itself is treated as Agile and Disposable. Meaning that when you choose a specific direction that does not work on the long run, you are free to ditch that solution for something more suitable, as ANY change is a risk and ANY change might jeopardize the project. Again: this is very much dependent on the coders and the team. Design Patterns? On paper first? The use and the design of Design Patterns might be done on paper first. The detail of that paper design, regardless if it is conceptual or concrete, depends on the team and software designers.

Page 53: Re Factoring and Design Patterns

Refactoring and Design Patterns 53

CLIMBING THE LEARNING CURVE ::Tag:SCOPE-EXP RAD/Agile and paper design of Desing Patterns? If you feel that you have to design your system and the use of Design Patterns on paper first, AND you using RAD, Agile and so on, you very likely are still in the learning process. Emerging result As I will get back onto many times later, Design Patterns are an Emerging Result. You do not choose them beforehand, UNLESS you are very well known with each of them and have used them over and over in many different circumstances.

CHALLENGES ::Tag:SCOPE-EXP-001 Why to have Design Patterns emerge? Instead of taking Design Patterns as a Starting Point, try to have them emerge from your own code instead. This is why:

Thinking and Training Design Patterns require a very specific way of thinking that requires a very specific way of training. Discipline Design Patterns require discipline. You have to be disciplined to apply them. The reason for this is stated in the next item: Reduced sense of Freedom Design Patterns at first seem to limit the freedom you were used to. They even might feel like Straight Jackets. Easy to mess up I have seen enough implementations of something relatively simple as the MVC pattern, that totally did make no sense at all

POSSIBLE ACTIONS ::Tag:SCOPE-EXP-001a Emergence of Design Patterns So: instead of trying to learn to understand Design Patterns, first, you start training to understand HOW Design Patterns emerge. From that, you will automatically develop the skills you need to implement the ones that exists. In such ways that are simple and completely to the point. 1: Analyze all System Variables you know What part of the systems needs your solution? Are there other parts that need that same- or similar solution? 2: Try and think of the most simple solution

Page 54: Re Factoring and Design Patterns

54 Peter Kaptein

Write it down in Conceptual Designs, get a good overview of the different actions. Try if you can make it even simpler. 3: Write your code Build it. Test it. See if it complies to your needs. 4: Break it down conceptually It it sufficient for all cases you know? Can it be done better? Is this really the best and most clear solution you can make? 5: Refactor it Repeat from step 1 and make it better. Make it more clear. Make it more readable.

Page 55: Re Factoring and Design Patterns

Refactoring and Design Patterns 55

PHASES, APPROACHES AND RELEVANCE WHEN BUILDING

SOFTWARE

::Tag:SCOPE-REL

APPROACHES TO BUILDING SOFTWARE ::Tag:SCOPE-REL-001

RAD, AGILE, PROTOTYPING, EXTREME PROGRAMMING ::Tag:SCOPE-REL-002 Relevance of these approaches RAD, Agile, Prototyping, Extreme Programming and likewise methods all focus on realization of the requirements as soon as possible. They rely on the following:

Frameworks Which have been tested or created specifically for the kind of application that needs to be built Refactoring and Agile code As you prototype, you start with best assumptions instead of a finalized design. This means that during the process, the code and your architecture will change. A lot. A supportive programming environment When you refactor, one possible consequence is that you will be breaking the project. Meaning that all kinds of compile-errors will arise. A supportive Programming Environment will tell you immediately where your project is broken and allows you to find and correct the broken parts Your OOP programming skills The better developed your OOP Programming Skills are, the easier it is to build code that is Agile

Results first, short development cycles RAD, Agile, Prototyping and Extreme Programming all assume that the sooner you can show results to the Client, the better. They also assume the programming and prototyping environment is supporting short development cycles of weeks and days and that a working system can be delivered in such time. Less preparation, shorter time to market Effectively RAD, Agile, Extreme Programming and Prototyping cuts away a lot of time from preparation, making the time to market / time to release significantly shorter than Waterfall. Documentation and design follows implementation The lack of documentation and design beforehand can be an issue. It is easy to overlook things and make mistakes only discovered later in the process. Then again: this is mostly compensated by the fast development cycles in which Working Proof of Concepts are shown in very early stages, allowing for fast feedback, refinement of requirements and discovery of issues you would have never found from the Paper Prototyping that is System, Functional and Interactive Design. Implement documentation sessions

Page 56: Re Factoring and Design Patterns

56 Peter Kaptein

Although this does not happen all the time, it is recommendable to have documentation sessions in which the result at that time is written down and verified against the Requirements. Steer on clear and clearly scoped requirements In my experiences, the best way for any of these methods is to steer constantly on clear and clearly scoped Requirements. In the end that is what needs to be built and met. Document them well during the process, make sure they are complete and make sure they are up to date. Requirements as contract and legal basis As a contract between you/your team and the client, the Requirements are one way to make sure things remain clean once your code and your application is delivered. Your updated, scoped (and signed by the Client) Requirements are the type of record that you can produce and reproduce with all legal validity when you are in dispute.

WATERFALL METHOD ::Tag:SCOPE-REL-003 Basic assumptions of Waterfall Waterfall Method is one of the first structured methods to help facilitate building reliable code within specifications and given time. It emerged in the 1960s when programming was a tedious process. Waterfall Method originally assumes that:

Changes in code are more expensive than changes in design When you build your code, any change afterwards will have deep impact as it will possibly break the project in many places and finding and repairing bugs will cost a lot of time. Additionally on old mainframe systems code would be compiled only once a day in Batch processes, only giving you feedback on bugs and errors the next day. So building and debugging one set of functionalities could easily take a week or more Intensive design on paper is less expensive than changes in code When changes in code are expensive (time and money) it is better to do a thorough and complete design on paper first. Going as far as paper-prototyping the code before entering it into the system

Still used in bigger organizations Waterfall Method is sometimes, and sometimes even most of the time, still used in bigger organizations for the level of control it seems to give over an IT project. Agile is slowly replacing this.

Page 57: Re Factoring and Design Patterns

Refactoring and Design Patterns 57

PHASE 1: INTENTION ::Tag:SCOPE-PH-001

2 41 3 5

Discovery ApprovalIntentionScoping, Budget

Design

6 7 8 9

Reali- zation

Test / Debug

ReleaseAccep-tation

In Phase one, the Client expresses a want or need that is in most cases vague and generic. There might be a problem to be solved, a potential commercial opportunity to be grabbed or competitors to be bested.

BASIC STEPS In general these are the steps that take place:

1. Recognition - of a need, want or opportunity 2. Gathering - of ideas and needs 3. Concretization - into a request to build

In most cases, the “Design Document” is one at “Business Level”, meaning that it is – in most cases – about earning and losing money, possible (business) opportunities, the improvement of business processes, mission and vision statement and how the new software solution would cater the mission and vision.

TWO EXAMPLES OF A RECOGNIZED NEED More sales via online shop Our physical stores are visited by our clients, but there is more tendency to buy online. As we can ship our products via mail, this is an opportunity to grab. Additional, location is less and less relevant as DHL and UPC can reach almost any location More efficiency through automization of business processes We lose a lot of time by writing down things on paper, having this copied into spreadsheets and having the spreadsheets sent by mail, to be processed again by a person in that department. Instead, people should be able to insert their data immediately into the system via some kind of interface. This will save us a lot of money on the long run and will enable the organization to respond quicker to change as the data we operate on can become almost real-time

Page 58: Re Factoring and Design Patterns

58 Peter Kaptein

RAD, AGILE, PROTOTYPING, EXTREME PROGRAMMING Coding not started yet In most cases, the company you are working for, working with or are the owner of, is not approached yet.

WATERFALL METHOD Coding not started yet In Waterfall Method, you – as a coder – very likely do not know this project even exists.

PHASE 2: DISCOVERY ::Tag:SCOPE-PH-002

2 41 3 5

Discovery ApprovalIntentionScoping, Budget

Design

6 7 8 9

Reali- zation

Test / Debug

ReleaseAccep-tation

BASIC STEPS 1: Gathering of requirements What is needed where? What is missing? What data is processed? What is required of that data? What is not? 2: Analysis of (business) processes How does stuff happens? Who does what, when and why? What kind of checks and double checks are made? How is stuff (data) validated and by whom? 3: Information and/or System Analysis Next to the analysis of business processes is the analysis of information needs. For instance: when you send a parcel to some location, what information do you need? Is Name, Address, Zipcode and Country enough? Or do you also need a Client Reference ID and some link to the systems of UPC and DHL to track the parcel and inform the Client when things went OK or wrong? 4: Filtering of requirements into Must Haves, Should Haves, Could Haves, Would Haves

Page 59: Re Factoring and Design Patterns

Refactoring and Design Patterns 59

What is really needed and crucial? What is important to have? What should be there, but is not crucial? What is nice to have, but not essential? MoSCoW as this approach is called, is used to filter out the priorities. This helps to create focus, but also to save money as not all items on the wishlist need to and have to be implemented to get a working system. In general: less if better At this point in time we have reached quite a concrete description of the software that should be there.

RAD, AGILE, PROTOTYPING, EXTREME PROGRAMMING Proof of concept In some cases, you might already be programming Proof of Concepts in this stage (using methods like RAD, Agile, Extreme Programming, Prototyping)

WATERFALL METHOD Coding not started yet In Waterfall Method, you – as a coder – very likely do not know this project even exists.

PHASE 3: SCOPING AND BUDGET ::Tag:SCOPE-PH-003

2 41 3 5

Discovery ApprovalIntentionScoping, Budget

Design

6 7 8 9

Reali- zation

Test / Debug

ReleaseAccep-tation

BASIC STEPS 1: Groupings of requirements What belongs where? With what? What relationships exist between specific parts? This results in groups of requirements, describing all required functionalities for specific parts of the application 2: Estimations per group and item in hours and costs Once the overall picture per item and requirement is clear, you can start estimating. Usually estimations are done based on past experiences and the effectiveness of the tools and frameworks available

Page 60: Re Factoring and Design Patterns

60 Peter Kaptein

3: Scoping of functionalities and time lines Here is where MoSCoW comes into place. Some requirements are simply not important enough and will be dropped (for this phase). Based on the estimates and immediate and long term needs, time lines are made and release schedules are put into place 4: Pricing totals and parts Closing this process, the parts and the totals of all functionalities are price tagged

RAD, AGILE, PROTOTYPING, EXTREME PROGRAMMING Analysis of proof of concept If you are already coding at this point (RAD, Agile, Extreme Programming, Prototyping) you will start weeding out specific solutions and create focus-documents stating which requirements and functionalities will be developed further into the actual application. Click through model? Depending on your tools and the novelty of the application, you might either have a click-through model or already a working application with a lot of rough edges.

WATERFALL METHOD Coding not started yet In Waterfall Method, you – as a coder – very likely do not know this project even exists, unless you have been asked to do some estimating on hours.

Page 61: Re Factoring and Design Patterns

Refactoring and Design Patterns 61

PHASE 4: FURTHER SCOPING AND APPROVAL ::Tag:SCOPE-PH-004

2 41 3 5

Discovery ApprovalIntentionScoping, Budget

Design

6 7 8 9

Reali- zation

Test / Debug

ReleaseAccep-tation

BASIC STEPS 1: Scoping What is really needed? What can be dropped (based on earlier Analysis) 2: Approval / rejection If the scoping is according to wishes and expectations, approval follows. In case of rejection the project will either not take place or the previous steps are repeated In this phase, in most cases, the final decisions are made.

Page 62: Re Factoring and Design Patterns

62 Peter Kaptein

PHASE 5: DESIGN STAGE ::Tag:SCOPE-PH-004

2 41 3 5

Discovery ApprovalIntentionScoping, Budget

Design

6 7 8 9

Reali- zation

Test / Debug

ReleaseAccep-tation

BASIC STEPS 1: System Design What will the final design look like? What is the best way to hook up things? What will be talking to what? And how? 2: Information Design What information is there? How do we want to approach it? How do me make it useful and easy to interpret and access for human beings? 3: Data Modeling What data do we have? How can we best store that into a database? What relationships exists? Where is most of the work? How, where and when can and do we optimize our data-storage and retrieval? 4: Functional Design, User Interaction Design, User Experience Design – What is needed? How does the user uses it? What logical patterns do we use to make it all happen and understandable? 5: Review Is this all we need? Does it cover everything? 6: Release of design -

RAD, AGILE, PROTOTYPING, EXTREME PROGRAMMING Review of proof of concept, definition of risky directions When you are already building (RAD, Agile, Prototyping, Extreme Programming), the Design Phase is where you take a step back from your prototypes and Proof of Concepts and your code and start reviewing the whole from a wholistic / integrated point of view. You should be ready to identify, shelve

Page 63: Re Factoring and Design Patterns

Refactoring and Design Patterns 63

and ditch specific development directions (risk assessment) which seemed right when you started, but will become increasingly problematic when you continue Start of assessment Did you miss something? Are your solutions covering all requirements? Are you moving towards a dead end or is your code and your prototype prepared for (major) changes? Can you easily shift your code design around and approach the same problem from completely different angles? Software design becomes crucial In this phase (which is crucial for the weeks and months that come) your software design is everything. If you are using OOP principles (see the Refactoring section for some very useful tips and strategies on achieving Agile software: that saved my life and that of my projects many times in the past years) this should not be an issue. Design Patterns are emerging or implemented In this phase (when you already started coding), Design Patterns will already be emerging or explicitly been implemented.

WATERFALL METHOD Coding not started yet, very detailed design documents In this stage, still, no single line of code is written yet. You will be waiting for – sometimes very detailed – Design Documents.

Page 64: Re Factoring and Design Patterns

64 Peter Kaptein

PHASE 6: REALIZATION ** ::Tag:SCOPE-PH-006

2 41 3 5

Discovery ApprovalIntentionScoping, Budget

Design

6 7 8 9

Reali- zation

Test / Debug

ReleaseAccep-tation

BASIC STEPS 1: Technical Design The technical design is (in Waterfall) the first thing you will write. It will describe all technical decisions you made before you started coding and all structures you will implement in your code. 2: Coding The coding is what it is: writing code. With Agile and RAD type of development processes you will do a lot of prototyping and refactorings along the way. With Waterfall you will follow the technical design. Probably exactly according to letter. 3: Testing / Debugging In the testing/debugging phase, which is almost constant, you will test if it works? You will also check the requirements and see if what you made complies to those requirements? 4: Documentation The Documentation is usually written in the code itself. There are different opinions on what you should and should not document in that code. My recommendation is to (buy and) read the book: “Clean Code” and also check out my take on this in this book. Short: make clear in your remarks what your intentions are, not what the code is doing. ::Link:RFCT-ELM-REM 5: Review The review consists of two parts. One is by your peers: did you do a proper job? Do you comply to the rules you use to build that code? Can it be improved? The second is by the client (in Agile and RAD). The client will check if the application is becoming what the client had in mind. Will it do the job? Does she likes where it is going? In most environments with Waterfall backgrounds, the client review is one of the most avoided steps, as it can lead to horrid things like the client changing its mind. 6: Release

Page 65: Re Factoring and Design Patterns

Refactoring and Design Patterns 65

Once the code and the application are to everyone’s satisfaction (or the time is up) the application will be released. Either online or as an application in a web store or on the site of the client.

RAD, AGILE, PROTOTYPING, EXTREME PROGRAMMING Coding has already been going on from day 2 In RAD, Agile, Prototyping, Extreme Programming and the likes, you have already been doing this from day 2.

WATERFALL METHOD Finally you can start! Only at this stage, the programming has started. The designs can no longer be changed and all requirements have to be met.

Page 66: Re Factoring and Design Patterns

66 Peter Kaptein

WHAT IS BENEFICIAL AND WHAT IS NOT? ::Tag:BENF ::includesubchapters

Page 67: Re Factoring and Design Patterns

Refactoring and Design Patterns 67

CHOOSING DESIGN PATTERNS DURING REALIZATION

INSTEAD OF IN DESIGN PHASE

::Tag:BENF-001 Design Patterns emerge I wrote a lot about the design versus realization issue. As “Design Patterns” contain the word “Design”, as stated before they are actually the emerging result of the realization process you and other people follow. With the right coding tools, change is not your enemy If and when you use coding tools that help you find bugs before you compile, changing course during the realization process is not going to jeopardize your project. Design Patterns can and should be chosen as you go The design that you will be doing, will be mostly Conceptual, writing down what you want to achieve, and finding the base way you know then, to achieve it. As you write the software, it might be that Design Pattern “A” is actually the worst choice ever while it looked really good when you were conceptualizing the solution. Nothing is worse than sticking to a losing game because that was decided a few days ago. Instead, change, choose another solution. Keep it simple Design Patterns must lead to a simplification of your code. Both on the implementation and the abstract levels you are working on. If Desing Patterns only make things more complicated, without solving the problem in a better way you could have achieved otherwise, drop that Desing Pattern. It probably sucks for that specific use and should go and play its game elsewhere. Do not fear to create your own You do not learn about Design Patterns by trying to work according to the book. In my case you will not get brownie points for the amount of Design Patterns you were able to cram into your solution. If your code is more complex than it should be, you have failed in my book to write good code. So: do not fear to create your own Design Patterns. Look at what you are copying and pasting. Look how you can simplify your code and your processes. Look how you can make these solution re-usable.

REFACTOR, REFACTOR, REFACTOR

::Tag:BENF-003 You want to maser Design Patterns? Learn to refactor If- and when you take Design Patterns seriously, you Refactor. Relentlessly. This means that each moment you have to think and look back on your code, you will take that code and refactor it:

1: Clearer To make it clearer, by renaming your variables, your methods. By restructuring your code. By adding Remarks to describe what your intentions are with blocks and lines of code 2: Cleaner To remove all garbage, all leftovers, al dead code and all messy code that is and was the result of all changes of mind and heart you went through

Page 68: Re Factoring and Design Patterns

68 Peter Kaptein

3: Leaner To do more stuff with less code. By Extracting and Encapsulating things otherwise done right at that place.

GOOD IS BETTER THAN PERFECT

::Tag:BENF-003 Know when to stop In coding, “Good” and “Good Enough” are better than Perfect, unless your budget and your time are unlimited. So when you Refactor, strive for “Good” and “Very Good” and allow some imperfections to remain. Do not lose yourself Especially when you are a perfectionist, it is easy to lose yourself into making good code, with OK namings even more better and more better every next phase. Things to take into mind Here are some things to take into mind when you refactor:

1: Progress – As long as you are refactoring, your Project is in a halting state. No new functionalities are added. No progress is made, except for (hopefully) better code. 2: Readability – The systems on which your software runs do not give a shit if all your methods are called after all dogs and cats you ever owned. If method names are really unclear, rename them, if they are OK, save the next step for the next time you have a problem with them. There is always a next time in Refactoring. 3: Budget – The Client does not care how beautifully or badly your code is written. As long as you deliver something that works within budget. 4: Result – Your main task as a programmer is to deliver a result. That result is a working application.

Page 69: Re Factoring and Design Patterns

Refactoring and Design Patterns 69

PART 3: BASICS OF

OBJECT ORIENTED

PROGRAMMING ::Tag:Part3

Page 70: Re Factoring and Design Patterns

70 Peter Kaptein

INTRODUCTION TO OOP ::Tag:OOP ::includesubchapters

Page 71: Re Factoring and Design Patterns

Refactoring and Design Patterns 71

LEARNING CURVE

::Tag:OOP-LCRV

Procedural programming learning curve

OOP learning curve

Dif

ficu

lty

in u

nd

erst

an

din

g

Progress of time

Hard to understand

Relatively high learning curve The learning curve on Object Oriented Programming is relatively high compared to Procedural Programming. There are several reasons for that: 1: Learning a new way of thinking OOP introduces a new (or other) way of thinking to building code 2: More theory With OOP comes a lot more theory of how you build and structure your code and what you should- and should not use and do. Then there are Design Patterns and Design Principles (like Inverison of Control and Model View Controller) and frameworks (like Spring and Swing and Swiz and PureMVC). 3: More restrictions OOP brings more restrictions per definition: the use of strong typing, Classes, Class Packages, the availability of public and private variables, the explicit return types of methods. In contrary to loosely typed environments like Visual Basic and JavaScript you can no longer get away with generic types (var myVariableDoesNotNeedAType) or by just defining Methods and Variables (function myFunctionWithoutReturnType).

Page 72: Re Factoring and Design Patterns

72 Peter Kaptein

PRODUCTIVITY CURVES

::Tag:OOP-PRDC

PROCEDURAL PROGRAMMING ::Tag:OOP-PRDC-PRC

Speed of progress

Progress of the project

Time spent on complexity

Tim

e sp

ent

/ Sp

eed

of

pro

gre

ss

Procedural programming: a lot of progress in the beginning, a drop in speed as you go The lack of strict rules in Procedural Programming allows you to setup your application relatively quick in the first phase. You do what is needed in the most practical way possible. As the project progresses, you might be re-using code here and there using Copy & Paste or some sort of Classes. The drop in the speed of progress is mostly caused by: hidden bugs that only emerge when you test that specific part of the application, messy code (which is not exclusive to Procedural Programming), and repetitive solutions in copy/pasted duplicate code.

Page 73: Re Factoring and Design Patterns

Refactoring and Design Patterns 73

OBJECT ORIENTED PROGRAMMING ::Tag:OOP-PRDC-OOP

Speed of progress

Progress of the project

Time spent on complexity

Tim

e sp

ent

/ Sp

eed

of

pro

gre

ss

OOP: hardly any visible progress in the beginning, hard comeback at the end When you look at the productivity curves of OOP and Procedural Coded Projects, the OOP Based projects are hardly showing any progress in the beginning. As the project progresses, the speed of progress in OOP projects (when executed properly) increases. The main reasons are found in the way the project is structured and elements can be re-used. Another important reason is the use of Strong Typing and the support your programming environment offers you in debugging issues before even running your program. Refactoring and the time spent on complexity One of the most important tools to keep the time spent on complexity in any code (Procedural and OOP) stable is the process of Refactoring. Why would the speed of progress increase with OOP? The theory is something like this: because you encapsulate complexity and promote the re-use of functionality you only have to do things once. If you do this well, you reap the benefits as your project progresses. Instead of repeating lines of code, you use settings to enforce specific behavior. Instead of creating increasingly mounts of intertwined code with numerous dependencies that is hard to change you have loosely coupled code that is easy to restructure and refactor. Can this only be achieved in OOP? You can achieve the same results in Procedural Programming. Re-use, refactoring and encapsulation is not unique to OOP. Why OOP is seen as a “step up” in programming and associated to all these benefits is because it offers a set of tools, principles, patterns and constraints in coding that help you to achieve these goals with a solid structural base that is embedded in the languages you use. Concrete these tools, principles and patterns are (to name some but not all): Strong Typing (where your variables and

Page 74: Re Factoring and Design Patterns

74 Peter Kaptein

methods are and return objects of a very specific type), Extending classes, using Interfaces and using Abstract Classes.

MESSING UP WITH OOP ::Tag:OOP-PRDC-OOP

Speed of progress

Progress of the project

Time spent on complexity

Tim

e sp

ent

/ Sp

eed

of

pro

gre

ss

Can you mess up with OOP? You can mess up with OOP just as much (and maybe even more) as you can with Procedural Programming. The biggest pitfall is over-complication. With all kinds of theory on Design Patterns and “How you should setup your code” it is easy to misunderstand the intentions of the writer and go for solutions that might look good when you read them but are complete overkill for the things that need to be done by your code: leading to 3 to 6 different classes with several methods and callbacks to do something you could have solved in 10 lines of code in one single Class.

Page 75: Re Factoring and Design Patterns

Refactoring and Design Patterns 75

HOW DO YOU REDUCE THE LEARNING CURVE? ::Tag:OOP-WHY-004 Work with people who already have experience The best step is to work with people who already have some experience in OOP (and Design Patterns). They will help you get past the first hurdles and get going in the right direction. Read the fucking manual There are many books on OOP. Some are good. Some suck big time. Find the books that help you. Find the books that speak to you in a language you understand. Read this book. Even though it is not perfect, I try to make things as clear as possible for you. Look into the code of others Use the code made by others as the source of your inspiration. Try to figure out what the fuck they are doing and why. Focus on the parts that make sense only. Sometimes coders simply mess up even worse than you can imagine and you do not want to waste time on stuff that is already done wronge from the beginning. Google Go and Google. Relentlessly. In principle you can find answers to all your questions as someone already asked them somewhere. Sorting Design Patterns on type and use I started sorting Design Patterns on type and use. So based on “what do you want to do?” I made several lists including the Design Patterns that are fit for that use.

Page 76: Re Factoring and Design Patterns

76 Peter Kaptein

WHY DO WE USE IT?

::Tag:OOP-WHY

CONTROL OVER COMPLEXITY ::Tag:OOP-WHY-000 OOP as the best solution to harness complexity Object Oriented Programming is currently the best way to structure and control the (emerging) complexity of any project. It uses concepts and metaphors that allow you to create code that is easy to expand, hard to break and easy to repair. Mastering OOP: code ramins simple while complexity grows Once you get the hang of the basic principles of OOP, you will notice that the code of your projects will remain relatively simple even though the complexity of your project and your application can become increasingly bigger.

RE-USE AND BETTER CODE ::Tag:OOP-WHY-001 Basis: extraction, encapsulation and abstraction One of the main pillars (in my book that is) on OOP and code re-use is the principle of extraction, encapsulation and abstraction. The base of this approach is simple: isolate the code that performs a specific job, take it out of its current environment (extraction) and place it into a new and clearly defined container (encapsulation). The next step that follows is abstraction: making it so that the concrete actions are hidden behind an abstract point of entry (the method and method call and even by extracting it into a separate class). Re-use: making code more generic Each project has code that repeats the actions made elsewhere, but just a little bit differently. I refer to this as copy & paste code as that is how such code is usually built and started. OOP principles (and the Design Patterns) help you to solve this kind of coding in different and more elegant ways. For instance by using generic code blocks in which you can inject specific “workers” that will do the specific job. Less repetition: better code The less repetition you have, the better your code becomes. The reason is simple: every time you change your mind about a specific solution, you only want to change this once. When you applied a lot of copy & paste coding, you will have to implement this new approach in several places. Especially when you are under pressure, this can lead to mistakes. Sometimes small enough not to be noticed much later. In other cases, leading to a crash & burn situation in which the only solution is a drastic rollback to an earlier version of your software.

Page 77: Re Factoring and Design Patterns

Refactoring and Design Patterns 77

MORE EFFECTIVE, SO ACCEPT THE LEARNING CURVE ::Tag:OOP-WHY-002 Learning curve? OOP has a relatively long Learning Curve. That learning curve does not lie in coding itself, but in how you and where you organize stuff to make your code and your project the best it can be. Why? Level of abstractions This Learning Curve has to do with the levels of Abstraction that you will introduce as your own experience grows. Horrid documentation Where do your start when you have no experience in OOP and nobody to show you? Most documentation you will find online and in books assume you have some level of expertise and some backup in the form of a teacher or coach. There is hardly any step-by-step guide that takes you through all the important places so that your first project is not the complete disaster it probably turns into, as OOP really adds a lot of new challenges. My take to harness the curve: using the metaphor of a company in the organization of my code The o so loved and hailed MVC did not work for me (see my breakdown of MVC via the link below). Instead I found the most helpful metaphor to organize my own code is the organization of a company. Most of your code deals with processes: getting things done by calling this or that. As both a Company and your Code need to make decisions and deliver results, both your code and an organization have useful overlaps you can use to simplify your Abstract Models. ::Link: MVC-PATT-MVHI My help: diving into OOP and (code) Design Principles As I struggled with OOP for a long time (over 2 years before I started to get it right) I offer you the best I can give you from my experience. The next chapter will handle OOP principles. In part 7 I will tread Design Principles like the MVC Pattern, the Extended MVC Pattern, the (horridly named) MHOPUDO model, which stands for Manager, Handler, Operator, Parser, Utility and Data Object. Each has a very clear role and position within your structure. ::Link: OOP-PRNC|INTRDP-MCRDP|MHOPUDO

SHORT-TERM RETURN ON INVESTMENT ::Tag:OOP-WHY-003 Doubts The first thing you will feel when starting to implement OOP (and Design Patterns) is doubt: “Is this worth it?” “Am I really going to reap the benefits this Peter Kaptein is promising me?” Resistance The second short term return on investment is resistance: “I can do this ten times faster without those shitty, anal OOP shit.” “Why am I doing this?” Fear The third is fear: “I will never finish this project on time.” “My code is a disaster.” “I suck.”

Page 78: Re Factoring and Design Patterns

78 Peter Kaptein

WHAT IS IT?

::Tag:OOP-WHAT A model that reflects objects and processes As many programs reflect processes and objects from the real world, OOP tries to hand you a model of programming that reflects just that: objects and Processes. Example: People, Buildings and Cars A simple example is an application that deals with People, Buildings and Cars. The first Classes you will create are the Classes: Person, Building and Car. Within each Class, representing the object, you will then add behaviors and methods to those Classes and objects. For instance:

Park Car in Garage – Where Garage might be a sub-set of Building Connect Person to Car – Where the person will be attached to the Car as long as your program runs and nothing else changes

Isolate processes The idea is to isolate processes and put them in the proper places. For instance, when we want to make the care “drive” from “A” to “B”, we manage that locally in the Car object. All processes required to get “Car” from “Building” could be placed in “Car”, or other Classes like “Navigator” accessed via “Car”. Self-organizing objects Where the power of OOP becomes visible is when we have two or more “Cars”, each Navigating from one “Building” to another “Building”. Each “Car” can drive independently from any “Building” to another without any need of any management outside each “Car”. Implications of self-organizing objects This principle implies the following:

1: Scalability – As each “Car” (and object) manages itself, you can create as much cars as you want, and each “Car” will be able to Navigate itself without increasing the complexity of your code or your project. The same goes for “Buildings” and “People” 2: Control over complexity – Since more “Cars” and “Buildings” will not lead to more complexity in your code (you can create as much as you like and your systems CPU and RAM allows you) you can create relatively large and complex systems where and while each individual part remains relatively simple

Page 79: Re Factoring and Design Patterns

Refactoring and Design Patterns 79

OOP PRINCIPLES ::Tag:OOP-PRNC

Page 80: Re Factoring and Design Patterns

80 Peter Kaptein

A VISUAL SUMMARY

::Tag:OOP-PRNC-VSM

Your Class

- someObject

+ doSomething(): do process A.1 do process B do process A.2 do process C do process A.3+ doSomethingElse()+ doProcessA( object )

do process A.1 do process A.2 do process A.3

Class A

Class B

«other classes and objects»

do process B

do process C

«separate actions and processes»

B: «be placed into / encapsulated by /

can refer to»

Class C

4: «can be encapsulated into methods into»

«base classes abstract classes

interfaces»

Abstract Class A

Base Class B

Interface C

D: «can extend or implement»

1: «can extend or implement»2: «can contain

reference to object from»

C: «can pass execution/request through to /

can be dependent of»

3: «can be extracted as»

An Object

5: «can be used to create»

A: «can be used by»

1: CLASSES ::Tag:OOP-PRNC-VSM-001 Containers for methods and code Classes are files and containers for methods and code. The basis for objects Each object you create in your code, is based on a Class. Private and public methods Any and all classes can have private and public methods. Private methods can only be called from within the object. Public methods are available and visible for other objects. Private and public variables

Page 81: Re Factoring and Design Patterns

Refactoring and Design Patterns 81

For variables the same rules count as with the methods. Private variables are only visible within the object (and Class). Public variables can be set and accessed by other objects.

2: EXTENDING AND IMPLEMENTATION ::Tag:OOP-PRNC-VSM-002 Extending another class You extend another class when you want to use and inherit specific properties of that class. This can be to use these functionalities within your own class, wrap that class to make it comply better to your needs (see the Adapter Pattern) or to deliberately add new functionalities to that Class. Implementing an interface An alternative is to implement an interface. The interface is a Class with empty methods you are forced to implement. The reason to do this is to make completely different Classes in your project part of the same family. Meaning that it does not matter which Class you instantiate, as long as they implement the same Interface, you can use that object for your code.

3: EXTRACTION ::Tag:OOP-PRNC-VSM-003 Extracting code You extract code when you feel that either a Method is doing too much for its role and responsibilities (“parking the car and taking out the groceries”). Instead you want to separate these actions and place them in specific methods (“parking the car”, “taking out the groceries”) so that you can re-use and mix these actions in any form later on. Extracting methods You extract methods when the Class it is in should not have this responsibility. (“Car” has: “take out groceries” but maybe that should be done by “Person” or even better, a separate Helper class: “ShoppingActions”)

4: ENCAPSULATION IN METHODS ::Tag:OOP-PRNC-VSM-004

5: OBJECTS ::Tag:OOP-PRNC-VSM-005

A: USING OBJECTS ::Tag:OOP-PRNC-VSM-00A

B: PUTTING EXTRACTED CODE INTO CLASSES ::Tag:OOP-PRNC-VSM-00B

Page 82: Re Factoring and Design Patterns

82 Peter Kaptein

C: PASSING EXECUTION TO-/DEPENDENCIES ::Tag:OOP-PRNC-VSM-00C

D: EXTENDING / IMPLEMENTING ::Tag:OOP-PRNC-VSM-00D

Page 83: Re Factoring and Design Patterns

Refactoring and Design Patterns 83

CLASSES AND OBJECTS

::Tag:OOP-PRNC-001 Classes and code All code you write is places in one or more Classes. In contrary to procedural programming environments like Basic and JavaScript, you are forced to create Data-objects for all of your code. Parts that form the classes Classes comprise of the following parts: 1: The Class Package This is where the Class lives. Like a physical address. In most cases, the Class Package is comprised of lower-case words, divided by dots: “root.your.class.path”. When you open existing projects created by others, you will find – in most cases – Class Packages that seem to make no sense. Like: “com.somename.someothername.something.viewcomponents”. This starts making sense when you know the convention. And – regardless if you agree or not – it is advisable to follow this convention in your own projects. Here are the main parts:

A: The domain name – Of the company or person. For instance: www.SomeCompany.com becomes: “com.somecompany” in your Class path B: Project name – Following the company name is the project name. Like this: “com.somecompany.someprojectname”. C: Concrete elements – Only now we start to find concrete elements of the project. But even here we might find some more sub-divisions.

2: The Class Name This is the concrete name with which your Class can be used in your project. The Class Name is usually built from one or more words chained together describing the object or Process it represents. Each For instance: “Person” represents the object “Person” and “PersonDataManager” represents the Process that Manages the Data related to Person. 3: The Class Constructor This is the Method that will be called when you instantiate the Class into a Concrete object. The Constructor is called “Constructor” as it is – and can be – used to “Construct” the object. In most cases you assign values to Variables and create objects you need and will use within your object. Static, Public, Private and Protected Variables – These are variables you can access from outside the Class (static) and object (public) or only from within the object (private and protected) 4: Public Getters and Setters These are methods you can call from inside and outside the Instantiated object to get and set variables usually stored in Private Variables within your Class. We get back on Private and Public variables later in this chapter. 5: Static, Public, Private and Protected Methods These are Methods you can access from outside the Class (Static) or on the concrete object (public) or only intenral (private and protected)

Page 84: Re Factoring and Design Patterns

84 Peter Kaptein

6: Your code The actual code within your methods

ALL YOUR CODE LIVES INSIDE METHODS, INSIDE CLASSES ::Tag:OOP-PRNC-002 Code is encapsulated All your code is encapsulated within Methods, living within Classes. Unlike with JavaScript, where your code can be directly on the Stage and can exist outside of any Method, OOP Programming Languages refuse to accept and compile any code that is not within a Method within a Class. Reasons There are several good reasons for that. Most of them have to do with the purpose of OOP:

1: To promote Encapsulation, Abstraction and re-use A lot of code was written by Copy & Paste. As your project grows, Copy & Paste starts to work against you. Especially when tha basis of that Copy & Paste code changes for all locations you used that code. Encapsulation and Abstraction (together with Extraction) are important tools to re-use code in such a way that it is written and defined only once, but can be used many times 2: To force you to do it right Once you get the hang of OOP, you will also start to get the hang of “write it once, use it many times”.

Page 85: Re Factoring and Design Patterns

Refactoring and Design Patterns 85

STRONG TYPING

::Tag:OOP-PRNC-STRT WTF? Strong typing If you ever started in programming languages like Basic and JavaScript, any Variable can contain any value, whether it is a String-, Numeric- or Date value or the reference to an object. Proper typing: this is what it contians With proper OOP comes proper Typing. This means that you declare explicitly that a variable is of a specific Type, like: String, Boolean, Number, Float or that it is based on a specific Class, like: YourClass, MyClass, HisClass. More solid / less breakable coding Strong Typing has been introduced in programming to create more solid / less breakable code. Breakable code without string typing A simple example of breakable code without Strong Typing:

1: Unexpected Return Types can lead to unexpected results In JavaScript, Variables are Typed when the first value is inserted. As a result, Numeric values can be treated as String Values, leading to errors like: “2” + 2 = “22” instead of 2 + 2 = 4. 2: Unexpected Return Types can crash your application In some cases, unexpected Return Types (which can be anything if you are not using Strong Typing) can lead to unexpected results and your code crashing

WHY WOULD YOU USE IT? ::Tag:OOP-PRNC-STRT-001 A lot of work until you start to get your IDE Strong Typing is a lot of extra work at first. Until you start using the pre-compiling options and Auto-finish options of your coding environment. Your IDE maps your application in a database Your programming environment uses it to map your application in a Relational Database, with all added advantages. By using Strong Typing and the Relational Database Mappings that can be built out of this, your code suddenly becomes like HTML, where each Variable and each Definition acts like a Hyperlink, allowing you to jump to base definitions and concrete implementations of the Classes and Methods you use. It makes your code verifiable While pre-compiling, your programming environment can check if you are connecting the right dots to the right objects. So instead of your code crashing at runtime, it already “crashes” on pre-compile, allowing you to correct your code. It helps your programming environment to help you An object of type: “something” or more concrete: “object” has no concrete implementation apart from the one given to the Class “object” you are using. An object of type “String” will suddenly reveal a lot of

Page 86: Re Factoring and Design Patterns

86 Peter Kaptein

extra, String specific options when you type: “myVariable.”. Once you start using this, you do not want to go back. It allows you to trace dependencies Your code will contain increasingly numbers of dependencies as it grows. Strong Typing is one way to find out what type of object “myVariable” is and jump to that actual code, simply by using a combination of keys on your keyboard. It increases the reliability of your code One reason Strong Typing was introduced to create more solid / less breakable code by eliminating any kind of ambiguity like: “2” + 2 = “22”. It makes your code run faster and more optimized when compiled When you strong-type your variables, your compiler can use specific tricks to optimize your code. Instead of having all kinds of tricks running to resolve the type of variable you use and instead of storing your variables as generic types, the compiler can use system and processor-specific variables to execute your code with.

Page 87: Re Factoring and Design Patterns

Refactoring and Design Patterns 87

SCOPING METHODS AND VARIABLES: STATIC, LOCAL,

PRIVATE, PROTECTED, PUBLIC, AND FINAL

::Tag:OOP-PRNC-SCOP Within your OOP objects and environment, there are several Scopes to work with. We start with the levels and move to the specific types.

STATIC: CLASS LEVEL VARIABLES AND METHODS ::Tag:OOP-PRNC-SCOP-001 Class-level methods and variables Static variables and methods are “Class level Variables” and “Class level Methods”. This means that you can call them directly on your Class, without instantiating an object from your Class Assigned to the Class itself Static Variables are assigned to the Class itself. This means that when you call a Static Method, or set a Static Variable, it will be set on the Class itself.

STATIC VARIABLES ::Tag:OOP-PRNC-SCOP-002 Accessing them via the Class Let’s assume we have “ClassA” with Static Variable: “staticVariableB”. When we want to access the Variable, we do that via the Class itself: myValue = ObjectClassA.staticVariableB Class level means: only one instance shared everywhere When we change the value of staticVariableB, it will be changed on Class level, so everyone accessing that Variable will get that (new) value. Benefit and disadvantage The Class-level variables have a set of benefits. One important one (which is also seen as a big disadvantage) is that it acts as a “global variable” within the Class. If someone changes the Static variable, everyone else that reads and uses that variable will get that new value. The Object Map, Singleton and Multiton are three Patterns making heavy use of that property of the Static variable.

Page 88: Re Factoring and Design Patterns

88 Peter Kaptein

LOCAL: OBJECT LEVEL VARIABLES AND METHODS ::Tag:OOP-PRNC-SCOP-003 Exist only in the scope of the instantiated object Local Variables and Methods exists only in the scope of a specific object. This object is created from a Class. For instance:

myObject = new MyObjectClassName(); Can only be addressed from the implemented object If Class “MyObjectClassName” has a Local Method called: “myLocalMethod” it can only be accessed from the object “myObject”. Like this:

// This will work myResult = myObject.myLocalMethod();

Cannot be called from Class level Calling myLocalMethod() on the Class itself will fail:

// This will fail as the Local method does not exist in the scope of the Class myResult = MyObjectClassName.myLocalMethod()

Page 89: Re Factoring and Design Patterns

Refactoring and Design Patterns 89

PRIVATE, PROTECTED AND PUBLIC ASSESSORS ::Tag:OOP-PRNC-SCOP-004 Private, public and protected Added to the Local and Class Scope are the Private, Protected and Public Accessors: 1: Private Private variables and methods are only visible within the Class you define them in. They can not be seen outside.

Not visible in Child Classes – When you Extend a Class (see later in this chapter), your Extended class will not see or Inherit that Private variable

2: Protected The problem with Private is, that any Child Class, extending the Parent, will not see Private Variables as they are defined by the Parent Class (or Superclass). In some cases, this specific aspect of Private variables is very unwanted.

Similar to Private, but visible in Child Classes – Protected Variables gives you all the good of Private variables (invisible for the outside world) with the added bonus that the Protected Variable will be inherited by the Child class

3: Public Public Variables and Methods are visible and available for the outside world of an object or Class.

USING PRIVATE, PROTECTED AND PUBLIC ::Tag:OOP-PRNC-SCOP-005 // Public Static function, visible outside the Class Public static function myPublicStaticFunction(); // Private Static function, only visible within the Class Private static function myPrivateStaticFunction(); // Public local function, visible for the outside world, only visible on concrete object Public function myPublicFunctionOnObject(); // Private local function, only visible within Object instantiation Private function myPrivateFunctionOnObject();

Page 90: Re Factoring and Design Patterns

90 Peter Kaptein

USING PRIVATE, PROTECTED AND PUBLIC IN YOUR CODE ::Tag:OOP-PRNC-SCOP-006 // Static function, using private and Local calls Public static function saveObjectInDatabase(Object object) { // We want to hide the real work (Abstration) and do the real work here // Static Private Method: doSomethingPrivate() // Local Private Method: will fail doSomethingLocal() } Private function doSomethingLocal() { // Notice the lack of “Static” // This method will only work within the scope of the concrete object } Private Static function soSomethingPrivate(MyClass concreteObject) { // Notice the word “Static”

// This method will work both on Static and Local levels // It can NOT use or access Local variables and methods // in this Class, unless it is passed (or it creates) a Concrete object // This will fail even though we created this method in this class myLocalMethodCall() // This will work, as we have a concrete object passed concreteObject.myLocalMethodCall();

}

Page 91: Re Factoring and Design Patterns

Refactoring and Design Patterns 91

EXTRACTION, ENCAPSULATION AND ABSTRACTION

::Tag:OOP-PRNC-EEA : OOP Principles – Extraction, Encapsulaton and Abstraction

SUMMARY ::Tag:OOP-PRNC-EEA-INTR Concrete code and actions In concrete code, each action is visible and each step can be followed. There are hardly any black boxes (systems in which things happen, but you can only see and control what goes in and what comes out). When code grows The disadvantage of concrete code is that it tends to grow. And the more actions take place, the more code there is to read. Tipping point: loss of “what happens when, why?” At a certain point, this code reaches a tipping point, where the clarity of Concrete Actions gets lost in the sheer bulk of all code around it. The forest starts to absorb the tree. It becomes unclear what happens when and why. Extraction and encapsulation When your code reaches this point, you start to extract specific parts. By preference the biggest parts and very specific processes. The next step is to put this code outside of your main process and “Encapsulate it” in a method or function.

EXTRACTING AND ENCAPSULATING TO A METHOD WITHIN YOUR CLASS ::Tag:OOP-PRNC-EEA-001 First logical move: extraction to a method in your class The first Extractions you will likely do is from your blobs of code into separate Methods within your Class. The code remains in the same Data-object as you were working (your Class) and you do not have to think about the greater picture

EXTRACTING AND ENCAPSULATION INTO A NEW CLASS ::Tag:OOP-PRNC-EEA-002 Extraction to a Class: promotion of code I tend to call this “Promotion” of a Method and of Code. Apparently your Code has done something very well to move to its own or a new Class. What is special about this There is something special about moving Code to a new (or its own) Class. I will summarize:

1: Easier to re-use You make your solutions available for more Classes than just the one you started with. This means that specific solutions – IF you generalize them well enough, can be used many times by many other parts of your project

Page 92: Re Factoring and Design Patterns

92 Peter Kaptein

2: You can start building Strategies A Strategy is one specific way to solve a problem. For instance: “Connecting to a Data Source”. It is possible to get this data from: online sources, local sources and the internal memory. Each of these ways is a “Strategy”. And each of these ways can be put in its own Class. For instance: RemoteDataStrategy, LocalDataStrategy, WebDataStrategy, RAMDataStrategy. Each will have a method call called (for instance) getData(). 3: Better separation of Responsibilities What happens where becomes more and more structured as you go

ABSTRACTION ::Tag:OOP-PRNC-EEA-003 Result of extraction and encapsulation As mentioned before, Abstraction is the direct result of Extraction and Encapsulation. Abstraction: hiding the concrete actions into a black box Once you have isolated specific processes and Extracted and Encapsulated them inside a Method and even promoted them to another or new Class, you can start Abstracting your code. This means that it is no longer clear and visible What is happening How. All that is placed into a black box and the only thing you need to know from that black box is that something is happening and that it caters your needs. The process has become an Abstract Process. See the diagram On the next page I give an example of the Extraction, Encapsulation and Abstraction process.

Page 93: Re Factoring and Design Patterns

Refactoring and Design Patterns 93

Methods: Encapsulated Process 1

Your Method

Methods: Encapsulated Process 2

Your Method

Part 2 of Process 2

Part 3 of Process 1

Part 1 of Process 1

Part 1 of Process 2

Part 2 of Process 1

Methods: Encapsulated Process 1

Part 3 of Process 1

Part 1 of Process 1

Part 2 of Process 1

Methods: Encapsulated Process 2

Part 2 of Process 2

Part 1 of Process 2

extract

ab

stra

ctio

n1

Your Method

Call Part 2 of Process 2

Call Part 3 of Process 1

Call Part 1 of Process 1

Call Part 1 of Process 2

Call Part 2 of Process 1

Methods: Encapsulated Process 1

Part 3 of Process 1

Part 1 of Process 1

Part 2 of Process 1

Methods: Encapsulated Process 2

Part 2 of Process 2

Part 1 of Process 2

use

Call Part 2 of Process 2

Call Process 1

Call Part 1 of Process 2

Part 2 of Process 1

Part 1 of Process 1

Part 3 of Process 1

Part 2 of Process 2

Part 1 of Process 2

ab

stra

ctio

n2

use

extract

Extraction, Encapsulation, Abstraction We start with a Method that has multiple processes going on. We separate the processes (“Process 1” and “Process 2”) and distinguish the parts (“Part 1 of Process 1”, “Part 2 of Process 2”). Then we Extract the parts into external Methods which we will call from our original Method “Your Method”. (“Abstraction 1”) As “Process 2” seems to be part of “Process 1”, we can Encapsulate and Abstract even further, by Encapsulating “Process 2” into “Process 1” via Methods Calls from “Process 1” to “Process 2”. As an end-result, “Your Method” now only has to call one Method and one Process (“Process 1”) to do both “Process 1” and “Process 2”. When and if “Process 1” and “Process 2” are needed and used from other parts of the code, we might and can use the Encapsulated code.

Page 94: Re Factoring and Design Patterns

94 Peter Kaptein

WHY WOULD YOU DO THIS? ::Tag:OOP-PRNC-EEA-004 Clear separation of processes Encapsulation is your first step to a clear separation of concrete processes. As you continue this process of Extraction and Encapsulation, your code becomes more and more OOP ready Clear separation of Responsibilities Whoe does what when starts to become more and more clear Clearer code When everything is programmed in one single blob of code, things tend to mix and mingle. What happens when and why becomes less and ess clear and so your code becomes more and more prone to errors More Agile Code By Extracting and Encapsulating Processes, you make your code ready for change. Using a different way to deal with a Process, no longer requires you to break your code and replace stuff inside a working solution. Instead you simply call another method or – as the next step in Extraction and Abstraction, another Class to do that specific job Simpler code At the end of the line, your code becomes simpler. Processes no longer mix together in one big lump, but are separated. To execute specific actions is simply to call methods with your extracted work. To maintain and change is simply change and maintain smaller amounts of code To make re-use a matter of fact Re-use is a big thing in OOP. Instead of Copy & Paste coding, you try and strive for solutions that do one thing only once. Extraction and Encapsulation are the two actions that gets you there. Extneding classes (see next part) are your smarter and more maintainable approach to Copy & Paste

Page 95: Re Factoring and Design Patterns

Refactoring and Design Patterns 95

BASE CLASSES

::Tag:OOP-PRNC-BCL Basis for more complex and concrete implementations Base Classes are the basis for more concrete and more complex implementations of specific functionalities. Specific and shared code over all derived classes In general your base-classes contain a very specific set of code, variables and functionalities that is shared over all derived Classes. Example For instance, assume you have Data Objects which all require a standard way of parsing and converting their values from XML and back to XML. Your Base Class (apart from the question if this is the best approach) can contain a set of two base functions dealing with parsing XML to your object and parsing values from your object to XML

Page 96: Re Factoring and Design Patterns

96 Peter Kaptein

SPECIALIZATION

::Tag:OOP-PRNC-SPC Separating two or more possible directions to do stuff The moment you are starting to add functionalities to your Base Class that is showing two or more different directions of specific implementation, you separate these different implementations in to separate Classes, extending your Base Class. Starting point to help understanding extending and subclasses We start with the concept of Specialization, that helps understand the underlying OOP principles of Extending, Subclasses and Super-classes.

SPECIALIZATION ::Tag:OOP-PRNC-SPC-001 Base class and generic functions When you create a Base Class, this Base Class has generic functionalities which have no specific direction yet.

ClassA

ClassB ClassC ClassD

ClassFClassE

1: «specializes into»

2: «specializes into»

BRIEF Class A 1: Specializes into Class B, C and D Class D 2: Specialized further into Class E and F

WHY WOULD YOUR SPECIALIZE? Your base class needs different specific implementations As your Project grows, it might be that your Base Class requires specific implementations. For instance: “Vehicle” needs to be specialized into specific types of Vehicles, like “Car”, “Motorcycle”, “Scooter” and

Page 97: Re Factoring and Design Patterns

Refactoring and Design Patterns 97

“Boat”, which all share the same Base Characteristics (like moving, stopping, steering) but implement them in a different way Inheritance: the road to specialization “Specialization” in OOP is done via Inheritance, which we will discuss next.

INHERITANCE ::Tag:OOP-PRNC-SPC-002 A road to specialization As stated in the previous part, Inheritance is the OOP way for Specialization of functionalities and Methods. Inheritance refers to a Parent / Child type of relationship, where the Child Inherits from the Parent.

AN EXAMPLE OF AN UML DIAGRAM SHOWING INHERITANCE

ClassA

ClassB ClassC ClassD

ClassFClassE

1: «inherit from»

2: «inherit from»

Dependencies: Classes B, C and D: 1: Inherit from Class A and get all Public Methods and Variables from Class A Class E and F: 2: Inherit from Class D and get all Public Methods and Variables from Class D, including the ones Class D inherited from Class A

INHERITANCE IN BRIEF Inheritance includes the following principles and concepts: Only Inheritance of Public Methods and Variables

Page 98: Re Factoring and Design Patterns

98 Peter Kaptein

All Public Methods and Variables are inherited by the Subclasses. This means that when you create an object based on a Subclass, you will only be able to see and use the Public Variables from the Parent Class (called Superclass). Private Methods and Private Variables of the Parent All private Variables and Private Methods as defined in the Parent (Super) Class can only be accessed via the Public Methods of that Parent Class Inherited Local Becomes Local Inherited Local (non Static) Variables and Local Methods become Local Variables and Methods of your Child Class. So when you instantiate Class B into “object X”, object X will have all local Variables from Class A as well to work with: as if they are an integral part of object X andClass B Static can be dangerous Static Methods and Variables, in most cases, will remain bound to the Parent- or SuperClass. This means that if you set the Static Variable: myStaticVarInSuperClass to some value, it will be set on the Super Class, not on your Sub Class. Inherited Private Variables and Private Methods are invisible for your Child Class Private variables from your Parent (Super) Class are usually invisible for your Child (Sub) Classes. This means that you cannot address them directly within your Child (Sub) Class. Inherited Private Methods and Variables can be accessed via Public Methods – Private Variables and Private Methods in your Parent (Super) Class can be accessed via Public Methods Inherited from the Parent (Super) Class. You will Protected is visible inside, but invisible outside If you need “private” variables to inherit to your Sub Classes, you can use “Protected” as variable type. Protected variables are inherited and local in each next Class Extension in your chain of Inheritance, but can never be accessed from outside

Page 99: Re Factoring and Design Patterns

Refactoring and Design Patterns 99

POLYMORPHISM ::Tag:OOP-PRNC-SPC-004 From Wikipedia:

Subtype polymorphism, almost universally called just polymorphism in the context of object-oriented programming, is the ability to create a variable, a function, or an object that has more than one form. The word derives from the Greek "πολυμορφισμός" meaning "having multiple forms". In principle, polymorphism can however arise in other computing contexts and it shares important similarities to the concept of degeneracy in biology.

Specialization and inheritance are polymorphism in action When you look at the previous two chapters: “Specialization” and “Inheritance”, you basically see Polymorphism in action.

CLARIFICATION OF POLYMORPHISM VIA A DIAGRAM

ClassA

ClassB ClassC ClassD

ClassFClassE

1: «creating multiple forms of / specializing into / extended by»

2: «creating multiple forms of / specializing into / extended by»

Dependencies: Class B, C and D 1: Are used to create multiple variations (polyforms) on the Methods and / or Variables which are represented by Class A. Via Class B, C and D you can create Multiple Forms of objects based on the one you would create with Class A. Class E and F 2: Are used to create multiple variations of what Class D represents.

Page 100: Re Factoring and Design Patterns

100 Peter Kaptein

EXAMPLES OF WAYS TO IMPLEMENT POLYMORPHISM By using Inheritance As described in this section. By using Abstract Classes Abstract Classes can be seen as a specific use of Inheritance. The other way around, Interfaces can be seen as a specific use of Abstract Classes. Abstract Classes, similar to Interfaces, are Classes that define the functionalities you would like to implement, without implementing them there. In contrary to Interfaces, Static Classes are Extended by Child-classes (Subclasses) and contain both Methods and Variables. By using the Bridge Pattern Where one object pretends to be something else. The added Bonus of a Bridge (which is a Base Class you can Extend) is that the Bridge can change its Base Class and therefore its behavior during runtime. By this option it becomes a Dynamic Base Class By using the State Pattern Where one object replaces itself for another object with the same Interface or Base Class) By using Interfaces Interfaces can be seen as a specific use of Abstract Classes. Instead of Abstract Classes, Interfaces are not Extended, but Implemented. By using or Implementing an Interface, the Compiler (and your coding environment) forces you, within the class that Implements the Interface, to Implement the Methods exposed by the Interface.

Page 101: Re Factoring and Design Patterns

Refactoring and Design Patterns 101

SUPERCLASS ::Tag:OOP-PRNC-SPC-005 Mentions of superclass In the chapters “Inheritance”, “Specialization” and “Polymorphism” we mentioned the principles and the concept of the Superclass. Why not “parent class”? For some reason, OOP terminology chose “Superclass” instead of “Parent class” to refer to a Parent Class. So wherever you read “Super” and “Superclass”, OOP terminology refers to “Parent” and “Parent Class” Diagram: repetition of concepts, but with proper OOP terms What you will see in the diagram below is nothing more than a repetition of the principles mentioned before, but using the terminology for the concrete process of Extending a Class that you will be using in your code.

EXAMPLE OF EXTENDING CLASSES

ClassA

ClassB ClassC ClassD

ClassFClassE

1: «extend»

2: «extend»

Dependencies: Class B, C and D: 1: Extend Class A – Class A becomes the Parent or Superclass of B, C and D Class E and F: 2: Extend Class D. Class D becomes the Parent or Superclass of E and F

PRINCIPLES OF THE SUPERCLASS Extension and Inheritance

Page 102: Re Factoring and Design Patterns

102 Peter Kaptein

SubClass1 and SubClass2 extend BaseClass. As a consequence all Public Variables and all Public Methods of BaseClass are Inherited by DerivedClass1 and SubClass2. Extending deeper down the line We can continue Extending classes as much as we like. So SubClass2 can be extended by SubClass3, and so on. One Base Class, many subclasses The relationship in Extending is always 1 to many. So one BaseClass can be extended by many Subclasse and all SubClasses always extend only one Super Class

SUBCLASSES ::Tag:OOP-PRNC-SPC-006 Child class A Subclass is a Child Class. It is the Child of the Class it extends. This Parent Class can be any class in your project, including the ones you created and the ones part of your programming language. A Subclass inherits all Public and Protected Variables and Methods from the Parent Class, more correctly called “Superclass” in OOP terminology. Shown in the previous diagram Each child in the diagram is a subclass of the Class it extends.

Page 103: Re Factoring and Design Patterns

Refactoring and Design Patterns 103

WHY DO YOU EXTEND A CLASS? ::Tag:OOP-PRNC-SPC-007 To re-use Code Inheritance and Extending a Class is one way to re-use Code. Each Class that Inherits a specific Method also Inherits the code inside that Method. In that way you can build a set of Generic solutions and then re-use them in more specialized- or Subclasses. To avoid Copy & Paste (duplicate) coding Putting re-use another way, Inheritance is just a very smart way of Copy & Paste, where you – instead of Copy & Paste specific methods and variables – simply Extend your Base Class and inherit all the contents of your Parent Class(es). To add functionalities to an existing Class while leaving the original Class intact It might be that you do not or can not change the original Class. In this case, you Extend the original and add these functionalities to the Subclass you created. To create several variations It can be that you deliberately need and want specific variations on a theme. For instance: to convert Data from one format to another To do things differently while leaving the original intact It is possible that your original Class has one way to do things, but that you need different implementations. In that case, you extend that class and Override the methods you think should deal with things differently

WHEN IS IT USED? ::Tag:OOP-PRNC-SPC-008 Frameworks A framework is a collection of Classes, performing a specific task. This can be the programming environment itself (Java, C#, ActionScript, JavaScript/HTML) or frameworks to parse data, render things in 3D or help you build applications faster. In Frameworks you will find a lot of use of Inheritance, where common functionalities, like dealing with User Input, or Connecting to a Data Source are shared and extended by a lot of the Subclasses Commands and Events Commands and Events are using a very basic design that is repeated in each and all derived Events and Commands. By Inherting all these Smarter re-use of code Any time you reach the point of Copy & Paste kind of coding, that is where you will consider to use Base Classes instead

Page 104: Re Factoring and Design Patterns

104 Peter Kaptein

WHERE DO WE FIND THESE PRINCIPLES IN DESIGN PATTERNS? ::Tag:OOP-PRNC-SPC-009 Used in almost all Desing Patterns We Extend, Specialize and Subclass in almost all Design Patterns. To give you an impression:

EXTENDING CLASSES TO CREATE MULTIPLE FORMS OR VARIATIONS ::Tag:OOP-PRNC-SPC-009-001 Abstract Factory The Abstract Factory uses Extension as the core of its definition (by creating Concrete Classes by Extending the Abstract Classes which are the Abstract Factory) to create Multiple Concrete Forms of the Abstract Factory Products from any Factory As we might want to have choice in the Concrete Implementation of a Product (is the Vehicle a “Car”, “Boat” or “Plane”?) we can use a Base Class and Extend it to Multiple Classes to become a Concrete Product Bridge The Bridge can be used as a Base Class and can be extended by other Classes. Unique to the Bridge is that the Bridge itself can “change shape” as you go, because it Pretends to be the Class it instantiates internally. So instead of Extending a fixed set of functionalities, you Extend a dynamic object or “Dynamic Class” Adapter The Adapter can be implemented in two ways: Extending the original Class, or by Encapsulating the original object Strategy In the Strategy Pattern, we want and need multiple Strategies to handle a Specific Process. This Process can be derived from one or more Base Classes and extended and specialized into very Specific Implementations: the individual Strategies Builder To build the Dynamic Structures the Builder can produce, we might want to use a Factory and objects which are Derived from one or more Base Classes Decorator The Decorators we might want to use might share the same basic functionalies. Composite – When we create Composite objects, we add Child-objects to Parents. It is beneficial when these Children all share some base functionalities and variables to create the Composite Structures to begin with Interpreter As Interpreters usually lean heavily on Composition and/or Decoration, we already use Inheritance there. But also the Interpreter itself might be using Inheritance. For instance, to create Specialized variations of itself, dealing with specific parts of the Interpretation process.

Page 105: Re Factoring and Design Patterns

Refactoring and Design Patterns 105

SPECIALIZED IN POLYMORPHISM ::Tag:OOP-PRNC-SPC-009-002 Bridge The Bridge Pattern is a pretender. It pretends to be the Class it instantiates within itself to do the actual work. The Classes which are Instantiated within the Bridge, by the Bridge all share either the same Interface or the same Base Class. This makes each Class look the same, while each is different in the implementation of the Processes behind the Methods. State Pattern The State Pattern, like Bridge, is a very specific implementation of OOP principles to create an “object” that can have multiple forms while seemingly be the same thing for the objects that approach it.

SUPPORTING POLYMORPHISM BY PROVIDING CHOICE ::Tag:OOP-PRNC-SPC-009-003 Factory The Factory Patter in all its forms and implementations supports Polymorphism in providing a simple way to create Multiple Variations on the same Type of object (“Vehicle”, “Car”, “Boat”) Strategy See Factory, but instead of delivering so called “Products”, the Strategy Pattern delivers specific Strategies: objects that Implement a Process in a specific way (the Strategy)

Page 106: Re Factoring and Design Patterns

106 Peter Kaptein

INTERFACES

::Tag:OOP-PRNC-INTF

BASIS ::Tag:OOP-PRNC-INTF-001

1.a: «exposes»InterfaceA

ClassA ClassB ClassC

1.b: «is implemented by»

Methods

ClassC

2: «must be implemented by»

DEPENDENCIES: Interface A: 1.a: Exposes Methods 1.b: Is Implemented by Class A, B and C The Methods : 2: Since Classes A, B and C Implement Interface A, Classes A, B and C are forced to Implement the Methods exposed by Interface A, thus “becoming” Interface A

NOTES: Used for two or more classes with the same interface An Interface is implemented by two or more Classes. By implementing the Interface, you are forced to implement the Methods as defined in that Interface: the so-called “Contract”. Overkill on only one class You will find projects where an Interface is used on only one Class. In most cases this is a “preparation” for more Classes in the same family, but these other members never made it. When possible and when the class indeed will not have any other peers in the forseeable future, kill the Interface as it serves no purpose. You can always refactor it back the next cycle. Consequence: Interchangeable for your code As a consequence, Each Class that implements that Interface can be used instead of the other, to perform a specific action as declared in the Interface. This is very handy when you want to create Flexible Systems where How things are done can be decided and changed while the application is running

Page 107: Re Factoring and Design Patterns

Refactoring and Design Patterns 107

WHAT IS AN INTERFACE? ::Tag:OOP-PRNC-INTF-002 Classes of a specific type In concreto, Interfaces themselves are Classes with Methods which are without any content and which are not capable of doing anything at all. What you find in an Interface When you open an Interface Class, the only thing you will find are:

1: Methods without code Which are your Interface Methods 2: Remarks describing each Function Which should be there to tell your peers what their intended role and implementation is

Ways to see the Interface Interfaces can be seen as:

1: Abstract implementation The Abstract implementation of functionality. Which means that something concrete will be filled in within the Scope of the function, but not here 2: Intention The intention of what should happen in an Class applying this Interface. Which means that your Interface should reflect what you want the Classes implementing

ANOTHER WAY TO BECOME PART OF THE FAMILY ::Tag:OOP-PRNC-INTF-002-A Where Inheritance is about a direct relationship between Parents and Children (the Super and Subclasses), Implementing an interface is like the contract that can make otherwise Unrelated Classes part of the family.

InterfaceA

ClassA ClassB ClassC

1: «is implemented by»

ClassCPart of the family now

Page 108: Re Factoring and Design Patterns

108 Peter Kaptein

INTERFACES AND POLYMORPHISM ::Tag:OOP-PRNC-INTF-003 Polymorphism, from Wikipedia:

Subtype polymorphism, almost universally called just polymorphism in the context of object-oriented programming, is the ability to create a variable, a function, or an object that has more than one form. The word derives from the Greek "πολυμορφισμός" meaning "having multiple forms". In principle, polymorphism can however arise in other computing contexts and it shares important similarities to the concept of degeneracy in biology.

USING INTERFACES TO ACHIEVE POLYMORPHISM

1.a: «expects object with»InterfaceA

ClassA ClassB ClassC

1.b: «is implemented by»

ClassC

ObjectX

1.b: «uses either/or»

Dependencies: Interface A 1.a: Is implemented by Class A, B and C Object X: 2: Uses either/or an object from Class A, B or C to do its work

Notes: As Class A, B and C all implement Interface A and the Implementation of Interface A forces Class A, B and C to implement the exact same Methods as Interface A exposes, all objects created from Class A, B and C share the same Interface. This means that if and when Object X retrieves an object from Class A, B or C, they all are “the same” for Object X. Polymorphism in action:

Page 109: Re Factoring and Design Patterns

Refactoring and Design Patterns 109

By using this principle, Object X.A, X.B and X.C all look the same on the outside (exposing the same Interface) but actually can be- and are completely different on the inside.

EXAMPLE OF AN IMPLEMENTATION OF AN INTERFACE AND A FACTORY ::Tag:OOP-PRNC-INTF-004

1.a: «has»

InterfaceA

ClassC

Concrete Product

4.b: «either uses / instantiates»

Factory B

4.a: «produces/returns»

5: «implements»

ClassB

Your Class

2: «is of type»

3.b: «will be put in»

Variable A

ClassA

1.b: «uses»

3.a: «implements»

DEPENDENCIES: YourClass: 1.a: Has Variable A 1.b: Uses Factory B to produce Product X from Class A, B or C Variable A: 2: Is of type Interface A and will contain Product X Product X: 3.a: Implements Interface A 3.b: Will be put into Variable A Factory A: 4.a: Returns Product X 4.b: Either uses / instantiates Class A, B or C

Page 110: Re Factoring and Design Patterns

110 Peter Kaptein

Class A, B and C: 5: Implement Interface A

NOTES: In this example, everything leads to Interface A. The benefits and result of using Interface A are the following: Class A, B and C: Can all Extend their own BaseClass and be whatever they want to be. ObjectX: Can be either of Class A, B or C, or any other additional Class as long as each Implement Interface A and the Methods exposed by Interface A. Your Application: Is more versatile and flexible as there is no limit to how or how many times you implement Interface A.

WHY WOULD YOU CREATE AND USE INTERFACES? ::Tag:OOP-PRNC-INTF-005 Choice in implementation When you want to create more than one solution for the same set of Methods, usually done by creating one Class per specific approach. Many Variations, one Interface Another way to put his is: to create many Variations on one theme, each using the same Interface and thus being interchangeable All Variations exposing the same Methods To have and to force the implementation of the same Methods on different Classes, thus making them “the same” Identification and Acknowledgement: part of the family Once a Class and an object shares the same Interface as other similar Classes and objects, it is Acknowledged and Recognized as being “part of the family”. Even when it has no other relationships Interchangeability Each class that Implements a specific Interface can be replaced by any other Class that implements that same Interface. Interfaces are the OOP version of “Plug and Play” but with the Drivers built in

Page 111: Re Factoring and Design Patterns

Refactoring and Design Patterns 111

USING COMPOSITION

::Tag:OOP-PRNC-CMP

BASIS ::Tag:OOP-PRNC-CMP-001

Your Class

ObjectA

ObjectB

ObjectC

1.a: «has» Variable A, B, C

ClassA

ClassB

ClassC

1.b: «uses functionalities encapsulated in»

2: «contain»

3.a: «is of»

3.b: «is of»

3.c: «is of»

DEPENDENCIES: Your Class: 1.a: Has Variable A, B and C 1.b: Uses functionalities encapsulated in Object A, B and C Variable A, B and C: 2: Contain Object A, B and C With Objects A, B and C: 3.a: Object A is of Class A 3.b: Object B is of Class B 3.c: Object C is of Class C

Page 112: Re Factoring and Design Patterns

112 Peter Kaptein

NOTES: Extending limited to only one class In many OOP languages, you can only extend one Class, so if you would like to combine properties from several Base Classes (or Derived Classes) you need another approach and strategy to access those properties. Enter Composition. Composition: compose what you need With Composition you “compose” your possibilities by “collecting” all code and functionalities inside all kinds of external classes and putting them together inside and by using your own code. Example: store data in a database For instance: we want to store data into a Database. Our Base Class does not Extend any class with that possibility. We also do not want (or need) to write all that code our self, again and again. Instead, we create an object with a set of these possibilities and properties we need and can not derive. Then we call these possibilities via Methods on that object, passing all variables we have and that it needs.

COMPOSITION IS USED MORE IN OOP THAN EXTENDING A CLASS ::Tag:OOP-PRNC-CMP-002 You already use it a lot You will use Composition in each and all Classes you write. With OOP, there is no escaping to Composition and Composition is part of the very basis of OOP. Alternative for extending a class Extending a Class is only in very specific cases, for instance, where Copy & Paste would be the other alternative choice to reach the same goal.

COMPOSITION IS THE OTHER ALTERNATIVE TO RE-USE COPY & PASTE CODE ::Tag:OOP-PRNC-CMP-003 Using Classes and objects with methods for specific actions With Composition, you use existing Classes with specific methods inside to perform specific actions, like opening Database Connections and parsing data from one format to another. Helpers and utils In most cases, you will create specific classes, like “Helpers” and “Utils” to do those specific tasks for you. Or other people already did so, for you to re-use.

Page 113: Re Factoring and Design Patterns

Refactoring and Design Patterns 113

SubClass1 HelperClass1

BaseClass

SubClass2 HelperClass2

«extends»

«uses»

«extends»

«uses»

n 1

n 1

Exte

nd

ing

: Sm

art

er, m

ore

sp

ecia

lized

Composition: Delegated, less control

Extending Classes and using Composition Smarter, more specialized When you Extend classes, the main goal is to make a more specialized and/or “smarter” version of the existing Class. Composition When you use Composition, you basically access the possibilities and smartness of other Classes to reduce the required code in your (Extended) Class. Delegation With Composition, you delegate specific tasks to other Classes (“HelperClass1”, “HelperClass2”), trusting them to handle your assignment with proper care and attention. Loss of control By doing so, you also lose a certain amount of control, as someone else takes care of dealing with that part of your problem. HOW that is solved is no longer your concern the moment you start the delegate.

WHY EXTEND CLASSES WHEN YOU HAVE COMPOSITION? ::Tag:OOP-PRNC-CMP-004 Composition: delegating actions Composition is like delegating assignments to other people and have them perform specific tasks. It simplifies your life and your list of things to do and monitor. Extending: making a base class smarter and more sophisticated Extending classes is like getting smarter or becoming more specialized in the execution of one specific job. It is like Cloning yourself, but with specific modifications and improvements to perform specific tasks. You will use both In most cases you use both: Extending Classes to make them smarter and more specialized and using Composition to Delegate tasks, to keep things short and simple in your Extended Classes.

Page 114: Re Factoring and Design Patterns

114 Peter Kaptein

OVERLOADING AND OVERRIDING METHODS

::Tag:OOP-PRNC-OVRL To be written

Page 115: Re Factoring and Design Patterns

Refactoring and Design Patterns 115

PART 4: SOFTWARE

ARCHITECTURE ::Tag:PART4 This chapter needs to be written.

Page 116: Re Factoring and Design Patterns

116 Peter Kaptein

PART 5: REFACTORING ::Tag:PART5

Page 117: Re Factoring and Design Patterns

Refactoring and Design Patterns 117

BASICS ::Tag:RFCT-BAS ::includesubchapters

Page 118: Re Factoring and Design Patterns

118 Peter Kaptein

WHAT IS IT?

::Tag:RFCT-BAS-WHT

REFACTORING ::Tag:RFCT-BAS-WHT-002

FROM A TO B: A VISUAL REPRESENTATION OF THE REFACTORING PROCESS ::Tag:RFCT-BAS-WHT-003

1 2 3

4 5 6

A

B

A

B

A

B

A

B

A

B

A

B

Short: 1: The mess It is unclear what is connected to what, how. 2: Lines straightened up Making the connections between the different parts more clear. 3: Re-organization of parts Removing crossing lines and making clear how the path from A to B can be 4: More clarification Knowing the path from A to B, we can make it more clear. 5: Reduction and simplification Maybe we can even remove steps between A and B, for instance by refactoring the parts into one single object.

Page 119: Re Factoring and Design Patterns

Refactoring and Design Patterns 119

6: The ultimate connection – A straight line from A to B

WHAT REFACTORING IS ABOUT ::Tag:RFCT-BAS-WHT-003a Improvement of Code Clarity by better naming The first choices you make are rarely the final choices you will make in your code. You will change, adapt and rewrite. The names you choose for Methods and Variables might be OK at first, but somewhat cryptic as you progress. So one way to solve this is by renaming your variables Cleaning up the mess Your code will get cluttered by “artifacts”: leftovers from previous coding sessions and previous approaches to solve the problem. At a certain point, this mess, these leftovers will become a burden. They will be in your way. They will hinder your development process. So one way to solve this is by taking the time to clean up your (And other peoples) mess Improvement of Code Clarity by restructuring Sometimes code becomes unclear because too many things are happening at one place. Restructuring can be the following:

1: Moving parts of code within your methods Moving parts of code within your methods so that things that belong together are together and not mixed with other things. 2: Extracting and Encapsulating parts of your code Extracting and Encapsulating parts of your code to Methods and even to new or other Classes (“Code Promotion”).

Improvement of clarity in the Project Structure As with your code, your Project Structure (where can you find what files containing what classes doing what specifically) will become stale and messy at a certain point, meaning that you will need more and more effort to find out what happens where. You improve the clarity of your Project Structure by:

1: Creating clear Package Structures Grouped and separated, organized and structured in such a way that finding things is simply following your gut feeling. 2: Moving files to other locations Sometimes a file gets “lost” because it is in a place you would not expect it to be (anymore). As you can find it via Class References this is – at first – not a problem, but you can not always rely on Class References to do your coding. The project browser is a nice tool as well.

We will cover each aspect in a separate chapter in this section.

Page 120: Re Factoring and Design Patterns

120 Peter Kaptein

TO REFACTOR OR NOT AT ALL?

::Tag:RFCT-BAS-WHT-VSM

CODING WITHOUT REFACTORING ::Tag:RFCT-BAS-WHT-VSM-001

Amount of required work

Productivity line

Ideal productivity line

Pro

du

ctivity

Time

Am

ou

nt o

f requ

ired w

ork

Effective work

In danger zone

In danger zone

Effective work

Effective work will drop When you do not refactor, your “technical debt” will continue to build up and continue to increase. Meaning that every next day you will spend coding, will be wasted on old code that is badly written and continues to be in your way. As a result your effectiveness will drop. You will spend more and more time solving problems from bad code than building new code that helps you finishing the project. And as a result of that the effective work you are doing drops as well. Amount of required work to get things done increases Imagine every time you enter your house, you have to move more and more garbage around to be able to do so. A simple process of: “open door, enter hallway, hang coat, enter living room” becomes: “open door, move garbage out of the way of the coat hanger, hang coat, move garbage out of the way of entrance to living room”. The more garbage you collect (instead of cleaning it op) the more work you have to do around your tasks (open door, hang coat, enter living room) to get things done. Productivity line will drop As your non-productive work (moving the garbage around) increases, your productivity drops. Imagine you have to go inside and outside the house more than three times in a row, each time spending more than 5 minutes moving the garbage around.

Page 121: Re Factoring and Design Patterns

Refactoring and Design Patterns 121

CODING WITH THE OCCASIONAL REFACTORING ::Tag:RFCT-BAS-WHT-VSM-001a

Attempt to regain productivity levels

Ideal productivity line

Pro

du

ctivity

Time

Danger zone

No refactoringRefactoring

This is what you are already doing In reality you will clean up your code from time to time, as it is obvious that if you do not, you will strand in a deadlock. Refactoring increases the productivity for a while Each time you refactor, you restore your productivity levels. But as your project progresses, you will also increase to produce more garbage on the way, leading to new drops and new refactorings.

Page 122: Re Factoring and Design Patterns

122 Peter Kaptein

CODING WITH CONSISTENT REFACTORING ::Tag:RFCT-BAS-WHT-VSM-002

Ideal productivity line

Pro

du

ctivity

Time Amount of required work

Am

ou

nt o

f requ

ired w

ork

Effective work

Danger zoneRefactorings

Your productivity line

Hell of a job at first, but pays off in the long run Consistent refactoring is like cleaning the dishes each time you are done eating, keeping your tables, floor and chairs free of clutter, throwing away the and vacuum-cleaning each Wednesday and Friday. When you first start it seems like a lot of work, but the more consistent you become, the more benefits you will reap as well. Keeping your productivity line in the safe zone One important goal of refactoring is to keep your productivity line constant and in the safe-zone. This means that when you code something at the beginning of the project, you still have the same levels of care-free-ness two months later: with a minimum of garbage to move around when you need to do something. Required work when refactoring When you refactor, the amount of required work to get things done increases for a moment: during your refactoring. In most cases that work is “non productive”. Your project will make no progress at all.

Page 123: Re Factoring and Design Patterns

Refactoring and Design Patterns 123

COMPARISON ::Tag:RFCT-BAS-WHT-VSM-004

Stabilization of productivity levels

Ideal productivity line

Pro

du

ctivity

Time

Danger zone

No refactoring

No refactoring: dropping productivity As stated before, no refactoring leads to a (continuous) drop of productivity: to the point where your project will come to a grinding halt because you spend more time moving your garbage around than being productive and getting things done. Refactoring: stabilization of productivity levels Refactoring is basically the art of organizing- and cleaning up your code. While productivity will drop dramatically during each refactoring, on the long run your productivity levels remain very stable, meaning that if you need to get something done, in most cases your environment is clutter-free and ready for your work.

Page 124: Re Factoring and Design Patterns

124 Peter Kaptein

WHEN WILL YOU REFACTOR?

::Tag:RFCT-BAS-WHT-004 Repetition of code Imagine you have a specific set of code that is repeated (Copy & Paste). When you use that same code a 3rd time, it is time to Refactor Annoyance When you hit the same spot over and over again and it is the 3rd time you get annoyed by it, it is time to Refactor. Annoyance can be caused by:

1: Clutter The code is cluttered with all kinds of stuff that should not be there anymore. 2: Cryptic nature The code is Cryptic. Every time you look at it, you need to make an effort to decipher its meaning and what it is intended to do. Even with the remarks on every line. 3: Crudeness The code is crude. It is not elegant. It could be better written, more pleasing to look at. In short: you can do better

Repetition of issues / troubled Code The code is troubled. It is unclear. It is unfinished. You (or some other programmer) have been ignoring this code and its issues or simply been avoiding cleaning up this section as long as possible as it seemed too much work without a clear reward or too complicated and troubled (“it works does it not? Why break it and create even more trouble?”). Now, each time a process fails fails, it fails in this section of your project. When you hit that same code a 3rd time, it is time to refactor it 3 is a pattern Do not wait for things (issues, problems) to happen or re-occur more than 3 times. Three is a pattern. Three means it will happen a fourth time. And a fifth. And a sixth. And each time it occurs you will be wasting your time. Again.

WHEN WILL YOU NOT REFACTOR?

::Tag:RFCT-BAS-WHT-005 Knowing when not to refactoring is as important as refactoring It is important to understand there are moments when you will not Refactor code, even if you think it is literally screaming for refactoring (or you, for all that is). Not enough time Time constraints might be a limiting factor. Good enough code is good code as well Too close to the deadline / Too much risk – If your Refactoring is structural (meaning that you will move around a lot of stuff and break a lot of code before making it work again) better not do it Too many dependencies

Page 125: Re Factoring and Design Patterns

Refactoring and Design Patterns 125

It is possible that the code is so interwoven with anything that Refactoring is going to take several days or even weeks with a very uncertain outcome. Alternative actions when refactoring will be intensive The alternative action here is to:

1: Encapsule the code as much as possible Basically, you leave it as is and limit the influence and impact of the code by encapsulation. Encapsulating the code also makes it ready for replacement (see “Rebuild it from scratch”) the next time you enter this section of code. 2: Rebuild it from scratch If the code is such a mess that it can not be refactored, the alternative option might be to rebuild the functionality.

WHY IS REFACTORING BENEFICIAL?

::Tag:RFCT-BAS-WHT-006 Agile and ready for change The cleaner your code, the more Agile it becomes. Agile means that any change in requirements or specifications can be implemented with less and lass impact to your project Cleaner and better organized code saves time Imagine working in an environment full of clutter. Clutter limits you and slows you down. When you Refactor you clean and structure and re-structure. You optimize your working environment Your peers benefit When you work with other people in a team, clean and organized code is beneficial for everyone. Reduction of bugs Bugs love messy, unclear and sloppy code. They build houses, cities and societies in it. The more confusing your code is, the easier it is for things to be overlooked, overcomplicated and prone for failure. The cleaning process that is part of Refactoring cuts out all the obvious living space for bugs. And the bugs that are still there are easier revealed as there is less space for them to hide than there was before

WHY IS IT RELEVANT?

::Tag:RFCT-BAS-WHT-007 Reduction of Smelly code and Debt Code-smell is code that is rotten, bad, already past its due date. It should have cleaned up a long time ago. Debt is where investments in cleaning up smelly code are postponed, leading to increasing costs every next phase. Reduction of maintenance costs Code will enter the maintenance cycle once it is delivered. The messier the code is, the more time it will take to repair and maintain the results.

Page 126: Re Factoring and Design Patterns

126 Peter Kaptein

Reduction of wasted time Messy code takes more time to work with and change than clean code. Something that might take a few minutes or a few days in clean code, might take hours or weeks when the code is messy.

WHY WILL REFACTORING BECOME ONE OF YOUR MOST

VALUED ASSETS?

::Tag:RFCT-BAS-WHT-008 Better quality code, better quality coder By cleaning up and refactoring your code, you actually become a better coder. Your thinking will change. You yourself will grow. Your coding will become better, more mature, more to the point Ready for anything As you continue to Refactor, your code becomes more Agile. More Agile code is ready for anything. Even drastic changes in Requirements It reveals Patterns in your Code As you continue to Refactor, more and more Patterns are revealed in your code. Some are very specific to your project. Others you will find useful for future projects as well Your will spend less time on bug-fixing – As your code will become more and more clean and more and more solid and bugs more and more easy to find and isolate than it was ever before

Page 127: Re Factoring and Design Patterns

Refactoring and Design Patterns 127

REFACTORING AND DESIGN PATTERNS

::Tag:RFCT-DPT ::includesubchapters

WHEN AND WHERE DO WE USE DESIGN PATTERNS? ::Tag:RFCT-DPT-001 Nowhere and never If it is not clear what Pattern to use, do not use one. They will either Emerge due to your Refactoring, simply do not apply, or you need to increase your understanding. Do not use them because you thing you should use them When they Emerge Your code and your project are always leading. In general, when you Refactor, Design Patterns will automatically Emerge as your progress. This might seem counter-intuitive, but is the most common situation and what you should focus on When it is obvious In some cases it is obvious that you should and could use one or more Design Patterns you master. Thse might be thre Design Patterns form the Gang of Four, or Design Patterns you discovered and used in this or a previous Project When you feel you might It is possible that your instinct or feeling is telling you you are close to an emerging Pattern. Follow the feeling. Also be ready to roll things back if it goes awkward

DESIGN PATTERNS AND EMERGENCE ::Tag:RFCT-DPT-002 Emergence Design Patterns are seldomly defined and designed up-front. Design Patterns are definitely not restricted to the ones defined in a book like: “Design Patterns” by the Gang of Four. Design Patterns happen Design Patterns happen. They happen because you do things in your code and your project that repeat themselves. Re-use happens In most cases, Design Patterns happen by re-use of your Code. And instead of simply Copy & Paste, you redesign and Refactor that code to be more versatile and re-usable in other places, Encapsulated in Classes and Methods. Refactoring can be so good that your code is re-usable elsewhere If you done it well, in some cases, these emerged Design Patterns are re-usable in a broader scope than your one Project in which they Emerged. And so you document them, improve them and take them with you in your next Projects. Design Patterns intend to be the most logical solution for a problem

Page 128: Re Factoring and Design Patterns

128 Peter Kaptein

In some cases, you are re-inventing existing Design Patterns, simply because that is the most logical and most effective way to implement the solution for a specific problem in a specific programming environment. Design Patterns are not always following the book Sometimes you are implementing a variation on an existing Design Pattern which is very effective for your Project, but not really “as should be” if you would follow the book. Improvement of Code is the key In all cases, Design Patterns are created because you (or other people) were Improving their Code. Because you and others repeatedly Cleaned up. Because you and others acknowledged that one part was doing something similar as another part of their code.

WHY BOTHER ABOUT THE GOF DESIGN PATTERNS? ::Tag:RFCT-DPT-003 Relevance Almost all Design Patterns of the Gang of Four are still relevant, even if they were put down to paper in the 1990s. Most of the issues they acknowledged and most of the solutions they found are still occurring now. Standards “Design Patterns” by the Gang of Four is a widely accepted book: known, used and referred to all over the world. The Patterns described in “Design Patterns” are widely accepted and the names given are widely used. So they must have done something right. Shared language and terminology As long as you work alone, who cares? But the moment you start working together, it is convenient to have some sort of shared language. Because the Design Patterns of the Gang of Four are widely accepted and used, the Terminology (the names they gave them) are widely accepted and used as well. To know what someone means by a: “Decorator” is to understand what happens in the code and what solution is used for a specific problem without having to decipher that from the code. Maturity The line of thinking behind Design Patterns is to use and find recurring Patterns in your code. This means that instead of Copy & Paste coding and instead of simply implementing some functionality, you will start thinking about the bigger picture. About the bigger structure Better code through understanding To understand the Design Patterns and the Principles of these Patterns by the Gang of Four means that you yourself will be able to write better code

Page 129: Re Factoring and Design Patterns

Refactoring and Design Patterns 129

REFACTORING STEP BY STEP ::Tag:RFCT-STP ::includesubchapters

Page 130: Re Factoring and Design Patterns

130 Peter Kaptein

THE STEPS IN A REFACTORING PROCESS

::Tag:RFCT-BAS-WHT -STPS

A VISUAL SUMMARY ::Tag:RFCT-BAS-WHT-VSM-STPS

1

2

3

4

1: What is wrong?2: What can be improved?

1: Define MoSCoW: a: Must-, Should-, Could- , Would have2: Check: a: What are the quick-wins? b: What is more difficult? c: What is most important? d: What can be done later?3: Keep Must-haves and quick wins4: Remove everything that is not quick win / must have

1: Define the sandboxes a: How much time do you have? b: What will you do when and in how much time? c: When is the cut-off point?

Shitlist

MoSCoW / Priorization

SandBoxing / Deadline

1: Save the current version so you can restore itBackup current

Refactoring

5

1: Start refactoring2: Do you still have time? a: Yes: continue b: No: abort? c: Does it work / compile?3: Out of time a: Broken? à Roll-back old version b: Working? à Check in refactored code

Refactor

Page 131: Re Factoring and Design Patterns

Refactoring and Design Patterns 131

STEP 1: CREATE A SHITLIST ::Tag:RFCT-BAS-WHT –STPS-001 Basics The shit list contains all the things you think are wrong about your code. It is a unsorted list that has no restrictions. Anything that is wrong or awkward is noted down. You have two primary topics: What is wrong? And: what can be improved? What is wrong? “What is wrong” is anything from naming conventions (and the lack of) to methods and classes not doing what they are supposed to. What can be improved? “What can be improved” is anything that needs improvement. It is not so much “wrong”, but you are not really happy with it.

STEP 2: DEFINE THE PRIORITIES / MOSCOW ::Tag:RFCT-BAS-WHT –STPS-002 Basics To make sure you will not waste (precious) time, you will define what is needed most and what can wait for later. MoSCoW is one way to do this. As it is maybe the most used approach for priorization, why not use it? It defines “Must haves”, “Should haves”, “Could haves” and “Would haves” Must haves These are all the changes and refactorings you must do in order to pick up pace and get things straight again. The items listed here are really in your way. Leaving them in your code is like having a pile of rotting garbage in the middle of your living room. Should haves Should haves are all the things you would like to improve and change, but it will not be a disaster when you wait a bit longer. Compare this to the empty bottles waiting on your balcony. You should really return them sometimes to collect the money, but it is not really a disaster when you leave them where they are for another week. Only when your mom drops by you might consider getting them out as it looks a bit daft when there are so many. Could haves Could haves are all the things you could do and improve when you have enough time left to get bored. Compare them to installing that new door-chime and replacing your dinner plates for something new. Really nice to have, but not essential for the process. Would haves Would haves are all the things you do when everything is already working and you really want to make things perfect. For instance: to please your fellow coders and prove that you really are a great contester in: World’s Most Clean Coder.

Page 132: Re Factoring and Design Patterns

132 Peter Kaptein

STEP 3: DEFINE DEADLINES, DO SOME SANDBOXING ::Tag:RFCT-BAS-WHT –STPS-003 Basics In order not to get lost in endless coding and refactoring, you need to set some deadlines. After all: you are delivering a project and that project has a deadline as well. The power of time limits Time limits do several things. One important one in refactoring is that it prevents you from doing things too well. “Good enough” is good enough. Five steps to do simple sandboxing Below you find five steps to do simple sandboxing. 1: How much time do you have? As your project progresses, time will be running out. Do you have one day? Two days? One hour? Half a day? Make this the basis for your time limit. 2: How much time do you think you need? The refactoring process will not happen out of its own or by magic fairies. You will need to invest some time and you will lose some time as well in the process. So: how much time do you need to make the refactorigns happen? Start with the “Must haves” and stop there as well. “Should haves” are for later. 3: Balance it out If you have 4 hours and you need 10 hours, pick the most essential elements and try limit your time to, say: 6 hours. 4: Define your absolute limit What is essential? How much time do you think you need? How much time do you have? This defines your absolute limit: the work you will do. This defines also everything you will not do. 5: Define when you will do this In most cases, you will do it “now”, but in some cases, other priorities go first. Set the moment and the day for your refactoring.

STEP 4: BACKUP THE CURRENT PROJECT ::Tag:RFCT-BAS-WHT –STPS-004 Basics Refactoring is a destructive process. You will break your project and then repair it again in a new and (hopefully) more improved version. As you break the project, you might fail in getting things done in time. In that case, you will have to have a “Plan B”. “Plan B” is a restore of your backup. No version control? Zip your project Make a copy by zipping your project. This is the simplest way to backup your project without creating a mess of folders. Name the Zip with the date of creation. Version control? Check everything in If you have Version control, check everything in.

Page 133: Re Factoring and Design Patterns

Refactoring and Design Patterns 133

STEP 5: REFACTOR YOUR CODE ::Tag:RFCT-BAS-WHT –STPS-005 Basis The Refactoring process can be broken into several parts. With a lot of other text on the process itself (see and read: “Elements of refactoring” and the link below), I assume here that you already know how to refactor. Instead I focus on time management here. Respect your deadlines Very important is that you respect the deadlines you chose. It is easy to lose yourself in refactoring and making things really awesome, but as long as you are refactoring, the project makes no progress at all. No new things are added. No problems are solved unless the refactoring is part of a debugging process. Check regularly if you still have enough time If so: refactor. Do what you need to do. If not: consider what your break-off point is. Can you do only a part? Will it work? Check if it works Fix as fast as you can, compile when you can. See if the project still works. Be willing to kill your darlings It can happen that you run out of time and the project is broken beyond repair. This can happen specifically when you deal with the mess left by other programmers who went before you. When time is more crucial than a clean solution, be ready to roll back to the version you backed up. Better to have a dirty but working code, than “almost clean” but broken code.

Page 134: Re Factoring and Design Patterns

134 Peter Kaptein

WHEN IS THE REFACTORING PROCESS DONE?

::Tag:RFCT-BAS-DONE

WHEN YOU ARE OUT OF TIME ::Tag:RFCT-BAS-DONE-001

WHEN YOUR “MUST HAVE” LIST IS DONE ::Tag:RFCT-BAS-DONE-001

Page 135: Re Factoring and Design Patterns

Refactoring and Design Patterns 135

REFACTORING PITFALLS AND DANGERS

::Tag:RFCT-BAS-DNGR

AWARD FOR CLEANEST CODE EVURRR… ::Tag:RFCT-BAS-DNGR-001 Basics It might be that you get a kick out of super-clean code. When your collegues see what you have written you expect softly expressed: “aaahs” of admiration. While clean code is really super, it is not the main goal of your work. Your work is to deliver something that works and does the job. Results and goals Refactoring has clean code as a result, not as (primary) goal. The goal of refactoring is to clean up the mess: do things better. The moment you stop refactoring is where the solution serves the needs.

FORGETTING YOUR PRIORITIES ::Tag:RFCT-BAS-DNGR-002 Basics Refactoring is all about priorities. You set priorities because there are deadlines. Even better and cleaner When you are in the process, it might be that you will get carried away. There is a lot of improvement in software once you start. Not all might be needed and necessary. Deadlines and launch dates Deadlines are usually related to launch-dates. Launch dates are usually related to some kind of campaign. Either to roll out something completely new, a newer version of something that existed or to offer an improved version that kills a specific set of problems from the previous one. Bigger picture Launch dates are usually related to commercial interests and specific moments in time where this product is best to be presented, seen and/or sold. When you forget your priorities, you might endanger the launch-date, leading to potential damage in revenue and imago of your client or employer.

TAKING THE PROJECT HOSTAGE ::Tag:RFCT-BAS-DNGR-003 Basics As long as you are refactoring, you take a part of the project hostage. Nobody but you (and your refactoring buddy) can do anything and this might lead to a block on progress on the project as a whole. Can’t touch this Whatever you refactor has consequences for the project and especially when you refactor the structure of the project, this might touch dependencies related to the work of others. For instance: refactoring the interface of objects, moving methods to other Classes and moving Classes to other packages.

Page 136: Re Factoring and Design Patterns

136 Peter Kaptein

ELEMENTS OF REFACTORING ** ::Tag:RFCT-ELM Some parts in this chapter need to be added and finished Topics We will cover the following topics: Separation of Responsibilities Using MVC and the Extended MVC Pattern we will see how you can use separation of responsibility to give a good home to different parts of your code and your applications. Promoting and Demoting your code Each part of your code plays a specific role. Each part has specific responsibilities. Based on these roles and responsibilities you can decide to promote that code into separate methods and separate classes or demote it back to where it came from. Using Constants In most code you will find hardcoded values like “somevalue” to indicate a specific choice in that code. Instead of hsardcoded values it is smarter and more solid to use Constants. Improvement of Code Clarity Code can become messy. There are several ways to clean that code up, including the techniques described above and below. Better Naming Names and naming conventions can break and make the clarity of your code. Does the name of a method, Class and variable really cover the content? Is it clear what actions and values the names represent? If not, you can achieve a lot by improving the names you choose. Remarks Remarks help to understand what is going on when you come back into that code after a while. It also help your colleagues to understand what you have been doing, what is going on in your code and why you choose that solution. Cleaning up the mess Cleaning up the mess can include a lot of things, including the removal of dead code and untangling entangled code. Restructuring your Code One of the next steps is to restructure your code: moving things into different methods, re-wiring connections between objects and Classes and moving things into separate Classes. Improving your Project Structure The structure of your project is one of the last things to take on. Is everything in the right place, the right folder, the right Class. Would your code clarity imprive if you would restructure things?

Page 137: Re Factoring and Design Patterns

Refactoring and Design Patterns 137

THREE MAIN TYPES OF REFACTORING

::Tag:RFCT-ELM-3ELM

A VISUAL SUMMARY ::Tag:RFCT-ELM-VSM May 4th, 2012. Work in progress: refactoring of names needs to be added

REFACTORING OF NAMES ::Tag:RFCT-BAS-WHT-VSM-STPS-REFNM To be inserted ::Link:DWNLD-REF

Page 138: Re Factoring and Design Patterns

138 Peter Kaptein

REFACTORING OF PROCESSES AND STRUCTURES ::Tag:RFCT-BAS-WHT-VSM-STPS-PSTR

Your Class

- someObject

+ doSomething(): do process A.1 do process B do process A.2 do process C do process A.3+ doSomethingElse()+ doProcessA( object )

do process A.1 do process A.2 do process A.3

Class A

Class B

«classes and objects»

do process B

do process C

«extractedactions and processes»

Class C

«base classes abstract classes

interfaces»

Abstract Class A

Base Class B

Interface C

To Methods

«extracted code put into / promoted to»

To Classes

extraction and abstraction of

code

Refactoring of processes

A

B

A

B

clarification of processes

interaction betweenelements

adding and removing (abstraction) layers

file structure / class packages

Refactoring (project)

structuresClass A

Class C

Class A

Class B

Class C

Class A

Class C

Class C

Class B

«clarificarion of processes»

«organization of classes and

files»

«code extracted and promoted to»

«# of layers increased / decreased»

«code extracted and abstracted»

«cleaner code put back into»

«organized structure put back into»

Cleaner code

Promotion of code (to classes)

Promotion of code (to separate

methods)

Clarification and reduction of

dependencies

Improvement of project structure

::Link:RFCT-ELM-PROC|RFCT-ELM-STRU|DWNLD-REF

Page 139: Re Factoring and Design Patterns

Refactoring and Design Patterns 139

TYPE 1: REFACTORING OF NAMES ::Tag:RFCT-ELM-NAM The first choices you make are rarely the final choices you will make in your code. You will change, adapt and rewrite. The names you choose for Methods and Variables might be OK at first, but somewhat cryptic as you progress. So one way to solve this is by renaming your variables

1: CHANGING AND CHOOSING CLASS NAMES ::Tag:RFCT-ELM-NAM-001 Class names are created by chaining words that describe: Purpose The purpose of your class defines the way you will name it. The way I learned to approach this is to use the following categories:

1: A Value Object – To store Values 2: A Data Transfer Object – To transfer data from one Object to another 3: A Handler – To handle data or processes 4: A Manager – To manage data or processes 5: A Parser – To parse data

::Link:RFCT-ELM-SRSP|RFCT-ELM-SRSP-PRO-MHPDO Using Object/Subject in the Class name The (linguistic) object or Subject it Represents. For instance: “Person”, “Vehicle”, “Book” Four steps in choosing the Class name I use the following steps when I name and re-name a Class:

1: Define the Purpose and Representation Define what the Class Represents and what the purpose is. 2: Generalize Try and Generalize the description. Are we talking about the object: “John”, “A Friend”, “A Man”, “A Person” or a “Human”? Which description fits the use of your object best? 3: Decide and implement Make your decision and implement 4: Repeat and Rename If your chosen Class name turns out to be less than optimal, you repeat the steps above and Rename it what fits best at that moment. Sometimes it takes five or more renaming actions before the Class name really hits the spot. Take that effort.

Use of upper- and lower case You use a specific combination of capital and lower case characters:

Camel Case

Page 140: Re Factoring and Design Patterns

140 Peter Kaptein

Class Names use Camel Case. This means that each word you use and chain to form the Class Name stats with a capital letter.

Examples of Class names Below you find three examples based on the “Person” entity:

Person The Class that is used for the object “Person” PersonHandler The Class that has the Purpose to Handle one or more Person-objects PersonDataHandler More explicitly, the Class that has the Purpose to Handle Data for or related to Person objects

What is not allowed Some characters are not allowed in Class names. I list them here:

1: Symbols Like: “!@#$%^&*()+-=”. Your Compiler will very likely refuse to accept the name as a whole when you try and use them 2: Dots and commas Dots and commas are reserved for other things

What not to do Some things you can do in Class names, but are better to avoid as they are not considered to be part of the standard naming conventions.

1: Using numbers You should not use Numbers in your Class-names. In most cases you probably have not taken the effort to think of something better 2: Using Underscores In general, underscores in your Classnames are weird.

Page 141: Re Factoring and Design Patterns

Refactoring and Design Patterns 141

2: CHANGING AND CHOOSING METHOD NAMES ::Tag:RFCT-ELM-NAM-002 What they describe Method names are created by chaining words that describe:

1: The purpose The purpose of your Method defines the way you will name it. The purposes of a Method can be anything. 2: The Object/Subject The (linguistic) object or Subject it will handle. For instance: “Person”, “Vehicle”, “Book” 3: The Action The action it will perform. Strive for one action per Method. So: “personHandlerAndParser()” might be a good name for what happens in the Mehtod, but not the best implementation of these actions (better might be to split the actions into two Methods)

Examples Methods are usually written in Camel Case, starting with the Action, then the Subject and Purpose. For instance:

handlePersonData: To handle the Person Data parsePersonData: To Parse the Person Data removePersonData: To Remove the Person Data storePersonData: To store the Person Data

Page 142: Re Factoring and Design Patterns

142 Peter Kaptein

3: CHANGING AND CHOOSING VARIABLE NAMES ::Tag:RFCT-ELM-NAM-003 Naming your variables Variables are used to store values, or references to objects. Naming a variable follows very much the same rules as for methods and classes:

1: Subject and object What will you store in the Variable? 2: Purpose How will the data “inside” the variable be used? 3: Scope Who does it belong to? What is the scope?

Examples The examples below give you an impression of variable names using subject, object, purpose and scope.

myData: Giving scope (in this case the object or the method), but not necessarily the best way to name it myPerson: Defining the type of object we store myPersonData: Stating that it is not the Person, but the Person Data. Scope of the Variable is related to Person. Content is Data personData: Better than myPersonData, as “my” is kind of a lazy way to state the Scope isCollected: Defining a state that is Binary. The value is either True or False collectedDataState: Reflects one or more possible states on the Collected Data

Page 143: Re Factoring and Design Patterns

Refactoring and Design Patterns 143

TYPE 2: REFACTORING OF PROCESSES ::Tag:RFCT-ELM-PROC OOP Principles Everything that is part of this refactoring process is nothing more than the application of specific OOP Principles. You will find several links in the HTML document to these principles per type.

1: CLARIFICATION OF PROCESSES ::Tag:RFCT-ELM-REST-001

A

B

A

B

A

B

From messy To clear

From messy to clarity Where your code might start off as messy code, before you start refactoring, the Clarification process should slowly untangle that mess into clear steps that reflect what is going on in clear steps. What happens where, why? When you look at your code, is clear what happens where, why? Usually this is the first step to take. Can you restructure your code so that everything that belongs together as part of one process is brought together? Kill useless dogmas One of the probably most damaging things against clear code is the assumption that a Method should have only one exit point. So instead of exiting wherever you want, you will have to do a lot of effort and coding to reach this absurd goal. The result of the “one exit” dogma is in most cases a tangle of conditions within your method to avoid “unnecessary” exits. There are (no doubt) many other of these dogma’s, describing how you should write code, without making things easier or better. Kill them. Good code is clean code is simple code. Kill chains Some people really love to do as much as possible in one line of code. Like this: // Yeah whatever: awesome chain! myObject.someMethod().doSomething().getObject().performMyAction( somethingElse( parameter ) ) While this kind of code looks cool if you want to impress idiots and work in complete solitude, they are not cool for people who have to work on your code. Instead: break apart the chains, put each step into a separate variable that has a clear and meaningful name and make sure you can clearly understand what is going on as a result. Extract clusters of actions to separate methods

Page 144: Re Factoring and Design Patterns

144 Peter Kaptein

Here you already are preparing the extracton of code. Take the chain of actions above: by extracting all the steps into one new and separate method you can simplify the call to something like: executeThePreviouslyChainedAction( parameter ) Where that method holds the broken-up chain. ::Link:RFCT-ELM-CLMS|OOP-PRNC-EEA

2: EXTRACT, ENCAPSULATE AND ABSTRACT PARTS OF YOUR CODE TO NEW METHODS ::Tag:RFCT-ELM-REST-002

Your Class

- someObject

+ doSomething(): do process A.1 do process B do process A.2 do process C do process A.3+ doSomethingElse()+ doProcessA( object )

do process A.1 do process A.2 do process A.3

do process B

do process C

«extractedactions and processes»

To Methods

«code extracted and abstracted»

Extracting and abstracting code to a new Method in the same Class ::Link:DWNLD-REF How many lines does your methods count? There are many opinions on how many lines a Method should maximally have. 10 lines? 20 lines? 100 lines? All are right in one way and totally wrong in another. “Keep it short and simple” is the bottom line. Golden rule #1: one method, one process Instead, focus on the golden rule: one method only performs one process. If your Method does two or more things, extract these “two or more things” and put them into separate methods. Golden rule #2: doing it twice? Use a method instead If you do the same thing twice, even if it is only with two lines of code, consider to extract the code and put it in a separate Method. Working towards re-use When you extract code, you work towards re-usable blocks of code. Each method contains specific actions with a clear entry point and a clear type of result. You will find that code that you extracted can be very handy on multiple places. Either because you copied and then pasted that code from some other source (very likely) or because you simply repeated a specific pattern that is so generic for your solution you can clear it up and make it into one single method. (Also very likely to happen). ::Link:INTRDP-WH-001 Can you isolate parts of your code and extract them to new Methods?

Page 145: Re Factoring and Design Patterns

Refactoring and Design Patterns 145

Can you isolate parts of your code and extract them to new Methods? Does that clean up your code? Does it make it easier to understand what is going on? What is Extraction? When you Extract code, you take one or more lines and place them outside of the Method where you found them. What is Encapsulation? Encapsulation means that you “encapsule” your code into something else. A closed shell like a Method or a Class. What is Abstraction? With Abstraction, whatever concrete actions you perform in code is hidden behind an abstract call. For instance to a method, an object or a Class. Extraction and Abstraction into a new method One way to extract and abstract is to place the code from its old environment into a new method. This can be within the same Class or within a different or new Class. Promoting your code I call the Extraction and Abstraction of code info new Methods is called “Promotion of code”. Apparently it is important enough to get its own Method. ::Link:OOP-PRNC-EEA|RFCT-ELM-SRSP-PRO

Page 146: Re Factoring and Design Patterns

146 Peter Kaptein

3: EXTRACT AND ABSTRACT PARTS OF YOUR CODE TO NEW CLASSES ::Tag:RFCT-ELM-REST-003

Your Class

- someObject

+ doSomething(): do process A.1 do process B do process A.2 do process C do process A.3+ doSomethingElse()+ doProcessA( object )

do process A.1 do process A.2 do process A.3

Class A

Class B

«classes and objects»

do process B

do process C

«extractedactions and processes»

Class C

«extracted code put into / promoted to»

To Classes

«code extracted and abstracted»

Extracting and abstracting code to (methods in) a new/other Class ::Link:DWNLD-REF Why move code to a separate Class? There are several reasons to move code (including entire Methods) to a separate (and/or new) Class. I treat them briefly below:

1: Your Class and code has become bloated There are more than 500 lines of code and a lot of stuff is happening inside that Class. 2: Some Methods handle processes you can easily extract and put into a separate Class Think if processes that are needed by, but not really a part of the Class itself. Like you and your mobile phone. You need it, you use it, but it is not part of you and you can also choose to replace it by something else at a certain time. 3: The processes are more generic / specific than your class should deal with Your Class has a specific responsibility, to deal with specific processes. The code simply falls outside these responsibilities. See: “Promoting your code” below.

Extraction, Encapsulation and Abstraction See more on this in the part on Extraction, Encapsulation and Abstractin in: “OOP Principles” ::Link:OOP-PRNC-EEA Promoting your code: to a new Class

Page 147: Re Factoring and Design Patterns

Refactoring and Design Patterns 147

As stated before, I call the Extraction and Abstraction of code info new Methods: “Promotion of code”. In this case, you promote that code to a new Class. Apparently it is important and useful enough to be used not only by the code you extracted it from, but also by other Classes. ::Link:RFCT-ELM-SRSP-PRO Removing and adding layers of abstraction In the next part on “Refactoring of strucutres” we will go into this subject. ::Link:RFCT-ELM-STRU-LAYRS

Page 148: Re Factoring and Design Patterns

148 Peter Kaptein

4: CLEANING UP THE MESS ::Tag:RFCT-ELM-CLMS Your code will get cluttered by “artifacts”: leftovers from previous coding sessions and previous approaches to solve the problem. At a certain point, this mess, these leftovers will become a burden. They will be in your way. They will hinder your development process. So one way to solve this is by taking the time to clean up your (And other peoples) mess

1: Dead Code ::Tag:RFCT-ELM-CLMS-001 Once written, no longer used Dead code is code once written and – due to changes in Requirements or Implementation no longer in use. It sits there, is executed, but serves no purpose at all, anymore. Never removed Dead code is code that should have been removed, but has not been removed Unclear intent Still there because it is unclear why it is there, what it exactly does and what happens (somewhere else) if it is removed Dead Code obscures your Project. It creates parts that you do not like, but you might be afraid to remove due to unwanted consequences. In some cases what seems to be Dead Code is actually still active, or required in very special cases. Whatever the reason and risks of removal of Dead Code is, Code without a clear Intent or Purpose should either be removed or cleaned up.

2: Cleaning up Dead Code ::Tag:RFCT-ELM-CLMS-002 The safe way By turning it into remarks. This way you can re-activate Dead Code by removing the Remark-signs. The radical way By removing the code all together without any mercy. Do not do this without the possibility to roll-back. Either you make Backups or use a Versioning System

Page 149: Re Factoring and Design Patterns

Refactoring and Design Patterns 149

3: Messy Code ::Tag:RFCT-ELM-CLMS-003 Dead parts Messy code can contain Dead Parts, which is Dead Code. Code that no longer has a use. Remove it Unclear parts Some parts of your Messy Code is simply unclear. In naming, structure and/or purpose. Here is what to do:

1: Rewrite your Comments Rewrite your Comments. Instead of repeating what your code is already saying, state the intent you think the code has or should have. 2: Rewrite your Code Rewrite your code to reflect the Intent you wrote down in the Comments. This will – in most cases – automatically result in dramatic improvements. 3: Remove the leftovers Leftovers are lines of code which have no purpose

Fluff Lines of Code which are there, have a purpose, but could be cut shorter

1: Rewrite your Comments Re-state the Intention you have with the fluffy Code 2: Rewrite your Code Following your restated Intentions, you code should become clearer too

4: Badly written / dirty code ::Tag:RFCT-ELM-CLMS-004 Code Chaining Code Chains are evil and horrid. They assume all is well along the line and that when an Error occurs, your Error Trapping (or someone else) will solve your problem. Code Chaining looks like this: myObject.getSomethingWithMyMethod().someOtherMethod().someAction().moreAction(); Each step in the Chain should be cut up and put into separate Variables. The main reason is that you want to know where things go wrong when they go wrong. If the chain occurs many times, this might be something you want to wrap into a Method. Like: myObject.doMoreAction() or something you want to solve via a Helper Class: myHelper = MyHelper( myObject ); myHelper.doMoreAction(); If / then / else soup In some cases you will find nestings of If/Then/Else that make what is happening when and why completely unclear due to the sheer size and depth of the Nestings. One reason is that it is apparently forbidden according to some writers to exit when you can exit. Another is the lack of a proper approach to several mixed states. I mention two below:

Page 150: Re Factoring and Design Patterns

150 Peter Kaptein

1: Getting rid of complexity: Extract to Methods One way to solve Nested if/then/elses is to extract the Code into separate Methods which have their own If/then/else chain. 2: Refusing to exit when you can One reason you might have nested if/then/elses is because you refuse to exit when you can. There is one theoretic line of thinking that states that your code should only have one point of Exit (“single point of exit”, see also the book: “Code Complete”). Martin Fowler in “Refactoring” prefers and advocates the view of multiple points of exit for Code Clarity reasons and I subscribe to this point of view as well. In general Practice prefers Multiple Points of Exit in functions to keep the code readable and the process and dependencies simple to understand.

If( someValue == something) { If(someOtherValue==somethingElse) { // More nestings and then the actual code } }

Might be simply translated into

If(someValue!=something) { // Exit here } If(someOtherValue!=somethingElse) { // Exit here } // Do the things!

Failed attempts to use specific Design Patterns When a Coder does not understand a Design Pattern, the result is like hammering a square peg through a round hole: a mess. Specific Design Patterns sometimes simply do not apply to specific situations in which you might want to use them. And so using no Official Design Pattern at all is better than trying to force one thing into something else that is not fit for it.

Page 151: Re Factoring and Design Patterns

Refactoring and Design Patterns 151

TYPE 3: REFACTORING OF STRUCTURES ::Tag:RFCT-ELM-STRU

1: COLLABORATION AND DEPENDENCIES OF ELEMENTS ::Tag:RFCT-ELM-PRST-COLL To be written Who communicates with whom? How are your parts connected? Who is dependent of who and what? Who points at what and how many layers are there? How flexible is your code when things change?

2: CREATING CLEAR PACKAGE STRUCTURES ::Tag:RFCT-ELM-PRST-001 To be written

3: MOVING FILES TO OTHER LOCATIONS ::Tag:RFCT-ELM-PRST-002 Sometimes a file gets “lost” because it is in a place you would not expect it to be (anymore). As you can find it via Class References this is – at first – not a problem, but you can not always rely on Class References to do your coding. The project browser is a nice tool as well. To be finished

4: USING ABSTRACT CLASSES, BASE CLASSES AND INTERFACES ::Tag:RFCT-ELM-STRU-ABS To be written

5: CHANGING THE WAY YOUR ELEMENTS ARE CONNECTED ::Tag:RFCT-ELM-STRU-CONN To be written

6: REMOVING AND ADDING LAYERS OF ABSTRACTION ::Tag:RFCT-ELM-STRU-LAYRS

A

B

A

B

A

B

An example: counting and reducing the steps from request (A) to concrete execution (B)

Page 152: Re Factoring and Design Patterns

152 Peter Kaptein

How many steps to get from request to execution? How many steps does it take to get from request to execution? How many classes and methods pass that request through to something else, which passes it through to something else? Golden rule #1: 3 is the magic number There is something weird in the human brain (or at least mine that is) that makes 3 a magic number. Anything more than 3 becomes “many”. Anything less is usually boring. If you pass things through to other methods and classes, which pass things through to other methods (and classes) see if you can reduce the amount of pass-through to a maximum of 3. Golden rule #2: Define clear start- and end-points While 3 might be a magic number, where do you start and stop counting? So: define clear start and end points, where your explicit request starts and where your code will explicitly handle that specific request (the end pont). It is very possible that from your end-point more delegation will take place, but very likely these delegations are to do part of the process. So the end-point becomes the start-point for those sub-processes.

Your Class

- someObject

+ doSomething(): do process A.1 do process B do process A.2 do process C do process A.3+ doSomethingElse()+ doProcessA( object )

do process A.1 do process A.2 do process A.3

do process B

do process C

«extractedactions / processes»

To Methods To Classes

«code extracted and abstracted» Your Class

Class A

What does what and what happens where? Adding layers of abstraction ::Link:DWNLD-REF Why add layers of abstraction? There are several reasons to add layers of abstraction. One is that your code becomes less dependent of the concrete implementation of the process. Meaning that if you need to change the implementation, you do not have to break other pieces of your code as well. You simply create a new approach and replace the old for the new one. The following Design Pattern explicitly focus of this possibility to change: Bridge, State, Delegate, Decorator and Strategy. When do you add these layers of abstraction? Imagine you have one piece of code in which a lot of stuff is happening. Several processes are handles and the code to deal with these processes are mixed and mingled. Also, you copied and pasted some solutions to deal with specific processes into different parts of your code.

To centralize specific actions you do over and over

Page 153: Re Factoring and Design Patterns

Refactoring and Design Patterns 153

Some code is copy & paste of a specific solution you use on several places in your code. When something changes in that approach, you need to go through all your code and change it everywhere (as worst case scenario). By extracting this code and placing it somewhere else, you make that code easier to re-use and easier to manage. To clean up and organize your code and define boundaries of responsibilities The more things are happening in one block of code, the harder it is to figure out which lines of code is responsible for what exactly. By extracting the different pieces and placing them somewhere else, you start the process of cleaning and organizing. Each part is given an explicit location and a clear boundary that defines what is and is not part of that process.

Extraction, encapsulation and abstraction The process as described above can be summarized as extraction, encapsulation and abstraction ::Link: OOP-PRNC-EEA|RFCT-ELM-PROC

Class A

Class B

Class C

Class A

Class C

Class C

Class B

What happens where? Removing layers of abstraction ::Link:DWNLD-REF Why remove layers of abstraction? Sometimes you can and do go too far in abstraction. The chain of requests becomes too long and to messy to the point where it becomes really hard to figure out what happens where exactly. Apart from the time you will spend on figuring out how things work each time you touch that code, it might lead to code that is very rigid and unwilling to change. Meaning that as time progresses, that code will become more and more dominant in your solution as well: blocking the progress at that point (cleaner code, alternative solutions, updates to newer insights) you could gain otherwise.

Page 154: Re Factoring and Design Patterns

154 Peter Kaptein

7: USING MVC, EXTENDED MVC AND MHOPUDO ::Tag:RFCT-ELM-PRST-003 Separation of responsibility The basis of the approaches mentioned here is what I call “Separation of Responsibilities”. The main question is: what does what why, where? There is a separate section on Separation of Responsibility in this chapter. More variations can be found in “Macro-Patterns and Design Principles” ::Link:RFCT-ELM-SRSP|INTRDP-MCRDP Model, View Controller Model, View, Controller is one of the older “Patterns” out there that help you organize your code in a different way. It assumes you have three parts in the application to do the work: the Model, the View and the Controller. ::Link: MVC Model, View, ViewModel/Presenter, Services Model, View, Controller is not without problems. One of which is the explosion of different interpretations of where and how MVC can be applied. Another is that MVC is per definition an incomplete model. MVC focuses mainly on the presentation layer of the application. The Controller originally is the part of your code that passes user interactions (keyboard strokes and mouse actions) to those parts of your application that should receive these interactions. More recent models and variations have tried to overcome these issues. Two I like are Model, View, Viewmodel and Model, View, Presenter. Still both lack one more important part: connecting to external data sources: which is done by “Services”. I wrote an analysis on the MVC Pattern and present the MVVM and MVP patterns in the chapters on MVC. I also decomposed the MVC Pattern into a Model, View, Hub, Interface model, just for the fun of it. Both are worth a read if you want to underastand the MVC pattern and the problems it has. ::Link: MVC-PATT-VAR|MVC-PATT-MVHI Extended MVC Extended MVC is another attempt on my side to create a more explicit implementation of MVC without becoming rigid: mainly by applying Distribution of Responsibilities. Manager, Handler, Operator, Parser, Utility, Data-object What do you do with all these different tasks and responsibilities? Where do you put what when you build and refactor your code? For this reason I started to think about the: “Distribution of responsibilities”. MHOPUDO is one result out of that. It basically states you have different types of Classes with different types of roles and a specific hierarchy in their responsibilities. Regardless of your implementation and what Design Patterns you might use, MHOPUDO tends to be a reasonably stable way to implement your solutions. ::Link:MHOPUDO

8: USING DOMAIN DRIVEN DESIGN ::Tag:RFCT-ELM-PRST-004 To be written.

Page 155: Re Factoring and Design Patterns

Refactoring and Design Patterns 155

MAINTAINING A STABLE PROJECT STRUCTURE

::Tag:RFCT-ELM-CONS To be written

CREATING AN DESIGN PATTERN AGNOSTIC CODE BASE

::Tag:RFCT-ELM-AGN To be written

Page 156: Re Factoring and Design Patterns

156 Peter Kaptein

PROMOTING AND DEMOTING YOUR CODE

::Tag:RFCT-ELM-SRSP-PRO Code might be better off doing the job somewhere else As you Code, at a certain point you will reach that moment where you feel that what you are doing there at that place, might be better done somewhere else. For instance: you are writing a Method that is growing and growing into something spanning several hundred lines of code. When Patterns are emerging You might also notice that a Pattern is emerging. For instance: your Method is Handling something. This is the moment to start thinking about Promoting your Code.

A MODEL TO PROMOTE, DEMOTE AND SPECIALIZE ACTIONS ::Tag:RFCT-ELM-SRSP-PRO-MHPDO

OperatorManager

Handler

Value Object

Data Transfer Object

Data Object Dem

oti

on

P

rom

oti

on

Specialization

Code from Your Object

Parser

Utility

Hub

ViewModel Object

::Link:DWNLD-REF In this chapter You will find a brief mention of the MHOPD model in this chapter on refactoring. ::Tag:RFCT-ELM-SRSP-PRO-003

Page 157: Re Factoring and Design Patterns

Refactoring and Design Patterns 157

On the MHOPUDO Model and refactoring A more elaborate description on the MHOPD model, the hierarchy of elements and refactoring can be found in the chapter on MHOPD in part 6: “Introduction to Design Patterns”. ::Link:MHOPUDO-REF

WHAT DOES IT MEAN? ::Tag:RFCT-ELM-SRSP-PRO-001 Promotion and Demotion: a metaphor In my Refactoring Process I found it handy to have a simple metaphor to define and decide why and when I would move Code from one place to another. Promotion and Demotion were two things that stuck. Code as an organization Another part of Promoting and Demoting Code is thinking in Code as an Organization with Roles and Responsibilities. When the Code is doing More or Less than the current location requires from it, you Promote or Demote that code: moving it “up” or “down” your Code Organization. Promotion: The Code is doing something beyond the current scope Promotion Code means that that Code is doing something good, but in the wrong place and within the wrong type of Role. And therefore you move it “up” in the Hierarchy of your Project and your Code. Demotion: The Code is doing something below the current scope When your Code is doing something simple related to the Role of your Class (say: a Manager Class) and takes a lot of space in your Code, it might be time to Demote that Code (to say: a Handler). The lowest point of Demotion is the Value object, where the Class is holding nothing more than Values.

OBJECTS AS A STARTING POINT ::Tag:RFCT-ELM-SRSP-PRO-002 You start with an object Let us assume that in most cases you start with an object. This object has some internal logic and performs specific actions. When that internal logic grows, you might want to start separating it into different logic blocks. Promoting and demotion Code promotion and code demotion is just another way to say:

Promotion: “This part of code does more things or smarter things than should happen in this specific Class” Demotion: “We should extract this specific part / these specific variables and place it in a separate class”.

PROMOTING YOUR CODE ::Tag:RFCT-ELM-SRSP-PRO-004 Moving code up in the hierarchical chain

Page 158: Re Factoring and Design Patterns

158 Peter Kaptein

A promotion means that the code moves one or more steps up the ladder. So code inside your object that is more than – let’s say – 10 lines, does smart stuff or handles specific things and shows ambitions to grow even more, will become a Handler or Manager.

DEMOTING YOUR CODE ::Tag:RFCT-ELM-SRSP-PRO-005 Moving code down the hierarchical chain When you are only storing values inside an object and it turns out to have no intelligence at all, you demote the object to become a Value object.

SEE ALSO ::Tag:RFCT-ELM-SRSP-PRO-SEE MHOPUDO and refactoring: going deeper into the refactoring process within the MHOPUDO model MHOPUDO and refactoring goes deeper into the refactoring process within the MHOPUDO model. ::Link:MHOPUDO-REF

Page 159: Re Factoring and Design Patterns

Refactoring and Design Patterns 159

USING MVC AND SEPARATION OF RESPONSIBILITIES

::Tag:RFCT-ELM-SRSP

SUMMARY ::Tag:RFCT-ELM-SRSP-SHS Why focus so much on MVC? In the roughly 30 years since its introduction in 1986, MVC has become one of the most consistent and widely used patterns in code design. As you continue to work in programming applications and sites it will become harder and harder not to use it. Many interpretations, many assumptions The original implementation of MVC is quite straight forward. It assumes you have a View in which you present things, it has a Controller to direct (the result of) user actions (mouse and keyboard) to the right components and objects and a Model with the current state of the Application: to store and process these actions in. In the years, the MVC Pattern has become a lot more and especially the role of the Controller has “evolved”. Clear structure and better Separation of Responsibilities This chapter focuses on the MVC Pattern and how to apply some simple principles to get to a clear structure and a better Separation of Responsibilities.

SEE ALSO ::Tag:RFCT-ELM-SRSP-SEE More on Separation of Responsibilities There are many ways to look at your code and how that code is organized. In this chapter we focus mainly on Model, View Controller, but there are many other “Macro Patterns” and “Design Principles” you can use. I wrote an extensive chapter on that in: “Macro Patterns and Design Principles”. ::Link:INTRDP-MCRDP Other chapters on MVC As MVC is quite misused and easy to misunderstand I wrote several other chapters on MVC.

Model, View, Hub, Interface: Deconstructing the MVC Pattern MVC has a different background from what you might think. From this especially the role of the Controller has “evolved” into something that might have nothing to do with a “Controller” at all. To look at this specific aspect I thought it might be fun to deconstruct the MVC Pattern and see what happens if I would refactor the very basis of the MVC Pattern against the current interpretation. ::Link: MVC-PATT-MVHI The Extended MVC Pattern The Extended MVC Pattern is my attempt to implement a model that allows you to have a better Separation of Responsibilities in your code. ::Link:EMVC-SR

Page 160: Re Factoring and Design Patterns

160 Peter Kaptein

To be finished

Page 161: Re Factoring and Design Patterns

Refactoring and Design Patterns 161

A VISUAL SUMMARY ::Tag:RFCT-ELM-SRSP-DIA

MODEL, VIEW, CONTROLLER ::Tag:RFCT-ELM-SRSP-DIA-001

MVC

Model

View Controller

Three components Model, View, Controller assumes three main Components: the Model, the View and the Controller. Who does what? What MVC lacks is a clear separation of Responsibilities within the Model, View and Controller. What exactly is the Model? How does the View communicate with the Model? What is the role and responsibility of the Controller related to the Model? Controllers and Views in models? As a consequence you might (I did anyway, in more than one Project) find Projects using Controllers and Views within Models, used to “control” things and offer “views” to data. Origins of MVC, see also: I will go deeper into the origins and base-definitions of the Model, View and Controller in section 6: “Design Patterns and Design Principles”. ::Link: MVC

Page 162: Re Factoring and Design Patterns

162 Peter Kaptein

EXTENDED MVC PATTERN ::Tag:RFCT-ELM-SRSP-DIA-002 An example of the structure of the Extended MVC Pattern as described in this book:

Layers

Extended MVC

Model

View “Controller”

Operator

Handlers, Managers, Utilities,Parsers

Simulations,Actors,Rules,

Behaviors

Services

1: P

resentatio

n2

: Bu

siness

3: D

ataData Objects

Observer / User

::Link:DWNLD-REF Attempt to overcome shortcomings of MVC Extended MVC is an attempt to overcome a shortcoming of MVC. MVC is incomplete if you want to use it as a basis for your entire application. Smalltalk MVC and the role of the Controller and the Model Unlike what seemed to be assumed with MVC, the Controller is mainly an interface between the User and the application. It does not deal with Business Logic or anything else. Instead, the Model can be anything and includes everything that has to do with data, decision making and data-retrieval. I discuss a breakdown of the MVC pattern in more depth in: “Model, View, Hub, Interface”. ::Link: MVC-PATT-MVHI Striving to a better Distribution of responsibilities The problem with MVC and the (unforeseen and unwanted shift in the) roles of the Controller and the Model is an unclear Distribution of Responsibilities.

Page 163: Re Factoring and Design Patterns

Refactoring and Design Patterns 163

Combination of MVC, MVVM, MVCS and extra set of elements Extended MVC is a combination of MVC, MVVMC and MVCS, with an extra organizational set of elements: Handlers, Managers, Operators, Parsers and Data-objects and Simulations, Rules, Behaviors. Attempt to provide a complete model for Software Development with MVC Extended MVC is an attempt to provide a complete model for Software Development using the principles of MVC, including the 3-Tier model as presented and promoted by Microsoft in the 1990’s. These three tiers or Layers are: the Presentation Layer, the Business Layer and the Data Layer. We will come back on the Extended MVC Pattern in section 6: “Design Patterns and Design Principles” ::Link: MVC|MHOPUDO

Page 164: Re Factoring and Design Patterns

164 Peter Kaptein

USING THE HIERARCHY OF THE MHOPUDO MODEL ::Tag:RFCT-ELM-SRSP-PRO-003

OperatorManager

Handler

Value Object

Data Transfer Object

Data Object Dem

oti

on

P

rom

oti

on

Specialization

Code from Your Object

Parser

Utility

Hub

ViewModel Object

::Link:MHOPUDO-REF|DWNLD-REF Manager The Manager is the highest in Ranking. It manages all other Classes within your Model and has most knowledge of your Application and the bigger picture Operator The Operator is close to be a Manager, with the difference that an Operator does not make any Decision at all. It is simply a “Pass-through Manager”. The Operator has some knowledge about the Application as a whole, as it knows how to connect what to what to make things work for the Requesting Parties, but its knowledge is only that. It has no knowledge about Processes or how to handle them. It does not perform Actions itself. Handler The Handler is closely related to the Manager. The Handler Handles stuff. It has no knowledge of the bigger picture, but specific knowledge about the things it is supposed to Handle. Parser

Page 165: Re Factoring and Design Patterns

Refactoring and Design Patterns 165

The Parser is a Specialized Handler. It has one simple role: to Parse objects and Structures from A to B and (sometimes but not always) form B to A. Data Objects The Data Objects are at the bottom of the Hierarchy and Organization. Data Objects do not perform any actions but simply contain stuff. And when and if it perform actions, these actions are mainly on itself. The Data Object – in general – is a closed universe and has not, and should not have any knowledge of the rest of the application.

THE TYPE OF OBJECTS WITHIN YOUR MODEL ::Tag:RFCT-ELM-SRSP-PRO-004

1.b: «use»

2.a: «apply»1.a: «apply»

Business Rules

1.c: «work with» 2.b: «use»

Data Objects

3: «can be»

Data Transfer Handler

Populator

2.c: «can be»

Handlers Parser1.d: «can use»

Data Structures

4: «receive and send»

5: «is derived from / parsed

into»

Data Services Managers

Model

Services

6.a: «granting access to»Data Transfer Objects

Utility

6.b: «can be»

Hub

ViewModel Object

Operators

::Link:EMVC-SR-OVV-MOD

Page 166: Re Factoring and Design Patterns

166 Peter Kaptein

THE TYPE OF OBJECTS WITHIN YOUR SERVICES ::Tag:RFCT-ELM-SRSP-PRO-005

1.b: «use»

2.a: «apply»1.a: «apply»

Business Rules

1.c: «work with» 2.b: «use»

Data Objects

3: «can be»

Data Transfer Handler

Populator

2.c: «can be»

Handlers Parser1.d: «can use»

Data Structures

4: «receive and send»

5: «is derived from / parsed

into»

Data Services Managers

Model

Services

6.a: «granting access to»Data Transfer Objects

Utility

6.b: «can be»

Hub

ViewModel Object

Operators

::Link:EMVC-SR-OVV-SER Additional text to be written

Page 167: Re Factoring and Design Patterns

Refactoring and Design Patterns 167

THE TYPE OF OBJECTS WITHIN YOUR VIEW ::Tag:RFCT-ELM-SRSP-PRO-006

1.b: «can contain»

1.c: «can contain / is a»

2.b: «can contain / is a»

View Component

3: «can be addressed by»

Container

List

2.c: «can be»

Container

Tab sheet

1.d: «has internal»

Event Dispatcher

3: «uses»

4: «can be observed by»

Controller

Panel / Page / Dialog / Popup

View

Controller

5.a: «granting access to / working with»

View Code

5.b: «can be»

Hub

ViewModel Object

Operators

State Managers

Injectors

ViewModel

View(Data) Managers6: «working

with»

5.b: «using»

7: «work with»

::Link:EMVC-SR-OVV-VW Additional text to be written

Page 168: Re Factoring and Design Patterns

168 Peter Kaptein

RESPONSIBILITIES WITHIN YOUR MODEL ::Tag:RFCT-ELM-SRSP-MOD Various approaches possible There are various approaches possible to divide the responsibilities within your Model and within your application. I choose to use the MHOPUDO model as a starting point, but you are free to choose any other approach. Main goal: what happens where? The main goal is to come to a clear definition of “what happens where?” in a way that remains relatively stable even after many, many refactoring sessions. The Value object (VO) The Value object is responsible for containing Values related to a (virtual) object. The Value object in general contains no, to almost no Methods and is not supposed to perform Actions on its own. Within the Extended MCV Pattern, the Value object is considered to be a Data-object (of Data) ::Link:MHOPUDO-DO The Data Transfer object (DTO) The Data Transfer object is a more specialized form of the Value object. The responsibility of the Data Transfer object is to make the Transfer of Data from A to B and from B to A easier. A Data Transfer object – in contrary to the Value object – can have Methods inside to perform specific Actions as they are required to make the Transfer simpler. In the Extended MVC Pattern, the Data Transfer object is considered to be a Data-object with some extra’s. ::Link:MHOPUDO-DO The ViewModel object (VMO), Hub or Operator The ViewModel object is responsible for managing the connection and interaction between the View and the Model. It is tightly coupled with the View it Represents and all Methods and Actions within the ViewModel object are aimed at making the View work according to the Requirements. In the Extended MVC Pattern, the ViewModel object is considered to be an Operator, used to access and perform Operations on the Model and the View. The ViewModel object can be a Façade or a Mediator. ::Link: MVC-PATT-CHUB-002|MVC-PATT-MVHI|MHOPUDO-OPR The object The object is a general purpose thing. The Responsibility of an object is to Represent a Concept, a Process or an object of a specific Type and perform all Actions related to that Concept, Process or object of specific Type. The object can be anything. Usually you start with the object and then Promote Methods to Handlers and Managers and Demote Variables to Value objects. The Handler (Handler) The Handler is responsible for Handling things. This can be the Parsing of Data, the creation of a Connection to something else, and so on. In most cases, you will move code that is “handling stuff” into a Handler Class. The Handler is not bound to any Design Pattern and is mostly a Data-object to Handle Processes in which one or more Design Patterns are used to perform the actual work. ::Link:MHOPUDO-HNDLR The Parser (Parser) The Parser is a specialized Handler. Its responsibility is to Parse Data from one Structure to another and/or/sometimes from one Type of object to another. ::Link:MHOPUDO-PARS The Manager (Manager)

Page 169: Re Factoring and Design Patterns

Refactoring and Design Patterns 169

The Manager is responsible for Managing Processes and Actions. The Manager has some overlap with the façade and Mediator Patterns, but is not bound to any Pattern and goes one step further in really Managing the processes inside your Application. ::Link:MHOPUDO-MGR

Page 170: Re Factoring and Design Patterns

170 Peter Kaptein

RESPONSIBILITIES RELATED TO YOUR VIEW ::Tag:RFCT-ELM-SRSP-VW Various approaches possible Like with the Model, various approaches are possible to divide the responsibilities within your View. Main goal: what happens where? As stated before, the main goal is to come to a clear definition of “what happens where?” in a way that remains relatively stable even after many, many refactoring sessions. Displaying content: View Components View Components are responsible for Displaying Content (Data, Images) and allowing the User to Input Values or take Action (like with buttons). View Components are well-rounded elements or Components to display something on screen. They contain all required functionality to perform a specific task and need little to no extra coding to make them work. View Components can be simple elements like a Text Box, more complex elements like Lists and Dropdown Boxes or Compound elements like an input-row for a form containing the Text Label, the Input Field and several elements to show visual feedback when Validation fails. Grouping elements: Containers Containers are responsible of Grouping or Containing elements. When empty, Containers do not show anything. Their main purpose in the View is to contain View Components. Hence the name: “Containers”. Containers can have Scroll-bars, a title bar and buttons when these elements are common in the Pattern of your application. Presenting the whole: Pages /Panels / Forms / Dialogs Pages, Panels, Forms and Dialogs are responsible for grouping a set of Elements into one single block that has a clear Function and Scope for the user. Each and all of the terms (Page, Panel, Form, Dialog) define the same type of View object, but is relative to the Context in which you work, or the Application Design Principles you use. Panels are more natural to use for “Pages” which can be moved left and right. Forms are more commonly used for the classic Desktop applications. Dialogs are more like a meta-name for anything you use to have a “dialog” with the Application and include Forms, Panels and Windows.

RESPONSIBILITIES RELATED TO YOUR CONTROLLER ::Tag:RFCT-ELM-SRSP-CTR Various approaches possible Like with the Model, various approaches are possible to divide the responsibilities within your View. Main goal: what happens where? As stated before, the main goal is to come to a clear definition of “what happens where?” in a way that remains relatively stable even after many, many refactoring sessions. Handling user input: The Controller In the model we use, the Controller Domain has only one type of object: the Controller. The Controller takes care of handling User Actions like Button Clicks, Key Presses and changes in values due to User Actions. All processes are then delegated to the Model.

Managing communication within your application: Don’t use a Controller

Page 171: Re Factoring and Design Patterns

Refactoring and Design Patterns 171

The Controller is in some approaches to MVC used as a Controller for things that happen within your application. I believe that this is a wrong use of the Controller. While it seems to be logical, as the Controller “controls” stuff in your application, it is like using an Adapter as a Proxy: the wrong pattern for the wrong job. Controller or actually a Mediator or Manager? When you want to use a Pattern to manage processes in your application, what you call a “Controller” is probably either a Mediator or a Manager. ::Link: PAT-MED|PAT-MGR More information on the role of the Controller For more information on the role of Controller within the MVC Pattern, see either: “MVC: The basics” in the chapter on Model, View controller or the texts on: “Deconstructing the MVC Pattern” and “MVC and 3-Tier Development”. ::Link: MVC-PATT-BAS-001|MVC-3TIER|MVC-PATT-MVHI|MHOPUDO-OPR

Page 172: Re Factoring and Design Patterns

172 Peter Kaptein

CONSTANTS AND REMARKS

USING CONSTANTS ::Tag:RFCT-ELM-CONS Constants are used in many cases where you would otherwise type hardcoded values like

someFunctionCall( ‘myhardcodedreference’)

Constants are for instance, but not exclusively, used: To indicate, or refer to, a State Especially when you move towards multiple States To refer to an object For instance when using Factory and Strategy Pattern or when To identify an Event of a specific Type When you use the Observer Pattern

Page 173: Re Factoring and Design Patterns

Refactoring and Design Patterns 173

REMARKS IN YOUR CODE ::Tag:RFCT-ELM-REM

INTENTION VERSUS DESCRIPTION ::Tag:RFCT-ELM-REM-001 Two parts that make your code When you write code, there are two parts making your code:

1: The concrete actions These are your lines of code 2: The Intention you have with these actions These are the goals you try to achieve. Why do you do stuff the way yo do it? What are you trying to achieve?

EXAMPLES ::Tag:RFCT-ELM-REM-002

// A: Add 1 to the ID myID += 1 // B: Increase the ID here, so we are sure it is unique for the next step myID += 1

Instead of just telling what we are doing in “A” (which is obvious from the code) we also state WHY we are doing this in “B”.

// C: For / next loop For( int i=0;i<myArray.lengthli++) { // Do stuff } // D: Go through each item and do stuff with that Item For (int i=0;i<myArray.length;i++) { // Do stuff }

Example “C” again tells us nothing about the intention we have with the following code. “D” tells us we are using the for/next loop to: “Go through items and do stuff with that Item”.

// E: If / then / else If(a<3) { // Do something } Else { // Do something else

Page 174: Re Factoring and Design Patterns

174 Peter Kaptein

} // F: Did we reach our limit of items? If(a<3) { // Not yet, do something } Else { // We did, do something else }

Example “E” tells us nothing, Example “F” tells us that we are checking some limit and within the If/then statement whether we met that limit or not.

// G: My variable Int myVariable // H: My variable to keep track on how many times we looped through valid items

“G” is telling us nothing. “H” is explicitly clear on why we created myVariable.

Page 175: Re Factoring and Design Patterns

Refactoring and Design Patterns 175

HOW DOES THIS HELP YOU? ::Tag:RFCT-ELM-REM-003 Easier to read Writing down your Intentions makes your code easier to read, as you include the What AND the Why of your lines of code Improve your code the moment you write it The intention is what you want to achieve. When you are writing your intents in your comments, you will find in many cases that your code can be improved immediately. For instance: take the for/next loop I used as an example. My Intention is to: “go through each Item”. While I chose for/next out of routine, my Intention actually already provides me a cleaner implementation, namely the for/each loop: “for each (SomeObject item in myArray) { // do stuff }” Helpful in debugging Reading your intentions helps if you are looking for bugs. Sometimes your code simply does not meet your intentions and when you compare your Intentions with the code, the bug is visible immediately Helpful in cleaning up If your Intentions where unclear, this will reflect in how they were written down and how your code is written. By clearing up your Intentions, your code will become more clear as well Clarification of purpose Especially with Variables, sometimes it is completely unclear why you created them or what you are using them for. By stating the explicit Intent, there is also no room for the use or usefulness of that variable State and rewrite your intention as first step In all steps to Refactor your code, stating and re-writing your Intention in your code is the first step you make. If you can make absolutely clear what you want to do and what the Code and these specific parts are Intended to do, your code will almost seem to rewrite itself as a consequence.

Page 176: Re Factoring and Design Patterns

176 Peter Kaptein

BOOK 2: DESIGN

PATTERNS

Page 177: Re Factoring and Design Patterns

Refactoring and Design Patterns 177

PART 6: INTRODUCTION

TO DESIGN PATTERNS

AND DESIGN PRINCIPLES ::Tag:Part6

Page 178: Re Factoring and Design Patterns

178 Peter Kaptein

INTRODUCTION TO DESIGN PATTERNS ::Tag:INTRDP ::includesubchapters

Page 179: Re Factoring and Design Patterns

Refactoring and Design Patterns 179

WHAT ARE DESIGN PATTERNS?

::Tag:INTRDP-WH From: “Design Patterns”, “What is a Design Pattern?” (GoF)

Christopher Alexander says, "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 a way that you can use this solution a million times over, without ever doing it the same way twice"

[…]

Design patterns are not about designs such as linked lists and hash tables that can be encoded in classes and reused as is. Nor are they complex, domain-specific designs for an entire application or subsystem. The design patterns in this book are descriptions of communicating objects and classes that are customized to solve a general design problem in a particular context.

From this book: “Factoring and Refactoring”

Design Patterns happen. They happen because you do things in your code and your project that repeat themselves. […] In all cases, Design Patterns are created because you (or other people) were Improving their Code. Because you and others repeatedly Cleaned up. Because you and others acknowledged that one part was doing something similar as another part of their code.

Page 180: Re Factoring and Design Patterns

180 Peter Kaptein

1: EMERGING AND RECURRING PATTERNS IN YOUR CODE ::Tag:INTRDP-WH-002 Copy and paste code Every time you copy and paste code, to do a specific job, you are repeating a simple and basic Design Pattern that emerged in your code. Specific and recurring structures in your class-design This is basically the advanced version of Copy & Paste. Each time you repeat a specific design in your project, you are re-applying a specific Design Pattern

2: THE RESULT OF SEVERAL CONSECUTIVE REFACTORINGS ::Tag:INTRDP-WH-003 Refactoring to achieve clearer and cleaner code When you refactor to clean up your code and make purpose and implementation clearer in each next step, specific Patterns will naturally emerge and improve as you go. Once you start abstracting these patterns and start re-using them on multiple places in your code, you basically have created a Design Pattern Refactoring to re-organize your project When you refactor to clean up your project (moving Classes around, extracting things from your code and placing it in separate classes for more general use), again Design Patterns will emerge as you progress

3: OFFICIAL/RECOGNIZED AND NON-OFFICIAL/NOT RECOGNIZED ::Tag:INTRDP-WH-004 Non-official Design Patterns When you “create” a Design Pattern (usually by refactoring recurring patterns) within your local project you can – by all means – call it a Design Pattern. When and as it is repeatedly used within your Project, and clearly recognizable as such, why call it anything else? Official Design Patterns The difference between your (and my) own Design Patterns and the ones widely accepted are:

Approved by a committee Whether this committee is official or “the public at large” does not matter. Described in a widely accepted book The Design Patterns have been described in a book that is widely accepted by many people in the field. Used by many people Apart from being accepter and described in a book, it is also used by many people.

Official? There is a weird mix of factors that make a Design Pattern “official” and “accepted”. If you feel overwhelmed and doubt your own, re-read the factors that makes a Design Pattern. It is not that

Page 181: Re Factoring and Design Patterns

Refactoring and Design Patterns 181

exclusive a thing. A Recurring Pattern is a Recurring Pattern and when normalized and re-usable, it becomes a Design Pattern.

WHAT ARE THEY NOT?

::Tag:INTRDP-WHNT Not the solution for everything Design Patterns are mainly aspects of maturity of you and your code. They are not the beginning of everything or a Holy Grail. More important than using Design Patterns is you structuring and refactoring your code until every part is clean, crystal clear and well documented. Not an automatic warranty for re-usable and maintainable code It is easy to mistake one Design Pattern for another when you just start and easy to think you “should use” Design Patterns, and “you should” fix on specific ones and then mess up astronomically in the cases where you do not understand them. Not easy to implement strategically Even more concrete, Design Patterns in general are far from easy to implement. While the theory and the practice is relatively simple, it is very easy to use the wrong Pattern for the wrong purpose. One reason is that there are always at least two Patterns that do the same job, but from a completely different point of view (or even in an inversed way as is the case with for instance with the Visitor and Parser and the Command and the Observer). To illustrate: even “the best” Pattern can be a wrong choice I find myself undoing certain solutions and choices I made the day before, because the chosen path (and Design Patterns) – that seemed completely reasonable at that time – is actually completely the wrong choice.

Page 182: Re Factoring and Design Patterns

182 Peter Kaptein

WHAT ARE THE MAIN ELEMENTS?

::Tag:INTRDP-MNEL

1: ABSTRACTION, ENCAPSULATION AND EXTRACTION ::Tag:INTRDP-MNEL-ABS

BASIS Design Patterns invite you to apply OOP Principles Design Patterns invite you to Extract, Encapsulate and Abstract the code you are writing and using to get to more flexible and more re-usable code. Extracting to methods One of the first things you will find yourself doing when programming is extracting code to new Methods. With these methods you encapsulate specific actions and make sure whatever happens has a clear entry- and exit point. Using and creating Classes Using and creating (new) Classes is the next step. You might find that it is more logical to put methods and actions into separate containers that can be used on multiple places. Using and creating Base Classes When you continue to build Classes and stat Extending specific (Base) Classes, you will find that some code can be re-used by many sub classes. Using and creating Interfaces and Abstract Classes Interfaces and Abstract Classes are two variations on one theme: a Class that defines Methods (and variables) but do not have Concrete Implementations of these Methods. ::Link:OOP-PRNC-EEA

DESIGN PATTERNS THAT IMPLEMENT THESE CONCEPTS The role of Interfaces, Base Classes and Abstract Classes Each of the Patterns below use objects created with either the same Base Class, Interface or Abstract Class. Bridge and State: using Abstracted and Extracted code to change behavior The Bridge and State Pattern uses Abstraction to allow you to create one single Base Class that can choose between several different Concrete Implementations (Classes) to do the work. The Bridge and State Base Class is very much like an empty shell (an Abstract Implementation), passing all requests to the Concrete Classes it has access to. By choosing another Concrete Class to do the work, the Bridge and State can change its internal behavior according to your needs. Strategy: using Abstracted and Extracted code as Plugins The Strategy Pattern shows you how you can implement a solution to re-use specific code and actions (the Strategy) in a Class and object that only needs specific actions to have a dynamic implementation.

Page 183: Re Factoring and Design Patterns

Refactoring and Design Patterns 183

Due to the way these actions are Extracted, Encapsulated and Abstracted, the Strategy Pattern allows you to treat each Strategy as a Plugin that you can replace for any other variant of that Strategy. Factory Patterns: creating Concrete objects from one of several Classes with the same basis The Factory Patterns rely on the concepts of a shared Basis, either created with an Interface, Base Class or Abstract Class. By decoupling the Interface from the Concrete Actions, you can create many variations on the same theme, each performing the standard set of required in a different way. Visitor and Decorator: extracting and encapsulating actions to perform on objects The Visitor and Decorator Patterns show ways to encapsulate specific actions you can perform on objects, which you can vary for each Visitor or Decorator in the same family (sharing the same Interface, Base Class or Abstract Class). By changing that intern (Abstracted) behavior, you can get completely different results out of a method call when you change the Visitor or Decorator to perform that action on an object.

2: RE-USE AND FLEXIBILITY ::Tag:INTRDP-MNEL-FLX

BASIS The role of Interfaces, Base Classes and Abstract Classes Base Classes, Interfaces and Abstract Classes are essential elements in solutions with flexible implementations. Using different Classes instead of conditional execution The main recurring element in flexible solutions is the use of different Classes for each specific situation that can occur. You see this in the Bridge, State and the Strategy Patterns, for instance, where you simply replace one set of solution for another to get a different behavior and a different outcome on a specific request. Create code with a clear intent In order to be able to re-use code and create flexible solutions you need to create Methods and Classes with very specific and clear intent. Make a plan “Know what you want” might be the most important rule when creating flexible solutions. What do you want to achieve? How do you want to reach these goals? Use Refactoring, extraction, encapsulation and abstraction Most re-usable code in other cases comes to existence via Refactoring. You let it evolve and then give it a proper place.

DESIGN PATTERNS THAT HELP IMPLEMENT THESE CONCEPTS The role of Interfaces, Base Classes and Abstract Classes

Page 184: Re Factoring and Design Patterns

184 Peter Kaptein

Each of the Patterns below use objects created with either the same Base Class, Interface or Abstract Class. What? The same Patterns again? Below you will find many of the same Patterns as in Abstraction.. The main reason is that once you start Extracting, Encapsulating and Abstracting code, you are working towards code that can be re-used and is very flexible. Re-use thanks to clear and well-defined actions and intents The objects and their qualities created from Extracting, Encapsulating and Abstracting the code can be used and re-used on many places as their actions and intent are (should be) clear and well defined. Bridge and State Patterns: focus on flexibility and choice in the execution of concrete actions The Bridge and State Pattern uses Abstraction to allow you to create one single Base Class that can choose between several different Concrete Implementations (Classes) to do the work. By choosing another Concrete Class to do the work, the Bridge and State can change its internal behavior according to your needs. The Strategy, Bridge and State Patterns: flexibility in execution As stated before, State, Bridge and Strategy are Patterns describing ways to create Classes and objects that can choose how they will execute specific actions. All use Extracted and Abstracted actions to do so: embedded in separate Classes for each specific situation. Factory Method and Abstract Factory: blueprints for re-use The Factory Method and Abstract Factory are two excellent examples of how Desing Patterns can proscribe the way you build your solutions to have interchangeable solutions from different Classes. Concrete Implementations of these Patterns can be exchanged for other Concrete Implementations and handle the exact same requests while delivering completely different results. Factory Patterns and Data Maps: providing specific objects for specific contexts Both the Factory Patterns and the Data Map Pattern provide objects that can be selected form two or more different Classes, each implementing the same Interface of (Base) Class. Visitor, Command and Decorator: interchangeable objects, same methods, different results Re-using the same Interface does not have to mean you get the same or similar results. Visitor, Command and Decorator are three examples of Patterns which can produce completely different results form the same Methods call.

3: DELEGATION ::Tag:INTRDP-MNEL-FLX-DEL

BASIS To be written

Page 185: Re Factoring and Design Patterns

Refactoring and Design Patterns 185

DESIGN PATTERNS THAT REVOLVE AROUND THESE CONCEPTS The Delegate Pattern The Delegate delegates actions to an object it either receives or creates internally. The Adapter, Bridge, State and Strategy Pattern The Adapter Pattern shows how you can adapt an existing Class or object. All actions you request on the Adapter are actually passed to that Class and/or object. The Bridge, State and Strategy Patterns do roughly the same, with different intents but the same results: actions you request on an object implementing the Patterns are not executed by that object, but passed to another Concrete Implementor that will do the actual work. The Command Pattern Each Concrete Command envelops a specific set of actions on a specific object or Interface. When executed, these actions are delegated to the object on which you want to perform that specific action. Façade, Mediator, Manager The Façade, Mediator and Manager delegate actions to one or more objectsi n a subsystem, in general to simplify the use of that Subsystem by other parts of your code and to centralize the communication to and by that subsystem. Observer The Observer Pattern does something that can be seen as a double-delegation. Each notification of an event or action is first delegated to the Dispatcher. The Dispatcher then delegates the requested Dispatch to all the objects that have been registered by the Observers on that object and on that Dispatcher.

Page 186: Re Factoring and Design Patterns

186 Peter Kaptein

4: STRUCTURE ::Tag:INTRDP-MNEL-FLX-STRU To be written

Page 187: Re Factoring and Design Patterns

Refactoring and Design Patterns 187

WHERE AND HOW DO THEY FIT IN YOUR PROCESS?

::Tag:INTRDP-FIT

1: LOW LEVEL - CONCRETE BUILDING PROCESS ::Tag:INTRDP-FIT-003 Low level, a consequence The Design Patterns documented by the GoF are Low Level Design Patterns, this means that they show up in your code, but as a consequence of something else. Materials, concrete implementation of design principles When you compare the design of Software with the design of a house, the Design Patterns are the materials you use to make the processes possible that you need inside the house. So where “Providing streaming water” is a Design Principle, “using copper tubes and specific type of faucets” is the equivalent of using Design Patterns. Can change when another solution is needed Where your Design Principle remains stable for all Houses, the Application of Materials can change for each specific situation as each individual Design of a House can be completely different, with different requirements for the Materials used. At the end, not at the beginning This is why Design Patterns come after defining and working out your Design Principles and after your analyzed which Requirements require what kind of practical solutions (your Design Patterns). This is also why they are never a Starting point.

2: SPECIALIZED MACHINES ::Tag:INTRDP-FIT-002 Specialized machines, useful for one thing Each Design Pattern is just one specific way to solve one specific problem. They are like specialized machines. You can use them for one thing and they will help you greatly to solve that problem with short and elegant code. But when you apply that same Design Pattern for a problem it is not created for, you will enter a world of pain. Patterns and solutions might change as your project moves forward You cannot beforehand decide which Design Pattern is best to solve a specific problem. In most cases you will find that as your project progresses, the choice for “Design Pattern A” was not so smart after all. And instead of trying to stick to your original plan, it is better to change to “B” or “C”.

3: IN STATE OF FLUX ::Tag:INTRDP-FIT-004 Code is in a state of flux, be willing to kill your darlings Most code is in a state of Flux: meaning that a lot might and will look different in your project as you progress, due to improvements and refactorings. The more you try to stop this state of Flux, the more your code will start to work against you. This also goes for the Design Patterns and specific solutions you

Page 188: Re Factoring and Design Patterns

188 Peter Kaptein

will implement. Do not fall in love with them. Be willing to kill your darlings when they no longer work for you. Be ready for change Re-stating: In most cases you will find that as your project progresses, the choice for “Design Pattern A” turns out to be not so smart after all. And instead of trying to stick to your original plan, it is better to change to “B” or “C”. Be willing to drop Design Patterns are disposable means that you should be willing and ready to drop “Design Pattern A” for “Design Pattern B” or “C” and ready and willing to repeat that process until you feel that it can not get any better than it is at that point in time.

4: AVOID DEAD END DESIGN ::Tag:INTRDP-FIT-005 “We will use Patterns A, B and C” When you first start with Design Patterns, you might think that using Specific Design Patterns is part of the design process. So when designing software you might strive to apply and implement: “Design Patterns A, B and C”. Dead end design Short and simple: that is dead-end design. Unless you know exactly what you are doing, it will cost you dearly as your real requirements in your Project might be different from the ones you defined in theory.

Page 189: Re Factoring and Design Patterns

Refactoring and Design Patterns 189

WHY ARE DESIGN PATTERNS AWESOME?

::Tag:INTRDP-AWSOME From “Design Patterns”, GoF, “Preface”

Design patterns make it easier to reuse successful designs and architectures. Expressing proven techniques as design patterns makes them more accessible to developers of new systems. Design patterns help you choose design alternatives that make a system reusable and avoid alternatives that compromise reusability. Design patterns can even improve the documentation and maintenance of existing systems by furnishing an explicit specification of class and object interactions and their underlying intent. Put simply, design patterns help a designer get a design "right" faster.

1: OBJECT ORIENTED PROGRAMMING AND DESIGN PATTERNS ::Tag:INTRDP-MNEL-OOP Design Patterns as a more deliberate use of OOP Principles Design Patterns can be seen as a more extensive and deliberate use of OOP principles. Extraction, Encapsulation and Abstraction Many Design Patterns focus on structures that help you Extract, encapsulate and Abstract your code into modules and Classes which are easier to replace and re-use.

2: INVERSION OF CONTROL ::Tag:INTRDP-AWSOME-000 Design Patterns help you implement Inversion of Control When you study Patterns like the Bridge, the Factories, the Delegate and the State Pattern, you will find the basics (Abstraction) that allow for Inversion of Control. I have included some extra information per Pattern related to Inversion of Control, to show you how you can achieve this in existing Patterns like the Abstract Factory, Factory Method, Bridge and Command.

3: RE-USE, CLEAR CODE, LESS CODE, BETTER CODE ::Tag:INTRDP-AWSOME-001 Using clear and repeating patterns of actions When applied properly, Design Patterns offer a clear and repeating pattern of actions. This means that wherever you encounter a specific Design Pattern you will be able to understand more quickly what is going on, how specific actions are handled and where to put your breakpoints when you want to debug the code of your project. Re-use of basic principles When you start applying Refactorings and Design Patterns, you will notice that you will focus more and more on re-use of existing code by centralizing them in Classes than by using Copy & Paste. You will start focusing more and more on Basic Principles of how things are done and you will re-use these principles. Less code, better code

Page 190: Re Factoring and Design Patterns

190 Peter Kaptein

Your numbers of lines of code will decrease while the quality of your code will improve, also making it better to maintain. Less code, more effect If applied properly you will need less code to reach more effect / results. Think of

4: HELP YOU CAPTURE RECURRING PATTERNS IN YOUR CODE ::Tag:INTRDP-AWSOME-002 Design Patterns are any Recurring Pattern in your code As stated before, the Design Patterns I refer to are not necessarily the ones documented by the Gang of Four in “Design Patterns”. They are any recurring pattern in in your code. Turn any Copy & Paste code into a Design Pattern Instead of trying to implement the Design Patterns in this book, I invite and even urge you to discover and develop your own Design Patterns first. Look at what you find in this book, see how you can refactor your code and build up some experience in creating your own libraries of smart solutions.

Page 191: Re Factoring and Design Patterns

Refactoring and Design Patterns 191

HOW DO YOU RECOGNIZE DESIGN PATTERNS IN YOUR OWN

CODE?

::Tag:INTRDP-REC

1: COPY AND PASTE CODE ::Tag:INTRDP-REC-001 The first and most clear pointer is when you use Copy & Paste. As one specific implementation of code works for other parts, you are basically sitting on right on top an emerging Pattern

2: REPETITION OF A SPECIFIC SET OF ACTIONS ::Tag:INTRDP-REC-002 It is possible that some actions are repeated on multiple places in your application. This is the first sign of a pattern or of an emerging pattern

3: REPETITION OF A SPECIFIC SET OF CLASSES ::Tag:INTRDP-REC-003 It is possible that you use the same basic structure on several places. This is another sign of a pattern or an emerging pattern

WHEN AND HOW DO YOU APPLY THEM?

::Tag:INTRDP-APP

1: WHEN YOU BUILD YOUR SOLUTION ::Tag:INTRDP-APP-001 You want to use existing Design Patterns in your code This is only recommendable when you know what you are doing and when you really understand the Design Patterns you use. It is easy to make the wrong decisions and end up with a bigger mess than you started with You know what you are doing You already implemented specific Design Patterns and know of their possibilities and limitations and when to use and avoid them.

2: WHEN YOU REFACTOR ::Tag:INTRDP-APP-002 They emerge In this most common and most recommendable way (I found it the best way to learn) you simply strive to make any emerging Pattern to become something really explicit and documentable You deliberately choose a Desing Pattern and refactor towards it In this case you take existing code and rework it to fit the chosen Design Pattern.

Page 192: Re Factoring and Design Patterns

192 Peter Kaptein

WHAT CAN GO WRONG?

::Tag:INTRDP-WRNG

1: INCOMPLETE UNDERSTANDING ::Tag:INTRDP-WRNG-001 Implementing “Design Patterns” without understanding them Design Patterns are easy to misunderstood. Especially since there is not much documentation online helping you to figure out where to place what.

2: WRONG FOCUS ::Tag:INTRDP-WRNG-002 Designing your application with Design Patterns as a starting point Even though the word “Design” is part of the duo “Design Patterns”, they are – as stated many times before – a result of your work. And which Design Pattern is the best to use in a specific situation might change as your requirements change during your creation process

3: OVERCOMPLICATION ::Tag:INTRDP-WRNG-003 Design Pattern Overkill You might stumble in a project where the lead architect claims they are using specific Design Patterns and specific frameworks forcing you to use specific Design Patterns. But there is one problem: when you look into the existing code you find that even the most simple processes are done in such a way that your main repeating thoughts are: “What the fuck?”. There are two main reasons for this:

1: You are do not have enough experience or knowledge yet You are do not have enough experience or knowledge yet and will have to learn a lot more then you know now 2: They fucked up by making something relatively simple into a mess Another team or person fucked up by making something relatively simple into a mess, pretending to do and understand Design Patterns, but failing on a lot of accounts

Double check your theoretical basis In both cases, the best thing is to double check your basics. It is easy to mistake a different type of implementation than you are used to for a fuckup and easy to assume both that you are right when you are wrong (and they did it right) or that you are wrong (while they fucked up).

Page 193: Re Factoring and Design Patterns

Refactoring and Design Patterns 193

4: HIGH COST OF DEVELOPMENT ::Tag:INTRDP-COST Overcomplicated code As you try and implement “Design Pattern A”, it might be that you actually should have chosen “Design Pattern B and C”. Since your design – however – states you will implent “A”, you need to do a lot of effort working around all limitations of “A” to actually implement a warped up verison of “B” Dead-end solutions It will be like taking the wrong turn and ending up at a dead end. Where the only way forward is to turn back and discard of all the work you have done until then Time lost by hammering round pegs in square holes As you are implementing something that is overcomplicated you will spend a lot of time finding ways around problems created by the wrong choices. This is time wasted as – in most cases – things can be done simpler and with less effort if you stand back and reset your purpose Code that is not maintainable If you applied the wrong Design Patterns for the wrong purpose, the people (including yourself) who will look at that code, will first see a jumbled mess of incomprehensible code. “What happens where, why” is completely unclear

Page 194: Re Factoring and Design Patterns

194 Peter Kaptein

HOW DO YOU IMPROVE YOUR USE AND IMPLEMENTATION

OF DESIGN PATTERNS?

::Tag:INTRDP-IMP To be written

HOW DO YOU KEEP CONTROL?

::Tag:INTRDP-MAST Focus on the practical The practical is this: the problem needs to be solved. Whether it is via something from the book, or something you made up in that place. Keep it simple Instead of becoming a slave of Design Patterns, for instance “because you have to use them” the idea is to work together with them, master them where necessary. If a Design Pattern forces you to jump though burning hoops while riding a unicycle, either the Design Pattern is not the right one, or you simply overstretch your own capabilities. Keep it simple instead of trying to do it “right”. As long as it does its job clear and simple and it reduces the Copy & Paste levels in your Code, you have succeeded for then. Do it now, Refactor later Even if your current implementation is not perfect, when it works, it works. Instead of wasting your time on hypothetical levels of Academic Design Pattern Awesomeness, simply wait until your implementation becomes a problem and Refactor then. Use Design Principles as your guide Design Principles help you create a structure that is completely open to change in any possible way. Instead of creating rigid rules, Design Principles simply identify the most common things you will encounter in your work and give you a language and structure to separate and place them.

Page 195: Re Factoring and Design Patterns

Refactoring and Design Patterns 195

DESIGN PATTERNS AND GAME DEVELOPMENT

::Tag:SUMM-DPGM Game Development is a separate branch of Software Development, usually not covered by the run-of the mill books on Design Patterns. Instead, you will find separate books on Game Development, offering a set of Design Patterns that might be useful for Game Development. I list the most basic Design Patterns useful here:

Page 196: Re Factoring and Design Patterns

196 Peter Kaptein

ANTI-PATTERNS ::Tag:INTRDP-ANTI ::includesubchapters To be written, will contain a summary of anti-patterns as defined in the industry.

Page 197: Re Factoring and Design Patterns

Refactoring and Design Patterns 197

PART 7: MACRO-

PATTERNS AND DESIGN

PRINCIPLES ::Tag:INTRDP-MCRDP

Page 198: Re Factoring and Design Patterns

198 Peter Kaptein

BASICS ::Tag:INTRDP-MCRDP-BAS ::includesubchapters

Page 199: Re Factoring and Design Patterns

Refactoring and Design Patterns 199

MACRO AND MACRO PATTERNS

::Tag:INTRDP-MCRDP-BAS-001 “Macro” stands for: “very large in scale or scope or capability”. Macro Patterns are Patterns which Encapsule or Contain several other Patterns.

DESIGN PRINCIPLES

::Tag:INTRDP-MCRDP-BAS-002 Design Principles are Basic Assumptions that apply for almost all situations. For instance: a House will have Walls, Rooms, Floors, Ceilings, Doors and Windows. A house will also (in most cases) provide Electricity, Heating and Water. Design Principles do not care much about the How. That is something you fill in later, when all basic Conditions and Requirements are defined and put info a General Design: the floor plan and the wiring plan.

DESIGN PRINCIPLES AND MACRO PATTERNS

::Tag:INTRDP-MCRDP-BAS-003 In this book we consider Design Principles and Macro Patterns to be the same- or a similar thing. We will speak mainly of Design Principles to Identify these Patterns.

OVERVIEW OF MACRO-PATTERNS AND DESIGN PRINCIPLES

::Tag:INTRDP-MCRDP-BAS-004 MVC and Extended MVC MVC and Extended MVC are considered to be Design Principles in this book. Where the concrete Implementation of MVC might vary for each and every Project, the Principle of MVC will always be the same wherever it is used (properly). MHOPUDO or Manager, Handler, Operator, Parser, Data-object MHOPUDO is another Design Principle in this book, used to Organize the Code within the Model of the MVC and Extended MVC Pattern. MHOPUDO helps in the process of Separation of Responsibilities: to put Code where it belongs according to the Role that code plays and the Responsibility that code has within the Process and the Project. SRB or Simulations, Rules, Behaviors Simulations, Rules and Behaviors is a Macro-Pattern primarily useful and created for Game Development. They help to distinguish the different parts that make a game (Simulations, Rules and Behaviors) and build a Clear and Clean Model within the Project. Inversion of Control and Dependency Injection Where in most cases we instantiate everything we need from within our objects, Inversion of Control (or IoC) turns this around and let us Inject the objects we are depending on (Dependency Injection). This Design Principle allows us to create solutions which become completely independent from the Concrete Execution of Processes. There are three ways for Dependency Injection at this moment and I will treat all three briefly. I will also show how this principle can be applied on Factories and Strategy Providers, making your Applications even more versatile.

Page 200: Re Factoring and Design Patterns

200 Peter Kaptein

Reflection and Data Mapping Reflection and Data Mapping are two Design Principles used together to bind Data via Definitions. This means that we no longer hard-code which value goes from what Source into what Destination object and Value, but we can use either Definitions (the Data Maps) or automatic mapping when the Destination and Source objects share the same Variable Names. The great benefit of this approach is that the amount of code needed to Bind Data is reduced dramatically. Declarative Programming Declarative Programming is a Design Principle in which the Code is no longer leading, but supporting. Instead of Coding our entire Application, we create a new- or use an existing Framework in which all our Base Functionalities and Base Components are pre-defined. Using a set of Declarative Structures in, for instance, XML, we can compose and build entire applications without the need of coding. This works best for applications where the functionalities and requirements are repetitive

Page 201: Re Factoring and Design Patterns

Refactoring and Design Patterns 201

MODEL, VIEW, CONTROLLER ::Tag: MVC

Page 202: Re Factoring and Design Patterns

202 Peter Kaptein

A SUMMARY OF THE CONTENT IN THIS CHAPTER AND THE

NEXT CHAPTERS

::Tag: MVC-SUMM The MVC Pattern To understand the MVC Pattern, it is good to go back to the roots first. While I will give a more detailed overview of the base rules in MVC in “Model, View, Hub, Interface” I give you the basics here. ::Link: MVC-PATT Implementing MVC: variations on a theme In Implementing MVC I will take three variations on implementing MVC and make links to where you can find these Implementations, either in certain environments, or in more recent variations on the MVC Pattern like: Model, View, ViewModel; Model, View, Presenter and: Model, View, Adapter. ::Link: MVC-PATT-VAR Model, View, Hub, Interface: a deconstruction of MVC As stated before, it is very hard to find documentation on the exact roles of elements in the MVC Pattern. What exactly are the limitations and the Scope of the Code in the Controller and the View when they interact with the Model? What happens if you expose the hidden parts of the View and the Controller? How far does the responsibility of these parts in the View and the Controller stretch? And what happens if you Refactor MVC and shift these responsibilities around? I will give a more elaborate definition of MVC, using the original SmallTalk-80 implementation as a basis. ::Link: MVC-PATT-MVHI MVC and 3-Tier development MVC leaves a lot of questions and open ends if you want to implement a 3-Tier approach. Using the analysis and models presented in the previous paragraphs on MVC I go deeper into MVC and 3-Tier Application Design, adding Services and using the MVVM Pattern as one of the starting points. ::Link: MVC-3TIER Use and abuse of MVC If you look at the different uses of MVC in different parts of the application, are we doing the right thing, or are we abusing something for something it was not intended for originally? This part reflects my personal opinions and is more a critical review than an analysis.

Page 203: Re Factoring and Design Patterns

Refactoring and Design Patterns 203

THE MVC PATTERN

::Tag: MVC-PATT

DIAGRAMS ::Tag: MVC-PATT-001

BASIC MVC DIAGRAM OF THE ACTIVE MVC PATTERN

MVC«SmallTalk»

Model

View Controller

3: «retrieves data from»2.a: «sends data to»

2.b: «notifies»

Actor

1.b: «triggers»

1.a: «uses»

Dependencies: Actor: 1.a: Uses the View 1.b: Triggers the Controller Controller: 2.a: Sends data to the Model 2.b: Notifies the View that a change has taken place in the Model View: 3: Retrieves data from the Model

Page 204: Re Factoring and Design Patterns

204 Peter Kaptein

Brief: The main problem of the MVC Pattern: what happens where? The main problem with the MVC Pattern is that it can be very unclear who does what how. Will the View pull in Data from the Model, therefore having knowledge of (part of) the Model itself? Is the View simply a Slave, updated by the Model: which consequently will have knowledge of the View? Or do we use the Controller as the Central Hub: having knowledge of both the View and the Model and thus updating both View and Model when something occurs? Original SmallTalk definition The original SmallTalk definitions offers two possible approaches. Passive In the Passive MVC definition Active In the Active MVC Definition, as displayed above, the Controller updates the Model, the Controller notifies the View and the View pulls in data from the Model. The Controller itself has some information of how the Application should work, and thus plays an active part in What Goes Where in the Model. “Using the view” The User uses the View in two ways: Looking at the presented results The View presents data from the Model in a way that appeases the User. It usually is placed into a design and structured in such a way that the User can easily understand what the options are and how to interact with the View when such options are given. Interacting with the View The interaction with the View is taking place by either “clicking” on elements (using the Mouse, a Touch Panel or Touch screen) or providing specific input by typing on a (virtual) keyboard or using elements like a Barcode Scanner.

Page 205: Re Factoring and Design Patterns

Refactoring and Design Patterns 205

BASICS ::Tag: MVC-PATT-BAS Back to the roots of MVC There are many different opinions on how MVC should and could be implemented. Each of them add their own value and neither of them is the ultimate solution. To understand the basics of MVC I went back to one of the original definitions by David Burbeck: “Appication Programming in SmallTalk-80: How to use Model View Controller” and I used a definition by Dean Helman from the “Objective Toolkit Pro whitepaper”. Both can be found online. Google for: “MVC Dean Helman” and: “David Burbeck Model Viww Controller”. Both papers give a better and less distorted view on the roots of MVC and help distinguish and understand the different variations like MVVM, MVP, MVCS and MVA. Relevance of MVC The MVC pattern is the most commonly used Pattern in Software Development to date. Apart from the implementation via Coding, there are probably over one hundred different Frameworks claiming to implement MVC, with over five to ten available per Programming Languages. MVC: Model, View, Controller MVC stands for “Model”, “View” and “Controller”.

MVC: THE BASICS ::Tag: MVC-PATT-BAS-001 Base definition of MVC according to Dean Helman According to the definition of Dean Helman in the: “Objective Toolkit Pro whitepaper” , the MVC pattern originates from this flow:

[User] Input –> Processing –> Output Controller –> Model –> View

The Model As you will read in the quotes and the next parts, the Model is more than storing and providing data alone. We assume in this book that the Model also contains all your application logic, including classes to process data and execute business logic.

Dean Helman, Objective Toolkit Pro whitepaper […] a model encapsulates more than just data and functions that operate on it. A model is meant to serve as a computational approximation or abstraction of some real world process or system. It captures not only the state of a process or system, but how the system works.

The View The View is the visible part of your Application. It includes your screens, windows, scrollbars and input elements like buttons, text fields, radio buttons and checkboxes. Within the original MVC Pattern, the View plays an active role in the MVC triangle and is allowed to contact the Model and retrieve the Data it needs.

David Burbeck, Application Programming in SmallTalk-80: The Passive Model

Page 206: Re Factoring and Design Patterns

206 Peter Kaptein

[…]It [the controller] could simply notify the view that something has changed -- the view could then request the current state of the string from its model

David Burbeck, Application Programming in SmallTalk-80: The View - Controller Link […] A view's instance variable controller points at its controller, and a controller's instance variable view points at its associated view. And, because both must communicate with their model, each has an instance variable model which points to the model object.

The Controller: handling User Input The Controllers first responsibility according to the original definition is to recognize and handle User Input from the keyboard and mouse. The SmallTalk definition explicitly states that each View has its own Controller to allow for a correct handling of whatever comes in from keyboard and mouse. The Controller then decides how to handle the input and what part of the Model it should update. From the original definition it is unclear what the exact scope of the Controller is: does it limit itself to port the specific input to a specific variable in the Model (updating a String value connected to a Text Field with Focus when the user types text? Updating the X and Y values of a Scrollbar when the user clicks on it and moves the mouse up and down?).

THE OPEN AND UNRESOLVED ENDS OF MVC ::Tag: MVC-PATT-BAS-002 Business logic or: who makes the decisions? The main question with the MVC pattern is: “who makes the decisions?”. In most modern interpretations, the Controller is the active part, taking care of management of that part of the Application as a matter of speaking. External data or: who provides? In most cases we simply assume the Model provides. But how? And where? Why is this not made explicit in MVC to promote a separation of Responsibilities there as well, as has happened for the Model and the View? MVC and 3-Tier I have tried to translate MVC to 3-Tier in the past and without adding elements and splitting other elements, MVC is simply to non-specific. The Model is assumed to do a lot of things, but when you try to find concrete examples, nobody seems to give a clear answer.

DECONSTRUCTING THE MVC PATTERN ::Tag: MVC-PATT-BAS-003 It is hard to find good documentation about the original scoping of the Controller. So what I done as an alternative is a deconstruction of the MVC Pattern, using a set of basic questions, including: “what is the scope of the role and responsibility of the Controller and the View when both access the Model?” “where do we get our external data from?” and “who makes the decisions, where?”.

Page 207: Re Factoring and Design Patterns

Refactoring and Design Patterns 207

DIFFERENT PERSPECTIVES ON THE MVC PATTERN

::Tag: MVC-PATT-VAR

MODEL AS HUB ::Tag: MVC-PATT-HUB

DIAGRAM OF MODEL AS A HUB ::Tag: MVC-PATT-HUB-DIA

MVC«model as hub»

Model

View Controller

1: «pushes data to / retrieves data from» 3: «notifies»

2: «notifies»

Dependencies:

1. Model – Pushes data to the View, retrieves data from View 2. View – Notifies Controller 3. Controller – Notifies Model

Model as a Hub in action: MVVM We see this same principle in MVVM. MVVM MVVM stands for Model, View, ViewModel, where the ViewModel is the Hub between the Model and the View. View Model, Application Model The ViewModel is a Model on its own, separate from the Application Model and in most cases specialized for- and tightly bound to that one View.

Page 208: Re Factoring and Design Patterns

208 Peter Kaptein

MODEL AS A HUB: AN EXAMPLE OF THE MVVM PATTERN ::Tag: MVC-PATT-HUB-001

MVVM«model as hub»

ViewModel

View Controller

1.a: «pushes data to / retrieves data from» 3: «notifies»

2: «notifies»

(Application) Model

1.b: «pushes data to / retrieves data from»

Clarity: each View its own Model MVVM helps you to extract the Model that is related to the View and give it a clear place in your overall project. Better Distribution of Responsibilities: all View-specific Actions collected You can use the ViewModel to collect and bundle all View-specific Actions, including the transformation of Data for that View and specific actions that need to take place in specific situations. In this book we split the ViewModel into more parts, using the ViewModel object as our Hub to View and Application specific data. What happens with the Controller in MVVM? Within most MVVM implementations, the Controller is taken out of the picture. The ViewModel simply registers Observers to the View, receives Events from the View when the User performs an Action and performs the required Actions as a result. All “Controller Logic” we would normally place in the Controller, has moved to the ViewModel. MVVM and Controller as a Hub The MVVM Pattern is also associated to the Controller, or a Smart Controller, so it will also be treated in “Controller as a Hub”

From Wikipedia, Model View ViewModel: The ViewModel […] It could be seen as a specialized aspect of what would be a Controller (in the MVC pattern) that acts as a data binder/converter that changes Model information into View information and passes commands from the View into the Model.

Page 209: Re Factoring and Design Patterns

Refactoring and Design Patterns 209

CONTROLLER AS HUB ::Tag: MVC-PATT-CHUB

DIAGRAM OF CONTROLLER AS A HUB ::Tag: MVC-PATT-CHUB-001

MVC«controller as

hub»

Model

Controller

1.a: «gets data from / pushes data to»

2: «notifies»

1.b: «pushes data to / gets

data from»

View

Dependencies: Controller: 1.a: Gets data from and pushes data to the Model 1.b: Pushes data to and gets data from the View View: 2: Notifies the Controller when a User Action occurred

Controller as a Hub in action: MVP, MVVM, MVA MVP: Model, View, Presenter MVP stands for Model, View, Presenter, where the Presenter takes the same place as the ViewModel, but with a different role: that as a pass-through station for data between Model and View. View as a passive Black Box Maybe the most important element of MVP is the “black boxing” of the View. MVP assumes that by making any and all Views into a Black Box with a generic and shared Interface, you can connect any type of View to the Presenter, making your Application easy to port to any Presentation Form. Like MVVM the Presenter pushes and pulls the Data to and from the View. The View itself is passive and has no knowledge of either Model or Presenter. Presenter holds no data The Presenter in the MVP Pattern holds no data of its own and responds to Events fired from the Model and from the View. In this it resembles the Controller.

Page 210: Re Factoring and Design Patterns

210 Peter Kaptein

MVVM: Model, View, ViewModel MVVM stands for Model, View, ViewModel. The MVVM pattern is described in more detail elsewhere. It is my favorite as it takes the View as a separate entity with its own Model. View as an active and independent entitity MVVM takes the View and isolates all activities and data into the ViewModel. Like the MVP Pattern, the View within the MVVM Pattern can be Abstracted into a Passive Black Box, where the ViewModel connects to the View using Methods exposed via an Interface. ViewModel holds data and State The ViewModel holds data and State related to the View.

AN EXAMPLE OF MVP AND MVVM ::Tag: MVC-PATT-CHUB-00

MVP«presenter as

hub»Presenter

View

1: «passes data to / receives data from»

Model

2: «pushes data to / retrieves data from» MVVM

«viewmodel as hub»

ViewModel

View

1: «passes data to / receives data from»

Model

2: «pushes data to / retrieves data from»

Differences between ViewModel and Presenter What makes the ViewModel different form the Presenter is that the ViewModel holds the State and manages the Processes related to the View. The Presenter is more a Manager and Pass Through Station for the data to- and from the Model. Who parses the data? Even though the theory is nice behind both MVVM and MVP, there still is the question to who massages and Parsers the Data from the Model to the View. As your View changes (View A is replaced by View B), the required Format and Structure might change as well. For instance, a List View might not accept the generic Data Structure you provide in a Collection and has to parse it to an Array first.

The same goes for User Input via the View. A HTML page offers these events and the resulting data in different ways than a Rich Client or a Desktop Application

Page 211: Re Factoring and Design Patterns

Refactoring and Design Patterns 211

Your View might still hold code It is possible that your View will hold some Code after all, to parse the Raw Data as offered and already Massaged by the Presenter or ViewModel into something even more friendly for local use.

A VISUALIZATION OF THE “VIEW AS BLACK BOX” PRINCIPLE ::Tag: MVC-PATT-CHUB-003

View APresenter / ViewModel

View B

Model

«interface methods»

«can also connect to»

Shared Interface View A and View B share the same Interface. This Interface consists of Methods (visualized as lines with a round, triangular and square connector) the Presenter can use to get data from the View (user Input) and set data on the View (from the Model). Interchangeable Views For the Presenter and/or the ViewModel, View A and View B are the same and completely interchangeable as both expose the same Methods and both share the same Interface or Base Class. View A can be an HTML page with “Code Behind” as implemented in, for instance, the Microsoft Visual Studio environment, while View B can be a Form in a Desktop Application. Presenter / ViewModel as Extended Controller In this model, the Presenter and ViewModel are like an extended Controller, taking full responsibility of all connections and communication to- and from the Model and Populating the View with the results. View communicates to Presenter / ViewModel via Events The View can communicate to the Presenter and ViewModel by dispatching Events. For a Web-based application, this “event” can be a GET or POST from the HTML form, or a call to a URL.

Page 212: Re Factoring and Design Patterns

212 Peter Kaptein

WHO MASSAGES THE DATA? ADDING THE “CODE BEHIND” INTERPRETER CLASS TO THE VIEW ::Tag: MVC-PATT-CHUB-004 As discussed before, the View might still hold View Specific code, to Massage the “Raw Data” as offered by the Presenter or ViewModel into something specific for that View.

Interpreter A

Interpreter B

View A

View B

«view»

“Code Behind” Within the Microsoft Visual Studio Platform you will find a concept called “Code Behind”. It is mostly used when building web pages. The “Code Behind” in that case is a Compiled Class made specifically for- and referred to by that Page (or View) to deal with the events and data specifically for that View or HTML page.

Interpreter The “Interpreter” here is not the Interpreter Pattern, but a “translator” or “mediator” or “bridge” between the View and the ViewModel / Presenter.

Roles and responsibilities of the Interpreter The Interpreter in this Diagram takes care of the following things: Translating Data from the Model Translating (Parsing) Data offered from the outside into a format specifically suited for the View. Translating Events from the View Trnaslating Events from the View into the format that the Presenter or ViewModel expects Translating Data from the View Translating Data as inserted or selected from the View to something that is expected by the Presenter or ViewModel.

Page 213: Re Factoring and Design Patterns

Refactoring and Design Patterns 213

VIEW AS HUB ::Tag: MVC-PATT-VHUB

VIEW AS A HUB ::Tag: MVC-PATT-VHUB-001

MVC«model as hub»

Model

View Controller

1.a: «retrieves data from»

3: «notifies / pushes data to»

1.b: «notifies / pushes data

to»

Dependencies:

1. View a. Retrieves Data from the Model b. Notifies and pushes Data to the Controller

2. Controller – Notifies and pushes Data to the Model

Notes: Too many responsibilities The View as Hub is what happens when the View gains too much Responsibilities. Collecting and sending data to the Controller Using the events and notifications to the Controller, it can collect and send the Data it holds to the Controller, where it is processed and passed through to the Model.

Examples of View as a Hub in action: You will find the implementation of “View as Hub” for instance in 4th generation visual programming environments like Microsoft Access, where the “Code Behind” of the View or Form is tightly associated and identified to the View and holds a lot of responsibility related to the View, the Model, and understanding relationships between other Views and View Components (like Sub-forms).

Page 214: Re Factoring and Design Patterns

214 Peter Kaptein

HTML ::Tag: MVC-PATT-VHUB-002

MVC«model as hub»

Model

View Controller

1: «generates / pushes data into» 3: «sends data to»

2: «notifies»

Dependencies: Model: 1: “Generates” the View and pushes Data into the View View: 2: Notifies the Controller Controller: 3: Sends data to the Model

Page 215: Re Factoring and Design Patterns

Refactoring and Design Patterns 215

MCV AND 3-TIER DEVELOPMENT

::Tag: MVC-3TIER

BASICS ::Tag: MVC-3TIER-BAS

Presentation Layer

Business Layer

Data Layer

«communicates with»

«communicates with»

(Graphical) User InterfacesReports

Business rulesData managementData manipulation

Data storage and Data retrieval(Dumb) Data Objects

«contains»

«contains»

«contains»

Three layers / Tiers in your application 3-Tier assumes there are three layers or Tiers in your application: Tier 1: The Presentation Layer The Presenation layer takes care of the presentation of your data. It displays data, allows the user to interact with your application through buttons, links and other elements. Tier 2: The Business Layer The Business Layer takes care of dealing with your data, applying all kinds of business rules and constraints, parsing it from one structure to another and offering the results to either your Presentation Layer or Data Layer. Tier 3: The Data Layer The Data Layer contains the actual Data and takes care of loading, parsing and storing that data, either from local or remote sources. Clear separation of responsibilities Within 3-Tier, the responsibilities are clearly divided. The Presentation Layer does not touch anything in the Business Layer or Data Layer and the other ways around. In the next chapters we will take a very close look to MVC and 3-Tier, to try and solve the last set of questions MVC leaves unanswered.

Page 216: Re Factoring and Design Patterns

216 Peter Kaptein

WHY IS 3-TIER RELEVANT FOR MVC? ::Tag: MVC-3TIER-WHY

Model

View Controller

«retrieves data from»«sends updates to»

«notifies»

The image above shows you a standard MVC Pattern. In this case in which the Controller notifies the View (the Passive MVC, see the beginning of this chapter on MVC for more info). In another official version, the View can also be notified by the Controller. Solves basic questions 3-Tier helps solving the following questions: Where do I get my External Data? When you look at the MVC Pattern, there is no clear indication where I get my External Data. I can assume that is done via the Model, but that is quite vague compared to the 3-Tier Application Model. Getting your Data becomes like a magical process: “from somewhere”. What fits where? As discussed earlier in this book, the MVC Pattern lacks a clear Distribution of Responsibilities. According to the rather un-specific definition of the Controller, the Controller can deal with just User Input, but is also allowed to handle Business Processes, which is part of the Business Layer. And what fdo you do with that? Split one Controller into two: “Presentation Controller” and “Business Controller”? My instincts tell me no: to avoid that direction against all odds. It is not part of any official description and thus does not exist. MVVC, MVCS, MVP Doing deeper research (summarized in this chapter and in the “Refactoring” section) I found that MVC had different implementations, including things like: MVVM (“Model, View, ViewModel) and MVCS (“Model, View, Controller, Services”) MVVC, MVCS, MVP: attempts to fill gaps and holes Each tried to cover the lack of something in MVC by adding something else. Bringing all variations together resembles 3-Tier In the end, bringing all of them together brought a Pattern resembling 3-Tier. We see that in the next chapters. Adding two more Patterns to complete the picture

Page 217: Re Factoring and Design Patterns

Refactoring and Design Patterns 217

Later additions in the form of MHOPUDO (Manager, Handler, Operator, Data-object) and SARB (Simulation, Actor, Rule, Behavior) helped improving the working model for the Separation of Responsibilities. You will see each and all come back in the next pages of this chapter.

MVVM: MODEL, VIEW, VIEWMODEL - BUT WHERE ARE MY SERVICES? ::Tag: MVC-3TIER-MVVM

Model

View

ViewModel

1.c: «processes and validates data / applies business rules»

1.a: «updates / retrieves data from»

1.b: «updates / retrieves data from»

In the model above you see the base MVVM implementation. The ViewModel updates both Model and View and is capable of retrieving data from both as well. It acts as the Hub that binds the Model and the View and that takes care of all actions required to make it work. 3-Tier In the 3-Tier Design Principle we have a Presentation Layer, a Business Layer and a Data Layer. With MVVM the Presentation Layer is reprtesented by the View and the ViewModel. The Business Layer is represented by the Model and used by the ViewModel. As the Model also contains raw Data,The Data Layer is also partially covered. Where do we get our data from? What is missing is the source of our Data. We can assume that the Model will take care of the Data Retrieval, but that is a trap. Anything implicit can be implemented wrongly. Adding the Services Below you see a compressed image with the Services added. We now at least cover all parts: Getting the Data (Service-part of the Data Layer), Storing the Data (Data Layer), Working with the Data (Business Layer) and Presenting the Data (Presentation Layer)

Page 218: Re Factoring and Design Patterns

218 Peter Kaptein

View Model Services

«gets / sets external data»

«uses» «uses» «uses»

Part of Presentation Layer

Part of Business Layer Part of Data Layer

ViewModel

MVCS: MODEL, VIEW, CONTROLLER, SERVICES – BUT HOW DO I SCOPE MY MODEL? ::Tag: MVC-3TIER-MVCS

Model

View Controller

«retrieves data from»«sends updates to»

«notifies»

Services«uses»

«gets / sets external data»

In the model above you see one of the interpretations of the MVCS model, leaving the decisions to get data from an external source up to the Model (some interpretations of MVC state the Controller could do this). The Model uses the Services to get Data from any Source the Service grants access to. 3-Tier What lacks in this model is the clear separation of Data, Presentation Logic and Business Logic. Who does what where if there are only 3 objects (the Model, the View and the Controller). Apparently the Model overlaps both Business Layer and the Data Layer. But what about the Controller? Does it belong in the Presentation Layer? Or is it also part of the Business Layer? Where do we get our data from? The Services The Services solve an important problem with the basic MVC Pattern: there is no clear player defined to get the Data. MVCS solves this with the Service. The Service is any Code taking care of connecting to any external Data Source. This can be a Database, a File system or a Remote Data Source. In principle we can make any Service interchangeable with any other Service, allowing you to get the same data from Local sources, Remote sources, File Systems, Databases and Webservices. In the end, Data is Data and it does not matter where it comes from, where it is stored or how it is formatted. Adding a View Model to scope and separate the Presentation Layer and Business Layer

Page 219: Re Factoring and Design Patterns

Refactoring and Design Patterns 219

Part of Presentation Layer

Part of Business Layer Part of Data Layer

View Model

View Controller

«retrieves data from»«sends updates to»

«notifies»

Services«uses»

«gets / sets external data»

Application Model«uses»

Our main problem is that the Model and the Controller are floating around in the 3-Tier model. They can be part of one, two and even all three Tiers, depending on your implementation. For instance: when your Controller also makes Business Decisions (something is or is not allowed to happen according to Business Rules) it is part of both Presentation Layer and Business Layer. When you Model contains information that is specific to a View or a set of Views (for instance: data that is formatted from a raw format to be presented in the View), your Model overlaps the Presentation Layer, while already living in the Business Layer (Handling data, doing validations and making decisions) and the Data Layer (storing raw Data). Better Separation of Responsibilities Adding the View Model, we isolate all parts that are specifically made to Present things from the parts that do the Business Logic and that store Data. We also limit the scope of the Controller, which now clearly only interferes with the Presentation Layer, leaving decision making and Data Access via Services to the Application Model.

Page 220: Re Factoring and Design Patterns

220 Peter Kaptein

CONCLUSIONS ::Tag: MVC-3TIER-CONC Clearer model By cutting the MVC Pattern into smaller pieces and adding the Services, we get a much more clear model to work with. Presentation layer: View Model, View, Controller By giving each View its own Model (the View Model) we can keep state on that View within a separated universe that does not affect anything else. Also, the View Model can take care of accessing the Application Model in which the more generic Business Logic is located. The View and the Controller both have been given a more limited scope, that stays within the Presentation Layer. The role of the Controller is limited to its original intent: to handle operations related to that specific View or View Component. It has no further access to the Application Model. That is now the responsibilities of the View Model. Not using Controllers in your Model, but using something like a Manager instead When you are used to use Controllers as kind of “God” components, or Managers, this approach and limitations might seem like a shock. Have you been doing wrong until now? The main problem with MVC is that it has gone all places. I advocate not to use Controllers in your Model and not to use Controllers as Managers: overlooking processes. It is not in their original intent (to take user input and update the state of the Model) and it creates a very fuzzy scope and too many responsibilities for one type of Class. MHOPUDO: releasing the Controller as a Jack of all Trades When I was working on the implementation of MVC I dropped the concept of the Controller as a Manager for and within the Model as it gave me both a bad feeling and too much headaches due to unclear scoping of what the Controller was actually intended to do. Instead I started using the metaphor of an organization and got rid of all ambiguities. See the chapter on MHOPUDO (“Manager, Handler, Operator, Parser, Utility, Data”) from page 244 onwards for more info on that topic.

SEE ALSO ::Tag: MVC-3TIER-SEE Model, View, Hub, Interface: Deconstructing the MVC Pattern To understand the quirks of the MVC Pattern I started a deconstruction of the MVC Pattern. This shows the different parts and the alternative approach you could take to the MVC Pattern. ::Link: MVC-PATT-MVHI The extended MVC Pattern: separating responsibilities The Extended MVC Pattern attempts to solve the main issue of the basic MVC Pattern: where do I put what? ::Link:MHOPUDO-DIA-002 Variations on a theme The basic MVC Pattern can be implemented in three different ways, giving each part a more central role. ::Link: MVC-PATT-VAR

Page 221: Re Factoring and Design Patterns

Refactoring and Design Patterns 221

MODEL, VIEW, HUB, INTERFACE: A DECONSTRUCTION OF

MVC

::Tag: MVC-PATT-MVHI

STARTING POINTS ::Tag: MVC-PATT-MVHI-001 SmallTalk80 MVC implementation We use the MVC implementation as described in: “Applications Programming in Smalltalk-80(TM): How to use Model-View-Controller (MVC)” by Steve Burbeck as a starting point. I will translate this base definition into statements and then quote the parts from: “Application programming” which are the source for each statement. To limit my freedom I will try and stay as close as possible to the SmallTalk80 implementation of MVC. Summary of statements In this breakdown I isolated eleven major statements on MVC, how the different parts work together and what their responsibilities are. Refactoring the MVC Pattern I then start refactoring the MVC Pattern, using simple Diagrams as example. I deliberately do not use code for several reasons: space, readability and relevance. Each step already takes at least one page and code tends to obscure the clarity of the example. Instead you will find “Dependencies” and “Notes”, to cover the main aspects of each next step.

Page 222: Re Factoring and Design Patterns

222 Peter Kaptein

THE SMALLTALK80 PASSIVE MVC IMPLEMENTATION ::Tag: MVC-PATT-MVHI-E001

MVC«SmallTalk»

Model

View Controller

3: «retrieves data from»2.a: «sends data to»

2.b: «notifies»

Actor

1.b: «triggers»

1.a: «uses»

DEPENDENCIES: Actor: 1.a: Triggers the Controller 1.b: Uses the View Controller: 2.a: Sends data to the Model 2.b: Notifies the View (in the Passive Model) View: 3: Retrieves the Data from the Model

NOTES: Passive versus Active MVC implementation In the Passive implementation of MVC, the Controller notifies the View that changes have accurred on the model. These changes are the changes made by the Controller. When the Model is updated by other Actors somewhere else, this model will fail. Instead we start Observing the Model directly from the View and any update on the Model related to what the View Observes, will trigger the View to get new data from the Model.

Page 223: Re Factoring and Design Patterns

Refactoring and Design Patterns 223

SMALLTALK80 MVC STATEMENTS ::Tag: MVC-PATT-MVHI-002

A SUMMARY ::Tag: MVC-PATT-MVHI-002a

1. View and Controller are tightly coupled 2. View has direct knowledge of Model and Controller 3. Controller has direct knowledge of Model and View 4. View requests data directly from Model 5. Model has no knowledge of Controller or View 6. View registers itself to Model 7. View can Observe the Model: using a “link” from Model to View 8. Controller is part of a separate Pattern 9. Controller is not created, but resolved by the View 10. View Registers itself to Controller 11. Controller interprets User Input

MVC STATEMENTS IN DEPTH ::Tag: MVC-PATT-MVHI-003 View and Controller are tightly Coupled Each View has its own Controller.

[...]The View - Controller Link […]Unlike the model, which may be loosely connected to multiple MVC triads, Each view is associated with a unique controller and vice versa. Instance variables in each maintain this tight coupling.

View has knowledge of Model and Controller Within the SmallTalk80 approach, the View has knowledge of the Model and the Controller

[...]The View - Controller Link […] A view's instance variable controller points at its controller, and a controller's instance variable view points at its associated view. And, because both must communicate with their model, each has an instance variable model which points to the model object.

Controller has direct knowledge of View and Model The Controller knows which View it is related to and what parts of the Model it should use.

[…] Basic concepts The controller interprets the mouse and keyboard inputs from the user, commanding the model and/or the view to change as appropriate.

View requests data directly from the Model In the smallTalk80 implementation, the View is allowed to request data directly from the View.

[…]The Passive Model

Page 224: Re Factoring and Design Patterns

224 Peter Kaptein

[…]It [the controller] could simply notify the view that something has changed -- the view could then request the current state of the string from its model

Model has no direct knowledge of Controller or View The Model has no knowledge of Controller or View

[…] The Passive Model […] The model is totally "unaware" of the existence of either the view or the controller and of its participation in an MVC triad. That isolation is not an artifact of the simplicity of the model, but of the fact that the model changes only at the behest of one of the other members of the triad. […]

View registers itself to Model The View registers itself to the Model, as we can read from the quote in the next statement.

[…]The Model's Link to the Triad […] When a new view is given its model, it registers itself as a dependent of that model

The Model can receive knowledge of Views, using a “link” from Model to View In current implementations we simply register an Event listener or Observer to the (part of the) Model: ending up in a Observer list that can be traversed when a specific event occurs. In SmallTalk80 there is no talk about Observers, but the principle is exactly that.

[…] The Model's Link to the Triad […] Because only the model can track all changes to its state, the model must have some communication link to the view. To fill this need, a global mechanism in Object is provided to keep track of dependencies such as those between a model and its view. This mechanism uses an IdentityDictionary called DependentFields (a class variable of Object) which simply records all existing dependencies. The keys in this dictionary are all the objects that have registered dependencies; the value associated with each key is a list of the objects which depend upon the key. […]

Controller is part of a separate Pattern In SmallTalk80he Controller is part of a separate Pattern: which I refer to as the Controller Tree. This Tree contains all Controllers in the Hierarchy of which they appear in the Application, usually contrived of Windows and View Components in those Windows. In this tree, for every User Action, the Tree is traversed until the Controller is found that has Focus.

[…]Communication Between Controllers […] that the active controllers for each project form a hierarchical tree. At the root of this tree is the global variable ScheduledControllers, which is a ControlManager attached to the active project. Branching from ScheduledControllers are the topLevel controllers of each active window, plus an additional controller which manages the main system yellowButtonMenu available on the grey screen background. Since each view is associated with a unique controller, the view/subView tree induces a parallel controller tree within each topView. Further branches from each topLevel controller follow this induced tree. Control passes from controller to controller along the branches of this tree.

Page 225: Re Factoring and Design Patterns

Refactoring and Design Patterns 225

[…]. The top level ControlManager asks each of the controllers of the active topViews if it wants control. Only the one whose view contains the cursor responds affirmatively and is given control. It, in turn, queries the controllers of its subViews. Again the one that contains the cursor accepts control. This process finds the innermost nested view containing the cursor and, in general, that view's controller retains control as long as the cursor remains in its view.

Controller is not created, but resolved by the View In this Pattern, the View requests the Controller to the Controller Manager. The controller is already instantiated. The View then binds that Controller to a Variable for later use.

[…] The View - Controller Link […] When the View receives the message model:controller:, it registers itself as a dependent of the model, sets its controller instance variable to point to the controller, and sends the message view: self to the controller so that the controller can set its view instance variable.

View registers itself to the Controller From the quote in the previous statement we see that the View: “sends the message view: self to the controller so that the controller can set its view instance variable” Controller interprets User Input The Controller is mainly used as a bridge between the User and the active View: to allow the user to input and manipulate that view.

[…] Basic concepts […] The controller interprets the mouse and keyboard inputs from the user, commanding the model and/or the view to change as appropriate.

Page 226: Re Factoring and Design Patterns

226 Peter Kaptein

STEP 1: IDENTIFICATION OF SUBCOMPONENTS ::Tag: MVC-PATT-MVHI-E002

MVC«split up»

Model

4.a: «retrieves data from» 3.a: «sends data to»

3.b: «notifies»

Actor

1.a: «percieves/uses»

View Presenter

4.b: «offers result to»

«view»

Interface

2: «triggers»

Controller LogicView Logic

1.b: «uses/triggers»

«controller»

DEPENDENCIES: Actor: 1.a: Perceives and uses the View as presented in the View Presenter (or Viewport) to take actions 1.b: Uses, triggers, sends input to the Interface within the Controller Interface: 2: Triggers and sends input to the Controller Logic Controller Logic: 3.a: Sends Data to the Model 3.b: Notifies the View Logic View Logic: 4.a: Retrieves Data from the Model 4.b: Offers the result to the View Renderer

Page 227: Re Factoring and Design Patterns

Refactoring and Design Patterns 227

NOTES: Controller and View more explicitly defined The Logic within the Controller and the View are hidden elements in the MVC Pattern. We start by making them more explicit. View: View Logic and View Renderer When you read the SmallTalk80 defintion for the View, the View consists of two parts: one to access the Model and get Data to be presented and the other to Present the data. I split this in two parts: the View Renderer, which does nothing more than Render the View; and the View Logic, which takes care of tasks like accessing the Model and Parsing the Data to something that can be used by the View Renderer. Controller: Controller Logic and Interface The Controller consists in this model of two parts: the Control Logic and the Interface. In this step we abstract the SmallTalk80 definition in which the Controller (via the Controller Pattern) is responsible for two tasks: Registering User Input (the Interface) and dealing with that User Input (the Controller Logic). Benefit of splitting the Controller and the View: better overview of Responsibilities What happens by splitting both the Controller and the View into two sub-components is that we are now able to see more clearly what the different steps and responsibilities in the process are. We can also start refactoring the Model, View, Controller Pattern into a more simple model: deconstructing it as we go. Revealing the hidden complexity of MVC Where MVC seems like a simple Pattern to begin with, revealing the Logic parts (making connections to the Model and working with each other) makes clear that something more is going on than just the three parts. A View is not just “a View” and a Controller is not just “a Controller”. Most used pattern, why are the hidden parts not documented? As MVC has become one of the most used Patterns in Software Development, why is it so hard to find anything on this hidden aspect of MVC? Moving to a different model In the next steps you will see how we leave the MVC pattern and move towards a slightly different Pattern, leaving the original SmallTalk80 definition behind us.

Page 228: Re Factoring and Design Patterns

228 Peter Kaptein

STEP 2: RE-ARRANGING THE COMPONENTS ::Tag: MVC-PATT-MVHI-E003

MVC«re-arranged»

Model

4.a: «retrieves data from» 3.a: «sends data to»

3.b: «notifies»

Actor

1.a: «percieves/uses»

View Renderer

4.b: «offers result to»

Interface

2: «triggers / sends input to»

Controller LogicView Logic

1.b: «uses/triggers/sends input to»

DEPENDENCIES: Actor: 1.a: Perceives and uses the View Presenter to take actions 1.b: Uses, triggers, sends input to the Interface Interface: 2: Triggers and sends input to the Controller Logic Controller Logic: 3.a: Sends Data to the Model 3.b: Notifies the View Logic View Logic: 4.a: Retrieves Data from the Model 4.b: Offers the result to the View Renderer

Page 229: Re Factoring and Design Patterns

Refactoring and Design Patterns 229

NOTES: Reducing Dependencies The more objects have a Dependency on the Model, the more static your solution becomes. Meaning that when you need a change, it takes more energy to “move” your code. By reducing Dependencies you start shifting and clarifying Responsibilities. Grouping View Logic and Controller Logic Both Controller Logic and View Logic have a Dependency towards the Model. As we want to reduce the amount of Dependencies, we group them, as a preparation for the next step: a Merge. Responsibilities of the View Logic and Controller Logic Apparently the View Logic and Controller Logic are both Responsible for accessing the Model. While the Controller Logic passes the User Input to the Model, the View Logic Gets or Retrieves Data from the Model to present to the View Renderer. Within the SmallTalk80 model, this makes sense, as the Controller is part of a different Tree as the View. The Controller registers User Input and then somehow has to pass this to the Application. As SmallTalk uses a Model Driven approach, the Controller will, in most cases, push this input to the Model first (after deciding what to do with it) before taking any possible action on the View. The View then retrieves the Data from the Model and with that Data is the update that is the Result of the User Actions as interpreted hand handled by the Controller. Model can notify the View Logic as well What we see in the Diagram is the Passive form, where the View will wait for the Controller to notify the View for any change. The View Logic can also have Obseervers to the Model, observing any change going on, on specific parts of the Model. Is there anything more the Controller does? The Controller is assumed to do all kinds of things without any concrete direction. For instance:

O’Reilly, Java 2EE Design Patterns, chapter 3.2.1: The Model-View-Controller Pattern […] A controller is the first point of contact for a request. Its job is to coordinate request handling, turning user input into model updates and views. The controller acts as a supervisor, planning what changes need to be made and what view needs to be shown, then calling the chosen model and view to execute the actual plan. An application may have multiple controllers, each responsible for a certain area of the application. By coordinating the response to the user's requests, controllers manage the overall flow of the application.

But what is the scope of: “planning what changes need to be made”? Are we talking about the application of Business Logic within the Controller? The association of the Controller as a “supervisor” can be interpreted as a Controller implemented as a Manager of sorts. Are we assuming here that the Controller is aware of the larger scope of the Application instead of just understanding where to place the Input received from the outside world?

Page 230: Re Factoring and Design Patterns

230 Peter Kaptein

Going back to the original definition, the Controller simply: “The controller interprets […] inputs from the user, commanding the model and/or the view to change as appropriate”, but even that is ambiguous as “commanding the model” can be anything as well.

STEP 3: MERGING VIEW LOGIC AND CONTROLLER LOGIC TO A HUB ::Tag: MVC-PATT-MVHI-E004

MVHI«MVC refactored»

Model

3.a: «sends data to /retrieves data from»

Actor

1.a: «percieves/uses»

View Renderer

3.b: «offers result to»

Interface

2: «triggers / sends input to»

Hub

1.b: «uses/triggers/sends input to»

DEPENDENCIES: Actor: 1.a: Perceives / uses result from View Renderer 1.b: Uses, triggers and sends input to the Interface Interface: 2: Triggers and sends input to Hub Hub: 3.a: Sends data to, receives data from Model 3.b: Offers result to View Renderer

Page 231: Re Factoring and Design Patterns

Refactoring and Design Patterns 231

NOTES: Merge of View Logic and Controller Logic to Hub The View Logic and the Controller Logic from the previous step have been merged into what I have called a “Hub”. This Hub takes care of all communication between the Model and the View Presenter. View and Controller: View Renderer and Interface As we are still following the base definitions of the SmallTalk80 implementation, the View is Rendered and all Input of Data comes from the Controller, which is split into an Interface to receive the Input and code within the Hub to process that Input. With this, we reduced both View and Controller to its most basic from towards the Actor: Dumb Input and Dumb Output. View Renderer, Commands, Focus and User Actions When we talk about the View Renderer in 1980, this is basically Code for a Bitmap Generator which draws the screens from rules to a bitmap that can be displayed on screen. This code has no internal Controller and is not aware of User Actions. In a way, the Controller Pattern has to guess which element has received Focus and which Controller will become active to handle the User Actions (typing on the keyboard, hovering over an element, clicking with the mouse pointer on an element). ViewComponents and Encapsulated MVC Patterns With almost all current programming environments, we have an integrated MVC Pattern for each Visual Element or ViewComponent, meaning that when you click on an element and change data, this Component holds the Values and Dispatches the Events to notify any Observer attached to that component. Hub could retrieve data from the View The Hub could retrieve data from the View Renderer and in most current languages, this is exactly what we do.

Page 232: Re Factoring and Design Patterns

232 Peter Kaptein

STEP 4: IDENTIFYING AND EXTRACTING ROLES FROM THE HUB ::Tag: MVC-PATT-MVHI-E005

MVHI«MVC refactored»

Model

3.a: «sends data to /retrieves data from»

Actor

1.a: «percieves/uses»

View Renderer

3.b: «offers result to»

Interface

2: «triggers / sends input to»

Hub

1.b: «uses/triggers/sends input to»

3.c: «uses»

Controller Logic«set data on model»

«application behavior»

View Logic«get data from model»«parse/massage data»

«push data to View»

DEPENDENCIES: Actor: 1.a: Perceives / uses result from View Renderer 1.b: Uses, triggers and sends input to the Interface Interface: 2: Triggers and sends input to Hub Hub: 3.a: Sends data to, receives data from Model 3.b: Offers result to View Renderer

Page 233: Re Factoring and Design Patterns

Refactoring and Design Patterns 233

NOTES: Controller Logic Is all the logic we extracted from the Controller. Depending on the different views on MVC, the Controller just deals with passing the (User) Input or actually takes an active part in deciding what to do next with that User Input, before any further action is taken. In this Diagram and exercise we assume the Controller Sets Data on the Model and deals with what I called: Application Behavior What is the exact role of the Controller? We are still circumventing the answer to this question, as “Application Behavior” can be anything, but we are slowly moving towards a solution as we continue to refactor. View Logic Using the original SmallTalk80 definition, we assume that the View Logic actively Gets the Data from the Model. Next, the View Logic prepares that data for the View Presenter, which is nothing more than code to Render that specific View.

Page 234: Re Factoring and Design Patterns

234 Peter Kaptein

STEP 5: MAKING THE HUB-RESPONSIBILITIES EXPLICIT ::Tag: MVC-PATT-MVHI-E006

MVHI«MVC refactored»

Model

3.a: «sends data to /retrieves data from»

Actor

1.a: «percieves/uses»

View Renderer

3.b: «offers result to»

Interface

2: «triggers / sends input to»

Hub

1.b: «uses/triggers/sends input to»

Data Setter / Data Getter

Application Behavior

Data Parser

4: «gets / sets data»

Data Pusher

3.c: «uses»

7: «pushes data to renderer»

6: Defines which Response should

follow from what user Action

5: Parses the raw data from the Model to

something that can be used by the View

Renderer

DEPENDENCIES: Actor: 1.a: Perceives / uses result from View Renderer 1.b: Uses, triggers and sends input to the Interface Interface: 2: Triggers and sends input to Hub Hub: 3.a: Sends data to, receives data from Model 3.b: Offers result to View Renderer Data Setter / Data Getter: 4: Gets data from the Model and Sets data to the Model Data Parser: 5: Parses the raw data from the Model to something (a structure and or format) that can be used by the View Renderer Application Behavior 6: Defines which response should follow from what User Action

Page 235: Re Factoring and Design Patterns

Refactoring and Design Patterns 235

Data Pusher 7: Pushes the Parsed data to the View Renderer

NOTES: Data Setter / Data Getter We now extracted the two separate actions from two separate objects (Controller Logic Sets data, View Logic Gets Data) into one Class. This class has one single Responsibility: to offer a bridge to the Model and deal with the process of Getting (Requesting) and Setting (storing) Data. Data Parser: another hidden part The Data Parser is one of the “hidden” parts of both the View Logic and the Controller Logic. Who is responsible to massage the Data? Whatever is received in the Controller or View is very likely “Raw” data not yet cut to shape for your View or your Model. As you want your application to be Agile and your Model to be re-usable and as Generic as possible, you have to sort out who massages the Data. Data Parser: make Each Specific Implementation Responsible for Data Massaging Instead of making the Model responsible for Each Specific Implementation, you make Each Specific Implementation responsible to Translate, Massage or Parse the Data to something Generic that can be used and understood by the Model. Data Pusher The Data Pusher simply pushes the data as it is Parsed, to the View Renderer. This removes any dependency from the View Renderer to the Hub and simplifies the architecture of the View Presenter. It simply renders the View with whatever data it has, and that is it. What about rules? Application Behavior The Class dealing with the Application Behavior is the one taking care of matching any User Input with the rules as they apply within the Application. Application Behavior, or: what is the exact role of the Controller? The Controller, which had a lot of (assumed, non specific and unclear) Responsibilities no longer exists. Instead of trying to create a new set of roles and responsibilities to the Controller, we solved the problem by splitting the Controller into separate parts, keeping the Interface part and merging everything else into the Hub. The Hub The Hub is really what it is: the central place where everything related to the View Renderer and the Interface comes together. Behaviors can be executed and managed locally, via a separate class we instantiate or Inject in the Hub

Page 236: Re Factoring and Design Patterns

236 Peter Kaptein

RESULT ::Tag: MVC-PATT-MVHI-E006a

CONCLUSIONS AFTER THE DECOMPOSITION OF THE MVC PATTERN ::Tag: MVC-PATT-MVHI-E007 The MVHI Pattern is something I made up to illustrate the problems with the MVC Pattern: that a lot of crucial complexity is hidden by the deceivingly simple structure of MVC. What happens where? The main problem of MVC is the ambiguity and guesswork related to: “what happens where?” when you try to implement the MVC Pattern. It simply provides no clear answer. Any approach to MVC is valid This makes any approach to MVC a “valid” one, even if you break partially with the original SmallTalk80 definition as MVC is more a Design Principle than anything else. MVC as an anti-pattern Because of the ambiguity and because any approach to MVC is “valid”, MVC has become something close to an Anti-pattern. A simple example: try and merge two different implementations of MVC, where roles and responsibilities are places in different parts of the Code. Where one might have Business Rules places and applied in the Controller, another might have them in the Model. MVVM: Model, View, ViewModel Instead of introducing yet another Pattern to the already rich set of variations on MVC, I simply limit my focus in this book to an already existing alternative to MVC, called MVVM or Model, View, ViewModel. MVVM is a Pattern that origins from Microsoft and simply discards the problem of: “What is the Controller actually supposed to do?”. MVVM and the Controller In MVVM the Controller simply “does not exist” (it is a hidden part of the View). All User Actions are captured by the View and Dispatched to the ViewModel. The ViewModel then applies all Business Logic and makes sure the Model is updates properly. The other way around: the ViewModel Observes the Model and updates the View according to the changes. MVVM and the View Within the MVVM Pattern, the View can become a Dumb view, moving all Processes to the ViewModel. MVVM and the Distribution of Responsibilities The setup of MVVM makes it easier to define the Distribution of Responsibilities as you now have only one Concept to work with in both directions: the ViewModel. MVVM and the Extended MVC Pattern The “Extended MVC Pattern” is a combination of many different things, including the MVVM Pattern, the integration of the Services part of MVCS and two Design Principles I introduce to help you organize your Code and your Classes.

Page 237: Re Factoring and Design Patterns

Refactoring and Design Patterns 237

USE AND ABUSE OF MVC

::Tag: MVC-ABS

MVC ON THE SERVER ::Tag: MVC-ABS-SRV Due to the ambiguity of MVC, the MVC pattern can be used anywhere, even when the View is not the thing we communicate with as is the case in an environment with a Graphical user Interface (for which MVC is originally developed). Server-side View The Server-side View is usually the part that creates the HTML if the server is an HTML Server. The HTML is considered to the “View” on the Model. The Server-side Controller The Server-side Controller is the part that receives the calls from the Browser and interprets these calls in order to return the appropriate Pages with the requested Content The Server-side Model The Server-side Model is anything else. Use or abuse of MVC? The problem I have about this approach is that there are many other approaches to separate Presentation Logic from Business Logic and Creational Logic. 3-Tier is one of them, more recent than MVC and specifically developed for Client-Server applications. As MVC is very unclear and unspecific on the Distribution of Responsibilities (see my Deconstruction and my critiques in the pages before) it is also the most dangerous to use as a paradigm. The less specific, the more variations are possible and the more messy the result will become. Even within the same organization, one Project can be and will be very different from another in the implementation of Server side MVC when that project is led by a different person. For systems that provide mainly data, for instance for Rich Clients, MVC is even a completely wrong choice as the: “Controller” also is the “View” returning the required “View” to the Actor. Alternatives Even a home-made structure is better than MVC when nothing is specified on: “what goes where” within an organization. Simply use solid design principles and design a good basis for your applications (in a process similar as I shown in the MVC breakdown).

Page 238: Re Factoring and Design Patterns

238 Peter Kaptein

NESTED MVC WITHIN THE MODEL ::Tag: MVC-ABS-NMVC When you consider the View to be “the View on the Data”, then anything a method returns is part of that “View” and the part that is been called by some external Actor can be seen as the “Controller”. Data-View The View on the Data: structured according to a specific format. Model The Model that is used to produce the View Controller The Class and the object used to access the Model and generate the Data View Use or abuse of MVC MVC involves at least three classes to get something done: a “Model” class, a View and a Controller. Nesting MVC in a Model leads to code-overhead. Alternatives The alternative for MVC within the Model to refactor your Classes into a simple Interface

Page 239: Re Factoring and Design Patterns

Refactoring and Design Patterns 239

NESTED MVC WITHIN A VIEW AND VIEW COMPONENT ::Tag: MVC-ABS-NST-MVC All current Development Environments offer nested MVC structures within your Views and View Components. Each component that is interactive (basically all objects you put on screen) are capable of intercepting User Actions (Controller) hold the State and the inserted Data (Model) and present the results on screen (View). Model The local model of the View Component, holding information like the State, (enabled, disabled visible, invisible) and the (User) Data: images, text, numbers, the index or value of a selected item View Your View Component, which can be anything from a List to a button to a hyperlink to an input-field. Controller The local and embedded Controller of the View Component Use or abuse of MVC? To embed MVC within Views and View Components delivers a lot of benefits you would otherwise not get in coding. A lot of complexity is isolated and encapsulated by the View Components. To use those View Components is simple as registering Event Listeners to them, setting values, inserting Data Providers and Data Structures and let the Components themselves do all the real work. Alternatives None. I think that embedded MVC within View Components has a lot of benefits, as stated above.

Page 240: Re Factoring and Design Patterns

240 Peter Kaptein

3-TIER ::Tag:INTRDP-MCRDP-3TR ::includesubchapters

Page 241: Re Factoring and Design Patterns

Refactoring and Design Patterns 241

DIAGRAMS

::Tag:INTRDP-MCRDP-3TRD

BASIC 3-TIER DIAGRAM ::Tag:INTRDP-MCRDP-3TRD-001

Presentation Layer

Business Layer

Data Layer

(Graphical) User InterfacesReports

Business rulesData managementData manipulation

Data storage and retrieval(Dumb) Data Objects

COMMUNICATION BETWEEN THE LAYERS ::Tag:INTRDP-MCRDP-3TRD-002

Presentation Layer

Business Layer

Data Layer

Presentation Layer

Business Layer

Data Layer

One way communication Two way communication

One way communication In a one-way communication system, the Presentation Layer can communicate to the Business Layer, but the Business Layer can not communicate with the Presentation Layer, other than by Returning a Result from a Request. The same goes between Business Layer and Data Layer. Two way communication In a two-way communication scenario, the Presentation Layer can send requests to the Business Layer and the Business Layer can call methods on- and interfere with the Presentation Layer.

Page 242: Re Factoring and Design Patterns

242 Peter Kaptein

Mediators, Operators and/or Events This can be done via a Mediator, allowing direct two-way communication or via Events and the Observer Pattern. Within the Extended MVC Pattern, we use an Operator and more concrete a ViewModel object to handle this in one central object. Between Business Layer and Data Layer, Events are the most common way to communicate from the bottom (Data Layer) up (to the Business Layer). Communicating top (Business Layer) down (Data Layer) is usually done via Method Calls on objects in the Data Layer.

COMMUNICATION BETWEEN TWO 3-TIER SYSTEMS ::Tag:INTRDP-MCRDP-3TRD-003

Presentation Layer

Business Layer

Data Layer

Presentation Layer

Business Layer

Data Layer

Client Server

«pull»

Pull-based communication The Client calls the Server. Communication happens between the Data Layers. The client calls the Server. The Server cannot call or reach the Client.

Presentation Layer

Business Layer

Data Layer

Presentation Layer

Business Layer

Data Layer

Client Server

«push»

Push-based communication The Client can call the Server, the Server can push information to the Server. The Client establishes the Communication to the Server, but once connected, both Client and Server can Push information to each other.

Page 243: Re Factoring and Design Patterns

Refactoring and Design Patterns 243

Page 244: Re Factoring and Design Patterns

244 Peter Kaptein

MANAGER, HANDLER, OPERATOR, PARSER,

UTILITY, DATA OBJECT ::Tag:MHOPUDO ::includesubchapters

Page 245: Re Factoring and Design Patterns

Refactoring and Design Patterns 245

ORIGINS

::Tag:MHOPUDO-ORIG This Design Principle emerged out of my own work and based on organizational principles.

DIAGRAMS

::Tag:MHOPUDO-DIA

HIERARCHIC STRUCTURE AND USE OF MHOPUDO ::Tag:MHOPUDO-DIA-001

Operator

Manager

Handler

Parser

Value Object

Data Transfer Object

Data Objects

Your Model

The rest of the world

«can access»

«can access»

«can access»

«can access»

«can access»

Page 246: Re Factoring and Design Patterns

246 Peter Kaptein

MHOPUDO WITHIN THE EXTENDED MVC PATTERN ::Tag:MHOPUDO-DIA-002

Layers

Extended MVC

Model

View “Controller”

Operator

Handlers, Managers, Utilities,Parsers

Simulations,Actors,Rules,

Behaviors

Services

1: P

resentatio

n2

: Bu

siness

3: D

ataData Objects

Observer / User

NOTES: Operator: gateway between Business and Presentation Layer The Operator functions as a gateway between the Business and Presentation Layer Handler, Manager, Parser: part of the Business Layer The Handler, Manager, Parser are part of the Business Layer. They deal with the specific aspects of handling Data (the Handler and the Parser), Managing the parts of the Application they are responsible for (the Manager) and applying Business Rules (the Manager). Data: part of the Data Layer The Data-part is about Data Objects. These Data Objects have the sole purpose to contain data. In 3-Tier, this makes them part of the Data Layer.

Page 247: Re Factoring and Design Patterns

Refactoring and Design Patterns 247

USING MHOPUDO IN REFACTORING

::Tag:MHOPUDO-REF

BASIC STARTING POINTS ::Tag:MHOPUDO-REF-STRT Separation of responsibilities The most important role of MHOPUDO is to simplify Distribution of Responsibilities. As your code base grows, your code and “who does what” might become more and more entangled as well. The MHOPUDO Principle allows you to separate the responsibilities in your code into clear and separate blocks and classes that have a very clear chain of command and communication. ::Link:RFCT-ELM-SRSP Stable project structure Another aspect and goal of MHOPUDO is to provide a stable Project Structure that will not change much even with concurrent and regular refactorings. ::Link:RFCT-ELM-CONS Agnostic of any Design Pattern The third roloe of MHOPDC is to provide a Project structure which is completely agnostic of any Design Pattern you might use within your project. So that when you decide to change your approach, your project is still stable in its setup. ::Link:RFCT-ELM-AGN

HOW TO ACHIEVE THIS ::Tag:MHOPUDO-REF-HOW Stable project, stable class names: choosing purpose instead of Design Pattern When you name your classes, name them according to their purpose, instead of the Design Pattern you might use inside. MHOPUDO provides five main class types and several derived class types from these five. The result is that the classes in your code-base no longer reflect the low-level implementations you chose at one point in the process, but the results you gain to achieve. Abstraction, encapsulation and direction: promoting and demoting code As you write code, the most usual approach in Agile programming is: implement first, refactor later. Meaning that you create and find the most simple working solution first and then think about where to put what parts of your code. The first three steps in refactoring are: Extraction, Encapsulation and Abstraction. But as you Extract, Encapsulate and Abstract your code: where should the result go to (Direction)? This is where promotion and demotion in the MHOPUDO structure will help you. ::Link:OOP-PRNC-EEA|RFCT-ELM-REST|RFCT-ELM-SRSP-PRO

Page 248: Re Factoring and Design Patterns

248 Peter Kaptein

PROMOTING AND DEMOTING CODE IN THE MHOPUDO MODEL ::Tag:MHOPUDO-REF-PROM

OperatorManager

Handler

Value Object

Data Transfer Object

Data Object Dem

oti

on

P

rom

oti

on

Specialization

Code from Your Object

Parser

Utility

Hub

ViewModel Object

NOTES: Directions of refactoring inside the MHOPUDO model The MHOPUDO Model knows three directions of refactoring (and a hidden fourth one): Promotion, Demotion and Specialization.

Promoting code: moving up the line When you promote code, you move it up the hierarchic line. It will be placed inside a Class that has more responsibilities and more “smarts” than where it started. Demoting code: moving down the line When your code does stuff that is below the scope of responsibilities of an object and Class, you demote that code. Code can be demoted from your object to a Data Object (variables) or from a Manager to a Handler or Data Object. Specializing code: moving it sideways

Page 249: Re Factoring and Design Patterns

Refactoring and Design Patterns 249

For the Handler, Manager and Data Object are several specializations. For instance: when a Data Object is just there to contain values, you can call it a Value object. However: when you use it to contain Data in order to transfer it from one structure to another, you can call it a Data Transfer object. The same goes for Handlers: which can be specialized in different types including (but not limited to): Data Handlers, Data Parsers, File Handlers and Database Handlers. Managers can be specialized into different types of managers including (but not limited to): Data Managers, Data State Managers and Application Managers.

is or does? Deciding where to move it The code from your object is either a variable, or performs a specific action (does).

Is a variable: demote to a Data Object When your code is a variable (or set of variables) you can demote this to a Data Object. Performs a specific action: promote to a Handler or Manager When your code performs a specific action, you can promote it to a Handler or Manager Class. Handles but does not Manager: demote to a Handler When code Handles stuff without managing, you can demote it to a Handler.

Promoting code: Manager or Handler? When you promote code that performs actions: when does it fit inside a Manager and when is it part of a Handler?

Manager: smart stuff and choosing and applying business rules The Manager is “smart” it knows and has to know the bigger picture to be able to do its work. Hander: handles stuff without the need to know the bigger picture The Handler simply handles things it is offered to handle. It does not know about other processes or what the bigger picture is. If it deals with business rules, these rules are given or injected from the outside in.

Specializing the roles:

Page 250: Re Factoring and Design Patterns

250 Peter Kaptein

THE MANAGER AND MANAGER CLASSES

::Tag:MHOPUDO-MGR

DIAGRAMS ::Tag:MHOPUDO-MGR-DIA

CONCEPTUAL MODEL SHOWING THE POSSIBLE RELATIONSHIPS OF THE MANAGER

1.d: «can use» 1.b: «uses»

2.a: «apply»1.a: «applies»

Business Rules

2.b: «use»

Value ObjectsData Transfer

Handler

Populator

2.c: «can be»

Handlers ParserManagerData Services

Other Manager

1.c: «works with»

1.e: «can work with»

Relationships: The Manager: 1.a: Applies Business Rules 1.b: Uses Handlers 1.c: Works with Value Objects 1.d: Can use Data Services 1.e: Can work with another Manager Handlers: 2.a: Apply Business Rules 2.b: Use Value Objects 2.c: Can be a Populator, Parser or Data Transfer Hander (out of many other possibilities)

Page 251: Re Factoring and Design Patterns

Refactoring and Design Patterns 251

BASICS ::Tag:MHOPUDO-MGR-BAS Short and simple: The Manager Manages. To be able to Manage things, the Manager needs knowledge about the part it Manages. This knowledge consists of knowledge about: Processes, Actions, Responses Knowledge about the Processes and Actions it manages Business Rules Knowledge about the Business Rules it should apply Classes and objects Knowledge about the Classes and objects it can use to manage these Processes Conversions Knowledge about the Conversions (from one datatype to another) it should apply where and when needed Destinations and Sources Knowledge about of data: where to retrieve it, where to store it In most cases we will Abstract all this knowledge and all the Code to make it work in separate Classes, which are organized in the following main parts: Handlers We create separate Handlers to handle Processes, Actions and Responses, Convert Data and to deal with- and apply Business Rules Other Managers We create and access other Managers to delegate specific work the Manager can not handle, or is not Responsible for Services We create and manage Services which deal with the storage and retrieval of data to and from External Data Sources (like Databases, File Systems and Remote Services)

Page 252: Re Factoring and Design Patterns

252 Peter Kaptein

AN EXAMPLE OF ROLES AND RESPONSIBILITIES ::Tag:MHOPUDO-MGR-EX To Manage Processes The Manager Class Manages processes. This means that they contain intelligence and information on what needs to happen when and why. To Manage Data The Manager Class, as a DataManager, can be used for the management of Data, including loading and storing that data locally and on External Data Sources. To Manage (Data) Services The Manager Class, in the shape of a Data- or Service Manager, is used within this Macro-Pattern to Manage (Data) Services: to Retrieve and Store Data from and to External Data Sources. To Manage States A Manager can deal with the Management of States. Anything in your application, including your Application itself can have and (actually) has a State.

VARIATIONS AND SPECIALIZATIONS ::Tag:MHOPUDO-MGR-VAR General Managers These Classes manage things, but haven ot been given a specific role yet. Data Managers Data Managers manage everything and anything that deals with Data, including:

Retrieving and Storing Data In any possible way, using (or choosing) a Data Service. Parsing Data Using (or choosing) a Data Parser to do the actual work. Storing and Retrieving Local Data For use within the entire Application. Using either a specific DataManager or a Data Map Checking and applying Business Rules Using a DataState Handler or DataState Manager. Short: The Business Rules define the State of the Data, which is either “Valid” or “Invalid” State Managers State Managers deal with the state of for instance: Data States Being called a DataStateManager. These Managers check the State of the Data, apply Business Rules and Validations to that Data and return the state after application of the Business Rules View States

Page 253: Re Factoring and Design Patterns

Refactoring and Design Patterns 253

Being called a ViewStateManager Application States Being called an ApplicationStateManager

Process Managers These managers deal with processes. For instance:

Emails Sending and receiving emails Workflow processes Managing everything related to the Workflow in an automated process Dataflow processes Managing everything related to a dataflow Steps in a process Managing everything that is related to the steps in a process Navigation processes Managing everything related to navigating from A to B and back

EXAMPLES OF MOST RELATED DESIGN PATTERNS ::Tag:MHOPUDO-MGR-EXRD Mediator The mediator Pattern reflects many of the properties of the Manager Class. However, a Mediator is not necessarily a Manager Class.

DESIGN PATTERNS USED WITHIN THE MANAGER ::Tag:MHOPUDO-MGR-CMUSE Façade: Interfacting to other parts of the aplication To access the Model and processes in the Model which are easier to use when they are “wrapped” ::Link: PAT-FCD Factory: Creating objects from parameters when needed Including Abstract, Simple and Factory Method. To offer and allow choice in Handlers to use to handle specific processes. ::Link: PAT-FAC|PAT-SFC|PAT-AFC Object Map: Accessing objects from persistent repositories To access objects from a Persistent Repository ::Tag: PAT-DTMP Singleton and Multiton: Accessing shared objects To access one single object that is used and shared anywhere in your Project

Page 254: Re Factoring and Design Patterns

254 Peter Kaptein

USEFUL PATTERNS AND INTERESTING DESING PATTERNS ::Tag:MHOPUDO-MGR-US State To act as a Self-managing Dynamic Handler for specific Processes Extending a Bridge To create a Manager that can change its internal workings without you having to change the Manager itself. (The Bridge pretends to be the object it represents and can change that object as your code runs) State, possibly Encapsulated by Bridge The State Pattern has similar properties as the Bridge, but replaces the Manager itself via the reference a State object (one of your Managers) has to the Container of that Manager. State requires some care and might be better encapsulated by a Bridge

Page 255: Re Factoring and Design Patterns

Refactoring and Design Patterns 255

THE HANDLER AND HANDLER CLASSES

::Tag:MHOPUDO-HNDLR

DIAGRAMS ::Tag:MHOPUDO-HNDLR-DIA

CONCEPTUAL MODEL SHOWING THE POSSIBLE RELATIONSHIPS OF THE HANDLER

1.d: «can use» 1.b: «uses»

2.a: «apply»1.a: «applies»

Business Rules

2.b: «use»

Data Transfer Handler

Populator

2.c: «can be»

Handlers ParserManagerData Services

Other Manager

1.c: «works with»

1.e: «can work with»

Value Objects

Page 256: Re Factoring and Design Patterns

256 Peter Kaptein

BASICS Short and simple: The Handler Handles. The Handler contains everything that is smart enough to Handle stuff, but has no clue on the why or when. The Handler is best compared to a Machine that deals with one specific Type of Processes and produces something a result from the elements it was given. The Handler has no knowledge of any process out of its own, nor of any process in the Application at large. All that is given and dealt with by the Manager. In most cases, the Handler has no knowledge of the Manager.

MOST COMMON OF ROLES AND RESPONSIBILITIES To Handle The Handler Handles stuff To Verify Part of the Handling might be to Verify whether something applies to the rules or not To Find and Return A Handler might be there to find and Return something from a List or a Data Source To Convert A Handler might Convert Data or a Data Source (like XML or an object Tree) from one Structure to another (and back) To Store and Retrieve A Handler might be used to store and retrieve Data, either locally or to and from a Remote Data Source (for External Sources, objects and Classes with this Role are extracted from the Model domain and placed into the Service domain)

Page 257: Re Factoring and Design Patterns

Refactoring and Design Patterns 257

MOST COMMON VARIATIONS AND SPECIALIZATIONS Data Handling Data in any possible way, including the:

DataParser or Parser Parsing data from one Data Structure to anther. ValidationHandler or Validator Validating the data it is offered using Business rules and Validators it has been given for use on each specific Data Item or Variable. Service or DataService Handling the retrieval and storage of Data to and from External Data Sources, including Databases, File Systems and Webservices. DataHandler Doing all kinds of stuff, including all of the above

State Handling the State of things, including the:

DataStateHandler Handling the actions that flow from a specific Data State. ViewStateHandler Handling the actions that flow from a specific View State. FlowStateHandler Handling the actions related to the Flow State.

Processes Handling processes in any possible way, including the:

EmailHandler Handling the sending and retrieval of Emails. WorkFlowHandler Handling (parts) of a defined Workflow. DataFlowHandler Handling the flow (steps in a process) of Data. StepHandler Handling the specific Step in a multi-step process like a Wizard or a multi-step Application Form. NavigationHandler Handling the navigation to a specific page in your site or a specific step in your process.

Page 258: Re Factoring and Design Patterns

258 Peter Kaptein

SEE ALSO ::Tag:MHOPUDO-HNDLR-SEE The Parser pattern: maybe one of the most used patterns in the Handler The Parser Pattern discusses the internal workings of the Parser. ::Link:PAT-PARS Iterator: iterating through lists To iterate through lists and retrieve information or set values on objects Data Map / Simple Repository: storae and retrieve data To store and retrieve local data Factory: create context-specific handlers To create Context-specific Handlers for context-specific processes, based on a specific context ::Link: PAT-FAC|PAT-SFC|PAT-AFC Singleton and Multiton To access shared objects over the Application and perform actions or set values ::Link:PAT-SING|PAT-MULT

Page 259: Re Factoring and Design Patterns

Refactoring and Design Patterns 259

THE HANDLER AND THE REFACTORING PROCESS When you Refactor your code, the following things might happen: Extracting Methods from your Manager to a Handler When your Manager grows to big, you will start extracting Code from your Manager. The first and most logical place is to create a new Handler, or use an existing Handler Splitting the Handler into Specialized Parts As your Handler grows, it might be that it will start to handle two or more Types of Processes. In this case, you will split the Handler into Specialized parts, which are new Handlers with a very specific task, like “DataHandler” and “DataParser” Promoting Code to the Manager It is possible your Handler starts to do stuff that requires knowledge about the environment (or Model) it lives in. As a Handler only Handles, like a Machine, this Code might better be moved (Promoted) to the Manager

Page 260: Re Factoring and Design Patterns

260 Peter Kaptein

THE OPERATOR AND OPERATOR CLASSES

::Tag:MHOPUDO-OPR

DIAGRAMS ::Tag:MHOPUDO-OPR-DIA

SIMPLIFIED REPRESENTATION OF THE OPERATOR ::Tag:MHOPUDO-OPR-DIA-000

Operator A Subsystem B

Your Class

1: «uses»

2.a: «addresses»

2.b: «uses / delegates to»

3: «can address»

Subsystem C

Page 261: Re Factoring and Design Patterns

Refactoring and Design Patterns 261

CONCEPTUAL MODEL SHOWING THE POSSIBLE RELATIONSHIPS OF THE OPERATOR ::Tag:MHOPUDO-OPR-DIA-001

1.b: «use»

2: «apply»1.a: «apply»

Business Rules

Handlers1.d: «can use»

Data Services Managers

Model

Services

Operators

3: «granting access to»

Page 262: Re Factoring and Design Patterns

262 Peter Kaptein

THE SIMPLE OPERATOR ::Tag:MHOPUDO-OPR-DIA-002

Co

nn

ects

to

Pre

sen

tati

on

La

yer

Bu

sin

ess

Laye

r

Application Model

Co

nn

ects

to

The V

iew

View Interface

View Components

Data Handler View Logic

Connector to Application Model

Operator Model Operator Logic

Connector to View

The O

pera

tor

Page 263: Re Factoring and Design Patterns

Refactoring and Design Patterns 263

SPLITTING THE OPERATOR INTO TWO PARTS: THE OPERATOR AND OPERATOR INTERFACE ::Tag:MHOPUDO-OPR-DIA-003

Co

nn

ects

to

Pre

sen

tati

on

La

yer

Bu

sin

ess

Laye

r

Application Model

The O

pera

tor

The In

terface

Co

nn

ects

to

Co

nn

ects

to

The V

iew

Operator Interface

Connector to Application Model

Connector to Operator Interface

Operator Model Operator Logic

Connector to View

View Interface

View Components

Data Handler View Logic

Page 264: Re Factoring and Design Patterns

264 Peter Kaptein

BASICS ::Tag:MHOPUDO-OPR-BAS

MOST COMMON ROLES AND RESPONSIBILITIES ::Tag:MHOPUDO-OPR-COM Offering a simple Interface to the Model Like the Façade, the operator offers one simple Interface for other objects and Classes to work with a Subsystem. For the Operator, that Subsystem is a part of the Model. While a Operator is similar to the Façade and can be the implementation of the Façade Pattern, it does not have to be one. Dealing with object-specific issues The object that uses the Operator has specific functions and processes to be dealt with. The Operator knows which these issues and processes are and offers and uses the appropriate objects and Classes (from the Model) to deal with that. To Abstract and Shield access to the Model The Operator acts as a guard to the Model itself. Objects using the Operator never get direct access to the Model, but always hae to go through the Operator To create a more Agile and Disposable solution As the Operator takes care of the actual Processes, the object using your Operator can simply switch to a totally other Handler by choosing a different Operator for the same Job. This makes your code and your solutions more Agile and more Disposable.

THE IMPORTANCE OF A DISPOSABLE SOLUTION As your Code changes, your Requirements might change as well. Instead of continuously rewriting your Operator, you cvan choose to freeze one set of Requirements into one Operator and implement the next set of Requirements into a new Operator. From this point on, your Application no longer relies on one single solution and your Solution as a whole has become Disposable. Meaning that you can “throw it away” and replace it by something else, without killing your Application as a whole. If and when your Application needs to switch from one Direction to another, you simply switch your Operator.

MOST COMMON VARIATIONS AND SPECIALIZATIONS ::Tag:MHOPUDO-OPR-VAR The VMO or ViewModel object The VMO is an Operator, specifically created for a Specific View or ViewComponent. It deals with all the actions related to that View and all triggers it receives from the Controller. The VMO “Operates” the Model to get done what needs to be done for the View

Page 265: Re Factoring and Design Patterns

Refactoring and Design Patterns 265

RELATED PATTERNS ::Tag:MHOPUDO-OPR-SEE Façade: a simplified, single point of access to a subsystem The Operator most resembles the Façade by offering a simplified point of access to Concrete Classes and objects to deal with the Process, but is not necessarily an Implementation of the Façade Pattern ::Link: PAT-FAC Mediator: another way to implement the Operator In the case of Game Development and Real Time Systems, it might be preferable to approach the Operator directly from the Model and use it as a Hub to push changes in any possible direction. In this case, the Operator will resemble the Mediator. ::Link: PAT-MED Factory: obtain context-specific objects To obtain Context-specific objects (Products) to deal with specific processes Singleton and Multiton – To get access to object used over the entire Application ::Link: PAT-FAC| PAT-SFC|PAT-AFC Object Map: retrieve objects from a map To get objects which are stored locally, within the Model and within the Application. Delegation: use someone else to perform the actions The Operator delegates all real tasks to objects and Classes it instantiates and calls from within the project. ::Link: PAT-DEL

NOTES: As the Operator mostly uses Delegation, the real work is done somewhere else, done by any pattern conceivable.

THE OPERATOR AND THE REFACTORING PROCESS ::Tag:MHOPUDO-OPR-REF Extracting Methods and Code from your View Most code in your ViewModel object Operator will start in your View. Move it to the VMO (your Operator for the View or ViewComponent) Simplification of processes Like with the Façade, the Operator simplifies processes spread over multiple Classes and objects by encapsulation. Extract all Code and Methods doing these jobs and place them into an Operator Class Extraction of Methods and Code to Handlers It can happen that your Operator becomes to crowded with Code, because you (or some other programmer) wants to do too much within the Operator. Extract this Code and these Methods and create new Classes (usually Handlers to Handle the process) Extraction of knowledge to Managers

Page 266: Re Factoring and Design Patterns

266 Peter Kaptein

Whatever deeper knowledge your Operator might build up about processes and why and when they should happen, as soon as it looks like your Operator starts Managing stuff, create a Manager Class and Extract that code to there. The chapter on the Manager and Manager Class gives you a nice oversight on when what might be done by the Manager

Page 267: Re Factoring and Design Patterns

Refactoring and Design Patterns 267

THE UTILIY AND UTILITY CLASS

::Tag:MHOPUDO-UTIL

BASICS ::Tag:MHOPUDO-UTIL-BAS Short and simple A Utility is a generic and re-usable method that performs one very specific task No state The Utility Class has no state by Default. Extracted utilities into a Utility Class You extract Utility Methods into a specific Utility Class. Static methods: no cost of object Instantiation As the utilities have no internal State, you can implement utiltity-methods as Static methods, allowing you to use and call them without the cost of object Instantiation.

RELATED PATTERNS ::Tag:MHOPUDO-UTIL-REL No related Patterns “Desing Patterns” has no similar patterns describing the workings of a Utility Class.

MOST COMMON ROLES AND RESPONSIBILITIES ::Tag:MHOPUDO-UTIL-ROLE Re-usable, general purpose actions The Utility Class contains re-usable, general purpose actions. Converting the content of objects from one type to another When two different systems communicate to each other, the Data Types delivered by one can be different from the ones used by the other. Especially when this data is serialized into an abstract datagram (like XML) of pure data without any meaning. Converting String values to Date objects, Booleans and Numeric values Utility methods can convert String values to Date objects and Numeric values. Converting Date objects, Booleans and Numeric values to String values Utility methods can convert Date objects and Numeric values to String values. Parsing complex datagrams When you receive complex Datagrams, Utility methods can convert these to object Models. Merging data with datagrams In some cases, you need to merge data with Datagrams.

Page 268: Re Factoring and Design Patterns

268 Peter Kaptein

NOT CONSIDERED TO BE PART OF THE DEFAULT SCOPE ::Tag:MHOPUDO-UTIL-OUTSC Handling stuff for one Class Utility methods should be very simple and very single-minded. You put stuff in and a result comes out. The moment a Utility only performs one specific process for one specific Class and can not be used anywhere else, you should consider if it should be put inside a Handler instead. Accessing and changing external sources If you want to use a Utility to access external data sources, be aware what you do and if this implementation is really a utility. If it is accessed by many different parts of your application, it might be. Accessing and changing a Object Map directly In principle, a Utility should not address a Object Map (in memory dataset) directly, but only handle data it gest injected via a variable in the method. Unless accessing and changing data inside a Object Map is explicitly the role and responsibility of your Utility, avoid this specific use of the Utility.

MOST COMMON VARIATIONS AND SPECIALIZATIONS ::Tag:MHOPUDO-UTIL-VAR Parser utility: a specialization The moment you can generalize a Parser into something you can use for many different Classes and implementations, you have a Parser utility. Injector utility: a specialization Like the Parser, the Injector (a specialization of the Parser) can be made into something generic and abstract that can be used over many different Classes in your project. The moment the Injector is no longer dependent on a specific set of Classes and a specific implementation of your code, it can become a Injector Utility. ::Link:MHOPUDO-PARS-VAR Parser: a variation The moment your Utility

Page 269: Re Factoring and Design Patterns

Refactoring and Design Patterns 269

THE PARSER AND PARSER CLASS

::Tag:MHOPUDO-PARS

DIAGRAM ::Tag:MHOPUDO-PARS-DIA

CONCEPTUAL MODEL SHOWING THE POSSIBLE RELATIONSHIPS OF THE PARSER

1.d: «can use» 1.b: «uses»

2.a: «apply»1.a: «applies»

Business Rules

2.b: «use»

Data Transfer Handler

Populator

2.c: «can be»

Handlers ParserManagerData Services

Other Manager

1.c: «works with»

1.e: «can work with»

Data Objects

BASICS ::Tag:MHOPUDO-PARS-BAS Short and simple The Parser parses. Specialized Handler The Parser is a specialized Handler to Parse Data from one Structure to another. This can be from XML to an object Tree, or to transform or parse one object Tree into a different and other object Tree. Parsers are quite common You will find the need for a Parser almost always in any of your Projects. The moment you start using Data, some kind of translation or conversion from A to B (and back) will happen.

Page 270: Re Factoring and Design Patterns

270 Peter Kaptein

RELATED PATTERNS ::Tag:MHOPUDO-PARS-SEE The Parser Pattern In the Design Patterns chapter you will find more and detailed information about the Parser Pattern and the different conceptual models, from Simple Parsing to Conversion to Merging of different Abstract Definitions and object Trees. ::Link: PAT-PARS Iterator To iterate through the object Tree as delivered by you or some external source. Factory To create Context-specific objects to contain the Values and to represent objects your Data Source provided. ::Link: PAT-FAC|PAT-SFC

MOST COMMON ROLES AND RESPONSIBILITIES ::Tag:MHOPUDO-PARS-ROL To Copy Data To copy Data from one structure into another. In most cases you simply want to copy the structure of one Data Source into another, which is more handy for internal use. Think of parsing XML to an object Tree or even directly to the objects it represents To Transform Data To transform Data from one Structure into another Structure. Sometimes the Structure of the Data you get is something you can hardly use for the processes in your Application. In that case you Transform the Structure of the Data into a new Data Structure that does make sense. To build an object Tree for specific use In some cases, you want to use your Data Source to build an object Tree, like a List that can be displayed on screen To Transform a Value from one Type into Another In some cases, your application needs to transform a Value into something else, for instance when a sub-system uses a different type of Format for a Data Value or wants a “Yes/No” where you produce a “True/False”

Page 271: Re Factoring and Design Patterns

Refactoring and Design Patterns 271

MOST COMMON VARIATIONS AND SPECIALIZATIONS ::Tag:MHOPUDO-PARS-VAR DataParser: a specialization To parse Data from one strcutrue and type to another. ValueParser: a specialization To parse a single Value from one Data Type to another. DataTransformer (still called Parser in most cases) To transform Data from one Data Structure to another Data Structure. Injector: a specialization The Injector is a limited and specialized form of the Parser. The role of the Injector is to inject values from one object into another. ::Link:PAT-INJ

RELATED TERMS ::Tag:MHOPUDO-PARS-RTRM Data Marshaling Data Marshaling is another way to describe the same process. I prefer the use of “Parsing” as I am simply more familiar with the term and “Parser” is easier for the eyes and more logic for the brain than “Marshaler”

Page 272: Re Factoring and Design Patterns

272 Peter Kaptein

THE PARSER AND THE REFACTORING PROCESS ::Tag:MHOPUDO-PARS-REF Extraction from your Code In most cases, a Parser starts somewhere in your Code, as a loop in which you take an existing Data Structure and work it into something else. By Extracting it to another Class: your Parser, you Abstract the process and make it more Agile (you can use other Methods to parse the same data in another way, or create multiple Parsers to choose from) Specialization of processes in your Handler Like above, it is possible that your Handler contains one or more Parsers. As a the requirements of your Parser might change, or your Parser might become handy in other places as well, you might want to Extract it to an External Parser Class Re-use If you are sure that there is need and possibility of re-use Multiple variations on the same process – When one Data Source is to be Parsed in different ways. For instance:

1. To Transform it into another Data Structure 2. To Display it on screen 3. To apply different Operation on for different Purposes 4. To make (disposable) copies for temporary use

Page 273: Re Factoring and Design Patterns

Refactoring and Design Patterns 273

DATA OBJECTS

::Tag:MHOPUDO-DO

DIAGRAMS

CONCEPTUAL DIAGRAM INCLUDING THE DATA OBJECTS

Value Objects

3.a: «can be»

Data Transfer Objects

1.d: «can use» 1.b: «uses»

2: «use»

HandlersManagerData Services

1.c: «works with» 3.b: «are Data Objects»

Relationships: Manager: 1.a: Can use Data Services 1.b: Uses Handlers 1.c: Works with Value objects Handlers: 2: Use Value objects Value objects: 3.a: Can be Data Transfer objects 3.b: Are Data-objects

Page 274: Re Factoring and Design Patterns

274 Peter Kaptein

BASICS ::Tag:MHOPUDO-PARS-BAS Brief and simple: The Data-objects contains things The Data-objects are any Class or Variable that has the sole purpose to contain something else. To be clear, Data-objects are only the Classes specifically created to Contain Values. As soon as a Class starts doing things with the values within itself it is no longer a Data-object.

MOST COMMON ROLES AND RESPONSIBILITIES ::Tag:MHOPUDO-PARS-ROLE To Contain an object or Value To Contain an object or Value like Variables and Value objects To Contain a (Data) Structure To Contain a (Data) Structure Like XML objects and

MOST COMMON VARIATIONS AND SPECIALIZATIONS ::Tag:MHOPUDO-PARS-VAR Value objects These are objects with one single purpose: to contain Values related to an object Data Transfer objects More specialized forms of Value objects are Data Transfer objects: created to transfer data from one object to another. Variables Variables contain either Values or References to an object

RELATED PATTERNS ::Tag:MHOPUDO-DO-SEE Composite The Composite Pattern is Contained in the Root object and has specific Data-objects per Child to Contain the Children of that Child. A Composite structure can be made out of Data-objects (called Value objects in most programming environments) without any internal code. Visitor –

Page 275: Re Factoring and Design Patterns

Refactoring and Design Patterns 275

THE DATA-OBJECTS AND THE REFACTORING PROCESS ::Tag:MHOPUDO-PARS-REF Isolation of Values Data-objects (in most cases Value objects) are created by Isolating the Values from the Processes that uses them. Extraction of Methods Into new or External Classes. By Extracting all Methods into external Classes, you extract the process from the Data-object, making the Data-object less bound to the Process it might be used in

Page 276: Re Factoring and Design Patterns

276 Peter Kaptein

EXTENDED MVC AND SEPARATION OF

RESPONSIBILITIES ::Tag:EMVC-SR ::includesubchapters

Page 277: Re Factoring and Design Patterns

Refactoring and Design Patterns 277

INTRODUCTION

::Tag:EMVC-SR-INTRO The problem with the MVC Pattern Within the MVC Pattern , it is not really clear who does what where. This makes the MVC model quite “weak” and more a Design Principle than anything else. Adding the 3-Tier model One way to get more clarity is by adding the 3-Tier model. The 3-tier model gives you a good insight in the three main roles within your application, dealing with Presentation, Business Riles (logic) and Data. Adding different types of Classes Within each part of the MVC pattern, multiple roles can be played. To just call something “Model” for instance does not help you clarify what it does or how big or small its responsibilities are. Avoiding specific Design Patterns It is tempting to focus on Design Patterns instead of a hierarchic model. The main reason is that in practice there is not just one solution to apply MVC. There are as many as there are applications you can build. Avoiding frameworks Additional, the idea is to avoid using MVC based frameworks as well. Solutions like Spring and PureMVC might promote the use of MVC, but they also force you into one specific solution, which might not always be the best for the type of solution you are building. Focusing on roles and responsibilities Instead we focus on roles and responsibilities. Who does what and what is the scope of knowledge and responsibilities in this? The use of MHOPUDO is one of the tools and attempts to keep this clear and simple.

Page 278: Re Factoring and Design Patterns

278 Peter Kaptein

A VISUAL SUMMARY OF THE EXTENDED MVC PATTERN

::Tag:EMVC-SR-VSM

THE EXTENDED MVC PATTERN ::Tag:EMVC-SR-VSM-001

Layers

Extended MVC

Model

View “Controller”

Operator

Services

1: P

rese

ntatio

n2

: Bu

sine

ss3

: Data

Data Objects

3.a: «updates / gets values from» 2.b: «notifies/updates»

3.b: «updates / gets values from»

4.a: «includes»

Handlers, Managers,

Parsers

4.c: «includes»

4.d «can use»

4.b: «can include»

Simulations,Actors,Rules,

Behaviors

Observer / User

1.a: «gets updates / results from»

1.b: «updates»

2.a: «updates»

NOTES: Defining the boundaries of the 3-Tier model On the right hand side you see the three tiers and the boundaries they create. Within those boundaries you find the different players, including the Model, View and Controller. Adding a lot of new roles To allow for a clear Separation of Responsibilities you find a lot of new roles in the MVC pattern. Each role has a specific set of responsibilities and has a specific role within the hierarchy of objects, allowing you to Refactor your code much easier than without them.

Page 279: Re Factoring and Design Patterns

Refactoring and Design Patterns 279

3-TIER ::Tag:EMVC-SR-VSM-002

Presentation Layer

Business Layer

Data Layer

«communicates with»

«communicates with»

(Graphical) User InterfacesReports

Business rulesData managementData manipulation

Data storage and Data retrieval(Dumb) Data Objects

«contains»

«contains»

«contains»

NOTES: The problem with the MVC Pattern Within the MVC Pattern , it is not really clear who does what where. This makes the MVC model quite “weak” and more a Design Principle than anything else. Extended MVC, Separation of Responsibilities and the 3-Tier model The Extended MVC pattern attempts to implement a clear Separation of Responsibilities. One of the angles used to gain an optimal model is the use of the 3-Tier model 3 layers The 3-Tier model has three layers: The Presentation Layer, the Business Layer and the Data Layer. Each has a specific set of responsibilities and a clearly defined scope to operate in. ::Link:INTRDP-MCRDP-3TR

Page 280: Re Factoring and Design Patterns

280 Peter Kaptein

OBJECTS AND PLAYERS IN THE MODEL AND SERVICES ::Tag:EMVC-SR-VSM-003

1.b: «use»

2.a: «apply»1.a: «apply»

Business Rules

1.c: «work with» 2.b: «use»

Data Objects

3: «can be»

Data Transfer Handler

Populator

2.c: «can be»

Handlers Parser1.d: «can use»

Data Structures

4: «receive and send»

5: «is derived from / parsed

into»

Data Services Managers

Model

Services

6.a: «granting access to»Data Transfer Objects

Utility

6.b: «can be»

Hub

ViewModel Object

Operators

NOTES: The Model: covering both the Business Layer and part of the Fata Layer The Model represents the Business Layer and a part of the Data Layer in the 3-Tier model. The Data objects and Data Transfer objects are part of the Data Layer within the 3-Tier model. The Operators: gatekeepers and mediators The Operators are the points of entry form outside of the Model. In this approach, anything that is not part of the Model can only access that model via the Operator. The Operator uses the same approach as the Manager and combines aspects of the Mediator and Façade Patterns to operate: allowing you to access a subsystem via a simplified interface and to interact directly with that Operator from both inside and outside the Model. ::Link: PAT-MED| PAT-FCD| PAT-MGR

Page 281: Re Factoring and Design Patterns

Refactoring and Design Patterns 281

OBJECTS AND PLAYERS IN THE VIEW ::Tag:EMVC-SR-VSM-004

1.b: «can contain»

1.c: «can contain / is a»

2.b: «can contain / is a»

View Component

3: «can be addressed by»

Container

List

2.c: «can be»

Container

Tab sheet

1.d: «has internal»

Event Dispatcher

3: «uses»

4: «can be observed by»

Controller

Panel / Page / Dialog / Popup

View

Controller

5.a: «granting access to / working with»

View Code

5.b: «can be»

Hub

ViewModel Object

Operators

State Managers

Injectors

ViewModel

View(Data) Managers6: «working

with»

5.b: «using»

7: «work with»

Page 282: Re Factoring and Design Patterns

282 Peter Kaptein

REFACTORING WITH THE HIERARCHY OF OBJECTS ::Tag:EMVC-SR-VSM-005

OperatorManager

Handler

Value Object

Data Transfer Object

Data Object Dem

oti

on

P

rom

oti

on

Specialization

Code from Your Object

Parser

Utility

Hub

ViewModel Object

NOTES: ::Link:MHOPUDO|RFCT-ELM-SRSP-PRO-MHPDO

Page 283: Re Factoring and Design Patterns

Refactoring and Design Patterns 283

HIERARCHIC FLOW WITHIN THE MHOPUDO IMPLEMENTATION ::Tag:EMVC-SR-MHOP

Operator

Manager

Handler

Parser

Value Object

Data Transfer Object

Data Objects

Your Model

The rest of the world

«can access»

«can access»

«can access»

«can access»

«can access»

Notes: ::Link:MHOPUDO

Page 284: Re Factoring and Design Patterns

284 Peter Kaptein

OVERVIEW OF THE TYPE OF OBJECTS WE USE WITHIN THE

EXTENDED MVC PATTERN

::Tag:EMVC-SR-OVV

GOOD TO KNOW ::Tag:EMVC-SR-OVV-NOTS One approach out of many The diagrams I show in the next pages show only one of many approaches to implement your Model, View and “Controller”. So if you have different views and ideas, do not feel hindered (or intimidated) by what I write. Main aspect: centralization of actions between the different systems What you will find is a centralization of actions between the different systems. One way this is achieved is via the Operator, which is discussed below. Another is the use of Managers, which follow a pattern that is described in detail in the Design Patterns section. The Operator: centralizing communication between systems, Façade and Mediator combined The Operator is basically a combination of a Façade and Mediator. It simplifies access to the (sub) system and centralized communication between elements in the subsystems that usw the Operator. It also act as a “gate keeper” for that subsystem, offering one single point of access that allows you for a clean separation and decoupling of dependencies. The Manager: centralizing communication within the system, Façade and Mediator combined The Manager plays a similar role as the Operator, but then within the system itself. It centralizes all communication for specific tasks and simplifies the access on parts of that system. Apart from that, the Manager has overall knowledge of how the system at large works and what kind of rules should be applied when.

Page 285: Re Factoring and Design Patterns

Refactoring and Design Patterns 285

THE TYPE OF OBJECTS WITHIN YOUR MODEL ::Tag:EMVC-SR-OVV-MOD

1.b: «use»

2.a: «apply»1.a: «apply»

Business Rules

1.c: «work with» 2.b: «use»

Data Objects

3: «can be»

Data Transfer Handler

Populator

2.c: «can be»

Handlers Parser1.d: «can use»

Data Structures

4: «receive and send»

5: «is derived from / parsed

into»

Data Services Managers

Model

Services

6.a: «granting access to»Data Transfer Objects

Utility

6.b: «can be»

Hub

ViewModel Object

Operators

The Value object (VO) or Data object The Value object is completely stupid. Its only function is to contain data. The Data Transfer object (DTO) The Data Transfer object is a specialized Value object and used in general to move Data from one Structure to another. The Operator, Hub or ViewModel object (VMO) The ViewModel object is what we call an Operator in the Extended MVC Pattern. Its main role is to offer a Gateway between the Presentation Layer containing the View and the Controller and the Business Layer, containing the Model. The Operator uses elements from both the Façade and Mediator Pattern, allowing your code inside and outside the Model to directly address specific methods on the Operator and to offer a simplified interface to the specific functionalities within the Model “managed” by the Operator. ::Link:MHOPUDO-OPR The object

Page 286: Re Factoring and Design Patterns

286 Peter Kaptein

The object is your generic all purpose thing and a bit smarter than the VO. It holds data like the Value object and is able to perform specific simple actions. The Handler (…Handler) The Handler is created to perform or “handle” specific but simple actions, like loading files, sending data to the server, and parsing data from one format to another. The Handler is like a specialized machine and only has knowledge of the process it should handle. A smarter version of the Handler is the Manager, which has more knowledge of the Application at large. A more specialized version of the Handler is the Parser. The Parser (…Parser) The Parser is a specialized version of the Handler. Where the Handler can handle any process, the Parser handles specifically the process of Parsing. The Utility (…Utility) The Utility classes usually perform very specific and very generic actions. Where the Parser is still very specific to your requirements, Utilities in general should be useable all over your projects. Typical utilities are to convert Date and Time to specific formats, convert String values to show a capital to each first letter or extract specific data out of text. The Manager (…Manager) The Manager is created to deal with the more complex issues. It usually deals with multiple issues from multiple sources, managing them using specific rules. Managers use and (can) contain the Business Logic and uses the Business Rules of your application. The Populator and Data Transfer Manager These are specific classes you might not need at all. Populators populate a View or Data object with data or objects. Data Transfer Managers manage the transfer of Data from A to B, using Services to get the job done. Game development: adding the Simulation, Actor, Rule and Behavior Games deal with a generated virtual reality that contains Actors, Rules and Behaviors that define that game. We deal with this in the separate chapter on Simulation, Action, Rule and Behavior. ::Link:INTRDP-SARB

Page 287: Re Factoring and Design Patterns

Refactoring and Design Patterns 287

THE TYPE OF OBJECTS WITHIN YOUR SERVICES ::Tag:EMVC-SR-OVV-SER

1.b: «use»

2.a: «apply»1.a: «apply»

Business Rules

1.c: «work with» 2.b: «use»

Data Objects

3: «can be»

Data Transfer Handler

Populator

2.c: «can be»

Handlers Parser1.d: «can use»

Data Structures

4: «receive and send»

5: «is derived from / parsed

into»

Data Services Managers

Model

Services

6.a: «granting access to»Data Transfer Objects

Utility

6.b: «can be»

Hub

ViewModel Object

Operators

The Data Services Data Services can be any Service towards an external data source, including Files and the file system, Databases, Data Services and Remote objects. The Data Structures The Data Structures is what you get back from the remote Data Source and what you send towards that data source. It can be that these Data Structures need to be parsed before they are useable. This can be arranged by the Manager or the Data objects itself.

Page 288: Re Factoring and Design Patterns

288 Peter Kaptein

THE TYPE OF OBJECTS WITHIN YOUR VIEW ::Tag:EMVC-SR-OVV-VW

1.b: «can contain»

1.c: «can contain / is a»

2.b: «can contain / is a»

View Component

3: «can be addressed by»

Container

List

2.c: «can be»

Container

Tab sheet

1.d: «has internal»

Event Dispatcher

3: «uses»

4: «can be observed by»

Controller

Panel / Page / Dialog / Popup

View

Controller

5.a: «granting access to / working with»

View Code

5.b: «can be»

Hub

ViewModel Object

Operators

State Managers

Injectors

ViewModel

View(Data) Managers6: «working

with»

5.b: «using»

7: «work with»

Controllers The Controllers are in most current OOP environments part of the View Components and do not have to be defined separately. Event Dispatchers Instead, to get to know if and what kind of User Event happened (usually mouse and keyboard related) you use Event Dispatchers related to the Controllers. You do this by registering one or more Observers to the Dispatcher. State Managers State Managers manage the State of your View. They determine if objects are visible or hidden, when to change State and how to change that State. Injectors Injectors Inject data into the View and data from the View into objects offered from the Model.

Page 289: Re Factoring and Design Patterns

Refactoring and Design Patterns 289

There are several ways to inject data into the View and from the View into objects from the Model. Each environment will offer you a specific selection and a set of options, including automated Data Binding and writing your own solutions. Operators Operators manage the communication between the different parts of your View and to your Model. The Operators can implement elements from both the Façade and Mediator Patterns, making it a simplified Interface to other systems and an object that can be addressed directly by your code, allowing you to perform actions immediately to it. View Components View Components are Components that represent a very specific and well rounded functionality. For instance: a Calendar object or a List Component. Containers When empty, Containers do not show anything. Their main purpose is to contain View Components. Hence the name: “Containers”. Containers can have Scroll-bars, a title bar and buttons when these elements are common in the Pattern of your application. Pages /Panels / Forms / Dialogs Each and all of these terms define the same type of View object (a Page, Panel, Form or Dialog), but which term you use Depends on the Application Design Principles, you use. Panels are more natural to use for “Pages” which can be moved left and right. Forms are more commonly used for the classic Desktop applications. Dialogs are more like a meta-name for anything you use to have a “dialog” with the Application and include Forms, Panels and Windows.

RELATED TO YOUR CONTROLLER ::Tag:EMVC-SR-OVV-CNT Dispatchers In most, if not all, current OOP environments, the Controller is part of your environment. Instead of you having to define how to get and deal with the input from the user, this is already covered by the components you use. What remains are the Event Dispatchers related to the Controller. You use these to register Event Listeners to, so that when the user does something, like using the mouse or the keyboard, you can act on this in other parts of your code as well.

Page 290: Re Factoring and Design Patterns

290 Peter Kaptein

INVERSION OF CONTROL ::Tag:INTRDP-IOC ::includesubchapters

Page 291: Re Factoring and Design Patterns

Refactoring and Design Patterns 291

DIAGRAMS

::Tag:INTRDP-DIA

NORMAL CHAIN OF CONTROL ::Tag:INTRDP-IOC-DIA-001

Object B Handler A

2: «creates»

Object A

1: «creates»

DEPENDENCIES: Object A: 1: Creates Object B Object B: 2: Creates Handler A

NOTES: Simple to create The normal chain of control is easy to setup. It is the most common way you create your classes and instantiate the objects you use within your Classes. Rigid in setup The setup is quite rigid. If you want to change the object used and created in a subclass, you very likely need to change the code.

Page 292: Re Factoring and Design Patterns

292 Peter Kaptein

INVERSION OF CONTROL AND DEPENDENCY INJECTION ::Tag:INTRDP-IOC-DIA-002

Object B Handler A2: «uses»

Object A

1.b: «creates / injects Handler A into»

1.b: «creates»

DEPENDENCIES: Object A: 1.a: Creates Handler A 1.b: Creates Object B and injects Handler A into Object B Object B: 2.a: Uses Handler A

Page 293: Re Factoring and Design Patterns

Refactoring and Design Patterns 293

BASIC DEFINITION

::Tag:INTRDP-IOC-BAS The Hollywood principle In “Design Patterns”, the basis of Inversion of Control is called “The Hollywood Principle”.

From Design Patterns, GoF: Template Pattern: Template methods lead to an inverted control structure that's sometimes referred to as "the Hollywood principle," that is, "Don't call us, we'll call you". This refers to how a parent class calls the operations of a subclass and not the other way around.

While the “Hollywood Principle” specifically refers to a Parent being in control of the Children, instead of Children calling the Parent object, the concept is what we see in Inversion of Control. Dependency Injection or: Telling the Child which objects to use Instead of Child object to create their own Instances of specific objects, we inject them from the outside in. The “Dependencies are Injected” this way.

SEE ALSO

::Tag: PAT-IOC-SEE Factory Singleton, Multiton and Data Map/Simple Repository Patterns

BENEFITS OF DEPENDENCY INJECTION

::Tag:INTRDP-IOC-BEN Switching objects makes Unit Testing easier Dependency Injection allows you to Inject Mockup objects into your project to simulate specific processes like “get data from the database”. These Mockup objects make it possible to test specific scenarios in a controlled way and see if the application is still behaving as it should. Changing behavior without changing your code or your application Where your Child objects might – at first – use objects they create internally, using Injected objects to do the job might help to make them more flexible in their behavior. Where one object might use Strategy A, another might offer Strategy B for the same process.

The role of Interfaces, Abstract Classes and Base Classes As mentioned in other chapters, the key step is to create some kind of shared Interface, either by using Base Classes, Abstract Classes (so that they are all from the same family) or Interfaces (where all objects share the same contract and expose the same set of Methods).

Page 294: Re Factoring and Design Patterns

294 Peter Kaptein

INVERSION OF CONTROL AND DESIGN PATTERNS

::Tag: PAT-IOC-REL

1: MAPPING AND ABSTRACTING THE CONCRETE IMPLEMENTATION

OBJECT MAP ::Tag: PAT-IOC-OMP Object Map and Inversion of Control One of the simplest ways to support Inversion of Control is by building your Object Map in one place and use the Mapped objects in another. Your Mapper defines which objects will be used in what circumstances and your Concrete Implementation simply requests whatever object you mapped via a shared reference (for instance a Static Constant value). Replacing the objects that do their work One of the main reason to use Inversion of Control is that you can dynamically decide which object and Class will do the work when used in a specific Context. So when you map “MyParserA” against the key “XMLparser”, you can simply replace that parser for “MyParserB” without having to rewrite any code outside your Mapping. Unit testing For this reason, Inversion of Control is quite popular in Unit Testing. With Unit Testing, you perform specific tests against specific components. And to allow these tests to be limited you sometimes replace specific Classes and objects for dummy-Classes that allow you to test against (for instance) predictable data-sources. By changing the mapping of these objects for the ones you want and need for the Unit Tests, you can easily test the code without any deep changes to the application or the code.

COMMANDS ::Tag: PAT-IOC-OMP Commands and Inversion of Control The Command supports Inversion of Control in a different way as the Object Map does. And Inversion of Control by using Command leads to an entirely different implementation than using Object Maps. With Commands, you abstract the Concrete Implementation from the code that will execute that Command. Instead of sending and using objects to do the work, you send and use Commands that contain that Concrete Implementation. Replacing the objects that do their work You can change the Concrete Implementation by injecting a different object into the Command. Even though everything seems to be the same and no line of code needs to be changed in your Application, the entire way of working can change when you change “MyWorkerA” for “MyWorkerB” within the Command you make available. Unit testing Like with the Object Map, applications build around the Command Pattern allow for an easy change in the Concrete Implementation of specific process, by changing the mapping of objects within your Commands.

Page 295: Re Factoring and Design Patterns

Refactoring and Design Patterns 295

Commands using the Object Map

2: WRAPPERS AND DELEGATORS

BRIDGE ::Tag: PAT-IOC-BRI Bridge and Inversion of Control

Delegate using the Object Map

STATE ::Tag: PAT-IOC-STT State and Inversion of Control

State using the Object Map

DELEGATE ::Tag: PAT-IOC-DEL Delegate and Inversion of Control

Delegate using the Object Map

STRATEGY ::Tag: PAT-IOC-STR Strategy and Inversion of Control

Strategy using the Object Map

PROXY ::Tag: PAT-IOC-PRX Proxy and Inversion of Control

Proxy using the Object Map

3: WRAPPERS/MANAGERS OF SUBSYSTEMS

FAÇADE ::Tag: PAT-IOC-FCD

Page 296: Re Factoring and Design Patterns

296 Peter Kaptein

Façade and Inversion of Control

Façade using the Object Map

MANAGER ::Tag: PAT-IOC-FCD Manager and Inversion of Control

Manager using the Object Map

OPERATOR ::Tag: PAT-IOC-FCD Operator and Inversion of Control

Operator using the Object Map

4: FACTORIES AND BUILDERS

FACTORY ::Tag: PAT-IOC-FCT Factory and Inversion of Control

Factory using the Object Map

BUILDER ::Tag: PAT-IOC-BLDR Factory and Inversion of Control

Factory using the Object Map

5: PATTERNS AND OBJECTS THAT CAN BE MAPPED

CONCRETE PARSERS

CONCRETE DIRECTORS AND BUILDERS

CLASSES FOR INSTANTIATION BY FACTORIES

Page 297: Re Factoring and Design Patterns

Refactoring and Design Patterns 297

CONCRETE FACTORIES

CONCRETE STRATEGIES

CONCRETE IMPLEMENTORS FOR BRIDGE AND DELEGATE

CONCRETE MANAGERS

CONCRETE OPERATORS

CONCRETE MEDIATORS

Page 298: Re Factoring and Design Patterns

298 Peter Kaptein

BONUS MATERIAL

::Tag:INTRDP-IOC-BNS

MAPPING: ABSTRACTION OF OBJECT CREATION ::Tag:INTRDP-IOC-DIA-003

Object A

1.b: «creates»

Map B

4.b: «is inserted in»

3: «instantiates»

Object B

2.b: «uses reference to retrieve Handler A from»

2.a: «has a reference to»

Interface D

4.a: «implements»

Object C«Handler A»

Object X

Your application The Mapping process for Objects

DEPENDENCIES: Object B: 1: Creates Object C Object C: 2.a: Has a reference to “Handler A” 2.b: Uses reference to retireve “Handler A” from Map B Object A: 3: Instantiates “Handler A”, which is in concrete “Object X” Handler A: 4.a: Implements Interface D 4.b: Is inserted in Map B

Page 299: Re Factoring and Design Patterns

Refactoring and Design Patterns 299

NOTES: Abstraction of Object Creation In this approach to Inversion of Control, the Object Creation is abstracted from the Application. The main benefit is that to change the behavior or objects used in the Application can be done without changing the code that does the actual work. Making testing and changing objects easier. Still Inversion of Control The Control over object Creation for specific use is now completely extracted from the Application. While the objects might be picking up the Concrete objects from the Map, it is still the Parent creating and Injecting that object: via a shared bus in the shape of the Map. Using the Interface as a reference Most modern languages can use the Reference of the Interface to register, map and retrieve the Concrete object that will be used. The idea is that the Interface “is” the Concrete object by representation and that only one of all possible Classes will be used to represent the Interface. Using a Constant Value as a reference Instead of using a quite rigid reference to the Concrete object (only one Interface and many different possible instantiations) you can also map the objects to a String Value. Singletons versus object Creations Many objects used in Inversion of Control are Singletons: Handling a specific process. The benefit is that you only have to instantiate one object to do all similar work. The disadvantage is that you can not store State information per User in the shared object. To overcome this limitation, the Injected “object” can also be the Class Reference itself: being instantiated when the User calls that “object” from the Map. Factory and Strategy The process described here, can be implemented in the Factory and Strategy Patterns. Both can use an interface on the objects they instantiate to create either a new object, or return the one single Instance of that object if it just deals with stuff and does not store Internal Values (keeps state) based on your actions.

Page 300: Re Factoring and Design Patterns

300 Peter Kaptein

SIMULATION, ACTOR, RULE, BEHAVIOR ::Tag:INTRDP-SARB ::includesubchapters

Page 301: Re Factoring and Design Patterns

Refactoring and Design Patterns 301

PART 8:

CLASSIFICATIONS OF

DESIGN PATTERNS

Page 302: Re Factoring and Design Patterns

302 Peter Kaptein

::Tag:CLSDP

THE “GANG OF FOUR” DESIGN PATTERNS ::Tag:PAT-CLASS

Page 303: Re Factoring and Design Patterns

Refactoring and Design Patterns 303

CREATIONAL PATTERNS

::Tag:PAT-CLASS-CREA From: “Design Patterns” Creational design patterns abstract the instantiation process. They help make a system independent of how its objects are created, composed, and represented. A class creational pattern uses inheritance to vary the class that's instantiated, whereas an object creational pattern will delegate instantiation to another object.

STRUCTURAL PATTERNS

::Tag:PAT-CLASS-STRU To be written

BEHAVIORAL PATTERNS

::Tag:PAT-CLASS-BEH To be written

Page 304: Re Factoring and Design Patterns

304 Peter Kaptein

PATTERNS ORDERED BY TYPE AND USE ::Tag:PAT-TYP ::Settings:include parent navigation in subchapters Finding patters by type and use Each Pattern is of one or more types and has one or more specific uses when you apply them in your code. This chapter is an attempt to create an overview of these uses and types to help you find specific Patterns with your needs as the point of entry. Each “type and use” group contains all the Design Patterns I think cater that specific use. Explore them to see what might comply to your needs.

1: Wrapping, Interfacing and abstraction Wrapping and abstraction are maybe one of the most common actions in OOP, to decouple dependencies, make your code more agile / ready for change and separate the different roles and dependencies within your code. I distinguish two types of wrappers: of objects and of Subsystems. ::Link:PAT-TYPWR 2: Delegation of actions The second most popular action in OOP is to delegate actions to code within a Method or even to code within an entirely different Class or object. I distinguish three types of Delegation: of all actions, of specific actions and to subsystems. ::Link:PAT-TYPDEL 3: Creation of dynamic classes In some cases, hardcoding your actions within a Class will not do anymore. The Class itself needs to be able to adapt its behavior to the Context that part of the application is in. I describe three approaches that achieve this goal: dynamic classes and objects, dynamic execution of actions and dynamic extension of possibilities. ::Link:PAT-TYP-DCL 4: Creation of objects and complex structures Next, we have Patterns that help you create objects and complex structures. Included in this chapter are also Patterns that help you read and use these structures. I distinguish two main directions: creating and instantiating objects and creating and reading complex objects. ::Link:PAT-TYP-CR 5: Sharing and re-using objects Some Patterns do just that: to help you share and re-use objects. The reasons might be different, from saving memory space to a simplification of your application model and more advanced ways to de-couple dependencies. Currently there is only one group. ::Link:PAT-TYP-SH 6: Events, instructions and communication While we can define all kinds of neat tricks to organize things and delegate actions, what Patterns help us the facilitation of communication between objects in our project? This chapter collects all that I know. I distinguish to approaches: direct communication between objects and decoupling dependencies. ::Link:PAT-TYP-EVTS

Page 305: Re Factoring and Design Patterns

Refactoring and Design Patterns 305

7: Data and data transfer The moment you start communicating with any external system, whether it is to store data on a hard drive, send data to a database or send data over a network, you will find some starting points in the Patterns in this chapter. As data is not only retrieved, but usually also in a format that is not immediately useable, I included Patterns that help you translate that data. I distinguish three subjects: injecting values into other objects, storing and retrieving data and objects and working with external data sources. ::Tag:PAT-TYPDA

Finding specific Patterns by name If you want to find specific Patterns by name, go to Part 9, which lists all Design Patterns I wanted to include (and thought to be useful) in this book. They include all 23 Gang of Four Desing Patterns and 7 additional Patterns I either found in my work or are used by Java and C# communities. ::Link: PAT Find their place If you are new to Design Patterns, I hope this chapter will help you to understand where to find and place what Pattern. Patterns with multiple roles and uses Some Patterns implement more than one principle. For instance: the Bridge and State Patterns are both wrappers, delegates and dynamic objects or classes. Reference to their full description Each Pattern has a reference to its full description in Part 9 of the book. Reference to additional information As some Patterns use specific Design Principles I added references to these principles as well. Word of advice: follow your instincts If you are new to Patterns, do not force yourself to implement Design Patterns you do not fully understand yet. Learn from what is written here, get inspired and implement what you think is right. Also, feel free to follow your own instincts and not implement any Design Pattern at all. Build, refactor and see what emerges as described in: “The steps in a refactoring process” ::Link:RFCT-BAS-WHT –STPS|RFCT-DPT

Page 306: Re Factoring and Design Patterns

306 Peter Kaptein

PATTERNS AND THEIR USE

::Tag:INTRDP-GMDV-DPT

MAPPING AND CREATING OBJECTS ::Tag:INTRDP-GMDV-DPT-001 Singleton, Multiton, Object Map : Map and store objects for easy access and re-use To keep score, to keep score on specific objects or per player. With Singleton and Multiton you create one or more objects that can be shared throughout your Application without having to pass it to any and all objects in your code. The Object Map goes one step further in creating a Map of all your objects and allowing you to traverse through that map as a list, or recall specific objects like the Multiton does: to perform specific actions on that object Factory Method, Simple Factory and Abstract Factory : create objects of specific types when needed The Factory in general allows you to create one or more Context specific objects (the Product) that all share the same Interface and basic functionalities. In that way you can – for instance – create a Base Enemy Class and Specialize that Enemy into different type of Enemies with each their own behavior, looks and whatever other properties they have.

CREATING (COMPLEX) OBJECT STRUCTURES ::Tag:INTRDP-GMDV-DPT-004 Composite, Interpreter, Builder, Parser : build complex object structures Composite objects are objects created by using other objects. Any object you will use in a game is a Composite of some kinds. The Parser and Interpreter are like a Builder, using some kind of definition (XML, HTML or whatever you can make up) to create any kind of structure it can. The moment you start using definition files to build your virtual worlds, you use Composite and Interpreter. But Composite and Interpreter can also be used to define the game rules and the way virtual players and virtual objects respond to specific actions

READING COMPLEX STRUCTURES ::Tag:INTRDP-GMDV-DPT-004 Parser, Visitor, Iterator : run through an object structure and perform the actions you need The Parser, Visitor and Iterator can all be used to read complex structures. All allow you to change the actions to be performed when you traverse the object structure by changing the object that does the actual work. Within the Visitor Pattern this is the Concrete Visitor itself. With the Parser and Iterator you will need to implement a Concrete Handler which you either inject or set beforehand on the Parser. Both the Iterator and the Visitor require you to implement specific methods on the objects you traverse.

DYNAMIC (POLYMPORPIC) CLASSES ::Tag:INTRDP-GMDV-DPT-002 Strategy, State and Bridge : Change behavior when needed Strategy and Bridge allow you to choose a specific way to deal with a specific Process. For instance: when one of your virtual players is in situation A, its behavior to a specific situation will be Behavior A. However when the situation (or Context) changes to B, the behavior and Response of the virtual player will change accordingly.

Page 307: Re Factoring and Design Patterns

Refactoring and Design Patterns 307

State and Bridge both allow you to change the Encapsulated behavior of an object directly, by changing the object it Encapsulated and pretends to be. Strategy is more a Factory for Behavioral Patterns or ways to deal with a Process, delivering a Strategy instead of a Product.

COMMUNICATION BETWEEN OBJECTS IN THE PROJECT ::Tag:INTRDP-GMDV-DPT-003 Observer : observe events in your system and respond where needed The Observer pattern is the basis of events and event driven systems. With the Observer pattern you register an Observer to a Subject or Dispatcher using a specific Event Handle. When the Dispatcher dispatches an event with that handle, each observer on that event handle will receive a notification. The big benefit of the Observer pattern is that you can decouple any system from any other system, allowing you to create independent code blocks which deal with specific processes and then dispatch an event to notify whomever and whatever that they are done. One big risk that comes with the Observer pattern is that your system becomes so dis-attached that it is no longer clear who sent what dispatch why and when. Leading to seemingly irrational behavior of your application. In most cases I dropped the Observer pattern in favor for Object Maps, variations on the Mediator and Façade patterns (the Manager and Operator) and using lists of objects which I explicitly address from the “Dispatcher” or a Mediator. Façade, Mediator, Operator, Manager : centralize communication and simplify the use of your subsystem Façade and Mediator both have a similar intent: to work with and talk to multiple objects and Classes to get a specific job done. The Operator and Manager patterns are derived from the Façade and Mediator: merging the two into a more versatile solution that combines the best elements of both. The difference between Façade and Mediator is that the Façade is using a Master/Slave kind of approach, where the Façade delegates every action to the subsystem, while the Mediator follows a more Democratic process in which each Actor can actively call the Mediator and the Mediator will put the request through to anyone who might be able to answer it. Commands : send objects into the world to have specific actions performed when needed Commands are a bit like packaged event handlers. Within each Command, which has a simple Interface shared over all Commands you use (starting with the method: “execute”), you implement the specific code you want to have executed on a specific object or class. In this, Commands are one way to extract code from your classes and package them in a different class, with only a very specific task: in this case your Command. The way Commands can be implemented varies. Best is to keep it limited. Chain of Responsibility The Chain of Responsibility goes well together with the Composite pattern. The Chain of Responsibility is basically a loop traversing through your object tree until it finds something or someone who can fulfill the Request it has (the one “responsible”). This can be handy when your virtual character hits an object or creates a chain reaction.

Page 308: Re Factoring and Design Patterns

308 Peter Kaptein

Chain of Responsibility traverses from a child to a parent up, seeking a more and more generic solution or answer for the request it has been given.

COMMUNICATION WITH OTHER SYSTEMS ::Tag:INTRDP-GMDV-DPT-004 Proxy Proxies Represent objects which are not there yet. The Proxy is used most in game development to save memory and postpone the instantiation of objects (which can be very heavy on code and memory) until the very last moment. Think of virtual players and buildings living in certain locations in your virtual world. As long as your player does not visit those places, there is no need to instantiate them. On the other hand: you do want to have some representation of those elements present. For instance to store and respond to changes in your virtual world that will be needed later when you show them, like a storm, or damage inflicted by bombs dropped by the player or other virtual players. The main benefit of the Proxy is that you can set all kinds of values on an object while it does not exist yet, while keeping the memory-requirements extremely low.

Page 309: Re Factoring and Design Patterns

Refactoring and Design Patterns 309

WRAPPING, INTERFACING AND ABSTRACTION

::Tag:PAT-TYPWR

TYPE 1: WRAPPERS OF OBJECTS AND CLASSES ::Tag:PAT-TYP-WR Main intent: man in the middle, translating and directing communication A Wrapper envelops and abstracts the actual functionalities you will access to perform the actions. It will act as a “man in the middle” to translate requests from your code to something the wrapped class and object can understand and translate the return values to something your code can use. Abstraction of actions, implementations and interfaces The wrapper allows you to abstract the concrete implementation of specific actions, objects and classes. Normalized interface In some cases, your project can and will involve Classes and objects already defined by someone else. While they are good as they are, they might need some adaptations to make them work within the flow that you are using. Wrappers allow you to change the Interface of a Class and object by wrapping it in additional code within a specific wrapper Class. Type 1: Object wrapping Object wrappers use an already instantiated object that is either injected or instantiated by the wrapper itself. When the object is instantiated by the Wrapper itself, probably a Factory or Object Map is used. Type 2: Class wrapping Class wrappers extend the original Class and wrap the methods and variables of that Class in new methods that comply to your needs. Adding functionalities, delegating things to other objects When needed in your project, a wrapper can add extra functionalities, including extra methods and delegating some actions that can not be performed by the wrapped class or object to other (helper) classes and (helper) objects. See also: the Wrapper family tree The Wrapper Family Tree shows the various variation on the Wrapper theme and the relationships and differences for each Wrapper. ::Link: WRIA-REL-001

Page 310: Re Factoring and Design Patterns

310 Peter Kaptein

1: ADAPTER ::Tag:PAT-TYP-WR-ADP : Adapter as wrapper

+ someMethodA( ): do something return result

«class»Adaptee

Client

+ desiredMethodA( ): do something execute someMethodA() do something else

Adapter A

1: «addresses object of type»

3: «delegates actions to»

2: «adapts»

Wrap and adapt the interface of existing Obejcts and Classes to your needs

4: «leading to»

Visual summary of the Adapter Pattern ::Link: PAT-ADP Wrapping an object and class to adapting/change the Interface Adapters adapt the Interface of a Class or object. This means that whatever methods are on the original object (the Adaptee) and whatever they return, will be wrapped in new methods and (where needed) translated to conform both the needs of your code in your project and to the needs of your adapted Class or object. Type 1: Object adapters Object Adapters adapt an object by placing it inside a variable. The adaptation takes place by delegating the requests received on the Adapter to the wrapped object. Any response from the wrapped object is returned to the caller. Type 2: Class adapters Class Adapters extend the Class that needs to be adapted to the needs of your project. By extending the Class, you can add the methods you need to perform and then call the concrete methods on the Class you are adapting. Adding functionalities is possible, not an intent As discussed before, where needed, the Adapter can add new functionalities which are not present in the Adapted class or object, in order to conform to the interface and requirements of the code in your project. However allowed, and sometimes needed, this is, this is not the main intent of the Adapter.

Page 311: Re Factoring and Design Patterns

Refactoring and Design Patterns 311

2: DECORATOR ::Tag:PAT-TYP-WR-DEC : Decorator as wrapper

Decorator A

+ yourMethodA: extended add extra functionalities execute: yourClass.yourMethodA()+ yourMethodB: extended do something extra execute: yourClass.yourMethodA()

Decorator B

1: «can be wrapped by any»

2: «can be wrapped by any»

+ yourMethodA(): extended+ yourMethodB(): extended

Main Interface / Base Class

3: «share the same»

Your Class

+ yourMethodA(): do something+ yourMethodB() do something else

variables

procedures

+ yourMethodA():+ yourMethodB()

Extended functionalities

4: «leading to»

Visual summary of the Decorator Pattern ::Link: PAT-DEC Wrapping objects to extend their possibilities The Decorators main intent is to extend (and change) the possibilities of existing objects, by acting as a man in the middle. Each request can be handled specifically the Delegate before and after passing the request through to the object it decorates. Adding functionalities When you wrap an object within a Decorator, you do this in order to add extra functionalities. These functionalities can be, for instance, new methods or new elements to be shown on screen. Nesting decorated objects The Decorator Pattern allows you to nest Decorated objects within new decorators, allowing you to dynamically add new functionalities as you go.

Page 312: Re Factoring and Design Patterns

312 Peter Kaptein

3: DELEGATE ::Tag:PAT-TYP-DEL-DEL : Delegate as wrapper

+ someMethodA( ): do something return result

Delegate A

Client

+ delegateMethodA( ): do something delegate.someMethodA() do something else

Delegator A

1: «addresses»

3: «delegates actions to»

2: «instantiates / uses either»

+ someMethodA( ): do something else return result

Delegate B

Visual summary of the Delegate Pattern Wrapping handlers to delegate everything to a target Delegate object The Delegate is mostly an empty pass-through station, passing calls for action through to the Delegation target object. The real actions and results are performed and returned by the target object. One Delegate can have multiple methods One Delegate can have multiple methods to do the delegation of specific actions. Each method can use a specific Delegate Each Method you call on a Delegate can use a specific Delegate object for that specific purpose. Per method and action, several alternatives can be used The Delegate (or you) can choose a specific object form a specific Class to handle that specific request. This means that you are not stuck to specific implementations to handle specific processes within your Delegate. Alternative for sub-classing Like the Bridge and the Strategy, the Delegate can be used as an alternative for subclassing when only the functionalities behind the methods change. Inject or select? The Delegate can either receive the target object by injection from your code, or by selecting one internally based on some kind of Context. Using a Factory or Object Map When your Delegate instantiates the objects it delegates the actions to, you can use either a (simple) factory or a Object Map. The Object Map can store concrete objects to specific keys you can offer as a context to the Delegate.

Page 313: Re Factoring and Design Patterns

Refactoring and Design Patterns 313

4: STATE ::Tag:PAT-TYP-DEL-STT :State as wrapper

Context

+ request()

+ setState( stateOject )

Concrete State A

+ handleRequest()

- stateObject

Concrete State B

+ handleRequest()

A self-organizing delegator that defines internally which concrete implementation should handle the next state of the process

4: «leading to»

«state object»

1: «contains»

2: «is handled by current»

5: «sets next state object via»

3: «has reference to / can inject another state object into»

4: «has knowledge of other»

Concrete State C

+ handleRequest()

::Link: PAT-STT Wrapping self-regulating dynamic execution The State Pattern wraps a Concrete State object which can replace itself for any other State object within the same family. Delegating the execution to another object The State Pattern explicitly delegates all actions from the Context object to the State object. The Context usually has no code that handles specific processes. Using a Object Map to store and select State objects When your State objects instantiate or choose the next State object to take over the actions to, you can choose to use a Object Map instead of hardcoded access to the State objects you might want to use. The Object Map can store concrete objects to specific keys you can offer as a context to the Delegate. ::Link: PAT-STT| PAT-DTMP

Page 314: Re Factoring and Design Patterns

314 Peter Kaptein

5: BRIDGE ::Tag:PAT-TYP-DEL-BRI : Bridge as wrapper

Base Abstraction

+ operationA()+ operationB(parameter)+ setContext(contextID)

+ operationA()+ operationB(parameter)

«class / object»Concrete Implementor

2: «contains»- implementor

RefinedAbstraction

+ operationC()

«Bridge»

4: «can be extended to»

3: «delegates actions to»

1: «can change»

A visual summary of the Bridge Pattern ::Link: PAT-BRI Wrapping a Concrete Implementor The Bridge wraps the Concrete Implementor, which will execute every action you request to the Delegator. Bridge can change the Concrete Implementor When needed, the Bridge can change the Concrete Implementor. This can either be due to a specific (goven) Context or due to business rules within the Bridge Abstraction Class. Intent: to adapt and be extended The main intent of the Bridge is to bundle and adapt one or more variations on a process into one single class. The second intent of the Bridge is to be and become extended by subclasses.

Page 315: Re Factoring and Design Patterns

Refactoring and Design Patterns 315

6: PROXY ::Tag:PAT-TYP-DEL-BRI : Proxy as wrapper

Real Subject A

Proxy

- realSubject+ variableA+ variableB

Client

- proxy

+ doSomething()+ doSomethingElse()

1: «contains»

+ methodA( )+ methodB( )

+ methodA( )+ methodB( )

+ variableA+ variableB

2: «will contain»3: «execute»

5: «will be delegated to»

4: «will be passed to»

Visual summary of the Proxy Pattern ::Link: PAT-PRX Wrapping the (not yet existing) Subject The Proxy is a “stand in” for the actual object you want to perform actions on. It wraps that object and delas with all communication to that object via the Proxy interface. In many ways the Proxy resembles the Object Adapter. Object might not be there yet As this object (the Real Subject) might not be there yet when you request a specific action (or set a specific value), the Proxy might act as a buffer, waiting for the real object to be there and then perform the required actions. Four types of Proxies There are four types of Proxies: the Remote Proxy, the Protection Proxy, the Virtual Proxy and the Smart Reference.

The Remote Proxy The Remote Proxy takes care of Remote objects. The Protection Proxy The Protection Proxy acts as a “gate keeper” for the real object, for instance implementing extra security layers over the object you want to approach and use. The Virtual Proxy The Virtual Proxy (in general) represents an object that is not there yet (like an image that is to be loaded) The Smart Reference

Page 316: Re Factoring and Design Patterns

316 Peter Kaptein

The Smart Reference handles with all kinds of extra book-keeping on an object you use and instantiate: to allow more control over the creation and destruction of objects.

TYPE 2: WRAPPERS OF SUBSYSTEMS ::Tag:PAT-TYP-WRSS Wrapping a subsystem? When do you wrap a subsystem and what does that mean? Like the object and class-wrappers, Wrappers of subsystems abstract the processes that happen behind the scenes. They offer you a simplified interface to work with and deal with all complex reeling and dealing behind the methods you call upon. Main intent: single point of entry for complex behavior A Wrapper envelops and abstracts the actual functionalities you will access to perform the actions. It will act as a “man in the middle” to translate requests from your code to something the wrapped class and object can understand and translate the return values to something your code can use. Abstraction of actions, implementations and interfaces The wrapper allows you to abstract the concrete implementation of specific actions, objects and classes. Hub: alternative definition of man in the middle Instead of talking of a “man in the middle” you will find the use of the word “Hub”, as in a “spoke and hub” construction. The Hub is the central place where all communication will come together and that will direct all successive actions. Total control: Pure Hub/Spoke implementation A pure Hub implementation will not allow any communication to happen between the different objects it connects. The Façade is an example of such an implementation. Whatever the Façade needs and requests and whatever combination of actions is required from the subsystem, all is directed by the Façade. The Mediator can be implemented as such too, but allows for more freedom, letting the subsystem solve specific things on its own and mainly operates as a decision-maker on what should happen next. Release of control: Dirty Hub/Spoke implementation The dirty Hub/Spoke implementation is less top-down as the Pure Hub/spoke implementation. While there is one single point of entry and one single point where communication comes together, the subsystem itself is allowed to make certain decisions otherwise made inside the Hub and objects within the subsystem are allowed to communicate to other objects in that subsystem. The Hub only receives updates on crucial parts, based on a “need to know” basis. The Manager and Mediator both allow for this kind of implementation.

Page 317: Re Factoring and Design Patterns

Refactoring and Design Patterns 317

1: FAÇADE ::Tag:PAT-TYP-WRSS-FCD : Façade as wrapper

1: «execute actions on»

4: «does stuff inside»

2: «refer to objects within»

Simplification of calls to- and actions on the subsystem

5: «leading to»

Façade

+ operationA()+ operationB(parameter)+ operationC()

- objectReferenceA- objectReferenceB- objectReferenceC

«subsystem»

Object from Class A

Object from Class B

Object from Class C

3: «delegate actions to»

Visual summary of the Façade Pattern ::Link: PAT-FCD Wrapping subsystems The Façade deliberately use the Subsystem to get things done. Intent: simplification of access to the subsystem The main intent is to simplify access to specific functionality within that subsystem. Delegation of actions to subsystems Facade, Mediator, Manager and Operator are four Patterns that use Delegation to a subasystem to get things done. Using a subsystem as a consequence of OOP The Bridge, Delegate and Strategy Pattern focus on one specific object or class to get things done. Calling and using other (helper) objects is a side-note and usually the result of using OOP principles.

Page 318: Re Factoring and Design Patterns

318 Peter Kaptein

2: MEDIATOR ::Tag:PAT-TYP-WRSS-MED :Mediator as wrapper

3: «has references to»Concrete Mediator

+ yourMethodA(): do something+ yourMethodB() do something else

Centralization of communication between objects in your subsystem

5: «leading to»

«colleagues in subsystem»

Concrete Collegue A

Concrete Collegue B

2: «have references to»

4: «communicate to»

5: «delegates actions to specific»

Client

1: «uses»

Visual summary of the Façade Pattern ::Link: PAT-MED Should it be here? The question is of the Mediator should be in this classification as a wrapper of subsystems. In almost all cases, the wrapped objects and subsystems have no knowledge of the wrapper and in almost all cases the wrapper directs instead of mediates. “Wrapping a system” by offering a single point of entry Because the Mediator is a communications hub, it can be used (and is used) as a single-point of entry to an entire subsystem. Request, action, callback Where the Façade directs, the Mediator requests, the subsystem acts and then calls back to the Mediator. Observing the subsystem: top down / bottom up To be able to know what is going on within the subsystem, the Mediator can register Observers to specific objects within that subsystem. Whenever something happens within that subsystem, the Mediator can respond and ignore it or take successive actions based on (business) rules. Injecting itself into the subsystem: moving to bottom up It is possible that the best way for your system to work is by injecting the Mediator into the subsystem. By doing so, the subsystem becomes the active player and the Manager simply responds when needed. Using Static methods to resolve the Mediator: simplification of your code

Page 319: Re Factoring and Design Patterns

Refactoring and Design Patterns 319

The disadvantage of Dependency Injection is that you still have a top-down approach where one point in your code needs to know which objects required your Mediator. You can turn this chain of control around by calling directly on the Mediator Class and have the Mediator return the appropriate Mediator for the Context that code is operating in. ::Link: PAT-MED|PAT-OBS|PAT-IOC

3: MANAGER ::Tag:PAT-TYP-WRSS-MGR : Manager as wrapper

Manager A Subsystem B

Your Class

1: «uses»

2.a: «addresses»

Business Logic

2.b: «uses»

3: «can address»

Visual summary of the Manager Pattern ::Link: PAT-MGR Combining the best of Mediator and Façade Mediator and Façade have a completely different way of “wrapping” a subsystem. Where Façade uses a pure top-down Hub/Spoke implementation, the Mediator is “part of the gang” and mediates the communication between the objects within that subsystem. In some cases you want to use both the directive top-down approach of the Façade and the “bottom-up” approach that can be used with the Mediator: where the objects in the subsystem are allowed to directly call the Mediator. The Manager is such a merge. It allows for a combination of top-down and bottom-up approaches without messing things up. Top down: pure Hub Like the Façade, the Manager can be implemented as a top-down system where it directs all actions. Part of the gang: dirty Hub Like the Mediator, the Manager can be used as a man in the middle for communications between objects in your subsystem. Always three players The Operator assumes there are always three players: Your Class and your code, a Subsystem it is intimately familiar with (and acts as a Mediator for) and a Subsystem that it approaches selectively using the Façade. In MVVM (Model, View, ViewModel)

Page 320: Re Factoring and Design Patterns

320 Peter Kaptein

“Subsystem C” can be the Applicaton Model while Subsystem B is the ViewModel and Your Class is the View Component that requires communication with subsystems. Observing the subsystem: top down / bottom up Like the Mediator, to be able to know what is going on within the subsystem, the Manager can register Observers to specific objects within that subsystem. Whenever something happens within that subsystem, the Mediator can respond and ignore it or take successive actions based on (business) rules. Injecting itself into the subsystem: moving to bottom up Like with the Mediator, you can inject the Manager into the subsystem. By doing so, the subsystem becomes the active player and the Manager simply responds when needed. Using Static methods to resolve the Mediator: simplification of your code The disadvantage of Dependency Injection is that you still have a top-down approach where one point in your code needs to know which objects required your Mediator. You can turn this chain of control around by calling directly on the Mediator Class and have the Mediator return the appropriate Mediator for the Context that code is operating in. ::Link: PAT-MGR|PAT-OBS|PAT-IOC

Page 321: Re Factoring and Design Patterns

Refactoring and Design Patterns 321

4: OPERATOR ::Tag:PAT-TYP-WRSS-MG : Operator as wrapper

Operator A Subsystem B

Your Class

1: «uses»

2.a: «addresses»

2.b: «uses / delegates to»

3: «can address»

Subsystem C

Visual summary of the Operator Pattern ::Link:MHOPUDO-OPR Wrapping a subsystem like a Façade and Mediator The Operator wraps a subsystem combining the possibilities of a Façade and Mediator, allowing for simplified access to that subsystem and centralization and the mediation of communication of objects within that subsystem. Delegating to another subsystem The Operator is a man in the middle for at least two subsystems: connecting them together. The Operator delegates explicitly to one (subsystem C) and uses and mediates with the other (subsystem B). Specialized Manager, man in the middle The Operator is the man in the middle between one subsystem and another. Connecting View to Model Within the scope of this book, the Operator is mainly used to connect a View to a Model, following the principles of MVVM (Model View, ViewModel) and MVP (Model View, Presenter) where the “Controller” is the hub between the Model and the View. ::Link:MHOPUDO-OPR|MVC-PATT-CHUB

Page 322: Re Factoring and Design Patterns

322 Peter Kaptein

BONUS MATERIAL: RELATIONSHIPS BETWEEN THE PATTERNS ::Tag: WRIA-REL

THE WRAPPER FAMILY TREE ::Tag: WRIA-REL-001

Adapter BridgeDelegate

Object WrapperFactory/Strategy-

Wrapper«is based on»

«can be either»

Can add extra functionalities

Can change internal Object when needed

Represents / pretends

Can do /use late instantiation

«is based on»

As a principle

Extended as Base Class

Uses / can use injected Objects

Functionality Wrapper

«is a spedcialization of»

Facade

Mediator

Manager

Inje

cts i

tsel

f in

the s

ubsyst

em

Stays

out o

f

subsy

stem

“Wra

ps”

subsy

stem

Uses

Observ

ers

Is ca

lled

direct

lyIn

terp

rete

s and

take

s act

ion

Notifications from subsystem?

Relationships with subsystem?

Main role?

Passes

inst

ruct

ions

Interpretes / takes action

Wrapper

«is a specialization of»

«is based on»

Class Wrapper

«can be either»

«is a specialization of»

CommandDecoratorState Proxy

«is based on»

Page 323: Re Factoring and Design Patterns

Refactoring and Design Patterns 323

RELATIONSHIPS BETWEEN FAÇADE, BRIDGE, STATE AND MEDIATOR ::Tag: WRIA-REL-003 Façade, Mediator, Bridge, State: wrapping and abstracting processes and behaviors Looking beyond the scope of this section (state is also part of group the group of Patterns dealing with Choice), the State Pattern Wraps and Abstracts the process it represents. This makes it relevant and interesting to compare State here with Bridge, Mediator and Proxy. Façade and Mediator: fixed objects, fixes subsystems Both Façade and Mediator represent fixed objects and fixed processes. The objects taking care of the Processes will not change. Both wrap and represent a Subsystem that does the actual work. Both Abstract the processes they represent. Where Façade is a Top Down approach and disconnects and decouples the Subsystem, not allowing any of the elements in the Subsystem to call the Façade, the Mediator allows for interaction by the Subsystem to the Mediator and the Subsystem is tightly coupled to the Mediator. Bridge and State: choice, change the Represented objects and processes during runtime Bridge and State both represent Choice and allow you to Change the objects they represent, based on either State or Context . Both Abstract the real process and hide it behind a Concrete object that does not change. Both can change their behavior during Runtime by choosing a different object to execute the process they represent. Where Bridge makes a choice based on a Top Down model: by some external impulse, State can and will change due to actions within the State object itself (Self regulating instead of Top Down). Both have a unique quality compared to the other Patterns in this section: they can change their Internal Working as your application runs, adding a Dynamic aspect to your Wrapping and Abstraction process Façade and Bridge: Top Down, not known in Subsystem , can represent processes and products Both use a Top Down approach to define what is bound to what. Both are decoupled from the Subsystem or object they represent. Both Abstract the real process. There are no dependencies to the Façade or Bridge in the Subsystem and the Subsystem can be used and exist elsewhere without the Façade or Bridge that implements it. Façade and Bridge can used to represent both Processes and Products. Mediator and State: dependencies in the subsystem, Self-regulating, process centered Both Mediator and State are self-regulating or Decentralized Patterns. Mediator uses a Man in the Middle or Hub approach and mainly takes action when it receives calls form the Subsystem. Based on these calls, the Mediator “mediates” the next step to be done by the Subsystem. Within the State Pattern, the State objects decide which other State object will pick up the next event and then Injects that State object into the Container of the State. Mediator and State are specifically Process Centered. Where Mediator Mediates / Manages complex processes multiple Classes and Multiple objects of sub-systems, State is mainly focused on managing itself. With the Mediator Pattern, the Subsystem is dependent on the Mediator to work. This makes that Subsystem tightly coupled to the Subsystem. The State Pattern is similar in this to the Mediator, but mostly for and between the State Classes of the State Pattern.

Page 324: Re Factoring and Design Patterns

324 Peter Kaptein

RELATIONSHIPS BETWEEN ADAPTER, DECORATOR, BRIDGE AND PROXY ::Tag: WRIA-REL-004 Adapter, Bridge, Decorator, Proxy: representing another object All four Patterns are made to represent another object that is either created internally (Bridge), Instantiated later (Proxy) or Injected (Adapter, Decorator). Adapter, Bridge: decouple abstraction from implementation Both Adapter and Bridge are used to “Adapt” an existing and (possibly) foreign Class (usually from a separate and existing system) to apply to the needs of another (and sometimes newer) system. Both Adapter and Bridge allow you to “decouple an abstraction from its implementation so that the two can vary independently”(GoF Intent of the Bridge). Bridge, however does not allow these objects to be Injected and Instantiates and creates the object it Represents internally, making it a different thing from the Adapter. Adapter, Proxy: provide a surrogate Both Adapter and Proxy provide a surrogate object that pretends to be the object they Represent. Where the Adapter gets that object Injected, the Proxy Instantiates that object internally Adapter, Decorator: adapting the object by injecting it into a Representative Both Adapter and Decorator Pattern change the way you can access and use an object by allowing you to inject it into a Surrogate or Representative: the Adapter or Decorator. Where the Adapter is specifically to Adapt the Interface of the object, the Decorator can be used do add things to that object (or Decorate it). Decorator, Proxy: adding behavior to the object that was not there before Both Decorator and Proxy add extra Behavior to the object they Represent. Where the Proxy does this specifically to allow you to perform actions on an object that can be instantiated later, the added behavior from the Decorator can be anything.

Page 325: Re Factoring and Design Patterns

Refactoring and Design Patterns 325

RELATIONSHIPS BETWEEN ADAPTER, DELEGATE, DECORATOR, ::Tag: WRIA-REL-005

Page 326: Re Factoring and Design Patterns

326 Peter Kaptein

USAGE OF THE PATTERNS ::Tag: WRIA-OV-USA

USAGE OF THE ADAPTER, DECORATOR, BRIDGE AND PROXY PATTERNS ::Tag: WRIA-OV-USA-001 Object Adapter: Inject your object and change the Interface You use the Adapter to change the Interface on an object. For instance when it is from another System and used in your Project. Decorator: Inject your object and add new Behaviors. Optionally change the Interface The Decorator can be seen as the next step of the Adapter. Apart from allowing you to change the Interface on an object, you can also change its behaviors and add extra things to it (Decorating your object). Proxy: Represents an object, allows you to perform actions while the real thing is not there yet The Proxy has a clear purpose: to offer a Representative for an object that is not there yet. While the object might be still on its way (an image loaded from an external source) or not instantiated at all (late or lazy instantiation) you can already perform all required actions on that object as if it actually were there. Bridge: create a Class that Represents one or more possible implementations The Bridge is in some senses an Adapter using Internal Instantiation of the object instead of having that object Injected from the outside. The purpose of the Bridge is to encapsulate the real Classes and can be seen as an Adapter with an Internal Simple Factory, doing a very specific type of Adaption: of a flexible implementation of a specific Type of object. Unlike the Adapter and Decorator, the Bridge “is” the object it Represents, does not accept Injected objects and is not fit to wrap existing objects as an afterthought.

Page 327: Re Factoring and Design Patterns

Refactoring and Design Patterns 327

USAGE OF STATE, FAÇADE, MEDIATOR ::Tag: WRIA-OV-USA-002 State: change the response on a request based on State Façade: simplify operations, access a Subsystem through one object Mediator: simplify operations, centralize crucial actions, access a Subsystem through one object

Page 328: Re Factoring and Design Patterns

328 Peter Kaptein

DELEGATION OF ACTIONS

::Tag:PAT-TYPDEL

INTRODUCTION ::Tag:PAT-TYP-INTR

TYPE 1: DELEGATION OF ALL ACTIONS ::Tag:PAT-TYP-DEL Main intent Explicit or implicit delegation? While the Adapter Pattern is as much a Delegator as the Delegate Class, passing all calls through to the object it wraps or extends, the intent of the Adapter is to Adapt that Class or object to a different Interface. The delegation therefore is implicit. It is a consequence instead of an explicit choice. Bridge and State? Delegate or not? You can discuss whether the Bridge and State are Delegates or not. I will go into this per Pattern.

Page 329: Re Factoring and Design Patterns

Refactoring and Design Patterns 329

1: DELEGATE PATTERN ::Tag:PAT-TYP-DEL-DEL : Delegate to delegate all actions

+ someMethodA( ): do something return result

Delegate A

Client

+ delegateMethodA( ): do something delegate.someMethodA() do something else

Delegator A

1: «addresses»

3: «delegates actions to»

2: «instantiates / uses either»

+ someMethodA( ): do something else return result

Delegate B

A cleaner way to define who executes what, how, when

4: «leading to»

Visual summary of the Delegate Pattern ::Link: PAT-DEL Delegating everything to a target Delegate object The Delegate is mostly an empty pass-through station, passing calls for action through to the Delegation target object. The real actions and results are performed and returned by the target object. Inject or select? The Delegate can either receive the target object by injection from your code, or by selecting one internally based on some kind of Context. Using a Factory or Object Map When your Delegate instantiates the objects it delegates the actions to, you can use either a (simple) factory or a Object Map. The Object Map can store concrete objects to specific keys you can offer as a context to the Delegate. ::Link: PAT-SFC|-DTMP

Page 330: Re Factoring and Design Patterns

330 Peter Kaptein

2: ADAPTER ::Tag:PAT-TYP-DEL-ADP : Adapter as delegator

+ someMethodA( ): do something return result

«class»Adaptee

Client

+ desiredMethodA( ): do something execute someMethodA() do something else

Adapter A

1: «addresses object of type»

3: «delegates actions to»

2: «adapts»

Wrap and adapt the interface of existing Obejcts and Classes to your needs

4: «leading to»

Visual summary of the Delegate Pattern ::Link: PAT-ADP Delegating everything to the Adaptee Like the Delegate, the Adapter is mostly an empty pass-through station, passing calls for action through to the Delegation target object. The real actions and results are performed and returned by the target object. Type 1: Object adapters Object Adapters adapt an object by placing it inside a variable. The adaptation takes place by delegating the requests received on the Adapter to the wrapped object. Any response from the wrapped object is returned to the caller. Type 2: Class adapters Class Adapters extend the Class that needs to be adapted to the needs of your project. By extending the Class, you can add the methods you need to perform and then call the concrete methods on the Class you are adapting. Adding functionalities is possible, not an intent As discussed before, where needed, the Adapter can add new functionalities which are not present in the Adapted class or object, in order to conform to the interface and requirements of the code in your project. However allowed, and sometimes needed, this is, this is not the main intent of the Adapter.

Page 331: Re Factoring and Design Patterns

Refactoring and Design Patterns 331

3: COMMAND ::Tag:PAT-TYP-DEL-COM : Command as delegator

Some CommandYour Object1: «uses»

Some Object

2.b: «executes actions on / delegates actions to»

Command Interface

2.a: «implements»

Visual summary of the Command Pattern ::Link: PAT-COM Delegating predefined actions to some object injected by someone else Like the Delegate, the Command is mostly an empty pass-through station, passing calls for concrete action through to the Delegation target object. The real actions and results are performed and returned by the target object. You can inject this target object somewhere else in your code Sent to you to perform its action The Command in general is sent from some part of your code to another part to execute a specific action when needed. This makes it perfect for sequences of actions (like Macros) or to handle specific callbacks (in the Observer Pattern) when you cannot send Callback Methods. Hardly any internal action Like the Delegate, the Command hardly performs any action inside, but passing through specific calls to the object it envelops. Only a very limited set of instructions The Command has a very limited set of instructions, usually consisting of “execute” to execute the required action the Command represents, and “undo” when an Undo-function is required. Can perform multiple actions behind the “Execute” command In order to be able to perform its Command, the Command can and might combine several calls and actions within the “Execute” command. These actions are limited to the sole purpose of the Command. One class, one specific purpose Each Command is implemented as one specific Class with only one specific purpose. This purpose is usually described in the Class name. Single-minded delegate Since the intent is very similar to that of the Delegate, the Command can be seen as a single-minded delegate.

Page 332: Re Factoring and Design Patterns

332 Peter Kaptein

4: STATE ::Tag:PAT-TYP-DEL-STT :State as delegator

Context

+ request()

+ setState( stateOject )

Concrete State A

+ handleRequest()

- stateObject

Concrete State B

+ handleRequest()

A self-organizing delegator that defines internally which concrete implementation should handle the next state of the process

4: «leading to»

«state object»

1: «contains»

2: «is handled by current»

5: «sets next state object via»

3: «has reference to / can inject another state object into»

4: «has knowledge of other»

Concrete State C

+ handleRequest()

Visual summary of the State Pattern ::Link: PAT-STT State: Delegator or not? Like the Bridge and the Delegate Pattern, the State Pattern relies solely on the Delegation of actions to the Concrete State object it envelops. The question is if the State Pattern can be called a variation on the Delegate Pattern or not. Dynamic Delegation Due to its intent, and more like the Bridge Pattern, the State Pattern can be considered a variation of the Delegate Pattern, where the main differentiator is the way the State and Delegate Pattern decide which Concrete Implementation will be used to delegate the requested actions to. Intent: to offer different implementations per state Unlike the Adapter and Bridge, the intent of the State Pattern does not attempt to adapt one object or Class to the Interface needed in your project. Instead, its intend is to offer different implementations of specific actions, based on the State of the process it represents. Using a Object Map to store and select State objects When your State objects instantiate or choose the next State object to take over the actions to, you can choose to use a Object Map instead of hardcoded access to the State objects you might want to use. The Object Map can store concrete objects to specific keys you can offer as a context to the Delegate. PAT-DTMP

Page 333: Re Factoring and Design Patterns

Refactoring and Design Patterns 333

5: PROXY ::Tag:PAT-TYP-DEL-PRO : Proxy as delegator

Real Subject A

Proxy

- realSubject+ variableA+ variableB

Client

- proxy

+ doSomething()+ doSomethingElse()

1: «contains»

+ methodA( )+ methodB( )

+ methodA( )+ methodB( )

+ variableA+ variableB

2: «will contain»3: «execute»

5: «will be delegated to»

4: «will be passed to»

Visual summary of the Proxy Pattern ::Link: PAT-PRX Delegating actions to the Subject – once it is there The Proxy is a “stand in” for the actual object you want to perform actions on. As this object (the Real Subject) might not be there yet when you request a specific action (or set a specific value), the Proxy might act as a buffer, waiting for the real object to be there and then perform the required actions. Four types of Proxies There are four types of Proxies: the Remote Proxy, the Protection Proxy, the Virtual Proxy and the Smart Reference.

The Remote Proxy The Remote Proxy takes care of Remote objects. The Protection Proxy The Protection Proxy acts as a “gate keeper” for the real object, for instance implementing extra security layers over the object you want to approach and use. The Virtual Proxy The Virtual Proxy (in general) represents an object that is not there yet (like an image that is to be loaded) The Smart Reference The Smart Reference handles with all kinds of extra book-keeping on an object you use and instantiate: to allow more control over the creation and destruction of objects.

Page 334: Re Factoring and Design Patterns

334 Peter Kaptein

6: BRIDGE ::Tag:PAT-TYP-DEL-BRI

Base Abstraction

+ operationA()+ operationB(parameter)+ setContext(contextID)

+ operationA()+ operationB(parameter)

Concrete Implementor A

- implementor

RefinedAbstraction

+ operationC()

«Bridge»

4: «can be extended to»

3: «delegates actions to selected»

1: «can select any of»

A polymorphic class that can change its behavior and concrete implementation on runtime

5: «leading to»

2: «contains selected»

Concrete Implementor B

«implementation»

::Link: PAT-BRI Delegating everything to the Concrete Implementor The Bridge Delegates every action you request to the Delegator. In principle the Bridge does not have any internal logic, but uses the Implementors instead to do all the work. Bridge: Delegator or not? Like with the State Pattern, you can discuss whether the Bridge is a Delegate or not. The reason I include the Bridge and State Patterns here is that (more than the Adapter where delegation is a consequence to adapt the Class or object) their functioning fully depends on the Delegation of actions to another object.

Adapter-Bridge: not really a delegator When the intention of the Bridge is to Adapt a specific set of Classes or objects to one specific Interface, the Bridge is an Adapter-Bridge. While Delegation is a central part of the process, it is not its main intent. Delegate-Bridge: yes, probably a delegator When you use the Bridge primarily to delegate actions to other objects, the Bridge is a Delegate-Bridge and can be considered to be a Delegator. The question is: does it make sense?

Intent: to adapt and be extended The main intent of the Bridge is to bundle and adapt one or more variations on a process into one single class. The second intent of the Bridge is to be and become extended by subclasses.

Page 335: Re Factoring and Design Patterns

Refactoring and Design Patterns 335

TYPE 2: DELEGATION OF SPECIFIC ACTIONS ::Tag:PAT-TYP-DE2

1: STRATEGY ::Tag:PAT-TYP-DE-STRA

Your Class

+ yourMethodA(): if A: do Approach A if B: do Approach B+ yourMethodB()

variables

procedures Concrete Strategy A.a

+ yourMethodA: do Approach A

Concrete Strategy A.b

+ yourMethodA: do Approach B

1: «extract and split conditional code into separate classes»

2: «injected into / replacement for: code inside yourMethodA»

Classes and Objects that can change part of their behavior

3: «leading to»

Visual summary of the Strategy Pattern ::Link: PAT-WRP-STRA| PAT-STRA Delegating only a part of the actions The Strategy Pattern only delegates a part of the actions to the Strategy object it has or receives. These actions are the actions that need to change when the context in which your Class operates changes and thus the way actions are to be performed has to change as well. Extracting different approaches: plug and play behavior The Strategy Pattern can be used to extract different approaches from your code and putting them in separate Classes to be used and executed instead. The main benefit is that you can expand the different approaches (or Strategies) and plug them into your code, while keeping a clean basis without any additional code-clutter. Injecting the behavior you want your code in the Context object to implement With the Strategy Pattern, you inject the behavior you want an object (the Context) to implement. This allows you to address one single object with one single interface and have you decide later on what explicit behavior should be implemented when called. The Context-object can choose the Strategy Based on a context passed by Your Code, the Context object can choose the Concrete Strategy to perform the actual actions.

Page 336: Re Factoring and Design Patterns

336 Peter Kaptein

Your code can choose the Strategy If you want to place the responsibility of instantiation of the appropriate Strategy in Your Code, Your Code can instantiate the Strategy and pass it to the Context object. The consequernce of this implementation is that Your Code (and any other location where the Context object is used) needs explicit knowledge of the available Strategies and which context is linked to each. Using a Object Map to store and select Strategies When your State objects instantiate or choose the next State object to take over the actions to, you can choose to use a Object Map instead of hardcoded access to the State objects you might want to use. The Object Map can store concrete objects to specific keys you can offer as a context to your Context object. Simple execution: Handlers or Utils? The strategies you execute are usually stateless objects. When you use Strategies to simply execute specific implementations of a process or action, these Strategies do not / should not remember previous states. Instead this is a task for your Context object. ::Link: PAT-DTMP|MHOPUDO-UTIL|MHOPUDO-HNDLR

Page 337: Re Factoring and Design Patterns

Refactoring and Design Patterns 337

TYPE 3: DELEGATION TO SUBSYSTEMS ::Tag:PAT-TYP-DE3

1: FAÇADE ::Tag:PAT-TYP-WRSS-FCD : Façade as wrapper

1: «execute actions on»

4: «does stuff inside»

2: «refer to objects within»

Simplification of calls to- and actions on the subsystem

5: «leading to»

Façade

+ operationA()+ operationB(parameter)+ operationC()

- objectReferenceA- objectReferenceB- objectReferenceC

«subsystem»

Object from Class A

Object from Class B

Object from Class C

3: «delegate actions to»

Visual summary of the Façade Pattern ::Link: PAT-FCD Wrapping subsystems The Façade deliberately use the Subsystem to get things done. Intent: simplification of access to the subsystem The main intent is to simplify access to specific functionality within that subsystem. Delegation of actions to subsystems Facade, Mediator, Manager and Operator are four Patterns that use Delegation to a subasystem to get things done. Using a subsystem as a consequence of OOP The Bridge, Delegate and Strategy Pattern focus on one specific object or class to get things done. Calling and using other (helper) objects is a side-note and usually the result of using OOP principles.

Page 338: Re Factoring and Design Patterns

338 Peter Kaptein

2: MEDIATOR ::Tag:PAT-TYP-WRSS-MED :Mediator as wrapper

3: «has references to»Concrete Mediator

+ yourMethodA(): do something+ yourMethodB() do something else

Centralization of communication between objects in your subsystem

5: «leading to»

«colleagues in subsystem»

Concrete Collegue A

Concrete Collegue B

2: «have references to»

4: «communicate to»

5: «delegates actions to specific»

Client

1: «uses»

Visual summary of the Façade Pattern ::Link: PAT-MED Should it be here? The question is of the Mediator should be in this classification as a wrapper of subsystems. In almost all cases, the wrapped objects and subsystems have no knowledge of the wrapper and in almost all cases the wrapper directs instead of mediates. “Wrapping a system” by offering a single point of entry Because the Mediator works as a communications hub, it can be used (and is used) as a single-point of entry to an entire subsystem. Request, action, callback Where the Façade directs, the Mediator requests, the subsystem acts and then calls back to the Mediator. Observing the subsystem: top down / bottom up To be able to know what is going on within the subsystem, the Mediator can register Observers to specific objects within that subsystem. Whenever something happens within that subsystem, the Mediator can respond and ignore it or take successive actions based on (business) rules. Injecting itself into the subsystem: moving to bottom up It is possible that the best way for your system to work is by injecting the Mediator into the subsystem. By doing so, the subsystem becomes the active player and the Manager simply responds when needed. Using Static methods to resolve the Mediator: simplification of your code

Page 339: Re Factoring and Design Patterns

Refactoring and Design Patterns 339

The disadvantage of Dependency Injection is that you still have a top-down approach where one point in your code needs to know which objects required your Mediator. You can turn this chain of control around by calling directly on the Mediator Class and have the Mediator return the appropriate Mediator for the Context that code is operating in. ::Link: PAT-OBS|PAT-IOC

3: MANAGER ::Tag:PAT-TYP-WRSS-MGR : Manager as wrapper

Manager A Subsystem B

Your Class

1: «uses»

2.a: «addresses»

Business Logic

2.b: «uses»

3: «can address»

Visual summary of the Manager Pattern ::Link: PAT-MGR Combining the best of Mediator and Façade Mediator and Façade have a completely different way of “wrapping” a subsystem. Where Façade uses a pure top-down Hub/Spoke implementation, the Mediator is “part of the gang” and mediates the communication between the objects within that subsystem. In some cases you want to use both the directive top-down approach of the Façade and the “bottom-up” approach that can be used with the Mediator: where the objects in the subsystem are allowed to directly call the Mediator. The Manager is such a merge. It allows for a combination of top-down and bottom-up approaches without messing things up. Top down: pure Hub Like the Façade, the Manager can be implemented as a top-down system where it directs all actions. Part of the gang: dirty Hub Like the Mediator, the Manager can be used as a man in the middle for communications between objects in your subsystem. Observing the subsystem: top down / bottom up Like the Mediator, to be able to know what is going on within the subsystem, the Manager can register Observers to specific objects within that subsystem. Whenever something happens within that subsystem, the Mediator can respond and ignore it or take successive actions based on (business) rules.

Page 340: Re Factoring and Design Patterns

340 Peter Kaptein

Injecting itself into the subsystem: moving to bottom up Like with the Mediator, you can inject the Manager into the subsystem. By doing so, the subsystem becomes the active player and the Manager simply responds when needed. Using Static methods to resolve the Mediator: simplification of your code The disadvantage of Dependency Injection is that you still have a top-down approach where one point in your code needs to know which objects required your Mediator. You can turn this chain of control around by calling directly on the Mediator Class and have the Mediator return the appropriate Mediator for the Context that code is operating in. ::Link: PAT-OBS|PAT-IOC

4: OPERATOR ::Tag:PAT-TYP-WRSS-MG : Operator as wrapper

Operator A Subsystem B

Your Class

1: «uses»

2.a: «addresses»

2.b: «uses / delegates to»

3: «can address»

Subsystem C

Visual summary of the Operator Pattern ::Link:MHOPUDO-OPR Wrapping a subsystem like a Façade and Mediator The Operator wraps a subsystem combining the possibilities of a Façade and Mediator, allowing for simplified access to that subsystem and centralization and the mediation of communication of objects within that subsystem. Always three players The Operator assumes there are always three players: Your Class and your code, a Subsystem it is intimately familiar with (and acts as a Mediator for) and a Subsystem that it approaches selectively using the Façade. In MVVM (Model, View, ViewModel) “Subsystem C” can be the Applicaton Model while Subsystem B is the ViewModel and Your Class is the View Component that requires communication with subsystems. Delegating to another subsystem

Page 341: Re Factoring and Design Patterns

Refactoring and Design Patterns 341

The Operator is a man in the middle for at least two subsystems: connecting them together. The Operator delegates explicitly to one (subsystem C) and uses and mediates with the other (subsystem B). Specialized Manager, man in the middle The Operator is the man in the middle between one subsystem and another. Connecting View to Model Within the scope of this book, the Operator is mainly used to connect a View to a Model, following the principles of MVVM (Model View, ViewModel) and MVP (Model View, Presenter) where the “Controller” is the hub between the Model and the View. ::Link:MHOPUDO-OPR|MVC-PATT-CHUB

Page 342: Re Factoring and Design Patterns

342 Peter Kaptein

CREATION OF DYNAMIC CLASSES

::Tag:PAT-TYP-DCL

Page 343: Re Factoring and Design Patterns

Refactoring and Design Patterns 343

INTRODUCTION ::Tag: PAT-CHC-INT

Your Code

Option A

Option B

Option C

Choice and Flexibility

??«use»

When you start programming, your first concern is to make things work, regardless how. Your first code and your first line of solutions is very likely rigid. Very reluctant to change. The first programming languages had specifically this problem. They allowed you to write things that worked, but woe you who wanted change. As discussed earlier OOP (Object Oriented Programming) and OOP principles searched- and were developed to break with that rigidness. Apart from re-use (using objects and Classes instead of Copy & Paste coding) Choice and Flexibility in what would be implemented and how that implementation would be plays a central role in OOP. The Design Patterns in this section are made for Choice and Flexibility, as they allow you to:

1. Change your mind – While the application is already running 2. Implement and switch between alternatives – To do the same thing, but differtently 3. Incorporate Change and Choice as a starting point – Instead of an afterthought

The result is that your Code is versitileand Agile without becoming brittle and vulnerable. Even better, your code will eat Change for breakfast and become stronger, better and more healthy as a result.

ELEMENTS TO MAKE IT WORK ::Tag: PAT-CHC-ELM Abstraction, Extraction and Encapsulation Each of the Patterns in this section exists and function through Abstraction, Extraction and Encapsulation. With Abstraction, the Concrete Implementation is no longer part of the code, but happens elsewhere. With Extraction we extract the Concrete Implementation of code from one place and with Encapsulation we “encapsulate” that Extracted code into something else: which might be a Method in your current Class or a Method in a new Class Decoupling

Page 344: Re Factoring and Design Patterns

344 Peter Kaptein

Decoupling is where dependencies between two (or more) parts are no longer fixed. Through Decoupling, code becomes like an advanced modular system. You can extract parts, replace them for something else and – as long as their function remains the same – the system will still work Black box principle Each of these patterns rely on what is called the “black box principle” which is that: as long as your Interfaces are well designed and properly implemented, it does not matter what happens inside your Black Box Interchangeable parts Part of the Black Box Principle is that I can replace any Black Box for any other Black Box as long as the functions are the same.

HOW DO WE ACHIEVE THIS? ::Tag: PAT-CHC-HOW Within OOP you have several ways to achieve these principles: Classes and Methods Using Classes and Methods, you can Extract, Abstract and Encapsulate Concrete Implementations Interfaces, Abstract Classes, Base Classes You create Interchangeable Black boxes by creating an identical basis for each Black Box in your series. The three tools you have for this are: the implementing of Interfaces, Abstract Classes or Base Classes, or a combination of the three. Whatever you do, the main goal is to create what is called the same “Signature” for the Methods and Variables that each of your Classes should Implement. By using the source of the Signature (the Interface, Base Class or Abstract Class) instead of one of the Concrete Classes as a reference, each and any instantiation of that basis will be accepted by your Compiler Choosing the Class to Instantiate Once we have “normalized” classes, sharing the same Signature, we can choose which Class we want to use to create a Concrete object. We then create that object and return it to the requester Each Design Pattern you find in this section uses these principles as a starting point, but implements them in different ways, to achieve different goals and cover different Use Cases.

Page 345: Re Factoring and Design Patterns

Refactoring and Design Patterns 345

TYPE 1: DYNAMIC CLASSES AND OBJECTS ::Tag:PAT-TYP-DCL1

1: BRIDGE ::Tag:PAT-TYP-DCL1-BRI : Bridge as a dynamic class

Base Abstraction

+ operationA()+ operationB(parameter)+ setContext(contextID)

+ operationA()+ operationB(parameter)

Concrete Implementor A

- implementor

RefinedAbstraction

+ operationC()

«Bridge»

4: «can be extended to»

3: «delegates actions to selected»

1: «can select any of»

A polymorphic class that can change its behavior and concrete implementation on runtime

5: «leading to»

2: «contains selected»

Concrete Implementor B

«implementation»

::Link: PAT-BRI Dynamic Polymorphic Class? The Bridge allows you to create a polymorphic single Class. With the Bridge Pattern you can implement several scenarios in several separate Classes and then implement these into the single Bridge object. How it works While your code is running, the Bridge can choose and implement another object with another scenario and execute your requests on that object: showing , making it a Dynamic Polymorphic Class. Basis You use the Bridge Pattern by implementing a Bridge Class. The Bridge object is actually nothing more than an almost empty shell pretending to be the actual object it instantiates internally. The Bridge object can use the Factory Method or Strategy Patterns to choose and implement Classes and objects Wrapping an internal object The Bridge, like the Adapter, wraps an internal object. Extending the Bridge as Base Class In “Design Patterns” the Bridge is explicitly implemented as a Base Class.

Page 346: Re Factoring and Design Patterns

346 Peter Kaptein

Setting a context If you want the Bridge to change the internal object to which it delegates the actions to, you can use and change a Context. Based on the Context, the Bridge can choose or instantiate another object from another Class to delegate the actions to. Using a factory or Object Map When your Delegate instantiates the objects it delegates the actions to, you can use either a (simple) factory or a Object Map. The Object Map can store concrete objects to specific keys you can offer as a context to the Delegate. ::Link: PAT-SFC|PAT-DTMP

Page 347: Re Factoring and Design Patterns

Refactoring and Design Patterns 347

TYPE 2: DYNAMIC EXECUTION OF ACTIONS ::Tag:PAT-TYP-DCL2

1: DELEGATE ::Tag:PAT-TYP-DCL1-DLG : Delegate as a dynamic class

+ someMethodA( ): do something return result

Delegate A

Client

+ delegateMethodA( ): do something delegate.someMethodA() do something else

Delegator A

1: «addresses»

3: «delegates actions to»

2: «instantiates / uses either»

+ someMethodA( ): do something else return result

Delegate B

A cleaner way to define who executes what, how, when

4: «leading to»

Visual summary of the Delegate Pattern ::Link: PAT-DEL Dynamic execution by changing the Delegate object The Delegate can use one or more objects to Delegate specific actions to. By changing the target object you automatically change the way an action is executed by the Delegate. Inject or select? The Delegate can either receive the target object by injection from your code, or by selecting one internally based on some kind of Context. Using a factory or Object Map When your Delegate instantiates the objects it delegates the actions to, you can use either a (simple) factory or a Object Map. The Object Map can store concrete objects to specific keys you can offer as a context to the Delegate. ::Link: PAT-SFC| PAT-DTMP

Page 348: Re Factoring and Design Patterns

348 Peter Kaptein

2: STATE ::Tag:PAT-TYP-DCL1-STT : State as a dynamic class

Context

+ request()

+ setState( stateOject )

Concrete State A

+ handleRequest()

- stateObject

Concrete State B

+ handleRequest()

A self-organizing delegator that defines internally which concrete implementation should handle the next state of the process

4: «leading to»

«state object»

1: «contains»

2: «is handled by current»

5: «sets next state object via»

3: «has reference to / can inject another state object into»

4: «has knowledge of other»

Concrete State C

+ handleRequest()

::Link: PAT-STT Dynamic execution by changing its behavior when the state changes The State Pattern changes its behavior when the State of the process changes. The State Pattern does this by changing the State object within the Context you operate on. This makes the State a dynamic Class that can change its internal behavior when and where needed. How it works: choosing a specific State object when a method is executed The State Pattern changes the State object within the Context when you call a method on the State object. Due to this, the behavior of the Context object changes as well. Dynamic object, polymorphic behavior Like the Bridge, the Context object in the State Pattern can change its behavior when needed. In the case of the State Pattern, this change is explicitly defined for each method in the State object that can lead to a change in the State of your object and your process. Using a Object Map When your State objects instantiate or choose the next State object to take over the actions to, you can choose to use a Object Map instead of hardcoded access to the State objects you might want to use. The Object Map can store concrete objects to specific keys you can offer as a context to the Delegate. ::Link: PAT-DTMP

Page 349: Re Factoring and Design Patterns

Refactoring and Design Patterns 349

3: STRATEGY ::Tag:PAT-TYP-DCL1-STR : Strategy as a dynamic class

Your Class

+ yourMethodA(): if A: do Approach A if B: do Approach B+ yourMethodB()

variables

procedures Concrete Strategy A.a

+ yourMethodA: do Approach A

Concrete Strategy A.b

+ yourMethodA: do Approach B

1: «extract and split conditional code into separate classes»

2: «injected into / replacement for: code inside yourMethodA»

Classes and Objects that can change part of their behavior

3: «leading to»

Visual summary of the Strategy Pattern ::Link: PAT-STRA Dynamic execution by allowing variation on specific actions The Strategy Pattern allows you to inject or choose specific strategies for specific uses and situations. By this, your Strategy Class becomes a dynamic Class that can change (part of) its behavior when it needs to. How it works: varying specific behavior based on context The Strategy Pattern varies only the Context specific (that need to be variable) actions. It does so by delegating these actions to an external object that can either be injected form the outside, or selected internally – based on a context. All other actions within the Delegate Pattern are executed in the Context object that does the delegation. Using a Object Map to store and select Strategies When your class instantiates or choose the Strategy, you can choose to use a Object Map instead of hardcoded access to the Strategies you might want to use. The Object Map can store concrete objects to specific keys you can offer as a context to your Context object. Execution of actions only: Handlers or Utils? The strategies you execute are usually stateless objects. When you use Strategies to simply execute specific implementations of a process or action, these Strategies do not / should not remember previous states. Instead this is a task for your Context object. ::Link: PAT-DTMP|MHOPUDO-UTIL|MHOPUDO-HNDLR

Page 350: Re Factoring and Design Patterns

350 Peter Kaptein

TYPE 3: DYNAMIC EXTENSION OF POSSIBILITIES ::Tag:PAT-TYP-DE3

1: DECORATOR ::Tag:PAT-TYP-DCL1-DEC : Decorator as a dynamic class

Decorator A

+ yourMethodA: extended add extra functionalities execute: yourClass.yourMethodA()+ yourMethodB: extended do something extra execute: yourClass.yourMethodA()

Decorator B

1: «can be wrapped by any»

2: «can be wrapped by any»

+ yourMethodA(): extended+ yourMethodB(): extended

Main Interface / Base Class

3: «share the same»

Your Class

+ yourMethodA(): do something+ yourMethodB() do something else

variables

procedures

+ yourMethodA():+ yourMethodB()

Extended functionalities

4: «leading to»

Visual summary of the Decorator Pattern ::Link: PAT-DEC Dynamic extension of possibilities by adding functionalities When you wrap an object within a Decorator, you do this in order to add extra functionalities. These functionalities can be, for instance, new methods or new elements to be shown on screen. Extending classes without subclassing The Decorator Pattern is used when you want to add new and extra functionalities to an existing Class, without creating new subclasses. Nesting decorated objects The Decorator Pattern allows you to nest Decorated objects within new decorators, allowing you to dynamically add new functionalities as you go.

Page 351: Re Factoring and Design Patterns

Refactoring and Design Patterns 351

BONUS MATERIAL: RELATIONSHIPS AND SOURCES OF CHANGE

Page 352: Re Factoring and Design Patterns

352 Peter Kaptein

RELATIONSHIPS BETWEEN BRIDGE AND STATE ::Tag: PAT-CHC-OV-REL002

StateBridge

Context specific State specific

Pre

ten

ds

to b

e

Change

Similarities between Bridge and State Both can change the actual object during runtime, while offering their services and functionalities via an object that remains the same

Differences Bridge is Context Specific State is State specific Bridge changes the object it represents and works from the outside A state object changes the content of the variable it is in and works from the inside to the outside Bridge can represent both an object (Product) or a Handler for one or more Processes (Strategy) A State object is a handler of a Process

Page 353: Re Factoring and Design Patterns

Refactoring and Design Patterns 353

CHANGE FROM: INSIDE OUT / OUTSIDE IN ::Tag: PAT-CHC-OV-REL003

Object A

«contains»

variableB

«changes»

Object C

«contains»

variableB

«changes»

Object A

Change: Outside in Change: Inside out

Object C

Brief There are two ways to change the object that does the actual work: from the outside in, or from the inside out. Most patterns in this section work from the Outside in, meaning that the Outside object will change the “worker”. I will give some concrete examples on that concept later

Outside in Patterns Bridge Strategy Factory

Inside Out Patterns State

Other Patterns that follow the same principle as the State Pattern There are no other Design Patterns in “Design Patterns” that follow this same “Inside-Out” principle.

Page 354: Re Factoring and Design Patterns

354 Peter Kaptein

Examples of a concrete implementation for Outside-In and Inside-Out ::Tag: PAT-CHC-OV-REL003-003

2.a: «has reference

to»ObjectC

ObjectA

1: «contains»

variableB

2.b: «changes»

ObjectC

3: «contains»

variableB

1.a: «uses»

Change: Outside in Change: Inside out

Factory A

2: «returns»

1.b: «changes»

ObjectA

Outside in Object A: 1.a: Uses Factory A or Strategy B 1.b: Changes variableB with the result from the Factory or Strategy Provider Factory A: 2: Returns Object C Variable B: 3: Contains Object C

Inside out Variable B: 1: Contains Object C Object C: 2.a: Has a reference to Object A 2.b: Changes variable B

Who is in control over variable B? Both approaches lead to the same result, but the Control over who sets Variable B is different.

Page 355: Re Factoring and Design Patterns

Refactoring and Design Patterns 355

For Outside-In the object that holds Variable B is in control over Variable B For Inside-Out the object that is held in Variable B is in control over the value of Variable B

Page 356: Re Factoring and Design Patterns

356 Peter Kaptein

CREATION OF OBJECTS AND COMPLEX STRUCTURES

::Tag:PAT-TYP-CR

Page 357: Re Factoring and Design Patterns

Refactoring and Design Patterns 357

INTRODUCTION ::Tag: PAT-DSTR-INTR In some cases, hardcoded solutions do no longer work. For instance, because your application needs to be able to adapt itself to specific situations, or because you have no information on what is needed or what should happen when you write the code, only how it should work For example, your Web-Browser, your Word Processor or your Operating System have no clue what will happen or what is needed until the moment something happens. In the case of a Web Browser, that something is “loading a web page” and “parsing a web page”. The moment you start loading a Web Page, a container will be created to contain the loaded content and the moment the Content is loaded, an object Tree – existing of Containers for Text, Images and Hyperlinks, to name some – will be created to present the content on your screen.

ELEMENTS TO MAKE IT WORK ::Tag: PAT-DSTR-ELM Dynamic construction of object Trees Everything in OOP has some hierarchic structure. We create this structure by nesting elements and nesting elements within nested elements. The only limit for nesting is basically your internal memory or RAM. (Builder, Parser, Interpreter) Context specific choice of implementations Based on the requirements at that time, usually based on context-specific needs, we want to decide how a specific functionality will be implemented, or what type of Concrete object we want to return to handle or contain specific data. (Builder) Dynamic addition of methods and properties In some cases, the context-specific choice of implementations is not enough, as we have too many different combinations of elements to capture them all in Classes and Subclasses. In this case we search and find solutions where we can dynamically add and alter behaviors of objects and Methods. (Decorator) Dynamic handling of the data within the objects in the composite structure Visitor

Page 358: Re Factoring and Design Patterns

358 Peter Kaptein

HOW DO WE ACHIEVE THIS? ::Tag: PAT-DSTR-ACH In OOP we have several ways to do this: Using encapsulation By encapsulating an object within another object, you can dynamically add properties and methods from the Container to the object you Contain. (Decorator) Using lists and iteration to build dynamic object Trees To create hierarchic object Trees, you need some kind of container to contain one or more Child Elements to a specific Node in your structure. This is done with Lists (also known as Arrays and Collections). (Builder, the Parser, Interpreter) Using Rules and Rules based Decisions to define what should be put where The moment you start building software that uses Rules Based decision making to build structures, your “programming” moves from code to definitions. The implementation of HTML is one example of this principle. (Parser) Creating a structured “language” that can be parsed You will find this application most in very specialized applications. Two examples are spelling checkers and parsing regular expressions. (Interpereter) All patterns in this section cover one or more of these principles to allow you a specific amount of flexibility to achieve some specific goal.

Page 359: Re Factoring and Design Patterns

Refactoring and Design Patterns 359

TYPE 1: CREATING AND INSTANTIATING OBJECTS ::Tag:PAT-TYP-CRI

1: FACTORY METHOD: PRODUCE OBJECTS USING A SHARED ABSTRACT METHOD ::Tag:PAT-TYP-CRI-FM : Factory Method as a creator of objects

1: «are implemented in»

Concrete Creator B

+ produceProductA()+ produceProductB()

Factory Method Definitions 3: «uses»

Concrete Product A.b

Concrete Creator A

«classes»

2: «will produce producs of type»

3: «produces / return»

Concrete Product A.a

Concrete Product B.b

Concrete Product B.a

2: «are implemented in»

«concrete products»

«abstract definitions»

Re-usable definitions for factory methods to produce concrete products in several classes

4: «leading to»

Base Product A

Base Product B

«base product definitions»

Visual summary of the Factory Method Pattern ::Link: PAT-FAC Create and produce a product of one specific type The main purpose of the Factory Method is to produce the concrete Product that is required in the context in which the specific Class and object operates. Abstract method The Factory Method is implemented as an Abstract Method that is implemented inside each Concrete Class. Not a simple factory

Page 360: Re Factoring and Design Patterns

360 Peter Kaptein

Unlike the Simple Factory, the Factory Method does not inted to produce several types of objects based on a context. See the next page for the Simple Factory.

Page 361: Re Factoring and Design Patterns

Refactoring and Design Patterns 361

2: SIMPLE FACTORY ::Tag:PAT-TYP-CRI-SF : Simple Factory as a creator of objects

+ produceProductA( subType )+ produceProductB( subType )

Simple Factory

Concrete Product A.b

1: «will produce producs of type»

Concrete Product A.a

Concrete Product B.b

Concrete Product B.a

2: «are implemented as»

«concrete products»

A very simple way to produce concrete products based on specific parameters

4: «leading to»

3: «produces / return»

Base Product B

Base Product A

«base product definition»

Visual summary of the Simple Factory ::Link: PAT-SFC Create and produce any object of a specific family The Simple Factory is everything you would have expected the Factory Method or Abstract Factory to be. It uses a specific Context to produces any object of any Class that relates to that Context. The only limitation within each Construction method is that these objects and Classes (from which they are produced) share the same Interface or Base Class (the specific family). Using subtypes to produce the products The Simple Factory uses subtypes per product to indicate which specific Class should be used to produce the Concrete Product. Simplified version of the Abstract Factory and Factory Method Where the Factory Method and Abstract Factory by explicitly state that you should implement an Abstract version of the Factory first, the Simple Factory does not. In most cases the Simple Factory will the preferred solution to make things work as re-use of a specific Factory is less frequent as the need for something that performs the actions of a factory.

Page 362: Re Factoring and Design Patterns

362 Peter Kaptein

3: ABSTRACT FACTORY ::Tag:PAT-TYP-CRI-AF : Abstract Factory as a creator of objects

3.b: «instantiates /returns»

2.b: «instantiates /returns»

Your Code

Product A.1

Product B.1

Pruduct C.1

Factory A

1.b: «uses»

Product A.2

Product B.2

Pruduct C.2

Factory B

1.c: «or uses»

Interface A

«2.a: implements»

«3.a: implements»

1.a: «has a»

Context

Defines multiple production lines to create and produce specific object The Simple Factory is everything you would have expected the Factory Method or Abstract Factory to be. It uses a specific Context to produces any object of any Class that relates to that Context. The only limitation within each Construction method is that these objects and Classes (from which they are produced) share the same Interface or Base Class (the specific family). Blueprint for concrete factories The Abstract Factory is mostly a blueprint that describes what a Concrete Factory (based on the blueprint) should look like, what production lines should be within the Factory, how these production lines are addressed and what each line returns. Constructor methods and Production lines The production lines are the concrete methods that will produce the objects (or Products) you expect form the Factory. Unlike the Simple Factory, each production line only returns one variation on a Type of

Page 363: Re Factoring and Design Patterns

Refactoring and Design Patterns 363

object. If you need another variation on that type of object, you will need to build and address another Factory. Products When you call a Constructor Method, the Factory will produce and return an object, called a: “Product”. Base Classes or Interfaces Each Product is based on a Class that either extends a common Base Class or implements a common Interface between all variations on that Product. This makes the Product itself interchangeable with all other variations on that Product. ::Link: PAT-AFC

Page 364: Re Factoring and Design Patterns

364 Peter Kaptein

TYPE 2: CREATING AND READING COMPLEX OBJECTS ::Tag:PAT-TYP-CRCO

1: PARSER ::Tag:PAT-TYP-CRCO-PAR : Parser as a creator of complex structures

Abstract Definition / Object Tree

Object Tree / Composite Object

Abstract Definition

1: «parsed to» 2: «can be parsed to» 3: «can be parsed to»

Visual summary of the parsing process ::Link:PAT-PARS Creating and parsing Composite structures The Parser is specifically suited to create and parse structures based on some kind of abstract definition. Using a Factory to get the right kind of objects To get the objects that suit the abstract definition (or as an alternative for the object you parse) you will use – in most cases – some kind of Factory. Most versatile pattern Compared to the Builder and the Interpreter, the Parser offers you a world of freedom. A Parser can parse anything to anything and has no specific use. Reflection Depending on what you parse, Reflection might be a handy and very important part of the process. Reflections allows you to take an existing object, “read” the structure and use that structure to insert into that object or get values form that object. Especially when working with clear-text data structures like JSON and XML this is a very handy feature: you can map values onto variables and variables to values. ::Link:PAT-TYP-CRCO-COM

Page 365: Re Factoring and Design Patterns

Refactoring and Design Patterns 365

2: BUILDER ::Tag:PAT-TYP-CRCO-BLDR : Builder as a creator of complex structures

Director

+ constructA(): buildPart .. buildPart .. buildPart .. getResult()

Concrete Builder

Overrides / implements:+ buildPartA()+ buildPartB()+ buildPartC()+ getResult()

Client

Composite Object

2: «uses»

1: «uses»

3: « construct and returns»

5: «returns composite object to»

4: «is returned to»

::Link: PAT-BLD Building object structures using building-instructions The Builder allows you to create (complex) structures using building instructions. Two main parts: Director and Concrete Builder The Builder Pattern uses two parts: the Director and the Concrete Builder. The Director describes which parts should be used and in which order (and structure) they should be assembled. The Concrete Builder chooses the specific type of objects to use and defines explicitly how the end result will be created. Changing the end result by changing the Concrete Builder Like the Visitor Pattern, the Builder can change the entire end-result of the Building process. In the case of the Builder by selecting a different Concrete Builder. Using a Builder and Visitor to parse a Composite object One of the fun parts of the Builder is that you can combine it with a Visitor. Where the Builder defines the Building Process, the Visitor can traverse through the Composite object and define the concrete results from that process. ::Link:PAT-TYP-CRCO-COM

Page 366: Re Factoring and Design Patterns

366 Peter Kaptein

3: ITERATOR ::Tag:PAT-TYP-CRCO-ITR : Iterator as a creator of complex structures To be written

Page 367: Re Factoring and Design Patterns

Refactoring and Design Patterns 367

4: VISITOR ::Tag:PAT-TYP-CRCO-VIS : Visitor as a reader of complex structures

Concrete Element A

Concrete Element B

Concrete Visitor A

Object Structure A

Concrete Visitor B

Client A

«visitors»

1: «selects a concrete visitor based on» 2: «has / sends selected visitor into»

«elements»

3: «consists of elements based on»

4: «visits / is sent through / can perform operations on»

5: «can be child of»

A dynamic solution to run through- and perform actions on an Object Structure from the inside using different type of “visitors”

6: «leading to»

Visual summary of the Visitor Pattern ::Link:PAT-VIS Reading an object structure, building something new The Visitor is sent inside of the object structure to read the content or perform actions on the objects within that structure. One outcome of the Visitor can be a new structure from the data within the object structure. Another outcome can be changes of data or properties of the objects within that structure. Think for instance of a Visitor in a File Structure. One Visitor can change read/write settings. Another can delete specific files. Like a Command: simple Interface, each Visitor performs a very specific task Each Visitor performs a very specific task from a very limited Interface. Like the Command, each Concrete Visitor can have a completely different internal implementation with completely different outcomes. Apart from the Interface each Visitor shares, the internals, tasks and responsibilities of each individual can be completely different. Requires a very specific implementation of the objects in the Composite As far as I understand, the Visitor Pattern requires you to implement methods in the Concrete Elements to allow the Visitor to visit that object.

Page 368: Re Factoring and Design Patterns

368 Peter Kaptein

Is not suited for a wide variation of Concrete Elements For each specific type of Concrete Element, the Visitor has a specific method: to deal with that object and the object-specific qualities. ::Link: PAT-DSTR-TRV|PAT-TYP-DEL-COM

5: COMPOSITE ::Tag:PAT-TYP-CRCO-COM : Composite as a holder of complex structures

Non-terminal node A

Non-terminal node B

Object Structure AClient A1: «contains»

«non-terminal nodes»

3: «can be child of»

An object tree with nodes and children, that can be of any depth

5: «leading to»

Terminal node A

Terminal node B

«terminal nodes»

4: «can be child of»

2: «can contain»

Visual summary of the Composite Pattern ::Link: PAT-CMP Complex objects by composition The Comnposite Pattern could be seen as the basis for any composite object, like object trees and the like. It describes the structure in which you can nest objects within objects. Due to this nesting, you create a “Composite”. Descriptive When your browser parses HTML, it builds a Composite object that is Descriptive. The HTML defines the objects and containers you use. Each element in the HTML represents a Concrete object. The Composite structure with objects that create DIVs, Images, Italics, Bolds, Headers, Links and Paragraphs is the result. Data

Page 369: Re Factoring and Design Patterns

Refactoring and Design Patterns 369

With data, the Composite represents the structure of the data it represents. This can be a tree-structure or something more networked, where nodes can have references to other nodes somewhere else in the tree-structure . Terminal nodes? Children.length==0? In “Desing Patterns”, the presence of Terminal nodes is seen as an essential part and reason for the Compiste Pattern (see “Motivation” of the Composite Pattern). The thing is that even a “terminal” node might have and want to have children at some point in time. Instead of using Terminal nodes you might just use non-terminals and simply not add children. Composite and Decorator The Composite and Decorator Pattern have some commonalities and possible overlaps. For instance: what do you do with the “Bold” tag in HTML? In some sense the “Bold” tag is a modifier, as is the “Italics” tag, making text Bold and Italics. This modification is typically a task you would give to a Decorator. ::Link:PAT-TYP-DCL1-DEC Composite objects influencing other objects in the chain Another thing is that the Decorator is in some ways a simplified Composite. You can create simple composite objects by nesting Decorators inside decorators. Like the Decorator, the Composite Pattern allows you to implement code within the Composite objects to influence other objects within the composite when something changes. One well know example with the Composite is chaining objects and when you drag one point, the rest of the chain follows as illustrated below. (“A” is pulled, leading to rotation of the elements (“B”) and points marked with “C” follow as a consequence, as will a rotation of the elements (“D”) and the following of elements E and F if they are in the chain).

A

C

BB

C

D D

Example of one use of the Composite Composite and the Visitor: endless variation of possible actions Unlike the code within the Composite, the Visitor allows for endless variation on what you could and would like to do with the objects within the Composite when a specific event occurs (part of chain gets dragged up, specific files in file-system need to be removed). Each specific handler of each specific situation can be made into a separate Visitor and the amount of different actions and possible Visitors is unlimited. ::Link:PAT-TYP-CRCO-VIS

Page 370: Re Factoring and Design Patterns

370 Peter Kaptein

Speed: moving through a Composite chain instead of iterating When you move into particle-systems, the (simple) composite is one of the most efficient ways to “iterate” through the objects in the “list”. It cuts out a lot of the extra cycles and actions required in the Iterator (for / next and all alternatives) and due to its efficient allows for many thousands of particles to be updated in a short amount of time.

6: REFLECTION ::Tag:PAT-TYP-CRCO-COM : Reflection to use in complex structures To be written

Page 371: Re Factoring and Design Patterns

Refactoring and Design Patterns 371

BONUS MATERIAL ::Tag: PAT-DSTR-REL

VISUAL SUMMARY OF FACTORY, BUILDER AND PARSER ::Tag: PAT-DSTR-REL-003

Factory

Builder

Prefab objects

Prefab parts + prefab assembly

Parser /Interpreter

Prefab parts + custom assemblyResults from custom/external assembly instructions allowing to create any possible result with prefab parts

Products from pre-programmed sets of combinations allowing to create more variation

Pre-programmed sets of products

«uses»

«uses»

«uses»

«can produce»

«can produce»

«can produce»

prefab assembly

instructions

«receives»

external / custom

assemblyinstructions

«uses»

Your classes

Page 372: Re Factoring and Design Patterns

372 Peter Kaptein

RELATIONSHIPS BETWEEN ALL PATTERNS THAT CREATE STUFF ::Tag: PAT-DSTR-REL-001

Composite

Dynamic Builders Results

Full

free

do

mR

estr

icte

d u

se c

ase

s

com

po

siti

on

creates

createscreates

Dynamic wrappers

Parser

Decorator

Parser

Full

free

do

m,

Spec

ific

use

creates

Full

free

do

m

Interpreter

SimpleComposite

Builder

Page 373: Re Factoring and Design Patterns

Refactoring and Design Patterns 373

RELATIONSHIP BETWEEN FACTORY, BUILDER AND INTERPRETER ::Tag: PAT-DSTR-REL-002

Diagram

Builder

Fixed Result Composite Structure

An

y M

od

elH

ard

cod

ed M

od

el

asse

mb

ly

Factory production

uses

Parser

Interpreter

Relationships Factory and Parser / Interpreter The Factory is used in most cases by both Parser and Interpreter to find and Instantiate the objects required to build the Composite Structures represented in the Abstract Definition. Parser and Interpreter The Interpreter uses a Parser to create the Composite Structure that needs to be Interpreted.

Page 374: Re Factoring and Design Patterns

374 Peter Kaptein

Similarities Factory and Builder Both Factory and Builder produce Products. The products which are created by Factory and Builder both have a Hardcoded Structure or Hardcoded Model. In the case of Factory by the Class that is instantiated. In the case of the Builder by the hardcoded “Building Instructions” within the Director. Factory and Parser / Interpreter The Factory, the Parser and the Interpreter all produce an object with the required properties. Builder and Parser / Interpreter The Builder, Parser and Interpreter all Assemble a Composite Structure. Parser and Interpreter Both Parser and Interpreter can take and build any Assembly from the Abstract Definition. The only restrictions they have are Memory, Parsing Speed and the available Classes to construct the Composite Structure with.

Differences Factory and Builder The Products from the Factory which have a hardcoded and fixed structure. The Assembly of Products from the Builder can vary, by changing the Production Process of that Product. Factory and Parser / Interpreter As stated before, the Factory is not able to create Dynamic structures. This makes the Factory a rigid producer. The Parser and Interpreter can produce any result, as long as it can be defined and created by either. Builder and Parser / Interpreter The Builder uses a hardcoded Assembly process which can be varied, but only by hardcoding the variations. The Parser and Interpreter can take and build any Assembly from the Abstract Definition. Parser and Interpreter The Parser is used for any generic Parsing Process. The Interpreter for language-specific issues. The Parser can also be used to create an Abstract Description from an Assembled object Tree. This is not a common use for the Interpreter.

Page 375: Re Factoring and Design Patterns

Refactoring and Design Patterns 375

LEVELS OF FREEDOM OF FACTORY, BUILDER, PARSER AND INTERPRETER ::Tag: PAT-DSTR-REL-002

ProductFactory

ProductBuilder

ResultParser /

Interpreter

1.b: «dynamic assambly»

2.b: «full freedom»

Choice from prefab products

Choice and dynamic assembly of the Product

Total freedom in the assembly of any Result

1.a: «produces»

2.a: «produces»

3: «produces»

Factory: Choice from Prefab Products Factory is the first choice if you want to have Choice in the Product that is returned from your Request.

Limitation of Factory: Prefab products from fixed Molds As mentioned before, the Factory offer choice from a limited set of Prefab Products, where the shape is defined by a limited set of Molds or Matrices: the Classes these Products are produced from. This limits the freedom and possibilities you have within a set Product, but also makes variation a dangerous thing, as each new Variation requires a new Mold or Matrix: the Class with which the Product is created.

Builder: Choice and the Dynamic Assembly of your Product Builder solves the limitations of the Factory by Dynamic Assembly. Within the Builder Pattern you create a Product via Composition. This means that any variation within a Product can be achieved by using different Parts, or putting these Parts together in a different way. Just by changing the Assembly Process, defined and placed within an object called the Director, you can produce an entire new and unique Product.

Limitations of Builder: hardcoded Assembly-Instructions As mentioned before, the limitation of the Builder Pattern is that the Assembly-Instructions that define the Composition of your Products is (usually) Hardcoded in the Director. This means that every time you need a new Composition for a specific Product, you need to add these additional Building Instructions to your Director.

Parser / Interpreter: Total freedom in the Assembly of any Result The Interpeter solves the limitations of the Builder by allowing you to inject the actual Building Instructions from an External Source. This solves any limitations you might have had from either the

Page 376: Re Factoring and Design Patterns

376 Peter Kaptein

Builder or Factory Pattern. Suddenly you can build any Custom Product you want, simply by passing the Interpreter any Building Instructions you think are sufficient.

Limitations of Interpreter: for specific use only The interpreter is only for specific use: to interpret language: words and sentences

Limitations of Parser: too much freedom leads to unclarity and loss of control The Interpreter might look like the solution for all problems, but one big issue with Interpreter is that it allows for too much freedom. You application no longer has a clear set of behaviors, but can do anything, at any time, solely depending on your External Definitions. The consequences are many. I mention a few:

1. Testability – How do you Test and Unit-test an application or set of functionalities that does not exists until the Interpreter had interpreted some External Definition?

2. Loss of traceable dependencies – How do you trace dependencies between different parts of your application when these Dependencies only exists in External Definitions, which will only be instantiated when these Dependencies are Interpreted?

3. Loss of control – Using External Definitions to define Products and even building entire Applications using this principle leads to a loss of Control in your process. Your IDE that used to inform you on errors in your code and illegal operations from one object to another, can no longer perform that function. This means that bug-tracing and bug fixing depends entirely on you testing the application in run-time

Page 377: Re Factoring and Design Patterns

Refactoring and Design Patterns 377

TRAVERSING FROM THE OUTSIDE, TRAVELLING FROM THE INSIDE ::Tag: PAT-DSTR-TRV

Composite Object

Visitor AYourClass

2: «is on a mission inside»

1.a: «instantiates»

3: «objects pass the Visitor»

1.b: «injects visitor into»

Composite Object

3: «objects reveal relationships»

Parser BYourClass

2: «uses the information from»

1.a: «instantiates»

1.b: «passes»

Dependencies on the Visitor and Composite object: Your Class: 1.a: Instantiates Visitor A 1.b: Injects the Visitor inside the Composite object Visitor A: 2: Is on a mission inside the Composite object Within the Composite object: 3: Objects pass the Visitor to other (child) objects

Dependencies on the Parser and Composite object: Your Class: 1.a: Instantiates Parser B 1.b: Passes the Composite object to Parser B Parser B: 2: Uses the information from the objects in the Composite object to do its job Within the Composite object: Objects reveal/expose their Relationships to the outside world

Page 378: Re Factoring and Design Patterns

378 Peter Kaptein

Notes: Visitor: active role for objects in the object Tree (Composite object) With the Visitor Pattern, the objects in the object Tree decide what to do with the Visitor and when and how to pass it. Parser: passive role for objects in the object Tree In contrast with the Visitor Pattern, the Parser is the one making all decisions. The objects in the object tree play a passive role, only revealing their relationships when they are asked by the Parser. Which Pattern do you choose? Depends on where you want to place responsibility The Parser and Visitor both have benefits and costs. The parser takes all responsibilities for traversing the Tree, giving you all control from the outside. The cost is an extra class, parsing the Tree. The Visitor Pattern places all responsibility for traversing inside the objects it travels through. This reduces the need for an external Class to read the Tree. The “cost” is a dependency on code within the objects you use in the Tree to do the traversing. This code is not always available.

Page 379: Re Factoring and Design Patterns

Refactoring and Design Patterns 379

SHARING AND RE-USING OBJECTS

::Tag:PAT-TYP-SH

1: SHARING AND RE-USING OBJECTS WITHIN YOUR PROJECT ::Tag:PAT-TYP-SH-T1

1: SINGLETON ::Tag:PAT-TYP-SH-STN

Singleton

+ static instance()+ someMethod()+ anotherMethod()

4: «returns instance of object to» - static _instance

3: «contains instance of»

1: «calls»Client

2: «uses»

One single instance of an object that can be retrieved and used anywhere

5: «leading to»

Visual summary of the Singleton Pattern ::Link:PAT-SING Sharing and re-using a single object The Singleton is a Pattern that allows you to share and re-use one single object though your entire project. Using a static method and calling the Class The main secret behind the Singleton is the use of static a method and static variable. The Static Method allows you to call on the Singleton Class itself. Returning the object Instance The Statich method “instance()” will do three things as described below in pseudo code:

Page 380: Re Factoring and Design Patterns

380 Peter Kaptein

// Singleton get instance method static instance(): MyClass { // Create and store object when not there yet If(_instance==null) { _instance=new MyClass(); } return _instance; }

2: MULTITON ::Tag:PAT-TYP-SH-MTN

Multiton

+ static instance( key )+ someMethod()+ anotherMethod()

4: «returns instance of object to» - static _instanceMap

3: «contains instance of»

1: «calls, using a key to identify the specific object»

Client

2: «uses»

One or more specific instances of an object can be retrieved and used anywhere

5: «leading to»

Visual summary of the Multiton Pattern Sharing and re-using one or more specific object The Singleton is a Pattern that allows you to share and re-use one single object though your entire project. Using a static method and calling the Class The main secret behind the Multiton is the use of a static method and a map with the objects mapped against a specific key. The Static Method allows you to call on the Multiton Class itself. Returning the object Instance The Static method “instance( key )” will do three things as described below in pseudo code:

Page 381: Re Factoring and Design Patterns

Refactoring and Design Patterns 381

// Singleton get instance method static instance( key:String ): MyClass { // Create and store object when not there yet object:MyClass= _instanceMap.getItem(key) If(object ==null) { object= new MyClass() _instanceMap.addItem(object, key); } return object; }

3: OBJECT MAP ::Tag:PAT-TYP-SH-DMP

3: «maps»ObjectMap

+ static getObject( key, classRef )+ static removeObject( key, classRef )+ static addObject( key, classRef )

5: «returns instance of object to» - static _objectMap

1: «calls, using a key and class reference to identify the specific object»

Client

2: «uses»

Mapping one instance of a specific object of any typeto be retrieved and used anywhere

6: «leading to»

Class A

Class B

Class C

«objects of type»

Visual summary of the Object Map Pattern Mapping, sharing and re-using one instance of a specific object The Singleton is a Pattern that allows you to share and re-use one single object though your entire project. Using a static method and calling the Class The Object Map uses a static method and a map with objects mapped against a specific key and Class Reference. The Static Method allows you to call on the Object Map Class itself, without creating any object to begin with.

Page 382: Re Factoring and Design Patterns

382 Peter Kaptein

More versatile than the Multiton While the Object Map looks a lot like the Multiton, its purpose is to literally map any object of any class against a specific key, so that you can store and retrieve any object of your wish, anywhere you need it. Promotion of persistency The primary goal of the Object Map is to promote and enable object persistency. One example is where you receive and send XML data to an external Data Service. Each time you receive that XML data, it can contain data on objects you already instantiated. Instead of creating yet another object you simply retrieve it from the Object Map and update it with the new data. Returning the object Instance The Statich method “instance( key )” will do three things as described below in pseudo code: // ObjectMap getObject method static getObject( key:String , classReference ): Object { // Create and store object when not there yet object:MyClass= _instanceMap.getItem(key, classReference) If(object ==null) { object= new classReference .create() _instanceMap.addItem(object, key, classReference); } return object; }

Page 383: Re Factoring and Design Patterns

Refactoring and Design Patterns 383

4: OBJECT POOL ::Tag:PAT-TYP-SH-OPL To be written

5: STATIC METHODS

Page 384: Re Factoring and Design Patterns

384 Peter Kaptein

EVENTS, INSTRUCTIONS AND COMMUNICATION

::Tag:PAT-TYP-EVTS

TYPE 1: DIRECT COMMUNICATION ::Tag:PAT-TYP-EVTS-T1

1: MEDIATOR ::Tag:PAT-TYP-EVTS-MED

3: «has references to»Concrete Mediator

+ yourMethodA(): do something+ yourMethodB() do something else

Centralization of communication between objects in your subsystem

5: «leading to»

«colleagues in subsystem»

Concrete Collegue A

Concrete Collegue B

2: «have references to»

4: «communicate to»

5: «delegates actions to specific»

Client

1: «uses»

Visual summary of the Façade Pattern ::Link: PAT-MED Enabling communicaton by offering a single point of entry The Mediator is a communications hub, it can be used (and is used) as a single-point of entry to an entire subsystem. Request, action, callback Where the Façade directs, the Mediator requests, the subsystem acts and then calls back to the Mediator. Observing the subsystem: top down / bottom up To be able to know what is going on within the subsystem, the Mediator can register Observers to specific objects within that subsystem. Whenever something happens within that subsystem, the Mediator can respond and ignore it or take successive actions based on (business) rules. Injecting itself into the subsystem: moving to bottom up

Page 385: Re Factoring and Design Patterns

Refactoring and Design Patterns 385

It is possible that the best way for your system to work is by injecting the Mediator into the subsystem. By doing so, the subsystem becomes the active player and the Manager simply responds when needed. Using Static methods to resolve the Mediator: simplification of your code The disadvantage of Dependency Injection is that you still have a top-down approach where one point in your code needs to know which objects required your Mediator. You can turn this chain of control around by calling directly on the Mediator Class and have the Mediator return the appropriate Mediator for the Context that code is operating in. ::Link: PAT-MED| PAT-OBS| PAT-IOC

2: MANAGER ::Tag:PAT-TYP-EVTS-MGR

Manager A Subsystem B

Your Class

1: «uses»

2.a: «addresses»

Business Logic

2.b: «uses»

3: «can address»

Visual summary of the Manager Pattern ::Link: PAT-MGR Combining the best of Mediator and Façade Mediator and Façade have a completely different way of “wrapping” a subsystem. Where Façade uses a pure top-down Hub/Spoke implementation, the Mediator is “part of the gang” and mediates the communication between the objects within that subsystem. In some cases you want to use both the directive top-down approach of the Façade and the “bottom-up” approach that can be used with the Mediator: where the objects in the subsystem are allowed to directly call the Mediator. The Manager is such a merge. It allows for a combination of top-down and bottom-up approaches without messing things up. Top down: pure Hub Like the Façade, the Manager can be implemented as a top-down system where it directs all actions. Part of the gang: dirty Hub Like the Mediator, the Manager can be used as a man in the middle for communications between objects in your subsystem.

Page 386: Re Factoring and Design Patterns

386 Peter Kaptein

Observing the subsystem: top down / bottom up Like the Mediator, to be able to know what is going on within the subsystem, the Manager can register Observers to specific objects within that subsystem. Whenever something happens within that subsystem, the Mediator can respond and ignore it or take successive actions based on (business) rules. Injecting itself into the subsystem: moving to bottom up Like with the Mediator, you can inject the Manager into the subsystem. By doing so, the subsystem becomes the active player and the Manager simply responds when needed. Using Static methods to resolve the Mediator: simplification of your code The disadvantage of Dependency Injection is that you still have a top-down approach where one point in your code needs to know which objects required your Mediator. You can turn this chain of control around by calling directly on the Mediator Class and have the Mediator return the appropriate Mediator for the Context that code is operating in. ::Link: PAT-OBS|PAT-IOC

Page 387: Re Factoring and Design Patterns

Refactoring and Design Patterns 387

3: OPERATOR

Operator A Subsystem B

Your Class

1: «uses»

2.a: «addresses»

2.b: «uses / delegates to»

3: «can address»

Subsystem C

Visual summary of the Operator Pattern ::Link:MHOPUDO-OPR Direct communication like a Mediator The Operator wraps a subsystem combining the possibilities of a Façade and Mediator, allowing for simplified access to that subsystem and centralization and the mediation of communication of objects within that subsystem. Delegating to another subsystem The Operator is a man in the middle for at least two subsystems: connecting them together. The Operator delegates explicitly to one (subsystem C) and uses and mediates with the other (subsystem B). Specialized Manager, man in the middle The Operator is the man in the middle between one subsystem and another. Connecting View to Model Within the scope of this book, the Operator is mainly used to connect a View to a Model, following the principles of MVVM (Model View, ViewModel) and MVP (Model View, Presenter) where the “Controller” is the hub between the Model and the View. ::Link:MHOPUDO-OPR|MVC-PATT-CHUB

Page 388: Re Factoring and Design Patterns

388 Peter Kaptein

TYPE 2: DECOUPLING DEPENDENCIES

1: OBSERVER

2: COMMAND ::Tag:PAT-TYP-EVTS-CMM : Command used for events and communication

Some CommandYour Object1: «uses»

Some Object

2.b: «executes actions on / delegates actions to»

Command Interface

2.a: «implements»

Visual summary of the Command Pattern ::Link: PAT-COM Using a command as a callback for events There are several reasons why you could use a Command within an event driven system. One important one is that your environment does not allow to send Methods as the call-back object. (Java, JavaScript). Instead you can use Commands with the Callback Method inside. In most cases the environment (Java and JavaScript for sutre) allow you to create these Commands within the Class your Callback Methods are living.

Why would you want this? The alternatives to Commands are a bit more rigid and require a lot more programming on your side. Where the Command has one simple standardized Interface: command.execute( someParameter ) , alternatives involve either your Class to implement a generic “callback” method which will then have to resolve and properly delegate the callback or your Dispatcher to understand what it can do with the Classes (by expecting a specific Interface on the Observer). The Command takes this kind of awkward solutions and makes them obsolete.

Sending Commands abroad to be executed when needed In some scenarios and some frameworks (like the Command Driven, and less and less used: Flex Cairngorn) Commands play a central role in sending instructions to several parts in your application. You can map and share Commands in central repositories and then retrieve these Commands for execution anywhere you like.

Why would you do this? The Command Encapsulates and Abstracts the Concrete Action and the Class it is performed on, reducing any dependency to an absolute minimum as the Code that executes a Command only has to know what Command to execute when, without the need of any knowledge what these Commands actually do.

Page 389: Re Factoring and Design Patterns

Refactoring and Design Patterns 389

The Command The Command is an object that performs a specific action on the nested object it envelops (“Some Object”) in the diagram. Each Concrete Command performs a specific action custom built within that Command. For instance: to delete a file or change color on an object.

3: EVENTS

4: MESSAGES

Page 390: Re Factoring and Design Patterns

390 Peter Kaptein

BONUS MATERIAL: WORKING WITH CALLBACKS, EVENTS, MESSAGES AND COMMANDS ::Tag: PAT-EVTS-BAS

CALLBACKS, EVENTS, MESSAGES AND COMMANDS ::Tag: PAT-EVTS-BAS-001 Callback: I am done / something specific happened The Callback is fired when a system is done with a specific action. You send the callback to the object that executes the required action and once done the object calls the Callback. Event: something has happened An Event always reflects something that has happened. Message: something has happened / I want you to do something / here is the info you requested A Message can contain anything, including a notification about something that has happened, a request to another part of your system to have something done and to send information requested by something or someone else. Command: execute specific actions, one single interface A Command has one single Interface that is standard to all Commands in your application. By default it has an “execute” command. Additionally it can have an “Undo” command. Commands can be sent to other parts of the application, can be used to create a sequence of actions stored in a List (a Macro) and to overcome limitations in Java and JavaScript regarding the remote calls on specific methods in your code. Using Commands as Callback objects Languages like Java and JavaScript treat Methods in a different way as C# and ActionScript. With Java, you can not simply send a Callback Method to the

DECOUPLING OF DEPENDENCIES ::Tag: PAT-EVTS-BAS-002 Basis: you called and I do not care who you are In a de-coupled system, the object that is supposed to perform an action does not care who called or how that object is structured. The only thing needed to make the interaction between these objects work is a specific pattern of interaction, either based on callbacks, events or messages. Dependencies? The moment one object is aware of another object, you create a dependency. “A” calls “B” and to be able to do so, “A” needs to know and define “B” as well. In code this can be as simple as: var b (type of Class) B = new B() Object A has knowledge of Object B

Object A Object B«has knowledge of»

Page 391: Re Factoring and Design Patterns

Refactoring and Design Patterns 391

What is wrong with dependencies? In general, nothing is wrong with (hard) dependencies. In most cases you explicitly define the types of objects you use and how they communicate to each other. In most cases, the dependency is one-sided. You call a method on an object and it will return a result. Multiple solutions for one problem The moment your system starts to depend on more than one specific implementation of specific functionalities (see: “Choice and Flexibility”, and the Factory patterns) you want to get rid of these so called “hard dependencies” as they stand in the way of flexible solutions. ::Link: PAT-CHC Bi-directional dependencies, asynchronous systems and callbacks Especially with systems where the object you call will not immediately respond, you need to come up with some kind of solution where that system can call back. If your system is simple and will not change, a bi-directional dependency is not a problem. “A” can have hard-coded knowledge of “B” and “B” of “A”. So A can call specific methods on B and B can call specific methods on A. Bi-directional dependency: A has knowledge of B and B has knowledge of A

Object A Object B«has knowledge of»

«has knowledge of»

When Bi-directional dependencies fail The moment your system becomes more versatile, and specific parts of your system is re-used by other parts, the hard-coded dependencies will start to break your project. It will force you to create code to solve these dependencies. You will have empty methods in Classes simply because the other side expects and demands the existence and so on. What about Interfaces? You can already decouple direct dependencies to specific Classes by implementing Interfaces. By using Interfaces you no longer refer to a specific Class, but to a specific set of methods: the Interface. Variable “B” can now be of type “Interface N” and contain Class B, C and D all based on that same Interface. Using Callbacks ::Link: PAT-EVTS-BAS-005a Using events Using messages

ASYNCHRONOUS SYSTEMS ::Tag: PAT-EVTS-BAS-003

Page 392: Re Factoring and Design Patterns

392 Peter Kaptein

performAction(paremeteX, callBackC)

callBackC()

Pro

cess B

Pro

cess A

Object A Object B

::Link:INTRDP-ASS An end to Holding States When you call an Asynchronous system, the response will either come later or never. Hardly ever the response will be “immediate” as is the case with a Synchronous system. The benefit of Asynchrous systems is that while your requested process is being executed, like loading and parsing a large file, your code and your application can continue doing other things. Knowing what is going on via Events, messages and callbacks In order to be able to respond to a change in the state of the Asynchronous process, you can either use an Event, a message or a simple, direct callback. A change in the state can be: “failed to execute”, “done with your request” or “busy now with step X in the process”.

USER INPUT AND EXTERNAL INTERRUPTS ::Tag: PAT-EVTS-BAS-003a User input: another form of Asynchronous behavior When your system starts, one of the sources of input can be the user. Either via mouse, keyboard or some other form of Human Computer Interface. Instead of putting your application into a Holding State, waiting for a response of the User before doing anything else, you run that process as an endless loop (in Java that is) into a separate thread in your code. Only when there is a change, the listener will dispatch an Event or call back to a Method or Command stating: “A key is pressed” (or released) or: “the mouse has moved”. External interrupts In the case of webservers and real-time systems, but also in the case of electronic systems with sensors, the code is waiting for external interrupts to happen: “some client requests a web-page” or: “sensor A registered movement”.

Page 393: Re Factoring and Design Patterns

Refactoring and Design Patterns 393

In these cases, again the listeners to these events can be considered objects running an Asynchronous process: while looping over an endless listening process, they will only report when a change happens: reporting the kind of change either via an Event or via a specific Callback.

EVENT DRIVEN SYSTEMS ::Tag: PAT-EVTS-BAS-004 Basic example of using Events

Object A Object B

«has knowledge of / registers observers on / calls»

«dispatches event on»

«including»

Event listeners / Observers X, Y ,Z

Observers can have registered Methods or

Commands

“Something has happened” An Event is a notification to who-ever is listening that something has happened. Not: “I want you to do something” An Event can never be an instruction. The moment you start using Events to give instructions to other parts of your application, you are building a Message driven system. Starting actions based on Events The basis of Event Driven Systems is that actions in your system are started when Events happen somewhere in your system. Sending extra information Each event can contain additional information, including: “Key x has been pressed”, “error Y has occurred” and: “Datagram NOP has been received”. The Event is, behind the scenes, the explicit callback to specific Callback Methods or Callback Commands. Where in some cases you only need to know something has happened, in other cases (for instance with data) you also want the data that is the result of the actions that have been executed. Inversion of Control: responding instead of commanding Event Driven Systems invert the chain of control. Instead of directing what should happen, your system responds on Events and starts new Actions when needed. Since Events can occur anywhere, there is no Center of control either. Anyone can do anything at any time, as long as the right Event is fired accross the right Event Bus.

Page 394: Re Factoring and Design Patterns

394 Peter Kaptein

Benefits and dangers of the Event Driven system

Benefit The Benefit of an Event Driven System is a simplification of control-lines. Objects no longer have to be aware of who is dependent on what. You simply throw an Event and whomever should respond will respond. This lack of Dependencies makes your system very scalable. Anything and anyone can be added and made to respond to specific actions.

Danger#1: Loss of control and increasing complexity of business rules The danger of this approach is that you can lose control over who sent what why. To remain control, the business rules in your application can become very complex as well. Should you respond to a specific Event or not? If yes/no why? According to what rules? According to which requirements? Danger #2: Explosion of event-types and/or Event Classes As you want to be explicit to each Event and to where and why an Event happened, you might end up in very specific Events per Class and per application or even worse, one or more very specific Event Classes per Class that can throw that Event, leading to a doubling of Classes in your project.

Limitations: events are not instructions One of the most important limitations of Event Driven Systems is that your system is always in a waiting-state. If you use Events properly, you cannot send Event to make something happen. Events are a result of a process, not an instruction for action to happen. Alternatives: Message Driven systems, Managers and Mediators

Message Driven Systems cover three main types of information: Events, Instructions and Updates. Events are notifications of things that happened. Instructions are requests for actions to be performed. Updates are blocks of information containing a new state on objects and Data. ::Link: PAT-EVTS-BAS-005 Managers centralize the decision making process into one or more Manager Classes. These Classes have all business logic to deal with the data. Within each Manager, Events, Messages and direct calls to objects can be used to handle the next step in the process. ::Link: PAT-MGR Mediators deal with events in a similar way has Managers. You call on the Mediator to get a specific action performed. The Mediator then decides which objects will be called next or which Events will be fired as a consequence. The Mediator operates as a specific Event Bus to the events and actions that are to be managed by the Mediator. ::Link: PAT-MED

Further info: Basics of the Event Events use the Observer Pattern. The Observer (your code) observes the object in which the action is performed and once that specific process is finished, the according Event (“I am done with X” or “I failed performing Y”) is dispatched by that object. Your code will receive that Event and then can execute the according actions.

Page 395: Re Factoring and Design Patterns

Refactoring and Design Patterns 395

The Dependency is only one-way. Your Code has knowledge of the object it uses to execute the action, the object that executes the actions does not need any knowledge of your object at all, reducing the Dependencies in your system. Dispatching events: Event Bubbling and the Event Bus When your code dispatches an Event, this happens on a list of Observers that is also referred to as “the Event Bus”. In systems and environments like Flash, these Events can cause a chain-reaction of successive Events to objects in the object Tree that listen to other objects in that tree. This process is called “Event Bubbling”. Object specific Events Object specific Events are dispatched from an Event Bus living in a specific object. This Event will only be visible for Observers who registered a listener to that specific object. All other Observers on other objects will not receive that Event. System-wide Events System-wide Events are dispatched on an Event Bus that is shared throughout the system. This Event Bus can be a Singleton object, or a Multiton object with a specific ID, making it possible to dispatch specific Events within a specific scope. How Events differ from Callbacks A Callback is a very explicit statement: “when done, execute this Method or Command from this specific caller”. Events are none-specific to who is calling or not. Anyone can listen in and there is not one specific receiver as is the case with a Callback. How Events use Callback Methods and Callback Commands When you look under the hood, Events use the exact same principle of a Callback. Each Observer on the Event registers either a Callback Method or Callback Command to that Event, using the Dispatcher as the Hub. These Callback Methods or Callback Commands are stored in a list, bound to the specific Event. Each time the Event is dispatched this Event-specific list is traversed and the Callback is executed.

MESSAGE DRIVEN SYSTEMS ::Tag: PAT-EVTS-BAS-005 “Something has happened” Like the Event driven systems, you can use a message to state something has happened “I want you to do something” Unlike an Event, which only broadcasts “something has happened”, a message can also be an instruction to have something done by someone or something else.

USING CALLBACKS ::Tag: PAT-EVTS-BAS-005a The basis of a Callback

Page 396: Re Factoring and Design Patterns

396 Peter Kaptein

When you call specific object, you can also send a specific object with that method call, to be used once the request is done. This is especially handy when the process executed is an Asynchronous process, meaning that your own code will continue to execute other processes while that specific requested process is still in action. When you call the object that executes the Action, you also send the callback object (a Method or a Command). The only thing Object B needs to know is how to make the callback, meaning: which parameters to use on the Callback Methods or Callback Commands. This de-couples the dependencies from a bi-directional dependency to an uni-directional dependenciy. A knows B, but B does not need to know A. Example of using Callbacks

Object A Object B

«has knowledge of / calls / sends callbacks to»

«calls back on»

«passed by / living inside»

Callbacks A, B, C

Can be Methods or Commands

Using Callback Methods Languages like C# and ActionScript allow you to send Methods as objects to the object that executes the actions. Once the requested process is finished the appropriate Method is called and executed. You can send methods for different result-states of the process (for instance: “finished successfully”, “executing this specific part of the process” and “failed executing”). Using Callback Commands Some languages like Java and JavaScript do not allow you to send Methods to the object that executes the actions. Java does not allow Methods to be executed by reference and in JavaScript, any Method you send as a parameter becomes part of the scope of the object that receives that Method. Instead, you can package the callback method inside a Command and have the object that executes the action execute the callback on the Command. The Command will then pass the Callback to the object it represents.

Page 397: Re Factoring and Design Patterns

Refactoring and Design Patterns 397

SHOUT-CASTING AND POINT-CASTING ::Tag: PAT-EVTS-BAS-006 Shout-casting Most Event Models use the principle of what I call: Shout-casting. Anyone, anywhere who is registered to that Event will receive the Dispatch of that Event. Even if that Dispatch is not relevant for that object at that point in time. It is like shouting through a full room that you have a message for everyone who wants to know something about the next Weather Forecast Point-casting Point-casting is more specific to whom will receive a specific Dispatch. Even though many objects might Observe the same Event Type to be Dispatched, they all Observe a different object or Event Bus. Point-casting is like making a telephone call to a very select list of people, instead of shout-casting your Dispatch to everyone.

THE PROBLEMS OF EVENT DRIVEN SYSTEMS ::Tag: PAT-EVTS-BAS-007 Code overhead due to Context Specific Event objects For each specific event that you Observe (via a central Event Bus), you should create a separate Event Class. This leads to Event Classes for each and everything that might and can happen in your Application. I will go into one solution for that later, in “Using the Observer Pattern with care”. Loss of Control The more Events are dispatched from different places in your system, the harder it will become to distinguish who sent what why. Where the Observer Pattern allows you to state the Sender or Dispatcher, you might not always take the effort to verify that at the receiving end. Loss of Relationships Where Classes, factories, Interfaces and Design Patterns like the Mediator can help you to keep Relationships explicit, Events invite you to do the opposite: decoupling any relationship except the Event and Event Type you share between Observer and Dispatcher. Unexpected side-effects Especially when you do not clean up the relationships between Observer and Dispatcher, Dispatched Events sometimes might reach objects that should no longer respond. For instance because these objects have been “removed” from your current Application State, but still are active, in memory and responding to every Dispatch of an Event as they still are referenced to via the Event Model Side-effects can be:

Memory Leaks As the Dispatcher – in most systems – build a reference list of the objects Observing their Dispatcher, these objects will not be cleaned from memory until that Reference is removed Unexpected Responses If you do not clean up your References, objects you though were removed might still respond to your Dispatches, leading to actions being performed without your intent or without your need and will. System overload

Page 398: Re Factoring and Design Patterns

398 Peter Kaptein

The more objects Observe, the more load will be on your system. Even if these objects do close to nothing. Also, when your system involves elaborate responses to an Event Dispatch, more and more load might be put on your CPU: to handle all actions related to that event

USING THE OBSERVER PATTERN WITH CARE ::Tag: PAT-EVTS-BAS-008 Event Dispatches should be used with care. While having several disadvantages, the basic principles of the Observer Pattern does have some very strong points to go for. Use the Observer Pattern when:

1. Shout-casting is wanted – When you deliberately want to shout-cast an Event to every registered Observer in your Application

2. Shout-casting is less costly than any other solution you can think of In the past five years I have reduced the use of the Observer Pattern more and more: to replace it for other Patterns, more related to the Mediator Pattern: where one object or Class deals with all “events”. In the cases where I use the Observer Pattern, I limit it to Point-casts on the objects and Classes in which the Events occur. This means that I can limit my Event Types and Event Classes dramatically. For instance the: “Changed” event for different situations do not require a separate class anymore. As I Dispatch “Changed” directly on the Class I Observe, instead on a Central Event Bus (which is the case for most implementations of the Observer Pattern) I can simply limit myself to Dispatch “new Event ( EventTypes.Changed );”

Page 399: Re Factoring and Design Patterns

Refactoring and Design Patterns 399

DATA AND DATA-TRANSFER

::Tag:PAT-TYPDA

TYPE 1: INJECTING VALUES INTO OBJECTS ::Tag:PAT-TYP-INJ

PARSER ::Tag:PAT-TYP-INJ-PARS ::Link:PAT-PARS

INJECTOR ::Tag:PAT-TYP-INJ-INJ

REFLECTION ::Tag:PAT-TYP-INJ-REF

TYPE 2: STORING AND RETRIEVING DATA AND OBJECTS ::Tag:PAT-TYPDA-T2

OBJECT MAP / SIMPLE REPOSITORY ::Tag:PAT-TYPDA-T2-DMP

MULTITON ::Tag:PAT-TYPDA-T3-MTT

OBJECT POOL ::Tag:PAT-TYPDA-T3-OBP

TYPE 3: WORKING WITH EXTERNAL DATA AND EXTERNAL DATA SOURCES ::Tag:PAT-TYPDA-T3

(REMOTE) PROXY ::Tag:PAT-TYPDA-T3-PRXY

DATA ACCESS OBJECTS ::Tag:PAT-TYPDA-T3-DAO

Page 400: Re Factoring and Design Patterns

400 Peter Kaptein

BONUS MATERIAL ::Tag:PAT-TYPDA-BNS

SERIALIZATION AND DE-SERIALIZATION OF DATA ::Tag:PAT-TYPDA-BNS-001

Serialization Structures into one single string of data Serialization of Data is the process where (Binary) data is and (binary) Data Structures are translated to one single string of (byte) data. Serialized data is no longer Functional objects Within the Serialized data, the separate objects and the separate Values within those objects are no longer functional. Meaning that you only have Data and no longer any Concrete objects. Identification and separation of elements To distinguish each object and each Value within the object, some sort of Identification and Separator is used. In XML this is the XML tag, like this: “<somevalue>123</somevalue>”. In JSON this looks like: “somevalue” = “123”; CSV, Binary data Within CSV, values are separated by a delimiter, like this: “value1;value2;value3”. In Binary data, the delimiter can be anything. Data Blob that can be sent from A to B The main goal of Serialization is to create some kind of simple Data Blob that can be sent form A to B.

De-serialization De-serialization of data to be able to work with it When your Application receives Serialized data, it will have to de-serialize that data first, before it is able to work with it. With XML, this means that the Clear Text String data blob you receive from the external source first has to be translated to XML objects (XML Nodes). For JSON this means either that the JSON has to be Evaluated to JavaScript objects or – when your environment is not JavaScript – De-serialized to objects. Column definition usually not in CVS and fixed width data For CVS and Fixed width, information on which Column represents what is given beforehand, either in some hardcoded line of text, or in a separate line or previous message. Binary data: deserialization is per implementation With Binary data, this can be done any way. Translate a Data Blob into an object Tree

Page 401: Re Factoring and Design Patterns

Refactoring and Design Patterns 401

The sole intention of Deserialization is to translate a Blob of Data, which is useless for your code, into some kind of object Tree that can be Iterated, Queried, Read and Modified.

Page 402: Re Factoring and Design Patterns

402 Peter Kaptein

FORMATS FOR SERIALIZED DATA ::Tag:PAT-TYPDA-BNS-002

An overview of data formats which are readable for humans XML, SOAP: Clear text object structures XML is a simple Clear Text, Hierarchic and Tag-based way to serialize data. XML can contain Nested information and complex Data Strcutures. In the basic XML is a Hierarchic Data Format, meaning that one Parent can have Many Children and Children can have Children on its own, but when one Data object is used and present many times it will be appearing multiple times in the Data Structure. Unless references are used to separate lists with the Entities presented only once. The main disadvantage of XML is the repetition of the Tags themselves, which makes XML quite expensive. In transfer of XML data from A to B this price is compensated by Zipping the Data before sending it. As XML tags are repetitive, each tag is replaced by a simple reference in the Zipped Data, to be Unzipped to the full XML data when it reaches B JSON: JavaScript objects JSON can be seen as the JavaScript equivalent of XML, but represents actual JavaScript objects. JSON can be converted to JavaScript objects simply by Evaluating the JSON data with the JavaScript method “eval()”. Like XML, the price of repetition of each Tag can be solved by Zipping the data before sending it from A to B Fixed width: old school Data Dumps Fixed With Data is one of the older formats to serialize data. With Fixed Width, each Column in your Data Structure has a fixed width. Remaining space in each Column is usually filled with spaces. Retrieving the data-elements, you simply clip each line of data into pieces of the specific length. Disadvantages are the amount of data wasted on empty space and the dependency you have on the exact width of each Column: which is usually not stated within the file with data that is serialized as Fixed Width Comma Separated Values: newer-school Data Dumps Comma Separated Values (CSV) is in its most pure form a Data format in which values are separated by a Comma (or semi-column). The advantage of CSV is that it is less expensive as Fixed Width as empty spaces are simply not there. Also, retrieving the values of the individual Columns is easier as you simply split each Row using the delimiter (Comma or Semi-column). The main disadvantage of CVS is the fact that the data-columns can contain the same character as used to separate these Columns. When you observe the way Microsoft implements CSV for Excel, you will see – at first glance – a very inconsistent implementation of CSV Serialization that seems to exist mainly out of Exceptions

An overview of data formats which are meant for machines Binary formats Binary Formats can be anything, from Open to Proprietary formats. In general, Binary Formats follow similar paths as XML, JSON and CSV, but with a more compressed approach as they are not meant to be read by Humans. Binary Formats can be very efficient in both size and the Serialization / Deserialization process as they do not suffer from the need and overhead of extra data that is only useful for humans.

Page 403: Re Factoring and Design Patterns

Refactoring and Design Patterns 403

MARSHALING / MAPPING VALUES FROM A TO B ::Tag:PAT-TYPDA-BNS-003 When you receive a Data Structure form an External Source, this Data Structure might not always fit to your Implementation of that Data. For instance: because you use two different systems with an entire different life before they met each other and started to communicate with each other. In that case, you will need to Map the Data from A to the Data Structure of B. The basic process for that is called Data Mapping. One specific implementation of Data Mapping is called Data Marshaling, where the Data is Actually mapped to the objects that require and use that data.

Page 404: Re Factoring and Design Patterns

404 Peter Kaptein

USING SERVICES TO ACCESS REMOTE DATA SOURCES ::Tag:PAT-TYPDA-BNS-004 Within the Patterns described in this book, I cover the Extended MVC Pattern. This Pattern combines several variations on MVC, including MVC, MVVMC (Model, View, ViewModel, Controller) and MVCS (Model, View, Controller, Services). The idea behind Services is to have a separate Conceptual Container for the Processes that retrieve and send data to and from External Data Sources like Databases, File Systems and Web Services. You will find the Service Pattern described earlier in this book, under the Extended MVC Pattern.

Brief on Services Data Retrieval The Service will Retrieve the data for you, using the specific protocols to connect to the External Data Source and get the data you need and request Data Storage The Service will also send your Data to the External Data Source, to be stored in whatever system is there. Again, the Service will take care of all protocols and translations need to send the data Transparency: same requests, different Services If properly implanted you can switch between different Data Sources by switching between differtent Services, without your Requester noticing any difference

See also Services:

Page 405: Re Factoring and Design Patterns

Refactoring and Design Patterns 405

USING DATA MAPPING TO TRANSLATE ONE OBJECT AND ONE STRUCTURE TO ANOTHER ::Tag:PAT-TYPDA-BNS-005

USING THE FACTORY TO RE-CREATE STRUCTURES ::Tag:PAT-TYPDA-BNS-006

See also The Factory Pattern The Parser

USING THE REMOTE PROXY TO COMMUNICATE TO A REMOTE OBJECT ::Tag:PAT-TYPDA-BNS-007 Focusing on the communication from one system to another, Bridge and Proxy are two patterns designed to help you simplify that process

Page 406: Re Factoring and Design Patterns

406 Peter Kaptein

PATTERNS MAPPED TO CONTEXT AND

ENVIRONMENT ** ::Tag:INTRDP-CONT

Page 407: Re Factoring and Design Patterns

Refactoring and Design Patterns 407

OVERVIEW

::Tag:INTRDP-CONT-BAS

CONTEXT ::Tag:INTRDP-CONT-BAS-CNTX Implementation and application of Design Patterns Each Context and each Language or Environment has its own implementation and application of Design Patterns. Especially with Macro-Patterns like MVC, this makes a “standard” approach impossible. Each MVC implementation for one Context or Environment will be significantly different from another. Different sets of challenges While there are many commonalities, Client / Server has a different set of challenges and focal points than Desktop Development. And the same goes for Rich Clients and Thin clients or Java and JavaScript / HTML environments. Overview The context I will cover briefly in this chapter are the ones below. See for a more elaborate treatment the later chapters.

CLIENT / SERVER ::Tag:INTRDP-CONT-BAS-CS The most basic Context for Web-development and systems using Remote Data Sources. With Client / Server, the system itself is distributed over at least two separate systems: the Client and the Server. Where the Client is – in most cases – the part that is running on the machine of the User, the Server runs somewhere in the Cloud ::Link:INTRDP-CLS

SYNCHRONOUS / ASYNCHRONOUS ::Tag:INTRDP-CONT-BAS-SYN Depending on your programming language, your needs and your approach the communication between Client and Server can be either / or ::Link:INTRDP-ASS

PUSH / PULL MECHANISMS ::Tag:INTRDP-CONT-BAS-PPL For each Client / Server Application two mechanisms can be used to communicate with the Server. One is Push, where the Client and the Server push Data through a (usually) persistent Socket Connection of some sort. The other is Pull, where the Client Pulls data from the Server, by sending Requests over (usually) temporary (Socket) Connections. ::Link:INTRDP-PP

THIN CLIENTS ::Tag:INTRDP-CONT-TCL Thin Clients are Client Applications which have little to no Logic running on the Client Side. ::Link:INTRDP-THCL

Page 408: Re Factoring and Design Patterns

408 Peter Kaptein

RICH CLIENTS ::Tag:INTRDP-CONT-RCL Rich Clients run a lot of Logic running on the Client side, mainly dealing with the View or Presentation Layer and making sure the View offers the best User Experience the Designers could come up with. Where there is the possibility of the presence of a rich Model on the Client Side, this Model mainly deals with Client Side issues like Retrieving data from- and Sending data to the Server and – if needed – making Data Persistent Client side, so whatever is already in Memory, Client side, does not have to be loaded again. Rich Clients can be implemented as Desktop Applications: running most of the Application locally and connecting to a Remote Source where needed. ::Link:INTRDP-RCL

DESKTOP APPLICATIONS ::Tag:INTRDP-CONT-DTP Desktop Application usually run everything Client side. Data and files are stored on the Client Machine and only when explicitly requested, the Desktop Application will store the data Remotely. ::Link:INTRDP-DSKTP

GAME DEVELOPMENT ::Tag:INTRDP-CONT-GMDV Where all previous Applications and Clients focus mainly on systems to insert, change and retrieve Data, create documents, visuals and audio/video productions, games are a different type of beast. Games mainly focus on the (usually) real time interaction between the Game and the User. Something happens and the User responds. The User responds and the Game updates its state, creating new possible responses. Another part where games differ from systems to create and manage content is that most games run a Simulation or Simulated World of some sort: in which the User Acts and Interacts. Whether it a Simple World, like the one of Pong and Tetris, or a Complex World in which you have simulated Physics, simulated Actors (people, animals, machines), and simulated objects (using either hand-drawn images or rendered images from 3D structures with textures and simulated light) ::Link:INTRDP-GMDV

IMPACT OF CHANGE FOR DESIGN PATTERNS AND MACRO-PATTERNS ::Tag:INTRDP-CONT-IMP Design Patterns Design Patterns are relatively specific and solve a specific problem. The application and choice of a Design Pattern will not vary much for the type of Client / Server applications Macro-Patterns / Design Principles For Design Principles like MVC and Extended MVC the choice of how the Client / Server implementation is done, is significant. Where (with 3-Tier kind of approaches) the impact on the Architecture of your Model and the use of the Design Patterns is minimal, for MVC and Extended MVC a change in direction usually means that about 70% to 90% of your code related to the View and how the View communicates to the Model has to be redone.

Page 409: Re Factoring and Design Patterns

Refactoring and Design Patterns 409

CLIENT / SERVER

::Tag:INTRDP-CLS Client / Server is the basis for most Web based applications. It is also increasingly becoming the choice for Desktop Applications via “the Cloud”, which is basically just a Cluster of Remote Servers waiting for you to make a connection.

OVERVIEW OF THE MAIN ASPECTS OF CLIENT / SERVER ::Tag:INTRDP-CLS-001 Delay It takes time for your connection to build up and for your data to be send and transported Connection You need a connection to send data to- and receive data from the Server Synchronous or Asynchronous? Depending on your programming language, your needs and your approach the communication between Client and Server can be either / or. We will get back to that in the next chapter Push or Pull? There are two ways to update both Client and Server. One is by using Push, where (usually) both systems Push their updates to the other, creating the possibility for a Real Time System: where actions happening somewhere are almost instantly sent and received everywhere else. With Push, both Client and Server lead. With Pull, the Client is in the lead. Regardless of what happens on the Server, the Client decides when it wants new data Rich Client or Thin Client? In general Thin Clients rely completely on the Server to do all the work, including rendering the pages and verifying the data you inserted. With Rich Clients, most of the work that can be done Client side is moved Client side, including Validations of the inserted data and transforming data into something that can be rendered on screen

RELEVANT PATTERNS ::Tag:INTRDP-CLS-RPT To be written

Page 410: Re Factoring and Design Patterns

410 Peter Kaptein

SYNCHRONOUS / ASYNCHRONOUS SYSTEMS

::Tag:INTRDP-ASS

OVERVIEW OF THE MAIN ASPECTS OF SYNCHRONOUS AND ASYNCHRONOUS PROCESSES ::Tag:INTRDP-ASS-001 Synchronous: Halting State Synchronous Processes creates a Halting State. Meaning that, until your process or request is executed, your Application (or that part of the Application) will be in a Halting State: doing nothing else but waiting for the Request to be fulfilled Asynchronous: No Halting State Asynchronous processes does not create a Halting State. With Asynchronous Processes you delegate the handling of sending and receiving data to a separate Thread which runs independently from the rest of your Application. Cause and Effect Synchronous Systems have a very simple Cause and Effect model. When A is requested, B will happen after A. With Synchronous Systems, C will not happen before B is done. With Asynchronous Systems, B can follow after C, D F and R are finished, and B can trigger J and K while E, G and H are already- and are still running on the background Event Driven Asynchronous Development usually is Event Driven, using some variation on the Observer Pattern. You register an Observer on your Handler, which gets notified once your Handler is done doing its work on the background, or failed to fulfill your request

EXAMPLES OF SYNCHRONOUS SYSTEMS IN ACTION ::Tag:INTRDP-ASS-002 ATMs and Electronic Payment Systems The payment process of an ATM and Electronic Payment System is Synchronous in the sense that while the system is checking all your credentials and negotiates the actual payment with your Bank. The System is blocking until that process is done, instead of – for instance – start another process like checking your account or start the process of a second withdrawal

EXAMPLES OF ASYNCHRONOUS SYSTEMS IN ACTION ::Tag:INTRDP-ASS-003 Postal orders and postal delivery Postal Orders can be made any time, in any quantity. Instead of you being blocked until Package A has arrived, you can Order B, C and D and each can arrive on a different time and in a different Order. Loading pages in your Web browser Most of the software you use is built on Asynchronous processes. When you ask it to do A, the system can perform B and C as a consequence without blocking you into doing D and E. One simple example is

Page 411: Re Factoring and Design Patterns

Refactoring and Design Patterns 411

your Browser. While you are waiting for a HTML page to load, you can type or select a new Url and navigate to that Url instead of the previous one. In the process of the Browser, the threads for all previous Requests are cancelled and the result (when it comes in) discarded.

RELEVANT PATTERNS Observer

Page 412: Re Factoring and Design Patterns

412 Peter Kaptein

PUSH / PULL MECHANISMS

::Tag:INTRDP-PP

Page 413: Re Factoring and Design Patterns

Refactoring and Design Patterns 413

THIN CLIENTS

::Tag:INTRDP-THCL

OVERVIEW OF THE MAIN ASPECTS OF THIN CLIENTS ::Tag:INTRDP-THCL-001 High responsibility Server side The Server is responsible for handling almost everything related to your Application, including Rendering the data into something that can be presented Client side (the View) Low responsibility Client side The Client side has only a few responsibilities, including: Rendering the View, allowing the user to Input anc Change data and allowing the user to Interact with the System itself, for instance: to request data, to store changes and remove items from the Data Source High demand on the Server Hardware As the Server does everything, including the preparation of the View by Rendering the data into something that can be presented Client Side, the CPU and the Hard drive of the Server are required to do a lot of extra work compared to Servers which only Retrieve, Handle and Store Data. Dense Data Flows As the Server prepares the entire View, a lot more data has to be sent to the Client, apart from the raw Data itself, also instructions are sent in how to Present that data

EXAMPLES OF THIN CLIENTS IN ACTION ::Tag:INTRDP-THCL-002 Websites and most current web-applications (2011) Most Websites are an example of Thin Clients. The User requests a page, searches through some dataset (including a Search Engine like Google Search) and is presented the result. The pre-cooked set of instructions to Render the View is usually made in HTML: which is then Rendered into something useable by the Browser. ATMs and Electronic Payment Systems Every time you make an Electronic Payment via a physical system, you are using a Thin Client. The Thin Client itself only has a very limited set of responsibilities (checking your PIN code and connecting to the Payment Server) where the Server has a lot of responsibilities (like checking your credibility, your identity and closing all kinds of deals with your Bank to allow and establish the payment) Remote Desktops and Citrix Clients While presenting you a working environment in which you can run Applications and do your work, Remote Desktops are Thin Clients using a Gateway to a Virtual or Physical machine somewhere else. The Remote Desktop (and Citrix Client) does nothing more than sending your Mouse and Keyboard strokes to the Server (which is the Remote Desktop) and send updates from that Remote Desktop (very local screenshots of changes in the GUI) to your Client.

Page 414: Re Factoring and Design Patterns

414 Peter Kaptein

RELEVANT PATTERNS ::Tag:INTRDP-THCL-RPT To be written

Page 415: Re Factoring and Design Patterns

Refactoring and Design Patterns 415

RICH CLIENTS

::Tag:INTRDP-RCL

OVERVIEW OF THE MAIN ASPECTS OF RICH CLIENTS ::Tag:INTRDP-RCL-001 Limited responsibility Server side With Rich Clients, the Server is mainly responsible for handling the Processes related to the Data, including but not limited to: applying Business Rules, processing and transforming the Data into different structures and formats and accessing External or Remote Data Sources Increased responsibility Client side The Client side has only a few responsibilities, including: Rendering the View, allowing the user to Input anc Change data and allowing the user to Interact with the System itself, for instance: to request data, to store changes and remove items from the Data Source Lower demand on the Server Hardware As the Server only has to focus on the main processes related to the Data, the CPU and the Hard drive of the Server have to do a lot less of work compared to Servers serving Thin Clients as Severs for Rich Clients only have to focus on Retrieving, Handling and Storing the Data. Reduced Data Flows As the Server only sends data to the Rich Client, most of the time, a lot less data has to be sent to the Client compared to Thin Clients. Also, as Rich Clients can have added procedures to Cache data Client side, the amount of Data required on successive calls can be reduced even more.

EXAMPLES OF THE RICH CLIENT IN ACTION ::Tag:INTRDP-RCL-002 Flash, Flex and HTML5 applications All three technologies (where Flex is basically a specialized implementation of Flash principles) attempt to move a lot of the Logic to Present the View towards the Client. Where Flex and Flash are very rare to find online due to the preference for Thin Clients in HTML, HTML5 applications are gaining more and more ground due to the main fact that it uses the same basis as the rest of the site: HTML and JavaScript. All three reduce the load on the Server to Providing and Handling the data as it is requested from- and sent back to the Server. Rendering the data to create the View is either done in ActionScript or in JavaScript. Database Applications All Database Applications installed locally and running within a Network, using a Central Data Repository are Rich Clients. All logic required to Process and Render the data to the View is done locally, reducing the communication between Client and Server to Requests to Send data and Store Changes. Desktop Applications storing data on the Cloud While still very early at present (January 2012), more and more applications we used to use only for Local Data will rely and work with Remote Data stored “in the cloud”

Page 416: Re Factoring and Design Patterns

416 Peter Kaptein

RELEVANT PATTERNS ::Tag:INTRDP-RCL-RPT To be written

Page 417: Re Factoring and Design Patterns

Refactoring and Design Patterns 417

DESKTOP APPLICATIONS

::Tag:INTRDP-DSKTP

OVERVIEW OF THE MAIN ASPECTS OF DESKTOP APPLICATIONS ::Tag:INTRDP-DSKTP-001 Installed on- and running completely from the Local Machine Desktop Applications are installed on the Local Machine and are started and running on that Local Machine. Prefer to store their data Locally Desktop Applications assume that your preferred location to store Data (files in most cases) is on the Local Drive. Used for relatively heavy processes Desktop Applications are used for relatively heavy and complex processes that run best on a local machine. Mainly because historically it was easier to develop such applications for one single machine (Distributed Computing and Distributed Processes are not a Mainstream thing yet within Office Environments). These relatively heavy processes include but are not limited to: Desktop Publishing, Graphic Design, 3D Design, Word Processing, creating Presentations, creating Illustrations and Drawings, manipulating Photos and Images and Programming and Compiling Applications.

EXAMPLES OF DESKTOP APPLICATIONS IN ACTION ::Tag:INTRDP-DSKTP-002 Office suites and productivity tools Including Word Processors, Spreadsheet applications and applications to create Databases and Presentations, Client Relationship Tools and Calendars Creative tools Including applications to make Illustrations and Drawings, 3D models and animations, Graphic Design, Desktop Publishing and other Pre-press work, and so on. Programming environments From simple Text Editors with line numbers to complete and complex environments like Visual Studio and Eclipse.

RELEVANT PATTERNS ::Tag:INTRDP-DSKTP-RPT

MVC AND EXTENDED MVC ::Tag:INTRDP-DPT-009

Page 418: Re Factoring and Design Patterns

418 Peter Kaptein

COMMUNICATION BETWEEN OBJECTS IN THE PROJECT ::Tag:INTRDP-DPT-003 Observer : observe events in your system and respond where needed The Observer pattern is the basis of events and event driven systems. With the Observer pattern you register an Observer to a Subject or Dispatcher using a specific Event Handle. When the Dispatcher dispatches an event with that handle, each observer on that event handle will receive a notification. The big benefit of the Observer pattern is that you can decouple any system from any other system, allowing you to create independent code blocks which deal with specific processes and then dispatch an event to notify whomever and whatever that they are done. One big risk that comes with the Observer pattern is that the connections in your system become so dis-attached that it is no longer clear who sent what dispatch why and when. Leading to seemingly irrational behavior of your application. Façade, Mediator, Operator, Manager : centralize communication and simplify the use of your subsystem Façade and Mediator both have a similar intent: to work with and talk to multiple objects and Classes to get a specific job done. The Operator and Manager patterns are derived from the Façade and Mediator: merging the two into a more versatile solution that combines the best elements of both. The difference between Façade and Mediator is that the Façade is using a Master/Slave kind of approach, where the Façade delegates every action to the subsystem, while the Mediator follows a more Democratic process in which each Actor can actively call the Mediator and the Mediator will put the request through to anyone who might be able to answer it. Commands : send objects into the world to have specific actions performed when needed Commands are a bit like packaged event handlers. Within each Command, which has a simple Interface shared over all Commands you use (starting with the method: “execute”), you implement the specific code you want to have executed on a specific object or class. Chain of Responsibility The Chain of Responsibility goes well together with the Composite pattern. The Chain of Responsibility is basically a loop traversing through your object tree until it finds something or someone who can fulfill the Request it has (the one “responsible”). Chain of Responsibility traverses from a child to a parent up, seeking a more and more generic solution or answer for the request it has been given.

COMMUNICATION WITH OTHER SYSTEMS ::Tag:INTRDP-DPT-004 Proxy Proxies Represent objects which are not there yet. The Proxy can be used to save memory and postpone the instantiation of objects (which can be very heavy on code and memory) until the very last moment. Think of virtual players and buildings living in certain locations in your virtual world. As long as your player does not visit those places, there is no need to instantiate them. On the other hand: you do want to have some representation of those elements present. For instance to store and respond to changes in your virtual world that will be needed later when you show them, like a storm, or damage inflicted by bombs dropped by the player or other virtual players.

Page 419: Re Factoring and Design Patterns

Refactoring and Design Patterns 419

The main benefit of the Proxy is that you can set all kinds of values on an object while it does not exist yet, while keeping the memory-requirements extremely low. Data Access Objects

CREATING (COMPLEX) OBJECT STRUCTURES ::Tag:INTRD -DPT-004 Composite, Interpreter, Builder, Parser : build complex object structures Composite objects are objects created by using other objects. Any object you will use in an application is a Composite of some kinds. The Parser and Interpreter are like a Builder, using some kind of definition (XML, HTML or whatever you can make up) to create any kind of structure it can.

READING COMPLEX STRUCTURES ::Tag:INTRDP-DPT-004 Parser, Visitor, Iterator : run through an object structure and perform the actions you need The Parser, Visitor and Iterator can all be used to read complex structures. All allow you to change the actions to be performed when you traverse the object structure by changing the object that does the actual work. Within the Visitor Pattern this is the Concrete Visitor itself. With the Parser and Iterator you will need to implement a Concrete Handler which you either inject or set beforehand on the Parser. Both the Iterator and the Visitor require you to implement specific methods on the objects you traverse.

MAPPING AND CREATING OBJECTS ::Tag:INTRDP -DPT-001 Singleton, Multiton, Object Map : Map and store objects for easy access and re-use With Singleton and Multiton you create one or more objects that can be shared throughout your Application without having to pass it to any and all objects in your code. The Object Map goes one step further in offering a Map of all your objects and allowing you to traverse through that map as a list, or recall specific objects like the Multiton does: to perform specific actions on that object Factory Method, Simple Factory and Abstract Factory : create objects of specific types when needed The Factory in general allows you to create one or more Context specific objects (the Product) that all share the same Interface and basic functionalities.

DYNAMIC (POLYMPORPIC) CLASSES ::Tag:INTRDP-DPT-002 Strategy, State and Bridge : Change behavior when needed Strategy and Bridge allow you to choose a specific way to deal with a specific Process. State and Bridge both allow you to change the Encapsulated behavior of an object directly, by changing the object it Encapsulated and pretends to be.

Page 420: Re Factoring and Design Patterns

420 Peter Kaptein

GAME DEVELOPMENT ::Tag:INTRDP-GMDV

OVERVIEW OF THE MAIN ASPECTS OF GAME DEVELOPMENT ::Tag:INTRDP-GMDV-001 Real Time Interaction systems Games are (in most cases) Real Time Interaction Systems, where the user performs an action, the System Responds and the user Responds to that action, creating a continuous cycle of Action and Response. Rules Based Each game is Rules Based and can be based on a Rules Based Engine which takes care of specific processes, from a simple Memory Game, to more complex games like Chess, to entire 3D environments like the Unreal Engine and Unity3D. The advantage of Rules Based Engines is that you can keep the Development of the Game itself simple. Basically, to create a new game, you only need to change the Assets, the Base Rules per Asset (how smart or dumb is an AI character, when will events be triggered? And so on) and the Environment that contain these Assets (is it a city, an island, a set of rooms?). Behavioral Models Most, if not all, games involve Behavioral Models, which are a simple form of Simulation. A Behavioral Model can be applied to simulate Physics (“when the ball hits the boundary, it will bounce under the same angle as it came in”), to simulate a Virtual Character (“when the player enters the room, the Virtual Character will be instantiated and start interacting with the Character of the Player”) and the game as a whole (“when the player dies, he is revived at the last checkpoint”, “when the player kills an opponent or wins a game, the game-difficulty increases”) Simulation of a Virtual Reality Any and all games simulate a Virtual Reality. Whether it is the simple world of Pong, where the “ball” either hits the boundaries of the playfield or the object that represents the virtual bat. In more complex systems, entire worlds in 2D and 3D are created, including the opportunities to climb ladders and jump on platforms (the so called “platform games”) and imitations of real-world phenomena’s like gravity, which can be applied to the character of the player and to the entire world and light, which can eiter be static (in hand drawn objects and elements) or dynamic (in rendered worlds where simple Phong Shading is used, or more complex and layered forms including Texture, Shadows and the use of Particles and Filters to create mist, fire, water drops and other natural elements) Many different Design Patterns As you build a game and the Rules Based Engine that shapes the basic Game Play and Behavioral Models of that

Page 421: Re Factoring and Design Patterns

Refactoring and Design Patterns 421

RELEVANT PATTERNS ::Tag:INTRDP-GMDV-RPT

MAPPING AND CREATING OBJECTS ::Tag:INTRDP-GMDV-DPT-001 Singleton, Multiton, Object Map : Map and store objects for easy access and re-use With Singleton and Multiton you create one or more objects that can be shared throughout your Application without having to pass it to any and all objects in your code. The Object Map goes one step further in offering a Map of all your objects and allowing you to traverse through that map as a list, or recall specific objects like the Multiton does: to perform specific actions on that object Factory Method, Simple Factory and Abstract Factory : create objects of specific types when needed The Factory in general allows you to create one or more Context specific objects (the Product) that all share the same Interface and basic functionalities. In that way you can – for instance – create a Base Enemy Class and Specialize that Enemy into different type of Enemies with each their own behavior, looks and whatever other properties they have.

CREATING (COMPLEX) OBJECT STRUCTURES ::Tag:INTRDP-GMDV-DPT-004 Composite, Interpreter, Builder, Parser : build complex object structures Composite objects are objects created by using other objects. Any object you will use in an application is a Composite of some kinds. The Parser and Interpreter are like a Builder, using some kind of definition (XML, HTML or whatever you can make up) to create any kind of structure it can.

READING COMPLEX STRUCTURES ::Tag:INTRDP-GMDV-DPT-004 Parser, Visitor, Iterator : run through an object structure and perform the actions you need The Parser, Visitor and Iterator can all be used to read complex structures. All allow you to change the actions to be performed when you traverse the object structure by changing the object that does the actual work. Within the Visitor Pattern this is the Concrete Visitor itself. With the Parser and Iterator you will need to implement a Concrete Handler which you either inject or set beforehand on the Parser. Both the Iterator and the Visitor require you to implement specific methods on the objects you traverse.

DYNAMIC (POLYMPORPIC) CLASSES ::Tag:INTRDP-GMDV-DPT-002 Strategy, State and Bridge : Change behavior when needed Strategy and Bridge allow you to choose a specific way to deal with a specific Process. For instance: when one of your Virtual players is in situation A, its behavior to a specific situation will be Behavior A. However when the situation (or Context) changes to B, the behavior and Response of the Virtual player will change accordingly. State and Bridge both allow you to change the Encapsulated behavior of an object directly, by changing the object it Encapsulated and pretends to be.

COMMUNICATION BETWEEN OBJECTS IN THE PROJECT ::Tag:INTRDP-GMDV-DPT-003

Page 422: Re Factoring and Design Patterns

422 Peter Kaptein

Observer : observe events in your system and respond where needed The Observer pattern is the basis of events and event driven systems. With the Observer pattern you register an Observer to a Subject or Dispatcher using a specific Event Handle. When the Dispatcher dispatches an event with that handle, each observer on that event handle will receive a notification. The big benefit of the Observer pattern is that you can decouple any system from any other system, allowing you to create independent code blocks which deal with specific processes and then dispatch an event to notify whomever and whatever that they are done. One big risk that comes with the Observer pattern is that your system becomes so dis-attached that it is no longer clear who sent what dispatch why and when. Leading to seemingly irrational behavior of your application. In most cases I dropped the Observer pattern in favor for object Maps, variations on the Mediator and Façade patterns (the Manager and Operator) and using lists of objects which I explicitly address from the “Dispatcher” or a Mediator. Façade, Mediator, Operator, Manager : centralize communication and simplify the use of your subsystem Façade and Mediator both have a similar intent: to work with and talk to multiple objects and Classes to get a specific job done. The Operator and Manager patterns are derived from the Façade and Mediator: merging the two into a more versatile solution that combines the best elements of both. The difference between Façade and Mediator is that the Façade is using a Master/Slave kind of approach, where the Façade delegates every action to the subsystem, while the Mediator follows a more Democratic process in which each Actor can actively call the Mediator and the Mediator will put the request through to anyone who might be able to answer it. Commands : send objects into the world to have specific actions performed when needed Commands are a bit like packaged event handlers. Within each Command, which has a simple Interface shared over all Commands you use (starting with the method: “execute”), you implement the specific code you want to have executed on a specific object or class. In this, Commands are one way to extract code from your classes and package them in a different class, with only a very specific task: in this case your Command. The way Commands can be implemented varies. Best is to keep it limited. Chain of Responsibility The Chain of Responsibility goes well together with the Composite pattern. The Chain of Responsibility is basically a loop traversing through your object tree until it finds something or someone who can fulfill the Request it has (the one “responsible”). This can be handy when your virtual character hits an object or creates a chain reaction. Chain of Responsibility traverses from a child to a parent up, seeking a more and more generic solution or answer for the request it has been given.

COMMUNICATION WITH OTHER SYSTEMS ::Tag:INTRDP-GMDV-DPT-004 Proxy Proxies Represent objects which are not there yet. The Proxy is used most in game development to save memory and postpone the instantiation of objects (which can be very heavy on code and memory) until

Page 423: Re Factoring and Design Patterns

Refactoring and Design Patterns 423

the very last moment. Think of virtual players and buildings living in certain locations in your virtual world. As long as your player does not visit those places, there is no need to instantiate them. On the other hand: you do want to have some representation of those elements present. For instance to store and respond to changes in your virtual world that will be needed later when you show them, like a storm, or damage inflicted by bombs dropped by the player or other virtual players. The main benefit of the Proxy is that you can set all kinds of values on an object while it does not exist yet, while keeping the memory-requirements extremely low. Data Access Objects

Page 424: Re Factoring and Design Patterns

424 Peter Kaptein

BONUS: MAPPING GAME DEVELOPMENT AND THE EXTENDED MVC PATTERN ::Tag:INTRDP-GMDV-002 Many books on Design Patterns do not- or hardly focus on Game Development. Most writers of books on Design Patterns come from Application Development backgrounds. This means that there is hardly any reference to how to Apply or how to Map Game Development to Design Patterns at all. As (almost) all basic principles apply for any Application or Software, it is not that hard to try. So here is my best attempt. ::Link:INTRDP-SARB

MODEL The Model for Game Development contains and includes: The Simulation models For the Virtual Reality that forms the basis of the Game World Rules The Rules of the Game Behavioral Models For the Game World itself, the characters in the Game World,

VIEW The View includes: Interaction Elements Including maps of the area, menus, soft-buttons to click on when your Game Controller is the mouse or your fingers on a Touch Screen Characters, visual elements, viewports

CONTROLLER The Controller takes care of: The interaction between the Player and the Game Via whatever means available Interactions between the Player and Game Elements Where Game Elements can be: Buttons, Characters and objects Allowing for different forms of Input

Page 425: Re Factoring and Design Patterns

Refactoring and Design Patterns 425

These different forms of Input can include but are not limited to: the Keyboard, a Touch Screen, Joysticks and the Mouse. In most cases, different users have different ways to interact with the Game. The time of one Console with one or two types of Interface (the Joystick, the keyboard) is not more since games broke through on Personal Computers (as they were called) and the Web. The unification of different forms of input Including but not limited to: actions from the Keyboard, a Touch Screen, Joysticks and the Mouse Note: Design Patterns come in extremely handy for this specific issuerelated to games and the Controller: to simplify the Code that is capable of translating Actions from the Keyboard to the exact same kind of In-Game Actions as the Mouse and elements on the Screen. Simply implement a Strategy (see Strategy Pattern) for each and let that Strategy handle the Input and let that Strategy normalize that input to your unified set of Actions.

VIEWMODEL OBJECT The ViewModel object is a sort of mediator between what happens on screen, between what the user does and the Model that simulates the World that forms the Game. It abstracts the direct contact between elements in your View and things that happen in your Model. This makes it easier to replace certain Implementations when you change your mind (or when you build a different game), and place them back when you want to roll back to an earlier type of solution. Façade or Mediator? Where the ViewModel object is implemented most as a Façade in systems where the user Interacts and the System Responds, in Real Time Systems, the ViewModel object is very likely implemented more like a Mediator: where the Model (with the running Simulation of your Game World) pushes changes to your View using the ViewModel object. Observers or Push lists? The next question is wheter you should use Observers or a Push-list to update ViewModel objects from the Model to the View. In most cases, both are valid and both have their advantages and drawbacks. Push lists (where each object in your View is registered in a list you loop through via the Model, via a Mediator to your View) can be used to skip elements which are not active. Push lists have the advantage that the user of the Push list know what it is addressing and can create custom actions and messages per item in that list. Observers and Dispatchers can be used to simply shout-cast some event in your Model, leading to all your Observers resolving that call and deciding whether they should take action or not. While the responsibility of action is placed at the receiving and (which can be an advantage) it also creates more overhead as all receivers will try and resolve the actions to be taken. Which takes more work and more cycles from your CPU (i.e. is more expensive) The ViewModel object takes care of- and can be used for:

Page 426: Re Factoring and Design Patterns

426 Peter Kaptein

User / Controller / Model interaction The ViewModel can Interaction between the User and the Model, including updating the position or state of elements after they have been dragged or clicked. Updates of elements in your game When your Model updates (for instance, objects fall down, things explode, a card is turned, new playcards are issued to each playere) the ViewModel object can relay these changes to your objects. The updates of elements in your game, including the score, health, Game Characters

SERVICES The Services take care of: Loading and Storing Data Loading data from- and Storing data on External Data Sources like Databases, the File System and Web-based locations Real time interaction Between two or more players on two or more computers and between players and the system, using a Real Time communication protocol, in most cases based on Push-mechanisms and Socket Connections

Page 427: Re Factoring and Design Patterns

Refactoring and Design Patterns 427

PART 9: DESIGN

PATTERNS ::Tag: PAT

Page 428: Re Factoring and Design Patterns

428 Peter Kaptein

ADAPTER ::Tag: PAT-ADP ::includesubchapters

Page 429: Re Factoring and Design Patterns

Refactoring and Design Patterns 429

INTENT (GOF)

::Tag: PAT-ADP-INT Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.

ADAPTER BASICS

::Tag: PAT-ADP-DIA-BAS

Adapter A

Class A / Object BYourClass

1.b: «uses» 2: «contains / wraps / adapts / extends / addresses»

1.a: «wants to address»

WHEN/WHAT? ::Tag: PAT-ADP-DIA-BAS-001 When you need to adapt Incompatible Interfaces You use the Adapter when the Class you want to use has an Interface that is not compatible with the needs of your code. Class Adapter and Object Adapter The Adapter Pattern knows two variations: the Class Adapter and the Object Adapter.

OTHER INFO ::Tag: PAT-ADP-DIA-BAS-002 Object Adapter The Object Adapter adapts an object by wrapping it and delegating the required actions to the Adaptee. Class Adapter The Class Adapter extends the Class that needs to be adapted, applies the required Interface your code desires and – like the Object Adapter – delegates the actions to the Adaptee, which is used as a Base Class.

Page 430: Re Factoring and Design Patterns

430 Peter Kaptein

DIAGRAMS

::Tag: PAT-ADP-DIA

VISUAL SUMMARY OF THE ADAPTER PATTERN ::Tag: PAT-ADP-VSM

+ someMethodA( ): do something return result

«class»Adaptee

Client

+ desiredMethodA( ): do something execute someMethodA() do something else

Adapter A

1: «addresses object of type»

3: «delegates actions to»

2: «adapts»

NOTES: Client addresses Adapter The Client (your code) addresses the Adaptee to have specific actions done Adapter addresses adaptee The Adapter addresses the Adaptee (the class or object that is to be adapted) to execute the concrete actions. The Adapter can contain additional code The adapter can contain additional code to comply to the needs of the Client (your code)

Page 431: Re Factoring and Design Patterns

Refactoring and Design Patterns 431

BASE CLASS DIAGRAM ::Tag: PAT-ADP-DIA-000

Adapter A

+ desiredMethodA()

+ someMethodA( )

«class»Adaptee

2.a: «implements»

Client

+ desiredMethodA( )

«interface»Target A

2.b: «extends»

«someMethodA()»

1: «addresses object of type»

Adapter A

+ desiredMethodA()

+ someMethodA( )

«class»Adaptee

2.a: «implements»

Client

+ desiredMethodA( )

«interface»Target A

«adaptee.someMethodA()»

1: «addresses object of type»

- adaptee

2.b: «contains»

Class diagram of the Class Adapter Class diagram of the Object Adapter

NOTES: Convert the Interface of a class to the one your code desires The Adapter lets you convert the interface of the Class to the one your code desires. Delegate actions The Adapter delegates the actions you request on the Adapter to the Adaptee. Added functionalities in the Adapter It is possible that your Adaptee is not able to do all required actions. In that case, the Adapter can add extra functions and actions to compensate the lacking code.

Page 432: Re Factoring and Design Patterns

432 Peter Kaptein

SIMPLE DIAGRAM OF THE ADAPTER ::Tag: PAT-ADP-DIA-001

Adapter A

Class A / Object BYourClass

1.b: «uses» 2: «contains / wraps / adapts / extends / addresses»

1.a: «wants to address»

RELATIONSHIPS: Your Class 1.a: Wants to address Class A / Object B 1.b: Uses Adapter A Adapter A 2: Instantiates, contains, wraps, adapts and addresses Object B created from Class A

Page 433: Re Factoring and Design Patterns

Refactoring and Design Patterns 433

SIMPLIFIED IMPLEMENTATION OF AN OBJECT ADAPTER ::Tag: PAT-ADP-DIA-003

AdapterA

1.a: «has a»

variable

2: «contains»

1.a: «addresses»

ObjectB from ClassA

RELATIONSHIPS: Adapter A 1.a: Has a Variable 1.b: Addresses Object B from Class A The Variable 2: Contains Object B from Class A

NOTES: Injection or Object Instantiation: same thing For the setup of the Adapter itself, it does not make a difference whether you Inject the object that will be Adapted (the Adaptee) or that the Adapter creates that object itself. The Adapter and the Variable When you look at the implementation of the Adapter, the Adapted object (or Adaptee) lives insite a Variable inside the Adapter object.

Page 434: Re Factoring and Design Patterns

434 Peter Kaptein

ADDING THE METHODS TO THE PICTURE ::Tag: PAT-ADP-DIA-004

Methods A, B, C

AdapterA

1.a: «has a»

variable

2: «contains»

1.b: «has»

Object B from Class A

3: «addresses»

Methods D, E, F

4: «inside»

RELATIONSHIPS: Adapter A 1.a: Has a variable 1.b: Has Methods A, B and C The Variable Contains Object B from Class A Methods A, B and C Address Methods D, E and F Methods D, E and F Live inside Object B from Class A

NOTES: Addressing the Adaptee As you address the Adapter, the Adapter will then address the Adaptee, acting as a man in the middle, passing all Method Calls from A to B and allowing you to Get and Set Values on the Adaptee as if you are directly communicating with it.

Page 435: Re Factoring and Design Patterns

Refactoring and Design Patterns 435

IMPLEMENTING THE CLASS ADAPTER ::Tag: PAT-ADP-DIA-004

Methods A, B, C

Adapter A1.c: «has»

Class A

1.a: «extends» 2: «addresses / can override»

Interface B / BaseClass C

1b: «implements»

Methods D, E, F

3: «inside»

DEPENDENCIES: Adapter A 1.a Extends Class A 1.b: Implements Interface B / BaseClass C 1.c: Has Methods A, B and C Methods A, B and C 2: Addresses and can override Methods D, E and F in Class A Methods D, E and F 3: Live inside Class A

NOTES: Interface / Base class on the Adapter The Interface or Base Class is implemented/extended by the Adapter. By doing this, the Adapter becomes a pluggable entity that can be used together with other Adapters with the same Interface. Single inheritance: Interface For languages that only allow Single Inheritance, only the Interface can be used to create a common and shared Interface to the outside world. Single Adapter, no Interface In some cases, or most cases (depending on your implementation and needs) you do not need an Interface at all, as your Adapter is the Base Class and there are no variations on a theme that you need to take care of. Your Adapter is used by the rest of the Code Your Adapter is then used by the rest of your Code, abstracting and shielding the Adaptee it extends.

Page 436: Re Factoring and Design Patterns

436 Peter Kaptein

USING OBJECT INJECTION INSTEAD OF OBJECT CREATING IN THE ADAPTER ::Tag: PAT-ADP-DIA-002

Adapter A

Class A / Object BYourClass

1.b: «uses / injects into» 2: «contains / wraps / adapts / extends / addresses»

1.a: «has / wants to address»

DEPENDENCIES: Your Class: 1.a: Has / wants to address Object B from Class A 1.b: Uses / injects Object B into the Adapter Adapter A 2: Contains, wraps, adapts and addresses Object B from Class A

NOTES: Fit for handling Data In some cases, you get Data that fits best in the objects and Classes from another or external system. While you might want to Adapt these objects in an earlier phase, this might be less efficient as Injecting the object into the Adapter and using the Adapter to address the object. Can be useful when Parsing An Adapter accepting foreign objects can be useful when Parsing data from one structure to another. Instead of hardcoding the required transformations in a loop, they can be extracted and encapsulated into an Adapter. Adapting XML and JSON While an Adapter in most cases is considered to Adapt an object, it can also Adapt structured Data like XML, offering an Adapted object that represents the XML. Almost a Decorator, but not quite The Adapter in this form is almost a Decorator. The main differences is that the Adapter does not add extra functionalities or behavior or nests itself into other varations on itself as the Decorator does. A possible alternative for a Data Transfer object

Page 437: Re Factoring and Design Patterns

Refactoring and Design Patterns 437

The Adapter as used here can be an alternative for a Data Transfer object: “converting” one standard into another.

COMPARISONS AND DIFFERENCES

::Tag: PAT-ADP-CDF

WHAT DIFFERENTIATES THE ADAPTER PATTERN? ::Tag: PAT-ADP-DIFF Adapt a Class or object Adapter is used to “Adapt” an existing Class or OBject, so that its methods and variables are exposed in the way you expect them or want them. The Decorator and Delegate As stated before, the Decorator and Delegate are kind of similar to the Adapter, but they differ very much in use. Where the main intent of the Adapter is to adapt the Interface of an existing Class to your needs, the intention of the Decorator is to add extra functionalities and to offer an alternative to Subclassing. The Delegate has a primary intent to delegate actions to other objects, without the intent to adapt these Classes or objects. Adapter is like Bridge, Bridge can be seen as a Dynamic Adapter The Bridge Pattern can be seen as a more sophisticated form of the Adapter. Where the Adapter only represents one type of object, the Bridge pretends to be one object while in reality it can represent and Wrap objects of many different Classes.

WHEN DO YOU USE IT? ::Tag: PAT-ADP-USE When the objects and classes are not from your code base It happens that Classes and objects you need to use in a specific Pattern are form another source than you code base. So it can be that you do not have any say in how they are implemented at all. As a consequence, you need to find a trick to make these objects and classes comply to your needs. Wrapping an existing Class or object The Adapter can be used to wrap an existing Class or object and give it the Interface, methods and variables that you need for your specific implementation. Normalize the Class or object to your needs For instance when you use a Factory and objects from another Source (an existing System) you can use the Adapter to normalize those objects so that they conform to the same Interface as all your other objects.

Page 438: Re Factoring and Design Patterns

438 Peter Kaptein

PATTERNS WITH SIMILARITIES ::Tag: PAT-ADP-SIM

DECORATOR ::Tag: PAT-ADP-DEC Similarities: using an injected object to perform the actions In some ways the Adapter can work in the same way as a Decorator, wrapping an object and adding or changing things to the existing Interface of that object. Differences: decorator should not exceed the Interface of the Base Class Decorators can be Decorated by Decorators. Unlike the Adapter, which has no restrictions in what you could and should implement within the Adapter, the Decorator should preferably only implement the Interface of the Base Decorator class. Any additional public method on a Decorator will become unreachable for your code the moment it gets decorated by another Decorator.

PROXY ::Tag: PAT-ADP-SIM-PRX Similarities: wrapping an object or Class to normalize it Both Adapter and Proxy “wrap” an existing object to normalize its behavior, Methods and Variables. Differences: representative, late instantiation of the actual object The Proxy is a Representative of an object that might not be there yet. While the Proxy can be seen as an Adapter for objects which are Instantiated later (or never), the Proxy has a “soft” link to the object it wraps. The Adapter “is” the object it wraps.

BRIDGE ::Tag: PAT-ADP-SIM-BR Similarities: abstraction and normalization The Bridge might be the most similar Pattern to the Adapter, as it is used to decouple concrete implementations of “foreign” objects from your needs in your specific code. By wrapping an object and Class with an Adapter, that Class and object can change without more implications than you needing to update your Adapter Differences: dynamic content, more flexibility The Bridge wraps the object it Represents, but can choose to change that object during runtime for any other object wit the same Interface, changing the entire behavior of the Bridge object if needed. The Adapter is usually created for one specific Class and one specific object.

FAÇADE, MEDIATOR AND MANAGER ::Tag: PAT-ADP-SIM-FAC Similar: creating a simplified and normalized interface to existing functionalities Like the Adapter, the Façade and the Mediator are used to create a simplified or more normalized interface to already existing functionalities. You can use the resulting Classes in the same way and for similar reasons as you would with the Adapter.

Page 439: Re Factoring and Design Patterns

Refactoring and Design Patterns 439

Differences of the Façade: simplification, multiple Classes and objects in a subsystem The Adapter usually only focuses on one object or Class. Even though the Façade “wraps and adapts” a collection of objects and Classes its main purpose is not to “adapt” that subsystem to the Interfaces you need, but to simplify access to that system. The “adaption” by the Façade is therefore more a consequence than a real goal. Differences of the Mediator: wrapping subsystems and direct interaction from that subsystem to the Mediator Like the Façade, the Mediator “wraps” the elements in a subsystem. Unlike the Façade, where the Façade is in control, the Mediator is like a “man in the middle”, being called by the objects it works with. Again, the potential “Adaption” a Mediator can achieve is more a consequence than a goal.

COOPERATION WITH OTHER PATTERNS ::Tag: PAT-ADP-COP To be added

Page 440: Re Factoring and Design Patterns

440 Peter Kaptein

SUMMARY

::Tag: PAT-ADP-SHS Wrapper The Adapter (like the Decorator) is also known as “wrapper” as it “wraps” the object and provides a different Interface to interact with that object. Making incompatible Classes compatible The Adapter is used to make incompatible Classes compatible to your Project and your needs within that Project. Class Adapter and Object Adapter There are two main tastes in the Adapter: the Class Adapter and the Object Adapter. The Class Adapter extends the Class that needs to be Adapted (the Adaptee). The Object Adapter addresses the object from the incompatible Class Adapting Injected objects: especially handy for Data objects The Object Adapter can be used in a more dynamic way than the default implementation by Injecting the Adaptee into the Adapter. This way, you can Adapt existing objects as you go, while keeping the original objects as they are. You will find this implementation of the Adapter (using Injection) most handy when you work with Data Objects. While using the original objects to receive and send the Data, you can use the Adapter to generalize these objects and make them work according to the standards you set within your Application. Adding extra Methods and Processes As the original Class has a different history and background, it might be that you need to add extra functionalities to make it work for your code. According to “Desing Patterns” you can use the Adapter Pattern to add extra methods and processes to an existing Class. These additional methods and process should be solely used to match and meet the required Interface for your application. Adapter and Decorator: two sides of the same coin? Both Adapter and Decorator share the same basic approach: wrapping an object within another object and addressing the wrapped object via the Wrapper. The difference is in the purpose of Adapter and Decorator. The Adapter is clearly intended to Adapt the Interface of the wrapped object (the Adaptee). The intent of the Decorator is specifically to add extra functionalities, as an alternative to subclassing.

Page 441: Re Factoring and Design Patterns

Refactoring and Design Patterns 441

SEE ALSO

::Tag: PAT-ADP-SEE Adapter as wrapper, delegate There are many ways to look at the Patterns in this book. In the overview on Patterns based on type and use you will find the patterns sorted on type and use. ::Link:PAT-TYP Overview of the Creational, Structural and Behavioral patterns Design Patterns have a basic classification in three different groups: Creational, Structural and Behavioral Patterns. ::Link:PAT-CLASS The Decorator: a specialized Adapter that is allowed to extend the Adaptee The Decorator is very similar in setup as the Adapter. While the internal workings are the same, the Intent of Decorator and Adapter are clearly different. Where the Adapter only extends the Adaptee to conform to a different or new Interface, the Decorator is used to intentionally extend the possibilities of the object it encapsulates. ::Link: PAT-DEC The Bridge: an Object Adapter with a dynamic Adaptee, used as a Base class When and if you need to Adapt a series of objects within the same family (doing the same thing in different ways) you might want to consider using a Bridge instead of an Adapter. The Bridge is explicitly used as a Dynamic Base Class. ::Link: PAT-BRI The Façade, Manager and Mediator: wrapping functionalities If you need the use of multiple objects and Classes to create the functionalities you need for your code, you shift to the wrapping (or adaption) of functionalities. The Façade, Manager and Mediator are three patterns taking care of that. See “The Wrapper Family Tree” for more info. ::Link: WRIA-REL-001 Relationships between the Patterns In “Relationships between the Patterns” I show the different relationships between the Patterns and what is used in which case. ::Link: WRIA-REL The Wrapper Family Tree The Wrapper Family Tree shows the various variation on the Wrapper theme and the relationships and differences for each Wrapper. ::Link: WRIA-REL-001

Page 442: Re Factoring and Design Patterns

442 Peter Kaptein

ASPECTS FROM “DESIGN PATTERNS”

::Tag: PAT-ADP-ASP From: Motivation [..] How can existing and unrelated classes like TextView work in an application that expects classes with a different and incompatible interface? [..] Instead, we could define TextShape so that it adapts the TextView interface to Shape's. We can do this in one of two ways: (1) by inheriting Shape's interface and TextView's implementation or (2) by composing a TextView instance within a TextShape and implementing TextShape in terms of TextView's interface These two approaches correspond to the class and object versions of the Adapter pattern. [..] Often the adapter is responsible for functionality the adapted class doesn't provide. [..] TextShape (the Adapter) can add this missing functionality From: Collaborations Clients call operations on an Adapter instance. In turn, the adapter calls Adaptee operations that carry out the request. From: Consequences [..] A class adapterl adapts Adaptee to Target by committing to a concrete Adapter class. [..] lets Adapter override some of Adaptee's behavior [..] An object adapter lets a single Adapter work with many Adaptees—that is, the Adaptee itself and all of its subclasses (if any). [..] The Adapter can also add functionality to all Adaptees at once. [..] makes it harder to override Adaptee behavior. [..] Adapters vary in the amount of work they do to adapt Adaptee to the Target interface. There is a spectrum of possible work, from simple interface conversion—for example, changing the names of operations—to supporting an entirely different set of operations. The amount of work Adapter does depends on how similar the Target interface is to Adaptee's.

Page 443: Re Factoring and Design Patterns

Refactoring and Design Patterns 443

BRIDGE ::Tag: PAT-BRI : D ::includesubchapters

Page 444: Re Factoring and Design Patterns

444 Peter Kaptein

INTENT (GOF)

::Tag: PAT-BRI-INT Decouple an abstraction from its implementation so that the two can vary independently.

BRIDGE BASICS

::Tag: PAT-BRIDC-DIA-BAS

BridgeFactory /

ObjectMap

«uses: either / principle of»

Your Class«extends»

Product / Concrete implementation

«pretends to be / delegates actions to»

«returns»

WHEN/WHAT? ::Tag: PAT-BRIDC-DIA-BAS-001 When you need a Class that can change its behavior/implementation You use the Bridge when you need a Class that can change its behavior and concrete implementation when needed. A Dynamic Base Class The Bridge is intended to act as a Dynamic Base Class, to be extended by your code. While you only extend one Base Class, that Base Class can internally instantiate any Concrete Implementation of a specific functionality. A Pretender The Bridge can be seen as a Pretender of the Classes it can Instantiate. While Your Code thinks it is working with one single object or Class (the Bridge), it is actually interacting with the Instantiated object wrapped by the Bridge.

OTHER INFO ::Tag: PAT-BRIDC-DIA-BAS-002 Using delegation The Bridge uses delegation of actions to do its work. Using a Factory or Object Map to get the delegate One way to look at the Bridge is as a wrapper around the Factory or Object Map. Using either the Factory or the Object Map you can return any object in a selected group and use it as the delegate for the delegation of actions.

Page 445: Re Factoring and Design Patterns

Refactoring and Design Patterns 445

Inversion of Control By adding an extra layer related to the object creation or retrieval within the Command Patter, you can define from the outside which object will be used to delegate against.

Page 446: Re Factoring and Design Patterns

446 Peter Kaptein

DIAGRAMS

::Tag: PAT-BRI-DIA

VISUAL SUMMARY OF THE BRIDGE PATTERN ::Tag: PAT-BRI-VSM

Base Abstraction

+ operationA()+ operationB(parameter)+ setContext(contextID)

+ operationA()+ operationB(parameter)

Concrete Implementor A

- implementor

RefinedAbstraction

+ operationC()

«Bridge»

4: «can be extended to»

3: «delegates actions to selected»

1: «can select any of»

A polymorphic class that can change its behavior and concrete implementation on runtime

5: «leading to»

2: «contains selected»

Concrete Implementor B

«implementation»

NOTES: Decoupling the “how” from the “what” The Bridge decouples the “how” (the concrete execution of actions) from the “what” (the Class you instantiate or extend in your code). Abstract and concrete implementation On the left hand side of the diagram is the Abstract implementation of the Bridge. These classes have little to no internal code and perform little to no concrete actions. The Concrete implementation is on the right hand side and allows for maximum freedom in what is implemented, as long as that concrete implementation uses the Base Class or Interface your Base Abstraction expects. Adapting the Concrete Implementation It is possible that the Classes you use to implement the actions for the Bridge have a different Interface and fingerprint from what your Base Abstraction expects. Polymorphic Class, Base Abstraction can change Concrete Implementor

Page 447: Re Factoring and Design Patterns

Refactoring and Design Patterns 447

The Base Abstraction can change the Concrete Implementor while running and – as a result – also changes its behavior. This makes the Bridge a polymorphic class. Base Abstraction / Base Class The Base Abstraction of a Bridge can be used and extended as a Base Class. All actions are delegated to Concrete Implementor All actions required form the Base Abstraction are passed through to the Concrete Implementor.

BASE CLASS DIAGRAM ::Tag: PAT-BRIDC-DIA-0000:Base class diagram of the Bridge

Abstraction

+ operationA()+ operationB(parameter)

Concrete Implementor A

+ operationA()+ operationB(parameter)

«interface»Implementor

1.a: «contains object of type»

- implementor

Concrete Implementor B

2.a: «implements»

RefinedAbstraction

2.a: «extends»

+ operationA()+ operationB(parameter)

+ operationA()+ operationB(parameter)

+ operationC()

«implementor.operationA()»

«Bridge»

NOTES: As true as possible to implementation in “Design Patterns” You will find a very similar diagram in “Design Patterns”. What I focused on are the relationships between the Classes. Interface or base class? The Bridge has no dependencies from the Implementor to the Abstraction. Each Concrete Implementor can be a completely different Class with completely different behaviors. In this case, a Interface might be the most logical choice. Abstraction as a polymorphic class Later in this chapter you will find me referring to the Bridge as a: “Polymorphic Class”. The Abstraction Class in the Bridge Pattern, according to: “Design Patterns” can be extendend and used as a Base Class. As the Abstraction can internally change the object that populates the implementor, the Abstraction Class can change its behavior during runtime. Implementing the same Interface on the Abstraction As the Abstraction Class is mainly a pass-through station like the Adapter, you might as well implement the very same Interface on the Abstraction Class as well.

Page 448: Re Factoring and Design Patterns

448 Peter Kaptein

Abstraction

+ operationA()+ operationB(parameter)+ setContext(contextID)

Concrete Implementor A

+ operationA()+ operationB(parameter)

«interface»Implementor

1.a: «contains object of type»

- implementor

Concrete Implementor B

3: «implements»

RefinedAbstraction

2: «extends»

+ operationA()+ operationB(parameter)

+ operationA()+ operationB(parameter)

+ operationC()

«implementor.operationA()»

«Bridge»

1.b: «can implement»

Setting the context in which the Bridge operates In the diagram above you will find an additional method on the Abstraction called: “setContext”. By using this further abstraction you can instruct the Abstraction object to change the Concrete Implementor when needed. The contextID can be a constant value mapped to a Concrete Implementor. Using a Factory to get the Concrete Implementor On the next pages I discuss using a Factory to get the Concrete Implementor. Using a Object Map to store and retrieve the Concrete Implementors As discussed in the State Pattern you can use a Object Map to store and retrieve the Concrete Implementors. ::Link: PAT-STT-DIA-000 What about the Flyweight? “Design Patterns” makes mention of the Flyweight in cases of re-use of objects. The Flyweight is very similar to the Object Map in the result it produces. What differs between the Flyweight and the Object Map is the way the objects are mapped and retrieved. ::Link:PAT-FLYWT

Page 449: Re Factoring and Design Patterns

Refactoring and Design Patterns 449

SIMPLE EXAMPLE OF THE BRIDGE PATTERN ::Tag: PAT-BRIDC-DIA-000

BridgeFactory /

ObjectMap

«uses: either / principle of»

Your Class«extends»

Product / Concrete implementation

«pretends to be / delegates actions to»

«returns»

DEPENDENCIES: Your Class: 1: Uses or Extends the Bridge Bridge: 2.a: Uses either a Factory Method or Strategy 2.b: Pretends to be a Product or Strategy Factory or Object Map 3: Returns the Product / Strategy

NOTES: Offering one object with choice in the concrete implementation The Bridge as described in “Design Patterns” by the Gang of Four allows for different Implementations for one single object, which the object that is Instantiated by your code is always the same object A Dynamic Base Class The Bridge is intended to act as a Dynamic Base Class, to be extended by your code. While you only extend one Base Class, that Base Class can internally instantiate any Concrete Implementation of a specific functionality. Using delegation The Bridge uses delegation of actions to do its work. Using a Factory or Object Map to get the delegate One way to look at the Bridge is as a wrapper around the Factory or Object Map. Using either the Factory or the Object Map you can return any object in a selected group and use it as the delegate for the delegation of actions.

Page 450: Re Factoring and Design Patterns

450 Peter Kaptein

MORE DETAILED DISCUSSION ON THE BRIDGE PATTERN ::Tag: PAT-BRIDC-DIA-001

Your Code

Option A

Option B

Option C

Bridge A

1.b: «uses /extends»

InterfaceA

2.a: «implements»

3.a: «instantiates / retrieves»1.a: «has a»

Context

Factory A / DataMap B

2.c: «uses»

«4: implements»

Product X

2.b: «pretends to be»3.b: «returns»

5: «is either»

DEPENDENCIES: Your Code: 1.a: Has a specific Context it lives in. 1.b: Extends or uses Bridge A Bridge A: 2.a: Implements Interface A, that is also implemented by Options A, B and C 2.b: Pretends to be the Product or Strategy that is returned from the Factory or Strategy 2.c: Uses Factory A or Strategy B to produce concrete Strategies or Products Factory A/ Object Map B: 3.a: Instantiates / retrieves Option A, B or C 3.b: Returns a Concrete Product or Strategy Option A, B and C: 4: Implement InterfaceA: the same Interface as implemented by the Bridge Product X: 5: Is either Option A, B or C

NOTES: Shared Interface: Interchangeable Bridge By using the same Interface for Option A, B, C and the Bridge itself, the Bridge becomes interchangeable with any Option instantiated by the Factory or Strategy used by the Bridge. The Bridge becomes a direct Representative of those Classes and the objects you create.

Page 451: Re Factoring and Design Patterns

Refactoring and Design Patterns 451

Bridge as Adapter When you use the Bridge as an Adapter, the game changes. You might want to implement a different Interface on the Bridge than on the objects you Instantiate to do the actual work. They might even differ deliberately. Simple pass-through Like the Adapter, the Bridge can be used to simply passes through any request / Method call to the instantiated Class, pretending to be that Instantiated Class. Using a Factory: stateless, some risks In the most simple implementation, the Options are created on demand by using a Factory. Each object returned is in that case a disposable object, not retaining any internal State, as each next time the Factory is used, a new object is created to offer Option A, B or C to the Bridge. The risk with using a Factory is that you can create a memory leak. Each object you instantiated needs to be destroyed. If some reference remains to each object you created, the garbage collector will not collect that object and it will remain in memory. Using a Object Map: creation on demand? When you want to retain some sort of State or reduce the risks to memory leaks, you can choose to use a Object Map. Each Option is stored under a specific Context ID and retrieved via that specific Context ID. You can combine the Object Map with a Factory so you can produce the object on demand: avoiding the costs of creating them all beforehand.

Page 452: Re Factoring and Design Patterns

452 Peter Kaptein

LOOKING MORE CLOSELY AT THE IMPLEMENTATION OF THE BRIDGE ::Tag: PAT-BRI-DIA-003

Bridge A

ImplementationB

InterfaceA /BaseClassB

ImplementationC

3: «implements»

2.b: «is either»

1.b: «contains /calls methods on»

1.a: «instantiates /Is bridge to /

pretends to be»

1.c: «implements»

2.a: «is of type»

ImplementationA

Variable A

DEPENDENCIES: Bridge A: 1.a: Instanitates / is bridge to / pretends to be Implementation A, B, C 1.b: Contains / calls methods on Variable A 1.c: Implements Interface A / Base Class B Variable A: 2.a: Is of type Interface A / Base Class B 2.b: Is either Implementation A, B or C Implementation A, B and C: 3: Implement Interface A / BaseClass B

NOTES: Implementing or extending the same Interface or Base Class One of the main ingredients of the Bridge is implementing the same Interface / Base Class on the Bridge and the Concrete Implementations. Using an Adapter when your Concrete Implementations differ When your Concrete Implementations come from different sources (for instance: loading the data from files, loading the data from a Web Service and loading the data from a Database, all having a different type of implementation) you can use Adapters to adapt the original code, Interfaces and Classes

Page 453: Re Factoring and Design Patterns

Refactoring and Design Patterns 453

This is illustrated on the next pages. Using a Factory or Strategy Provider In the next pages I show how a Factory or Strategy Provider can be used to offer the proper Implementation based on the Context your Class lives in.

WHEN YOU NEED TO ADAPT THE CLASSES YOU USE IN THE BRIDGE

InterfaceA /BaseClassB

Implementation C

1.b: «is either»

1.a: «is of type»

Variable A

Adapter B

Adapter C

3.a: «imple-ments»

Adapter A3.b: «adapts»

3.b: «adapts»

3.b: «adapts»

2: «is not compatible with»

Implementation B

Implementation A

Variable A 1.a: Is of type Interface A / BaseClass B 1.b: Is either Implementations A, B and C 2: Are not comparible with Interface A / BaseClass B Adapter A, B and C: 3.a: Implenent Interface A / BaseClass B 3.b: Adapt Implementation A, B and C

NOTES: Adapting incompatible Classes When your Class is not compatible with the Interface you want to use and Instantiate in your Bridge you can use an Adapter to adapt that Class.

Page 454: Re Factoring and Design Patterns

454 Peter Kaptein

WHEN DO YOU USE BRIDGE? ::Tag: PAT-BRI-USE Different implementations for the same set of functionalities When you need different implementations for the same set of functionalities Only one object as access point When you do not want to use different objects for different implementations, like can be the case with Strategy and some implementations of Simple Factory Polymorphic Base Class To create a Dynamic / Polymorphic BaseClass that can take any shape you need it to take. Any type of object within the scope of its Interface To create an object that can be any type and shape within the scope of its Interface. Abstract the choice of the actual implementation To isolate, abstract and separate the choice of the actual implementation of the functionalities (the Classes) from your project code To make your code more Agile As you encapsulate the creation process of objects AND by offering one single object to the outside world, any change behind the scenes of the Bridge can be dealt with and solved by the Bridge itself. By taking this role, the Bridge reduces the impact of change in your project To work with one concrete object instead of Interfaces and multiple Concrete Classes The Bridge wraps the choice and implementation of specific approaches in one single Class. Instead of implementing a specific Class, you simply pass the Context to your Bridge Class and the Bridge will instantiate the right Class for you. ::Link:PAT-TYP

Page 455: Re Factoring and Design Patterns

Refactoring and Design Patterns 455

COMPARISONS AND DIFFERENCES

::Tag: PAT-BRI-CDF

PATTERNS WITH SIMILARITIES ::Tag: PAT-BRI-SIM

ADAPTER, DECORATOR, PROXY ::Tag: PAT-BRI-SIM-APD Similarities: encapsulation of the Concrete system Adapter, Decorator and Adapter Abstract and Encapsulate the real object and passes all Method Calls through to the Concrete Class it represents. Adapter: represents only objects of one Type An Adapter is usually created for one single type of object, instead of a possible collection of object Types. Decorator: explicit Injection of objects to Represent, extending possibilities of object Unlike the Decorator, the Bridge does not receive an Injected object, but creates it by it self. The Bridge also is more like the Adapter in the sense that it normally does not add any extra functionality to the object it Represents. Proxy: late binding and buffering of settings Unlike the Bridge, the Proxy allows Late Binding to the actual object, taking care of all requests and settings on Values by acting as a Buffer. The Bridge does not allow Late Binding (unless it uses a Proxy as the object it bridges).

FAÇADE, MEDIATOR, MANAGER, OPERATOR ::Tag: PAT-BRI-SIM-FMMO Similarities: Encapsulation and Abstraction of the actual processes The Façade, Mediator, Manager and Operator offer one single object (the Concrete Façade, Mediator, Manager, Operator) to offer access to a set of functionalities located in a set of other objects and Classes. Like the Bridge they use other objects to perform the real actions on. Façade: only one type of implementation, represents a subsystem, fixed The Bridge offers access to different implementations, the Façade only to one specific implementation of a set of functionalities. Unlike the Façade, the Bridge does not represent a Subsystem, but only one object. Unlike the Bridge, the Façade cannot switch/change its Implementation or Subsystem. Mediator: known to the subsystem, used by that subsystem, fixed The Mediator is an active player in the Subsystem it Mediates. Instead of a Top Down approach, where the Mediator directs and the subsystems follows, the Mediator “works together with” the subsystem and Mediates which action should follow when, based on calls from the players in the subsystem. The Mediator can not switch to a different implementation when needed

DELEGATE, STATE ::Tag: PAT-BRI-SIM-DS

Page 456: Re Factoring and Design Patterns

456 Peter Kaptein

Similarities: Close relatives, delegation of the actions The Delegate might be the closest relative to the Bridge. Like the Bridge you can and would use the Delegate to encapsulate and abstract actions into a separate set of Classes you then use to create a “dynamic class” with dynamic and context-specific behavior. Like the Bridge, the State uses one single object within the wrapper to implement the Concrete Actions and this object can be an Instantiation of different Classes. State: active change of implementation The State Pattern actively changes the Implementation when a State changes: changing the behaviors behind the Methods called on the wrapper of the State Pattern. If you want to change the object that Implements the Methods of the Bridge, this needs to be done by the Bridge object itself.

COOPERATION WITH OTHER PATTERNS ::Tag: PAT-BRI-COP

OBJECT MAP, SINGLETON, MULTITON ::Tag: PAT-BRI-COP-DS Re-using the same objects In some cases where the Bridge only executes actions without any State (meaning that there are no values saved within the Bridge object) you could choose to use a Singleton, Multiton or Obect Map to map the Obejct you use over all instanitations of the Bridge. Alternative for the Factory The Object Map and Multiton specifically might be an alternative for the Factory in this case, where re-use of the same objects is preferred over creation when needed.

FACTORY ::Tag: PAT-BRI-COP-FCT Creating the objects you want to use In order to be able to switch the Concrete Implementations you can use a (Simple) Factory. Pass it the Context in which you want the Bridge to operate and the (Simple) Factory will produce the required object and Concrete Implementation.

FACTORY / OBJECT MAP ::Tag: PAT-BRI-COP-FCTOM Combining the Factory and Object Map When a Bridge changes the Concrete Implemention quite regularly due to your implementation, you might like to do only one instantiation of that object per Concrete Bridge, so that you can recall the already instantiated Implementation from a (local) Object Map instead of creation yet a new object.

ADAPTER ::Tag: PAT-BRI-COP-ADP Adapting the Concrete Implementation

Page 457: Re Factoring and Design Patterns

Refactoring and Design Patterns 457

When you use objects from another source than your Code Base, you might need and want to adapt the Classes to the needs of the Bridge and your code.

Page 458: Re Factoring and Design Patterns

458 Peter Kaptein

SUMMARY

::Tag: PAT-BRI-SHS Bridge as Pretender Bridge is a Pretender of the Concrete Classes it can implement internally Decouple actual implementation from the instantiated object The Bridge is used to de-couple the actual implementation of specific functionalities from the object (the Bridge) you use or instantiate Used as base class A Bridge can be used as a Base Class, to be extended by your specific Classes Multiple possible Implementations, only one Main Class The Bridge Pattern creates a solution in which one Class and one object (the Bridge) can represent and instantiate multiple Classes with multiple Implementations of the same thing (the Concrete Implementations of the Abstraction). Bridge as an Encapsulated Strategy and Factory Bridge can be seen as an Encapsulated implementation of the Strategy and Factory pattern, where the object itself you instantiate always remains the same and the way the functionalities are implemented is handled behind the scenes Bridge as a Polymorphic Adapter Bridge can be seen as a flexible or polymorphic version of the Adapter, “Adapting” the concrete classes it can implement to one single Class and passing through any method call on the Bridge to the Concrete Implementor. Context to decide which object to instantiate Bridge uses a specific Context to decide which Concrete Class it will implement. This Context is passed by the Requester or can be retrieved from a generic variable, like the System Settings. Decoupling of methods and their implementation Bridge decouples the concrete implementation of functionalities from the Bridge object that you Access or Extend Factory to instantiate the Class Bridge generally uses a Factory to instantiate the actual Class Different strategies for the same task Bridge can offer different strategies to solve a specific task, but all through one concrete object as the access point Using Adapters for incompatible Classes As discussed before, when you want to use or need to use Classes not compatible with your Interface or Base Class, you can use an Adapter for that Class to adapt the Interface. Inversion of Control within the Bridge Pattern by using Object Maps, Singletons or Multitons

Page 459: Re Factoring and Design Patterns

Refactoring and Design Patterns 459

Instead of letting the Bridge decide which Concrete Implementations will be used in what Context, you can use a Object Map, Singleton or Multiton to map (or store) Concrete Implementations with the Context as the key. When the Bridge requests the appropriate Implementation for a specific Context, the Map will return the Implementation you set and defined elsewhere. Inversion of Control and Unit tests This also allows you to make the Bridge easier to adapt for Unit tests. Instead of using the Concrete Implementation for the actual application, you can use and run specific classes you need to make Unit Testing of the Bridge easier.

SEE ALSO

::Tag: PAT-BRI-SEE Overview of the Patterns based on type and use There are many ways to look at the Patterns in this book. In the overview on Patterns based on type and use you will find the patterns sorted on type and use. ::Link:PAT-TYP Overview of the Creational, Structural and Behavioral patterns Design Patterns have a basic classification in three different groups: Creational, Structural and Behavioral Patterns. ::Link:PAT-CLASS The Wrapper Family Tree The Wrapper Family Tree shows the various variation on the Wrapper theme and the relationships and differences for each Wrapper. ::Link: WRIA-REL-001 The Delegate Pattern: when you simply want to delegate stuff The Delegate Pattern is very closely related to the Bridge and could be a direct copy of the Bridge when it is implemented with a Factory. Where Bridge can be used to create dynamic Classes, the Delegate can be used to create a dynamic object: to execute actions in a specific way according to your needs. ::Link: PAT-DEL Variations on the Bridge: when you need something special The most common implementations of the Bridge instantiate the Concrete Implementation in your Bridge via a Factory, a Strategy Provider or using internal code. Instead, you might need slightly different ways to do this, using for instance a State Pattern or a Data Map. ::Link: PAT-BRI-VAR State Pattern: similar behavior, changes from the inside The State Pattern uses the same setup as most of the Wrappers described in “Wrapping, Interfacing and Abstraction”. In “Relationships between the patterns” the State is mentioned as well. ::Link: WRIA-REL The Factory Pattern As discussed, the Factory Pattern can be used to provide the object that will be used to perform the concrete actions. ::Link: PAT-FAC The Strategy Pattern The Strategy Pattern provides a way to choose a specific implementation of a specific Process by using some kind of Context. As dicussed, the Strategy Pattern can provide the object the Bridge will work with. ::Link: PAT-STRA Object Maps, Multitons, Singletons: using existing objects / Inversion of Control

Page 460: Re Factoring and Design Patterns

460 Peter Kaptein

Instead of using a Factory or Strategy Provider, you can use a object Map, Singleton or Multiton to provide the object the Bridge will work with. ::Link:DTAPO Inversion of Control As discussed before, the Bridge can use a object Map, Multiton or Singleton to achieve Inversion of Control. ::Link: INTRDP-IOC

BONUS MATERIAL

::Tag: PAT-BRI-BNS

USING THE ADAPTER WITHIN THE BRIDGE FOR INCOMPATIBLE CLASSES ::Tag: PAT-BRI-DIA-004

Bridge A

Implementation B

Interface A /BaseClass B

Implementation C

4.a: «implements»

3.b: «is either»

1.b: «contains /calls methods on»

1.a: «uses»

1.c: «implements / extends»

3.a: «is of type»

Implementation A

Factory A /Strategy B

2: «returns»

Variable A

Adapter A

Class C

5.b: «extends / adapts»

4.b: «actually being»

5.a: «implements»

DEPENDENCIES: Bridge A: 1.a: Uses Factory A / Strategy B 1.b: Contains / calls methods on Variable A 1.c: Implements / extends Interface A / BaseClass B Factory A / Strategy B 2: Returns Implementation A, B or C Variable A:

Page 461: Re Factoring and Design Patterns

Refactoring and Design Patterns 461

3.a: Is of type Interface A / BaseClass B 3.b: Is either Implementation A, B or C Implementation A, B and C: 4.a: Implement Interface A / BaseClass B 4.b: Can actually be an Adapter (Adapter A, B and C, only A displayed) Adapter A: 5.a: Implements Interface A / BaseClass B 5.b: Extends / Adapts Class C

NOTES:

Page 462: Re Factoring and Design Patterns

462 Peter Kaptein

USING EITHER THE FACTORY METHOD OR OBJECT MAP ::Tag: PAT-BRI-DIA-002

Bridge A

Factory Method

Strategy

2.a: «uses either»

Your Class

1.b: «uses /extends»

Product X / Strategy Y

3: «returns»

2.b: «pretends to be»

Context

1.a: «has a»

4: «relates to»

DEPENDENCIES: Your Class: 1.a: Has a Context 1.b: Uses / extends Bridge A Bridge A: 2.a: Uses either Factory Method or Strategy 2.b: Pretends to be Product X / Strategy Y Factory Mathod / Strategy: 3: Returns Product X / Strategy Y Product X / Strategy Y: 4: Relates to the Context on Your Class

NOTES: Factory and Strategy are one option You can achieve the dynamic aspect of the Bridge by using the Factory and Strategy Patterns. Another options is to use the State Pattern. More on that later. Using a Context You need to inform your Bridge somehow what kind of object(s) it should instantiate. For this, you can pass a Context that is used by the Factory or Strategy Provider to return the appropriate Product or Strategy.

Page 463: Re Factoring and Design Patterns

Refactoring and Design Patterns 463

IMPLEMENTING THE BRIDGE PATTERN WITH A FACTORY OR OBJECT MAP ::Tag: PAT-BRI-DIA-005

Bridge A

ImplementationB

InterfaceA /BaseClassB

ImplementationC

4: «implements»

3.b: «is either»

1.b: «contains /calls methods on»

1.a: «uses»

1.c: «implements / extends»

3.a: «is of type»

ImplementationA

FactoryA /StrategyB

2: «returns»

Variable A

DEPENDENCIES: BridgeA: 1.a: Uses – Factory A or Strategy B to create a Concrete object 1.b: Contains and Calls methods on Variable A 1.c: Implements or Extends InterfaceA / AbstractClass/BaseClassB Factory A / Strategy B: 2: Returns an object, based on the Concrete Implementation A, B or C Variable A: 3.a: Is of type InterfaceA or AbstractClassB 3.b: Is either Implenetation A, B or C Concrete Implementations A, B, C 4: Implements Interface A or extend Abstract Class B

Page 464: Re Factoring and Design Patterns

464 Peter Kaptein

NOTES: Bridge can implement any Concrete Implementation As discussed, this setup makes it possible to implement any of A, B and C and access them via Bridge A and Variable A. Bridge can pretend to be any object It allows Bridge A to pretend to be any object it instantiates this way, going as far as allowing you to Extend Bridge A as a Concrete class which can take any Concrete shape as you use it in your code. Using Adapters for incompatible Classes As discussed before, when you want to use or need to use Classes not compatible with your Interface or Base Class, you can use an Adapter for that Class to adapt the Interface.

Page 465: Re Factoring and Design Patterns

Refactoring and Design Patterns 465

USING A OBJECT MAP, MULTITON OR SINGLETON TO BRIDGE AND ACCESS AN EXISTING OBJECT ::Tag: PAT-BRI-DIA-006

Bridge A

ImplementationB

Interface A /BaseClass B

«Implementation C»Object Z

4: «implements»3.b: «contains

either»

1.b: «contains /calls methods

on»

1.a: «uses»

1.c: «implements/extends»

«Implementation A»Object X

«Implementation B»Object Y

Singleton A /Multiton B /DataMap C

2.b: «returns»

Variable A

3.a:«is of type»

2.a: «uses»

1.d: «has a»

Context

Dependencies: Bridge A: 1.a: Uses Singleton A, Multiton B, Object Map C 1.b: Contains / calls methods on Variable A 1.c: Implements / extends Interface A / BaseClass B 1.d: Has a Context Singleton A / Multiton B / Object Map C: 2.a: Uses the Context 2.b: Returns Implementation A, B or C Variable A: 3.a: Is of type Interfface A / BaseClass B 3.b: Contains either Implementation A, B or C Implementation A, B or C: 4: Implement / extend Interface A / BaseClass B

Page 466: Re Factoring and Design Patterns

466 Peter Kaptein

NOTES: Using a Factory / Strategy Provider To get a specific Object Map / Singleton / Multiton you might want to use a Factory / Strategy provider The difference in approach: Mapping re-usable objects The difference in approach to the previous implementations in this chapter on the Bridge Pattern is the use of three Patterns that allow you to map, store, share, re-use and retrieve already Instantiated objects with a specific implementation. Where the Singleton simply returns one Instance, the Multiton and Object Map allow you to store and retrieve several Instantiated (persistent) objects. Using the Context to retrieve a specific object You can map the Concrete Implementations in your object Map and Multiton using the Context as your reference. Inversion of Control and Dependency Injection This variation on the Bridge allows you to apply Inversion of Control and Dependency Injection, by moving the responsibility of choosing which Implementation should be used under what Context outside the Bridge. Using Adapters for incompatible Classes As discussed before, when you want to use or need to use Classes not compatible with your Interface or Base Class, you can use an Adapter for that Class to adapt the Interface. The difference in this implementation is in using a Object Map, Multiton or Singleton in step 1.a. As long as the returned object uses the same Interface (InterfaceA) or BaseClass (AbstractClassB) it is interchangeable with any other Class and object in that range and useable by the Bridge.

Page 467: Re Factoring and Design Patterns

Refactoring and Design Patterns 467

ASPECTS FROM “DESIGN PATTERNS”

::Tag: PAT-BRI-ASP From: Motivation [..] When an abstraction can have one of several possible implementations, the usual way to accommodate them is to use inheritance. An abstract class defines the interface to the abstraction, and concrete subclasses implement it in different ways. [..] The Bridge pattern addresses these problems by putting the Window abstraction and its implementation in separate class hierarchies. From: Consequences [..] An implementation is not bound permanently to an interface. The implementation of an abstraction can be configured at run-time. It's even possible for an object to change its implementation at run-time. From: Implementation [..] In situations where there's only one implementation, creating an abstract Implementor class isn't necessary. [..] How, when, and where do you decide which Implementor class to instantiate when there's more than one? [..] If Abstraction knows about all ConcreteImplementor classes, then it can instantiate one of them in its constructor; it can decide between them based on parameters passed to its constructor. [..] Another approach is to choose a default implementation initially and change it later according to usage. [..] It's also possible to delegate the decision to another object altogether. In the Window/WindowImp example, we can introduce a factory object From: Related patterns An Abstract Factory can create and configure a particular Bridge. The Adapter pattern is geared toward making unrelated classes work together. [..] Bridge, on the other hand, is used up-front in a design to let abstractions and implementations vary independently.

Page 468: Re Factoring and Design Patterns

468 Peter Kaptein

BUILDER ::Tag: PAT-BLD: Discussing the Builder Pattern ::includesubchapters

Page 469: Re Factoring and Design Patterns

Refactoring and Design Patterns 469

INTENT (GOF)

::Tag: PAT-BLD-INT Separate the construction of a complex object from its representation so that the same construction process can create different representations.

BUILDER BASICS

::Tag: PAT-BLD-DIA-BAS

Director A

2: «uses / requires build actions from

either »

3: «constructs / returns»

3: «constructs / returns»

3: «constructs / returns»

Your Code

1.b: «uses / injects builder into / asks to construct product»

1.a: «selects»

Builder A

Builder B

Builder C

Product Composition X.b

Product Composition X.a

Product Composition X.b

WHEN/WHAT? ::Tag: PAT-BLD-DIA-BAS-001 To build dynamic structures The Builder pattern is used to allow you to build several versions on the same product, using object composition. Fixed set of build-instructions, variable outcome While the Builder Pattern can have fixed building instructions inside the Director, the Builder Classes can implement these instructions each in a different way, leading to the same kind of constructions with completely different implementations. See the illustration below.

OTHER INFO ::Tag: PAT-BLD-DIA-BAS-002 Builder and Composition In most cases, the Builder will produce a Product using the Composite Pattern. Builder and Factory

Page 470: Re Factoring and Design Patterns

470 Peter Kaptein

Like the Factory, the Builder constructs a Product. Unlike the Factory, the Builder constructs each Product using a set of Building Instructions in the Director. By changing the Director, or using a different set of Building Instructions, the Builder can produce a different Product with a different Composition Builder and Interpreter The Builder resembles the Interpreter in the sense that both Interpreter and Builder create Composite objects that can vary depending on the Building Instructions. Where Builder uses a fixed / hardcoded set of Instructions to Build the Composite Product, the Interpreter uses a variable definition. This variable definition is an External Structure like – for instance – an XML definition of the Product that should be produced.

Builder

Prefab parts + prefab assemblyProducts from pre-programmed sets of combinations allowing to create more variation

«uses»

«can produce»

prefab assembly

instructions

«receives»

= Your classes The concrete products made from the parts

Page 471: Re Factoring and Design Patterns

Refactoring and Design Patterns 471

DIAGRAMS

::Tag: PAT-BLD-DIA

VISUAL SUMMARY OF THE BUILDER PATTERN ::Tag: PAT-BLD-VSM

Director

+ constructA(): cb.buildPart .. cb.buildPart .. cb.buildPart .. result=cb.getResult() return result

Concrete Builder

Overrides / implements:+ buildPartA()+ buildPartB()+ buildPartC()+ getResult()

Client

Composite Object

2: «uses»

1: «uses»

4: « construct and returns»

6: «returns composite object to»

5: «is returned to»

3: «addresses»

NOTES: Director and Concrete Builder The Builder Pattern consists of two main parts: the Director and the Concrete Builder. The Director: defines the order and use of build-instructions The Director defines the order and use of build-instructions. Alternation in build-instructions leads to different objects By alternating the order of the build-instructions in the Director and adding specific instructions and leaving others out, you can compose very specific products for very specific needs. The Concrete Builder: creating the Composite object The Concrete Builder creates the Composite object. Altering the Concrete Builder leads to different results As each build-instruction can be implemented in a different way and with different types of objects, altering the Concrete Builder can lead to a completely different product, as other “materials” can be used to produce the same type of object as instructed by the Director.

Page 472: Re Factoring and Design Patterns

472 Peter Kaptein

BASE CLASS DIAGRAM ::Tag: PAT-BLD-DIA-000:Base class diagram of the Builder Pattern

«base class/interface»Base Builder A

+ buildPartA()+ buildPartB()+ buildPartC()+ getResult()

Concrete Builder A

Director A

+ setBuilder( builder )+ construct()

- builder

Override / implement:+ buildPartA()+ buildPartB()+ buildPartC()+ getResult()

3.b: «is of type»

Composite Object

3.b: «produces / builds / returns»

Concrete Builder B

Override / implement:+ buildPartA()+ buildPartB()+ buildPartC()+ getResult()

2: «extends / implements»«for all objects in structure buildPart .. () buildPart .. () buildPart .. () return getResult()»

NOTES: Setting the Builder The Director only defines what the construction process will be, by calling a specific set of “build Part” methods on the Concrete Builder. Which Builder is used is defined by the code that instantiates or used the Director. Constructing the Product The Construction of the Product is a step by step process, ended by a “get Result” call. Many Builders, same instructions, similar products, different parts Each Builder you create within a series implements the same Interface and exposes the same Building Instructions. When you Director use Builder A or Builder B, it will use the same instructions on either. Using Builder A, it will build a cabinet with red doors made of plastic, while Builder B will make a similar cabinet use brown doors made of wood. The end-result might be the “same” cabinet, but with a different look and made from (entirely) different materials. Relationship with the Factory Patterns Where the Factory Patterns only return one specific object that is restricted to the Classes the Factories use to produce the specific Product, the Builder can construct any possible variation on that Product by defining and determining the composition of that Product itself. ::Link: PAT-FAC Relationship with the Parser

Page 473: Re Factoring and Design Patterns

Refactoring and Design Patterns 473

The Parser is similar to the Builder in the sense that the result of the Parsing Process is a Composite object that can have any possible composition. Where the resulting Composite object from the Builder Pattern is restricted to the (hardcoded) variations in the Director, the Parser can use any Abstract Definition (including an external XML file) to build any Composite object possible. ::Link:PAT-PARS Using parameters and Factories with the Builder To allow a more dynamic way to construct the products, you can use factories and parameters. These approaches are included in the Bonus Material section in this chapter. ::Link: PAT-BLD-BNS

Page 474: Re Factoring and Design Patterns

474 Peter Kaptein

SIMPLIFIED DIAGRAM OF THE BUILDER PATTERN ::Tag: PAT-BLD-DIA-001

Director A

2: «uses / requires build actions from

either »

3: «constructs / returns»

3: «constructs / returns»

3: «constructs / returns»

Your Code

1.b: «uses / injects builder into / asks to construct product»

1.a: «selects»

Builder A

Builder B

Builder C

Product Composition X.b

Product Composition X.a

Product Composition X.b

DEPENDENCIES: Your Code 1.a: Selects a Builder 1.b: Uses Director A, injects the selected Builder into Director A and asks Director A to construct the Product Director A 2: Uses Builder A, Bo or C and instructs the Builder to build the Product using a fixed set of instructions Builder A, B or C 3: Constructs and returns a Product Composition of variation X.a, X.b or X.c

Page 475: Re Factoring and Design Patterns

Refactoring and Design Patterns 475

IMPLEMENTING THE BUILDER PATTERN ::Tag: PAT-BLD-DIA-002

Director A

Your Code

1: «uses / injects builder into / asks to construct product»

BuilderX

4.a: «is injected

into»

Set of building instructions

2.b: «has»

3: «are invoked on»

Variable B

Product X.n

5: «is returned to»

4.b: «produces»

2.a: «uses»

DEPENDENCIES: Your Code 1: Uses Director A, injects builder into Director A, asks Director A to construct the Product Director A 2.a: Uses Variable B 2.b: Has a set of Building Instructions The Set of Building Instructions 3: Are invoked on Variable B Builder X 4.a: Is injected into Variable B 4.b: Produces Product X.n Product X.n 5: Is returned to Your Code

Page 476: Re Factoring and Design Patterns

476 Peter Kaptein

NOTES: Multiple sets of Building Instructions in the Director The Director can contain multiple sets of Building Instructions to be performed on the Builder. Using these sets, your Code can create several sets of Products each with small (or big) differences in their implementations. Composite Structures The Builder produces Composite Structures, using Constructors which are either hardcoded in the Builder, or placed into external classes. Builder is one of many possible implementations The Builder injected into the Director is one of many possible implementations. Using the Pattern as described in “Design Patterns”, you can create several different Builders, each implementing the same Interface, but each creating their own variation on the theme. Allows for the use of a Factory or Strategy to choose a Builder out of a set many As you will see on the next pages, the Builder Pattern is quire open to the use of the Factory to allow you to choose one of many possible implementations of the Builder. Inversion of Control On the other hand, you can also choose to inject the Concrete Builder into the Director, leaving the choice of the right Concrete Builder up to your Code.

Page 477: Re Factoring and Design Patterns

Refactoring and Design Patterns 477

SUMMARY

::Tag: PAT-BLD-SHS A more versatile version of the Factory: building dynamic structures Where the Factory Pattern allows you to create any number and mix of Prefab Products, the Products themselves are always the same. Any change that is required in the way that Product is constructed has to be implemented as yet another subclass. The Builder allows you to build any variant of a Product, based on Prefab Parts, allowing you to create variation in the way a Product can be built. So instead of creating yet another Subclass, you simply add and change the set of Assembly Instructions. The Director: containing the building-instructions The Director contains the building instructions. The Builder: using Prefab Parts to Build the Products The Builder uses Prefab Parts to build the Products. These parts are like LEGO blocks or the different parts of an IKEA product. You choose the Builder, the Director creates Within the Builder Pattern, according to the Gang of four, you choose which Builder will be used to create the Product. To create the actual Product you need, you then pass it to a Director which will invoke a set of Building Instructions on the Builder to produce the wanted Product. Shared interfaces and limitations of connections Each of these Prefab Parts share some kind of Interface allowing the Builder to do and do not perform specific actions, like connecting parts to other parts and embedding one set of parts into another set of other parts. So, for instance: where you can connect a door to a hinge, you cannot connect a door directly to the cabinet. The Director: using Prefab Building Instructions to Build The Director uses a set of Prefab Building Instructions to create a set of different Products. While the Director can build different variations of Products, the possibilities and variations on Products made from the available Prefab Parts are limited to what is hardcoded in the Director. These hardcoded Instructions are like the manual with which the Product is put together. Many Builders, same instructions, similar products, different parts Each Builder you create within a series implements the same Interface and exposes the same Building Instructions. When you Director use Builder A or Builder B, it will use the same instructions on either. Using Builder A, it will build a cabinet with red doors made of plastic, while Builder B will make a similar cabinet use brown doors made of wood. The end-result might be the “same” cabinet, but with a different look and made from (entirely) different materials. Dynamic building instructions: using a Parser You can choose to bypass the limits of the known Builder Pattern by implementing a Parser that uses String Values or XML instead of hardcoded instructions to build a Product.

Page 478: Re Factoring and Design Patterns

478 Peter Kaptein

SEE ALSO

::Tag: PAT-BLD-SEE Overview of the Patterns based on type and use There are many ways to look at the Patterns in this book. In the overview on Patterns based on type and use you will find the patterns sorted on type and use. ::Link:PAT-TYP Overview of the Creational, Structural and Behavioral patterns Design Patterns have a basic classification in three different groups: Creational, Structural and Behavioral Patterns. ::Link:PAT-CLASS The Decorator: using an alternative pattern to build a Composite object Instead of building your Composite objects with the Composite Pattern, you can also use the Decorator Pattern. While the type of objects are slightly different, the result can be very much the same. ::Link: PAT-DEC The Parser: using an Abstract Definition to create a Composite object The Parser uses Abstract definitions to create Composite objects. This approach is very similar to what the Director does, but not bound to a hardcoded definition of the Building Process. ::Link:PAT-PARS The Factory: more single-minded, using classes The Factory Pattern can be seen as a simple relative to the Builder Pattern. All aim to provide your code with an result that is created from choice based on one or more input parameters (the Context). ::Link: PAT-AFC The Visitor: getting or constructing something from the Composite object It is possible you use the Builder to create an object structure to be translated into something else. For instance: the HTML code for a HTML page. The Visitor can visit each object in the Composite and extract the data or information you need to create another type of object. ::Tag:PAT-VIS

Page 479: Re Factoring and Design Patterns

Refactoring and Design Patterns 479

COMPARISONS AND DIFFERENCES

::Tag: PAT-BLD-CDFF

WHEN DO YOU USE THE BUILDER? ::Tag: PAT-BLD-USE As an alternative for the Factory The Builder can be used as an alternative for the Factory. By choosing both the Director and the Builder from a “Builder Factory” When you have a lot of variations on a theme but want to limit your classes The Builder Pattern allows you to create a lot of variations using only a handful of classes. Like the IKEA range of products, your Builder can create completely different things using some basic materials like the body of your product and then “decorate” it using a selection of Prefab Parts. When an Interpreter is overkill and a Factory does not provide The Interpreter is basically a very ambitious version of the Builder Pattern: allowing you to build anything with any Prefabricated Part that you have available using some kind of instruction set (like XML). As it is, the Interpreter can be overly complex and overkill for your needs. By using String Values or XML and a simple “interpreter”, based on your very specific needs, you can use the building instructions passed from Your Code to the Director. By looping through your instructions and using some kind of recognition / selection mechanism, the Director can invoke the proper Methods on your Builders to construct your Product and pass your variables to refine the actions. Game development The Builder can be useful in Game Development to create Virtual objects from basic components which can be varied endlessly. These components can be behaviors to attack, retreat, negotiate and so on, but also parts to construct vehicles, buildings.

WHAT DIFFERENTIATES THE BUILDER PATTERN? ::Tag: PAT-BLD-DIFF Factory: rigid structure The Factory produces a Product with a rigid and unchanging structure. Parser: based on Abstract Definitions The Builder uses hardcoded Building Instructions to build the Composite object. The Parser uses definitions that can be XML to build the Composite object. Interpreter: language and semantics-centered The Interpreter is primarily focused on language and semantics. Composite: a result The Composite is a Result of the Building Process. The Composite Pattern itself does not construct any Composite structures. Decorator: wrapping only a single object

Page 480: Re Factoring and Design Patterns

480 Peter Kaptein

The Decorator wraps an existing object and extends the possibilities by adding extra functionalities. Decorators are used and – in general – do not play an active role themselves.

PATTERNS WITH SIMILARITIES ::Tag: PAT-BLD-SIM

FACTORY ::Tag: PAT-BLD-SIM-FCT Similarites: produces objects (Products) Like the Builder, the Factory is used to create and build objects (Products) within a shielded environment, with the main goal to abstract the actual process from the requester. Fixed result, using Classes instead of constructing composite objects The Factory creates a fixed set of Products using and instantiating classes. The Builder can build any kind of product using Classes as Building Blocks or Prefab Parts: like a Do It Yourself object Construction Kit. This makes the Builder much more fit to produce objects with the same Interface, but slight differences in their internal buildup.

INTERPRETER ::Tag: PAT-BLD-SIM-INT Similarities: builds dynamic composite structres Like the Interpreter, the Builder can build Dynamic Structures, usually as Composite Structures. Language / semantics centered The Interpreter focuses on language and semantics.

PARSER ::Tag: PAT-BLD-SIM-PAR Similarities: building Composites The Parser, like the Builder creates Composite objects based on building instructions. Parser: more freedom, no fixed building instructions The Parser relies on Abstract Definitions (or Building Instructions) usually provided as XML or another form of open format. This allows for maximum freedom as there are no fixed building instructions in your code.

COOPERATION WITH OTHER PATTERNS ::Tag: PAT-BLD-COP

COMPOSITE ::Tag: PAT-BLD-COP-COM A result of the Building Process The Composite is one of the possible results the Builder can produce.

Page 481: Re Factoring and Design Patterns

Refactoring and Design Patterns 481

FACTORY ::Tag: PAT-BLD-COP-FCT Produces the objects for the Concrete Builders In most cases you will use a (Simple) Factory to produce the objects you need in the Concrete Builder.

Page 482: Re Factoring and Design Patterns

482 Peter Kaptein

BONUS MATERIAL

::Tag: PAT-BLD-BNS

IMPLEMENTING THE BUILDER PATTERN WITH A FACTORY OR OBJECT MAP ::Tag: PAT-BLD-DIA-002

Director A

Builder A

Builder B

Builder C

Your Code

1.b: «uses / injects builder into / asks to construct product»

1.a: «uses» Factory A / DataMap B

BuilderX

2.b: «produces»

4.a: «is of type»

4.b: «is injected

into»

Set of building instructions

5.b: «has»

5.b: «are invoked on»

Variable B

Product X.n

6: «is returned to»

2.a: «chooses / instantiates»

3: «implement»

4.c: «produces»

5.a: «uses»

Interface B

DEPENDENCIES: Your Code 1.a: Uses Factory A 1.b: Uses, injects Builder into, asks to Construct Product to Director A Factory A / Object Map B 2.a: Chooses or instantiates Builder A, B or C 2.b: Produces Builder X Builder A, B and C 3: Implement Interface B Builder X 4.a: Is of type Interface B 4.b: Is injected into Variable B 4.c: Produces Product X.n The Set of Building Instructions 5.a: Uses Constructors on Variable B 5.b: Has Building Instructions Product X.n

Page 483: Re Factoring and Design Patterns

Refactoring and Design Patterns 483

6: Is returned to Your Code

NOTES: Factory A / Object Map B Since we want to dynamically choose a Builder, we can use a Factory or Object Map to do so. An alternative is to produce the Builder from a Singleton, so that we use just one Instantiation of a Builder throughout our Project Interface B Since each Builder should be interchangeable, they all implement the same Interface. Director A and the construction of Products Director A does the actual Construction using the rather “Dumb” Builder and has and provides the Building Instructions. Each Builder simply provides the Assembly Line to make the products based on prefab parts, but the Director decides how these parts are combined and put together. Building Instructions on each Builder The Building Instructions on each Builder are actually the Methods you call to “create” that specific part of the Assembly. Concrete implementations of the shared Interface These Methods are Concrete Implementations of the Shared Interface between each Builder. The Director revisited The Director contains a set of Prefab Assembly Instructions it can evoke on any Builder. These Assembly Instructions are derived from the shared Interface between each Builder. By putting these instructions in a- and any specific Order and by using repetitions and patterns of construction, the Director can create any kind of construction the Prefab Parts allow it to build. Result from the Building Instructions Even though the Building Instructions might be the same for all Builders (A, B and C) each uses and produces a different type of “Prefab Part” (your Classes, each producing a object doing a specific task or presenting a specific part). See the illustration we used before:

Builder

Prefab parts + prefab assemblyProducts from pre-programmed sets of combinations allowing to create more variation

«uses»

«can produce»

prefab assembly

instructions

«receives»

= Your classes The concrete products made from the parts

Page 484: Re Factoring and Design Patterns

484 Peter Kaptein

Using different Parts and different Combinations Each Builder can build an set of Products with the Parts is has access to. Using these parts, the Builder can produce or Build any variation that these parts allow. Including combinations leading to more complicated constructions like shown in the 3rd result in the image above. Using different Builders: same construction, but made from different parts Each Builder constructs Products from the Prefab Parts it has access to. Where one Builder has wooden parts made by Brand A, another Builder might use golden parts made by Brand B to construct the same Product. So while the construction might be the same, the Parts on which the construction is based can be completely different. Leading to different behaviors and different looks.

IMPLEMENTING THE BUILDER PATTERN USING A CONCRETE FACTORY ::Tag: PAT-BLD-DIA-003

Director X Builder A

Builder B

Builder C

Your Concrete Factory

2.c: «asks to construct product»

2.b: «selects»

Director A

Director B

Director C

2.a: «selects»

3: «is used as»

Your Code

1: «uses»

Builder Y

5: «uses»

Product Z.1

6: «creates»

4: «is used as»

DEPENDENCIES: Your Code:

Page 485: Re Factoring and Design Patterns

Refactoring and Design Patterns 485

1: Uses Your Concrete Factory Your Concrete Factory : 2.a: Selects Director A, B or C 2.b: Selects Builder A, B or C 2.c: Asks to construct a Product to Director X Director A, B, C: 3: Is used as Director X Builder A, B, C: 4: Is used as Builder Y Director X: 5: Uses Builder Y Builder Y: 6: Creates Product Z.1

NOTES: What if you can dynamically choose both the Director and the Builder The Director contains the Building Instructions. The Builder contains the Concrete instructions to produce the resulting Product. What if you can dynamically choose and combine them? It would allow you to create a great variation of Products while you only need to pass two parameters (the Context), to choose the Director and the Builder. Moving it further Below you find a diagram taking this concept even further:

Page 486: Re Factoring and Design Patterns

486 Peter Kaptein

CREATING DYNAMIC PRODUCTS USING THE BUILDER PATTERN INSIDE A FACTORY ::Tag: PAT-BLD-DIA-004

Your Concrete Factory A

Director 1

Director 2

Director 3

1.b: «uses»

Product 1.A2: «creates»

Product 2.A2: «creates»

Product 3.A2: «creates»

Your Concrete Factory B

Director 1

Director 2

Director 3

1: «uses»

Product 1.B2: «creates»

Product 2.B2: «creates»

Product 3.B2: «creates»

Builders of type A1.a: «gets/uses»

Builders of type B1.a: «gets/uses»

Your Abstract Factory M

1.c: «extend»

DEPENDENCIES: Your Concrete Factory A, B 1.a: Gets / uses Builders of Type A or Type B 1.b: Uses Directors 1, 2 and 3 1.c: Extend Your Abstract Factory A Directors 1, 2 and 3 2: Creates Product 1, 2 and 3 of type A or B

NOTES: Stable Directors, variable Builders In this version of the “Builder Factory”, the Directors are stable and we only change the Builders (A or B). The Directors can remain stable as we want to create similar Products (1, 2 and 3) in each Factory and only want to vary the concrete implementation or internal construction of each Product (variation A and B). Directors Instruct, Builders deliver the Concrete Parts As stated before, the Directors Instruct the Builder how to Assemble the Product. The Builder itself (A or B) then selects the Prefabricated Parts (your Classes) to create the Concrete Product. More variation possible with less Classes

Page 487: Re Factoring and Design Patterns

Refactoring and Design Patterns 487

This construction allows you to create a lot of variation in producing different Products in your Factory, using Prefab Parts and Assembly Instructions instead of Prefab Product Molds to create the result. It is most useful when your Factory has to produce Products with the same basic structure, but slight differences in the Building Parts. Short and simple: The IKEA Principle. Can you solve this via Injection / Inversion of Control? You can reach the same goals by using Inversion of Control / Dependency Injection. The result we achieve here however is that we extend the Factory itself to produce the products with a Builder instead of using Classes. This combination uses the benefits of both the Factory and Builder Pattern.

Page 488: Re Factoring and Design Patterns

488 Peter Kaptein

ASPECTS FROM DESIGN PATTERNS

::Tag: PAT-BLD-ASP From: Applicability Use the Builder pattern when [..] the algorithm for creating a complex object should be independent of the parts that make up the object and how they're assembled. [..] the construction process must allow different representations for the object that's constructed. From: Participants ConcreteBuilder [..] constructs and assembles parts of the product by implementing the Builder interface. [..] defines and keeps track of the representation it creates. [..] provides an interface for retrieving the product Director [..] constructs an object using the Builder interface. Product [..] represents the complex object under construction. ConcreteBuilder builds the product's internal representation and defines the process by which it's assembled. From: Collaborations [..] The client creates the Director object and configures it with the desired Builder object. [..] Director notifies the builder whenever a part of the product should be built. [..] Builder handles requests from the director and adds parts to the product. [..] The client retrieves the product from the builder. From: Consequences [..] It lets you vary a product's internal representation. [..] It isolates code for construction and representation [..] Clients needn't know anything about the classes that define the product's internal structure; such [..] Each ConcreteBuilder contains all the code to create and assemble a particular kind of product. The code is written once; then different Directors can reuse it to build Product variants from the same set of parts. [..] It gives you finer control over the construction process. Unlike creational patterns that construct products in one shot, the Builder pattern constructs the product step by step under the director's control. Only when the product is finished does the director retrieve it from the builder. From: Implementation [..]Builders construct their products in step-by-step fashion. From: Related Patterns Abstract Factory is similar to Builder in that it too may construct complex objects. The primary difference is that the Builder pattern focuses on constructing a complex object step by step. Abstract Factory's emphasis is on families of product objects (either simple or complex). Builder returns the product as a final step, but as far as the Abstract Factory pattern is concerned, the product gets returned immediately. A Composite is what the builder often builds.

Page 489: Re Factoring and Design Patterns

Refactoring and Design Patterns 489

CHAIN OF RESPONSIBILITY * ::Tag: PAT-CRS ::includesubchapters To be done

Page 490: Re Factoring and Design Patterns

490 Peter Kaptein

COMMAND ::Tag: PAT-COM ::includesubchapters

Page 491: Re Factoring and Design Patterns

Refactoring and Design Patterns 491

INTENT (GOF)

::Tag: PAT-COM-INT Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.

COMMAND BASICS

::Tag: PAT-COM-DIA-BAS

Some CommandYour Object1: «uses»

Some Object

2.b: «executes actions on / delegates actions to»

Command Interface

2.a: «implements»

Some System

3: «provides the command» 2.c: «is passed to»

WHEN/WHAT? ::Tag: PAT-COM-DIA-BAS-001 Sending command objects into your project, have them executed elsewhere The Command Pattern allows you to send objects into your project that contain specific callbacks to specific parts of your code. Combined with an Object Map you can even create a system that has no dependencies between the caller and callee of a specific Command. Inversion of control Commands allow for Inversion of Control by separating the definition of the Command from the actual execution. Each and any Command can be executed to perform a specific action and by sending a different Command for the same action, you can change the location where and way in which that command is executed.

OTHER INFO ::Tag: PAT-COM-DIA-BAS-002 Who creates and passes the Command to Some System? The Command is passed and created by what is called the “Client”. Using an unified Command Interface

Page 492: Re Factoring and Design Patterns

492 Peter Kaptein

Each Command implements exactly the same Interface as any other Command in your collection. While each Command can be handling completely different actions on completely different objects, you can use each and all Commands in exactly the same way. Depending on the type of Command, this Interface shares the methods “execute()” and, if there is an Undo: “undo()”

Page 493: Re Factoring and Design Patterns

Refactoring and Design Patterns 493

DIAGRAMS

::Tag: PAT-COM-DIA

BASIC CLASS DIAGRAM ::Tag: PAT-COM-DIA-000

Client

Receiver

+ action()

Concrete Command

+ execute()+ undo

2.b: «extends / implements»

+ receiver2.a: «has reference to /

calls methods on»

Invoker

+ doSomething()+ undoSometing()

+ command(list)

Base Command

+ execute()+ undo()

1.b: «creates / injects Receiver into»

3: «has reference to / calls methods on»

1.a: «can create / has knowledge of»

1.c: «makes command available for»

NOTES: As true as possible to implementation in “Design Patterns” You will find a very similar diagram in “Design Patterns”. What I focused on are the relationships between the Classes. Client can be Receiver As you will see in the next diagrams, the Client can be the Receiver as well: creating the Command and making that Command available for the Invoker. This can be the case, for instance, when you use the Command Pattern within the Observer Pattern: to invoke callbacks on the Client / Observer.

Page 494: Re Factoring and Design Patterns

494 Peter Kaptein

BASIC COMMAND PATTERN ::Tag: PAT-COM-DIA-001

Some CommandYour Object1: «uses»

Some Object

2.b: «executes actions on / delegates actions to»

Command Interface

2.a: «implements»

Some System

3: «provides the command» 2.c: «is passed to»

DEPENDENCIES: Your object: 1: Uses Some Command Some Command: 2.a: Implements the Command Interface 2.b: Executes Actions on Some object 2.c: Is passed to Some System Some System: 3: Provides the command to Your object

NOTES: Who creates and passes the Command to Some System? The Command is passed and created by what the authors from “Design Patterns” call the “Client”. Where is the Client? In the previous diagram you saw the Client, who creates the Command and binds the Receiver to the Command. In this diagram we assume that process to be done and handled by another part of the application. We see that process come back in the next diagram. Using an unified Command Interface Each Command implements exactly the same Interface as any other Command in your collection. While each Command can be handling completely different actions on completely different objects, you can

Page 495: Re Factoring and Design Patterns

Refactoring and Design Patterns 495

use each and all Commands in exactly the same way. Depending on the type of Command, this Interface shares the methods “execute()” and, if there is an Undo: “undo()” Commands as standard units for the execution of Actions By using the unified Interface, the Commands become Standard Units for the execution of Actions. This means that you can inject any and all Commands into a container and execute each and all using the exact same Method without the need for your code to know what Actions it executes or how those actions are executed by each Command.

Page 496: Re Factoring and Design Patterns

496 Peter Kaptein

INJECTING AN OBJECT INTO THE COMMAND OBJECT ::Tag: PAT-COM-DIA-002

Some CommandYour Object3: «uses»

Some Object

4.b: «executes actions on»

Command Interface

4.a: «implements»

Object A

1.a: «injects Some Object into»

1.b: «can be / can instanitate»

Some System

2: «provides the command»

1.b: «passes command to»

DEPENDENCIES: Object A: 1.a: Injects Some Object into Some Command 1.b: Can be / can instantiate Some Object 1.c: Passes Command to Some System Some System: 2: Provides the Command to Your Object Your Object: 3: Uses Some Command Some Command: 4.a: Implements Command Interface 4.b: Executes actions on Some Object

NOTES: Where is the Client? Object A can be considered the “Client” as we seen it in the class diagram. It can either be the Receiver (“Some Object”) or Instantiate the Receiver.

Page 497: Re Factoring and Design Patterns

Refactoring and Design Patterns 497

USING SEVERAL COMMANDS ON THE SAME OBJECTS ::Tag: PAT-COM-DIA-003

Command AYour Object3: «uses»

Object X

Interface B

2.a: «implement»

1.b: «injects Object X into»

Command B Command C

2.b: «executes actions on»

1.a: «creates / can be»Object A

DEPENDENCIES: Object A: 1: Injects Object X into Command A, B and C Command A, B and C: 2.a: Implement Interface B 2.b: Executes actions on Object X Your Object: 3: Uses Command A, B and/or C

NOTES: Command as a specialized Decorator In a way, the Command is similar to the Decorator. It allows you to extend the possibilities of an object by adding extra Operations to the Command and using these Operations to do stuff with the object inside the Command object. As the Command only executes one Method to perform the action (and one to undo that action), the Command can be seen as a specialized Decorator with a very specific use: to execute a Command on the object it contains. Extracting and extending functionalities into and via the Command You can use the Command to extract (secondary) functionalities from the object and the Class it Commands, to simplify that Class. Additional to this, the Command can be used to extend the functionalities of that object by implementing these functionalities and Actions inside the Command instead of the Class and object it Commands.

Page 498: Re Factoring and Design Patterns

498 Peter Kaptein

WHEN DO YOU USE THE COMMAND PATTERN

::Tag: PAT-COM-USE To pass the execution of a specific set of actions to another object Using the Command Pattern, you can pass the execution of specific actions to other objects by passing the Command itself To abstract and normalize the execution of actions You can use the Command to normalize the execution of specific actions to a basic set of actions like: “execute” and “undo”. To create lists of actions (a Macro) to be performed You can use Commands to create a list of actions that can be performed in sequential order, also called a “Macro”. As each Command has the same Interface and set of commands, but the code behind those commands differ, you can achieve a lot by simply run these commands in a specific order. As you can easily change the order of actions and create new lists, the Command Pattern can be very useful for any process of actions you want to standardize. Observer Pattern: If you need a callback on an action When you want to send standardized

Page 499: Re Factoring and Design Patterns

Refactoring and Design Patterns 499

COMPARISONS AND DIFFERENCES

::Tag: PAT-COM-CDFF

PATTERNS WITH SIMILARITIES ::Tag: PAT-COM-SIM

DELEGATE ::Tag: PAT-COM-DEL Similarities: delegating the actions Like the Command, the Delegate delegates the actions to another object. Not sent to another place, interface is not standardized Unlike the Command, you do not use the Delegate to be sent somewhere else to execute the specific actions. Where the Interface of the Command is very much standardized in order to create any Command and have them all executed in exactly the same way, the Delegate is created for very specific uses and use cases.

OBSERVER ::Tag: PAT-COM-OBS Similarities: sending an object abroad for later callback The Observer Pattern relies on callbacks to the Observers that observe a Subject. Calling back a list of objects, no internal logic The Observer assumes you can have many callbacks based on an Event. In principle the Observer does not include any additional actions to the callback. It will not try to perform any specific additional tasks.

COOPERATION WITH OTHER PATTERNS ::Tag: PAT-COM-COP

THE COMMAND AND INVERSION OF CONTROL ::Tag: PAT-COM-IOC

Page 500: Re Factoring and Design Patterns

500 Peter Kaptein

SUMMARY

::Tag: PAT-COM-SHS A Command object invokes actions on the object it contains A Command object is used to invoke a set of Actions on the object it contains, via one Method. Command.execute() The most common method to execute the Actions within the Command is the “execute()” method. This Method contains all the actions that Command object and Class can invoke on the object it Commands. Undo: Command can be used to store and retrieve the state of an object The Command object can be used to extract and store the State of an object. Using this State, the Command can then Undo the action it performed earlier. Objects can be injected into the Command The Command object is in its most basic form a wrapper with a limited and standardized set of instructions. To keep things simple you can inject the object on which you want to execute the actual actions into the Command object. A Command can be seen as a specific variation on the Delegate Pattern The Command does the same or similar work as the Delegate: delegating the real action to the object it wraps. Can be used to implement specific aspects of Inversion of Control

SEE ALSO

::Tag: PAT-COM-SEE Overview of the Patterns based on type and use There are many ways to look at the Patterns in this book. In the overview on Patterns based on type and use you will find the patterns sorted on type and use. ::Link:PAT-TYP Overview of the Creational, Structural and Behavioral patterns Design Patterns have a basic classification in three different groups: Creational, Structural and Behavioral Patterns. ::Link:PAT-CLASS The Observer Pattern: using Commands to remove any dependency on Interfaces You can use the Command in the Observer Pattern to provide a standardized way to handle callbacks. ::Link: PAT-OBS-ALT-001 The Delegate Pattern: delegating actions Like the Command, the main purpose of the Delegate Pattern is to invoke commands on another object and delegate the actual execution of the required actions to that object. : :Link: PAT-DEL The Visitor: similar to the Command, travelling inside object trees The Visitor is used as a “Command” sent into and inside an object Tree to perform specific actions within that Tree. These actions can vary from collecting data to changing values and performing actions on the Tree itself.

Page 501: Re Factoring and Design Patterns

Refactoring and Design Patterns 501

::Link:PAT-VIS The Decorator Pattern: the more versatile cousin of the Command The Command Pattern can be seen as a specialized Decorator. Like the Decorator it allows you to extend an object by adding axtra actions to that object. The Command Pattern has a very specific use: to execute a specific set of Actions on the object it “decorates”. ::Link: PAT-DEC Bypassing limitations in Java and JavaScript: using Commands inside the Observer Pattern The problem with languages like Java and JavaScript is that you cannot pass Methods as Callbacks to the Dispatcher (or Subject). By using Commands instead of the Observer object, you can work around that possible shortcoming. ::Link: PAT-OBS-ALT The Memento Pattern: enabling undo The Memento Pattern is used by the Command to create a backup of the current state of that object, by creating a backup of the state of that object: the objects and values it contains. Depending on your needs, that Memento can be a deep copy or a shallow copy. Reflection: reading the contents of any object Reflection is a way to “read” the structure of any object that allows Reflection (not all languages allow Reflection by default and some need explicit settings to do so). You can use reflection to travers through any object in your structure and make a data-dump to allow an “undo”. ::Link: PAT-REFL The Parser in combination with Reflection The Parser (in combination with Reflection) is a more generic variation on the Memento Pattern, allowing you to Parse the content of an object to an Abstract Defintion or object Model. ::Link:PAT-PARS

Page 502: Re Factoring and Design Patterns

502 Peter Kaptein

COMPOSITE ** ::Tag: PAT-CMP ::includesubchapters

Page 503: Re Factoring and Design Patterns

Refactoring and Design Patterns 503

INTENT (GOF)

::Tag: PAT-CMP-INT Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.

Page 504: Re Factoring and Design Patterns

504 Peter Kaptein

DIAGRAMS

::Tag: PAT-CMP-DIA

VISUAL SUMMARY OF THE COMPOSITE PATTERN ::Tag: PAT-CMP-VSM

Non-terminal node A

Non-terminal node B

Object Structure AClient A1: «contains»

«non-terminal nodes»

3: «can be child of»

An object tree with nodes and children, that can be of any depth

5: «leading to»

Terminal node A

Terminal node B

«terminal nodes»

4: «can be child of»

2: «can contain»

NOTES: Composites, Leafs and nodes In “Design Patterns” the Composite Pattern contains Leafs and Composites. In this diagram, Leafs and Composites are displayed as “terminal” and “non-terminal” nodes. Object tree In the most basic implementation the Composite object is an object Tree, starting from one object (the “root”) and branching into several directions (via “nodes” or “branches”). Endless depth In theory there is no depth to the Composite object except what memory and performance concerns. Essential for three other Patterns The Composite Pattern is essential for three other Patterns: the Parser, Builder and the Interpreter.

Page 505: Re Factoring and Design Patterns

Refactoring and Design Patterns 505

Reading the object Tree To read the object Tree, two Patterns come into mind: the Parser and the Visitor Pattern.

Page 506: Re Factoring and Design Patterns

506 Peter Kaptein

BASE CLASS DIAGRAM ::Tag: PAT-CMP-DIA-000 : Base class diagram of the Composite Pattern

- compositeObject

«base class / interface»Base Component A

+ someMethod( )+ add( component )+ remove( component )+ getChild( index )

Leaf A Composite A

2: «extends»

Client

Override / implement:+ someMethod()+ add( component )+ remove ( component )+ getChild( index )

Override / implement: + someMethod()

- children

3: «are of type»

«for each item in children: item.someMethod()»

1.a: «is of type»

1.b: «contains either»

NOTES: Leafs and nodes The Composite Pattern recognizes two main items: leafs and nodes. The nodes can contain one or more children. The Leafs are the endpoint of each and all node. Composite object: the node The Composite object is the Node within the tree structure. It can contain one ore more children. Leafs: who cares anymore? In most implementations of the Composite Pattern, the Leaf is simply a Node without any children. A more contemporary version of the Composite Pattern A more contemporary version of the Composite Pattern does not necessarily include Leafs. Instead you can focus more on different type of Nodes, for instance representing specific objects as defined in an XML structure you parse.

Page 507: Re Factoring and Design Patterns

Refactoring and Design Patterns 507

- compositeObject

«base class / interface»Base Node A

+ someMethod( )+ add( component )+ remove( component )+ getChild( index )

Node Type A Node Type B

2: «extends / implements»

Client

- children3: «are of type»

1.a: «is of type»

1.b: «contains either»

+ yourMethod()Override / Implement:+ someMethod()

+ myMethod()Override / Implement:+ someMethod()

«for each item in children: item.someMethod()»

Extending a Base Component with all relevant methods and variables The simplest, but not only way, to implement the Composite Pattern is by extending a Base Class that contains all methods and variables you need to build the Composite object. As you extend this Base Class, you automatically make each Node interchangeable for any other Node where it concerns the base type and base methods. Implementing the Interface When your Classes do not allow for extension of the Base Class, you can implement an Interface instead. Naturally you will have to implement the variables and methods on the Base Node in each Class you apply the Interface to.

Page 508: Re Factoring and Design Patterns

508 Peter Kaptein

COMPARISONS AND DIFFERENCES

::Tag: PAT-CMP-COM

WHAT DIFFERENTIATES THE COMPOSITE PATTERN? ::Tag: PAT-CMP-DIFF Composite object: unrestricted structure and size The Composite Pattern is the only Pattern focusing on the creation of a Composite object without boundaries. All other Patterns have a fixed structure and fixed size. Versatility The Composite Pattern can be used to build almost any and every from and shape. This makes the Composite Pattern one of the most versatile Patterns. Essential basis for three other Patterns Without the Composite Pattern, three other Patterns are not possible. These Patterns are the Parser, Builder and Interpreter. While shown as part of those Patterns, the Composite is really a stand-alone Pattern.

PATTERNS WITH SIMILARITIES ::Tag: PAT-CMP-SIM

DECORATOR ::Tag: PAT-CMP-SIM-DEC Similarities: building a composite structure The Decorator, like the Composite, can be seen as a simplified Composite structure. Used to change and extend the possibilities of existing objects Where the Composite Pattern has the intent to create composite objects “that can be treated as one”, the intent of the Decorator is to change and extend the possibilities of the objects a Decorator wraps.

COOPERATION WITH OTHER PATTERNS ::Tag: PAT-CMP-COP

BUILDER, PARSER, INTERPRETER ::Tag: PAT-CMP-COP-BPI Uses Composite Pattern The Builder, Parser and Interpreter all use the Composite Pattern to build the Product it will return to the Client.

VISITOR, PARSER ::Tag: PAT-CMP-COP-VIS Can be used to traverse the Composite Pattern, no similarities The Visitor and the Parser can be used to travers through the Composite Pattern.

Page 509: Re Factoring and Design Patterns

Refactoring and Design Patterns 509

INTERPRETER ::Tag: PAT-CMP-COP-INT Builds a composite structure, can be iterated with the Visitor The Interpreter can be seen as a very specialized Composite, used specifically to translate semantic data to an object structure. Both Interpreter and Composite can be traversed by the Visitor Pattern to get and use the data in the Composite structures.

SUMMARY

::Tag: PAT-CMP-SHS Hierarchic structures The Composite Structure is a Hierarchic Structure starting at the Root and branching into different nodes. Represents a dynamic structure The Composite Pattern represents a dynamic structure, that can change depending on needs. Can contain and represent anything The Composite can contain and represent anything, from data-structures, to instructions and workflows to be performed, to objects and View Components on a display list. Unlimited size The size of a Composite object can be unlimited. The only restrictions you will encounter are memory and processing speed. Is used by several other Patterns The Composite Pattern is used by the Interpreter, Builder and Parser, to build the Composite objects that are the result of the process in each of the three Patterns. Can be traversed by Parser, Visitor and Iterator Once a Composite object is created, it can be traversed by the Parser, Visitor and Iterator. The Parser and Visitor can be used to perform actions on the objects in the Composite object (object Tree) and collect data from the objects within the Composite object.

SEE ALSO

::Tag: PAT-CMP-SEE Overview of the Patterns based on type and use There are many ways to look at the Patterns in this book. In the overview on Patterns based on type and use you will find the patterns sorted on type and use. ::Link:PAT-TYP Overview of the Creational, Structural and Behavioral patterns Design Patterns have a basic classification in three different groups: Creational, Structural and Behavioral Patterns. ::Link:PAT-CLASS The Decorator: using an alternative pattern to build a Composite object

Page 510: Re Factoring and Design Patterns

510 Peter Kaptein

Instead of building your Composite objects with the Composite Pattern, you can also use the Decorator Pattern. While the type of objects are slightly different, the result can be very much the same. ::Link: PAT-DEC The Parser, Builder and Interpreter: creating Composite objects The Parser, Builder and Interpreter all use and can use the Composite Pattern to build dynamic structures and dynamic objects. ::Link:PAT-PARS|PAT-BLD|PAT-INPR The Decorator: a simplified Composite The Decorator can be seen as a simplified Composite Pattern. Where the Composite Pattern allows for one or more children, the Decorator only has one child. ::Link: PAT-DEC

Page 511: Re Factoring and Design Patterns

Refactoring and Design Patterns 511

ASPECTS FROM DESIGN PATTERNS

::Tag: PAT-CMP-ASP

Page 512: Re Factoring and Design Patterns

512 Peter Kaptein

DATA ACCESS OBJECT * ::Tag: PAT-DAC

Page 513: Re Factoring and Design Patterns

Refactoring and Design Patterns 513

DECORATOR ::Tag: PAT-DEC : Discussing the Decorator Pattern ::includesubchapters

Page 514: Re Factoring and Design Patterns

514 Peter Kaptein

INTENT (GOF)

::Tag: PAT-DEC-INT Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.

DECORATOR BASICS

::Tag: PAT-DEC-DIA-BAS

Decorator C

Class A / Object BYour Class

1.b: «injects Object into / uses functionalities of»

1.a: «has»

2.a: «offers»

2.b: «contains / wraps / decorates / addresses»

3: «extend»

Added functionalites

WHEN/WHAT? ::Tag: PAT-DEC-DIA-BAS-001 To dynamically add and change functionalities to/on an object The Decorator allows you to dynamically add functionalities to an existing object. This can either be extra components and parts when it is a visual component, or extra and different actions in methods it exposes to the world.

OTHER INFO ::Tag: PAT-DEC-DIA-BAS-002 Injection instead of internal creation The Decorator differs from patterns in the way it obtains the object it wraps. Where the Adapter usually creates the Adaptee, the Decorator gets that object via Injection by your Code. Wrap-and-add The Decorator wraps the object you Inject and then adds new functionalities to it.

Page 515: Re Factoring and Design Patterns

Refactoring and Design Patterns 515

DIAGRAMS

::Tag: PAT-DEC-DIA

VISUAL SUMMARY OF THE DECORATOR PATTERN ::Tag: PAT-DEC2-VSM

Decorator A

+ yourMethodA: extended add extra functionalities execute: yourClass.yourMethodA()+ yourMethodB: extended do something extra execute: yourClass.yourMethodA()

Decorator B

1: «can be wrapped by»

2: «can be wrapped by»

+ yourMethodA(): extended+ yourMethodB(): extended

Main Interface / Base Class

3: «share the same»

Your Class

+ yourMethodA(): do something+ yourMethodB() do something else

variables

procedures

+ yourMethodA():+ yourMethodB()

NOTES: Your Class and your collection of decorators share the same Interface or Base Class Your Class and the decorators share the same Interface or Base Class. In principle the Decorators will not add any new public methods of their own and will reflect the Interface of Your Class in any public method. Decorators wrap your object The Decorators wrap your object and add extra functionalities to the methods it exposes. Decorators can wrap each other Decorators can wrap each other, adding even more functionalities where needed. Decorators pass all calls through to your Class The Decorators pass all method calls through to your Class, unless a Method call is willingly interrupted by a Decorator.

Page 516: Re Factoring and Design Patterns

516 Peter Kaptein

Variables? Keep them private or make them getters / setters As the Decorators ad new layers around your object it is hard to say who holds what value based on what. If you want to expose variables, better make them methods as well, in the form of Getters and Setters.

BASE CLASS DIAGRAM ::Tag: PAT-DEC2-DIA-000:Base class diagram of the Decorator Pattern

«interface / base class»Base Component A

+ someMethod()+ anotherMethod()

Concrete Component A

Override / implement:+ someMethod()+ anotherMethod()

Base Decorator A

+ setComponent( component )Override / implement:+ someMethod()+ anotherMethod()

1: «implements / extends»

«component.someMethod()»

Concrete Decorator B Concrete Decorator C

- yourAddedMethodC()- yourAddedMethodD()Override:+ someMethod()+ anotherMethod()

- component

2: «is of type»

- yourAddedMethodB()Override:+ anotherMethod()

Concrete Decorator A

- yourAddedMethodA()

3: «extends»

NOTES: As true as possible to implementation in “Design Patterns” You will find a very similar diagram in “Design Patterns”. What I focused on are the relationships between the Classes. Subclassing by wrapping the component The Decorator allows you to change the behavior and add extra methods and elements by creating several variations and then let you combine these variations by wrapping the components and the decorators into other Decorators.

Page 517: Re Factoring and Design Patterns

Refactoring and Design Patterns 517

Overriding methods to execute the additional behavior When you wrap a Component into a Decorator, the Decorator allows you to overrides the methods on your component and use the internal logic of your Decorator object before and after callin the target method on the Component you decorate. Limited scope and use of the additional methods: set them to private While there is nothing providing you from adding public methods to each Concrete Decorator, it makes no sense to change the public Interface of the Concrete Decorators. Each Concrete Decorator only knows the public Methods as defined in the Base Decorator. All additional methods as defined in the Concrete Decorators will therefore not be used by the other Concrete Decorators. To keep the scope of your additional methods in the Concrete Decorators clear, set them to Private. Adding additional methods to the Base Decorator You might add one or more Decorator-specific methods to the Base Decorator, allowing you to perform extra actions when the Decorated object is a Concrete Decorator. The question is whether this is wise and clean. Probably it is neither.

Page 518: Re Factoring and Design Patterns

518 Peter Kaptein

SIMPLE DIAGRAM OF THE DECORATOR PATTERN ::Tag: PAT-DEC-DIA-001

Decorator C

Class A / Object BYour Class

1.b: «injects Object into / uses functionalities of»

1.a: «has»

2.a: «offers»

2.b: «contains / wraps / decorates / addresses»

3: «extend»

Added functionalites

DEPENDENCIES: Your Class: 1.a: Has Class A / Object B 1.b: Injects object into / uses functionalities of Decorator C Decorator C: 2.a: Offers added functionalities 2.b: Contains / wraps / decorates / addresses Class A / Object B The Added Functionalities: 3: Extend Class A / Object B

NOTES: Injection The Decorator gets the object it decorates via Injection by your Code. Wrap-and-add The Decorator wraps the object you Inject and then adds new functionalities to it. Added functionalities: hardcoded composition When you study the Builder, Parser and Composite Patterns in “Design Patterns” you will find references to the Decorator Pattern. All create dynamic structures based on nested and nesting objects. The Main difference between the Decorator and the Builder, Parser and Composite Pattern is that the “Composition” in the Decorator is achieved by hardcoded logic.

Page 519: Re Factoring and Design Patterns

Refactoring and Design Patterns 519

TAKING A CLOSER LOOK AT THE DECORATOR PATTERN ::Tag: PAT-DEC-DIA-003

Base Decorator D

Decorator B

Decorator C

Methods A, B and C

Methods D, E and F

Methods G, H and I

4.b: «add»

4.b: «add»

4.b: «add»

4.a: «extend»

Base Methods X, Y and Z

1.b: «has»2.b: «lives inside»

Variable A

Base/Abstract Class A /Interface B

2.a: «is of type»3: «are derived

from»

Decorator A

1.a «extends / implements»

DEPENDENCIES: Base Decorator D: 1.a: Extends Base/Abstract Class A or Interface B 1.b: Has Base Methods X, Y and Z 1.c: Has and invokes methods on Variable A Variable A: 2.a: Is of Type Base/Abstract Class A or Interface B 2.b: Lives inside Base Decorator D Base Methods X, Y and Z: 3: Are derived from Base/Abstract Class A or Interface B Decorator A, B and C: 4.a: Extend Base Decorator D 4.b: Add Methods A, B, C, D, E, F, G, H and I

Page 520: Re Factoring and Design Patterns

520 Peter Kaptein

NOTES: Injecting your object into a variable To allow your Decorator to Decorate an object, you inject it inside a variable within your Decorator. All part the same family: using an Interface or Base/Abstract Class To make sure all Decorators and Concrete Implementations can be Decorated, we use the same Interface/Abstract Class on each and any of them Invoking known methods on the variable To operate the object we Decorate, we invoke the Methods we know it will have through the Interface or Base/Abstract Class (Base Methods X, Y and Z). Extending the object by adding methods and functionalities to the Decorator To extend your object with new methods and functionalities, you add these extra methods and functionalities to the Decorators instead of extending the Class directly. By doing this, we are “subclassing” the objects in a different way: keeping the base objects and encapsulating the additional functionalities within the Decorators. Flexible subclassing instead of fixed subclassing: dynamic structure Using the Decorator, we are able to do: “Flexible subclassing”, meaning that we can decide on runtime what we will “extend” our base object with. This allows for a very dynamic flow to solve specific issues that arise within the application as it continues to grow.

Page 521: Re Factoring and Design Patterns

Refactoring and Design Patterns 521

GOING ALL THE WAY: USING THE DECORATOR PATTERN FOR MULTIPLE CLASSES ::Tag: PAT-DEC-DIA-002

Base Decorator D

Base/Abstract Class A /Interface B

Decorator A

Decorator B

Decorator C

Your Class A

Your Class B

2.b: «can be decorated by»

1.b: «can be decorated by»

2.a: «extends»

1.a: «extends / implements» 3: «extends / implements»

Your Class C

«Concrete Classes» «Decorators»

DEPENDENCIES: Concrete Implementation A, B and C: 1.a: Extend Base/Abstract Class A or Interface B 2.b: Can be decorated by Decorator A, B and C Decorator A, B and C: 2.a: Extend Base Decorator D 2.b: Can be decorated by Decorator A, B and C Base Decorator D: 3: Extends Base/Abstract Class A or Interface B

NOTES: Same Base Class or Interface for Decorator and Concrete Implementations In the Decorator Pattern, both the Concrete Implementations and the Decorators share the same Base/Abstract Class or Interface. Decorator can decorate a Decorator Any Decorator of the same family can decorate any other Decorator of that same family.

Page 522: Re Factoring and Design Patterns

522 Peter Kaptein

DECORATING YOUR OBJECT ::Tag: PAT-DEC-DIA-004

Decorator X

Base Methods X, Y and Z

3.b: «has»2.b: «lives inside»

Variable A

Base/Abstract Class A /Interface B

4.a: «are derived from»

Your Object

4.b: «are invoked on»

1.a: «is injected into»

1.b «extends / implements»

Methods A, B, CFunctionalities D,E

3.a: «has / adds»

2.a: «is of type»

Added functionalites5: «contains»

6: «can invoke»

DEPENDENCIES: Your Object: 1.a: Is injected into Variable A 1.b: Extends Base/Abstract Class or implements Interface A Variable A: 2.a: Is of type Base/Abstract Class or implements Interface A 2.b: Lives inside Decorator X Decorator X: 3.a: Has and adds Methods A, B, C and functionalities D, E 3.b: Has Base Methods X, Y and Z Base Methods X, Y and Z: 4.a: Are derived from Base/Abstract Class A or Interface B 4.b: Are invoked on Your Object Methods A, B, C and Functionalities D, E: 5: Contains Added functionalities The Added functionalities: 6: Can invoke Base Methods X, Y, Z on Your Object

Page 523: Re Factoring and Design Patterns

Refactoring and Design Patterns 523

NOTES: Objects are injected into a Decorator Within the Decorator Pattern, the objects to be decorated are Injected into the Concrete Decorator. Extra methods are added to the object via the Decorator The Decorator “adds” extra Methods and functionality to the Decorated object. These Methods can be and do anything, including adding lines and extra controls to visual components, adding extra processes to the ones the object has to offer and adding different ways of processing what is produced by the Decorated object. Decorating Products and Strategies The Decorator Pattern is not exclusive to a Product (an object) or Strategy (a Process), but can be used for both.

Page 524: Re Factoring and Design Patterns

524 Peter Kaptein

WHEN DO YOU USE IT?

::Tag: PAT-DEC-USE When you want to extend the functionalities of an object without subclassing it As discussed before, the Decorator is used to extend the functionalities of an object without subclassing it. The main advantages are that you can combine any Decorator with any other Decorator of the same family, adding bits and pieces to your Base object as and when you need to. When your class gets too heavy: to extract and re-use specific operations from your Class Like with subclassing, you can choose to extract specific methods and operations from your Classes and place them inside your Decorators. ::Link: PAT-DEC-DIA-005 To perform specific actions on your object You can use the Decorator to perform very specific actions on your objects (or on the Data they contain, or on the structure they are part of). ::Link: PAT-DEC-DIA-005

Page 525: Re Factoring and Design Patterns

Refactoring and Design Patterns 525

COMPARISONS AND DIFFERENCES

::Tag: PAT-DEC-CDFF

WHAT DIFFERENTIATES THE DECORATOR? ::Tag: PAT-DEC-DIFF One single intent: to extend an object without subclassing The intent of the Decorator is to extend an object without subclassing, allowing you to combine and add functionalities to your object it did not have before. Adding functionalities, alternative to subclassing The main intent of the Decorator is to add extra functionalities and to offer an alternative to Subclassing. Can extend the wrapped object with entire new functionalities The Decorator can add complete new functionalities to the wrapped object, while pretending to be that wrapped object as well. Allows you to build dynamic structures by nesting Decorators in Decorators When you nest Decorators into other Decorators, you are basically creating new objects with new functionalities. Each object can be specific for a specific case. Think of Decorators as the peripherals you can add to your computer. Starting from a simple point, you can extend that one object into any direction adding extra things to the object to make it do and perform as you need. Can be nested and nested and nested A Decorator can wrap and Decorate another Decorator, which can wrap and Decorate another Decorator. What about the Adapter? As stated before, the Decorator is very similar to the Adapter, but they differ in use. Where the main intent of the Adapter is to adapt the Interface of an existing Class to your needs, the intention of the Decorator is to add extra functionalities and to offer an alternative to Subclassing.

Page 526: Re Factoring and Design Patterns

526 Peter Kaptein

PATTERNS WITH SIMILARITIES ::Tag: PAT-DEC-SIM

ADAPTER, DELEGATE, BRIDGE, PROXY ::Tag: PAT-DEC-SIM-ADBP Similarities: similar setup, wrapping objects The Decorator has a very similar setup as the Adapter, Delegate and Proxy. All Patterns wrap an object, pretend to be that object and use the encapsulated object to perform the actual actions. Adapter: adapt the Interface of an object, can extend the adaptee Class The Adapters intent is to Adapt the Interface of an object and Class. It can do this by Adapting the object (an Object Adapter) or by Extending the Class of the objects that need to be adapted (Class Adapter). Delegate: delegate the method call to a wrapped object, does not use Injection The Delegate delegates the actual actions to a wrapped object. It can use a Factory or Data Map to choose and get the object. It normally does not use Injection to gain the object to delegate the method call to. Bridge: is more an Adapter or Delegate, not a Decorator. No Injection, no nesting, objects by context The Bridge is more an Adapter with an internal Factory than it is anything else. The Bridge normally does not allow the wrapped object to be Injected. It usually chooses that object instead by Context, either from a Factory or Data Map. Like the Proxy it usually shields the actual object from the outside world. Like the , the Bridge does not allow other bridges to be nested in itself.

FAÇADE, MANAGER ::Tag: PAT-DEC-SIM-FM Similarities: wrapping functionalities, allow for injection Like the Façade and the Manager, the Decorator wraps functionalities, usually derived from other Classes and objects to perform the extra actions it is supposed to perform on and with the object it wraps. Both Façade and Manager allow the objects they work with to be Injected from the outside. Proxy: late instantiation, no nesting, no injection from outside The intent of the Proxy is to represent an object that is not necessarily there yet. The Proxy also usually shields the actual object it represents and does not allow that object to be injected by anyone or anything outside the scope of the Proxy. Façade: wraps functionality, is not designed for nesting of Façades inside Façades The main intent of the Façade is to wrap functionality, where the main intent of the Decorator is to extend existing objects by wrapping them into a container with the added functionalities.

Page 527: Re Factoring and Design Patterns

Refactoring and Design Patterns 527

COOPERATION WITH OTHER PATTERNS ::Tag: PAT-DEC-COP Not clear There are no clear cooperations with other Patterns in the Decorator. I might add these later.

Page 528: Re Factoring and Design Patterns

528 Peter Kaptein

BONUS MATERIAL

::Tag: PAT-DEC-BNS

EXTRACTING ACTIONS FROM A CLASS INTO DECORATORS ::Tag: PAT-DEC-DIA-005

Your Class

Actions D, E and F

Actions A, B and C

1.a: «extraction of»

Decorator A Decorator B

2.a: «encapsulation into»

Base/Abstract Class A /Interface B

1.b: «extends / implements»

Base Decorator

3.b «extends»

4: «extends / implements»

3.a: «decorate / perform extracted actions on»

DEPENDENCIES: Your Class: 1.a: Actions A, B, C, D, E and F are extracted from Your Class 1.b: Extends Base/Abstract Class or implements Interface A Actions A, B ,C, D, E and F: 2: Are encapsulated into Decorator A and B Decorator A and B: 3.a: Perform the extracted Actiond on Your Class 3.b: Extend your Base Decorator Your Base Decorator: 4: Extends Base/Abstract Class or implements Interface A

Page 529: Re Factoring and Design Patterns

Refactoring and Design Patterns 529

SUMMARY

::Tag: PAT-DEC-SHS Addition functionalities to existing methods The Decorator adds additional functionalities to existing methods and behavior. The Decorator can also cancel-out specific behavior or take them into another direction. Wrapping and “Adapting” The Decorator adds specific functionalities to an existing Class and object by wrapping it within the Decorator object and operating as the point of entry for your code. The functionalities added can be by using other objects and Code witin the Decorator itself. Straight forward implementation The Decorator Pattern requires a straight-forward implementation. If your Base Component has Methods A, B and C, all your Concrete Decorators will expose Methods A, B and C as well, without any change or additional methods D, E or F. Alternative for subclassing Within “Design Patterns”, the Decorator is described as an alternative for subclassing. “Dynamic subclassing” One reason to choose the Decorator that it allows you to dynamically add the functionalities you need to your base-class. You can nest several Decorators within each other, where each Decorator adds new functionalities to the original basis. Extracting and re-using specific operations from your Class You can choose to extract specific methods and operations from your Classes and place them inside your Decorators. ::Link: PAT-DEC-DIA-005 Keeping added functionalities private: avoid “dirty decorators” It is tempting to make additional methods in each Concrete Decorator public: allowing you to subclass your Components with added functionalities. The problem is that other Decorators have no knowledge at all of Decorator Specific functionalities, making your solution “dirty” and confusing.

SEE ALSO

::Tag: PAT-DEC-SEE Overview of the Patterns based on type and use There are many ways to look at the Patterns in this book. In the overview on Patterns based on type and use you will find the patterns sorted on type and use. ::Link:PAT-TYP Overview of the Creational, Structural and Behavioral patterns Design Patterns have a basic classification in three different groups: Creational, Structural and Behavioral Patterns. ::Link:PAT-CLASS The Wrapper Family Tree

Page 530: Re Factoring and Design Patterns

530 Peter Kaptein

The Wrapper Family Tree shows the various variation on the Wrapper theme and the relationships and differences for each Wrapper. ::Link: WRIA-REL-001 The Adapter: a simple Decorator? The Adapter is the most straight forward Wrapper in the family. It adapts a Class or object to a specific Interface, so that your code can work with it as if it was invented within your project. ::Link: PAT-ADP The Command Pattern: a more specialized Decorator? The Command Pattern is used to execute specific Commands on the object it encloses. Looking at the buildup of the Command, the Command can be seen as a specialized Decorator with a very specific use. ::Link: PAT-COM The Delegate: delegating the execution of actions to encapsulated objects The Delegate has very much the same internal structure as the Decorator. Where you call the methods and set the variables on the Delegate, it passes these to the embedded object to be executed there. ::Link: PAT-DEL|PAT-ADP The Visitor: adding functionalties which are not there yet Like the Decorator, the Visitor adds functionalities to the objects it visits. The main difference between the Decorator and Visitor is that the Decorator works outside in and the Visitor works from the inside. ::Link:PAT-VIS The Parser: building dynamic structures What the Decorator does via hardcoded additions, the Parser can create by creating Composite objects based on Abstract Definitions. If and when you need a more flexible way to extend existing objects or build Composites, think of the Parser. ::Link: PAT-PARS The Composite: what is created inside the Decorator When you decorate an object, you create a simple Composite. Not only by nesting one object into another, but also by the additional Classes and objects the Decorator adds to perform its duties. Even though they are usually hardwired inside the Decorator, the result is a Composite object with your Injected object as one of the players. ::Link: PAT-CMP The Delegate and Adapter: delegating the execution of actions to encapsulated objects The Delegate has very much the same internal structure as the Decorator. Where you call the methods and set the variables on the Delegate, it passes these to the embedded object to be executed there. ::Link: PAT-DEL|PAT-ADP The Visitor: adding functionalities which are not there yet Like the Decorator, the Visitor adds functionalities to the objects it visits. The main difference between the Decorator and Visitor is that the Decorator works outside in and the Visitor works from the inside. ::Link:PAT-VIS

ASPECTS FROM “DESIGN PATTERNS”

::Tag: PAT-DEC-ASP From: Motivation Sometimes we want to add responsibilities to individual objects, not to an entire class. [..] One way to add responsibilities is with inheritance. [..]

Page 531: Re Factoring and Design Patterns

Refactoring and Design Patterns 531

A more flexible approach is to enclose the component in another object that adds the border. The enclosing object is called a decorator. The decorator conforms to the interface of the component it decorates so that its presence is transparent to the component's clients. [..] Transparency lets you nest decorators recursively, thereby allowing an unlimited number of added responsibilities. [..] Decorator subclasses are free to add operations for specific functionality. From: Applicability Use Decorator when [..] extension by subclassing is impractical. Sometimes a large number of independent extensions are possible and would produce an explosion of subclasses to support every combination. From: Participants Decorator [..] maintains a reference to a Component object and defines an interface that conforms to Component's interface. From: Collaborations [..] Decorator forwards requests to its Component object. It may optionally perform additional operations before and after forwarding the request. From: Consequences [..] The Decorator pattern provides a more flexible way to add responsibilities to objects than can be had with static (multiple) inheritance. [..] With decorators, responsibilities can be added and removed at run-time simply by attaching and detaching them. [..] Instead of trying to support all foreseeable features in a complex, customizable class, you can define a simple class and add functionality incrementally with Decorator objects. Functionality can be composed from simple pieces. From: Implementation [..]A decorator object's interface must conform to the interface of the component it decorates. From: Related Patterns [..] A decorator is different from an adapter in that a decorator only changes an object's responsibilities, not its interface; an adapter will give an object a completely new interface. [..] A decorator can be viewed as a degenerate composite with only one component. However, a decorator adds additional responsibilities—it isn't intended for object aggregation. [..] A decorator lets you change the skin of an object; a strategy lets you change the guts. These are two alternative ways of changing an object.

Page 532: Re Factoring and Design Patterns

532 Peter Kaptein

DELEGATE ::Tag: PAT-DEL ::includesubchapters

Page 533: Re Factoring and Design Patterns

Refactoring and Design Patterns 533

INTENT

::Tag: PAT-DEL-INT To delegate and abstract the actual execution of an Action to another object. To offer one single Interface for the execution of these Actions, independent of the Concrete Implementation of these Actions.

DELEGATE BASICS

::Tag: PAT-DEL-DIA-BAS

Delegate A

Class A / Object X

YourClass1: «uses»

2: «instantiates / contains / wraps / uses / executes via»

WHEN/WHAT? ::Tag: PAT-DEL-DIA-BAS-001 Delegating actions to other objects The main goal of the Delegate is to delegate the execution of Actions to other objects it can either retrieve or instantiate based on specific parameters. Plug & play code: a cleaner way to define who executes what, how and when If and when you want to have a flexible way to execute specific processes, you can follow several different routes, including conditional execution, where a Switch or and if/then/else statement separates the different approaches. In the Delegate Pattern, you extract these approaches and place them in a separate Class, allowing you to create “plugins” that execute specific actions in a specific way. To change the way an action is executed, you simply replace “Plugin Object A” for “Plugin Object B”.

OTHER INFO ::Tag: PAT-DEL-DIA-BAS-002 Can delegate to a single object The Delegate can use one single object to delegate the actions to. Can delegate to an object from one ore more classes The Delegate can use multiple classes to select from (see next page) Can offer multiple actions to be executed via Delegation The Delegate can expose one or more Methods to be executed by Delegation via another object.

Page 534: Re Factoring and Design Patterns

534 Peter Kaptein

Allows your system to expand possibilities without the need to rewrite your base code In most cases, where the selection and use of solutions are hardcoded in the application, adding new functionalities lead to a partial re-write and update of that code. Instead, when you use the Delegate Pattern wisely, you can add any new Delegate to the list, without having to change any line of code. Imagine for instance, that every time a new printer hits the stores, you need to wait for an update of all your applications that use that specific printer. Inversion of Control The Delegate Pattern can implement a specific use of Inversion of Control where the Delegate itself remains the same, but the objects and Classes it uses to retrieve and create the Concrete Delegates can be set from another part of your application, using an Object Map. Not part of the 23 patterns in “Design Patterns” The Delegate is not part of the 23 patterns in “Design Patterns”. The Delegate Pattern can be found in Java (EE) Patterns.

DIAGRAMS

::Tag: PAT-DEL-DIA

VISUAL SUMMARY OF THE DELEGATE PATTERN ::Tag: PAT-DEL-VSM

+ someMethodA( ): do something return result

Delegate A

Client

+ delegateMethodA( ): do something delegate.someMethodA() do something else

Delegator A

1: «addresses»

3: «delegates actions to»

2: «instantiates / uses either»

+ someMethodA( ): do something else return result

Delegate B

Plug & play code: a cleaner way to define who executes what, how, when

4: «leading to»

Page 535: Re Factoring and Design Patterns

Refactoring and Design Patterns 535

NOTES: Principle of the Delegate can be found in several other Patterns The Patterns from “Design Patterns” that use the principle of Delegation are: the Bridge, the Adapter, the Proxy, the Strategy, the Decorator, the State and the Mediator Pattern. Device drivers: an example Device drivers (like for printers and scanners) use this same principle. While your base code it the same: allowing you to use one instruction to print or scan, the way this action is executed is wrapped into a Driver that can be switched for and by any other driver of the same type. In this way, there is no “Device Lock” in your software. Using switches and if/then/else: not so good practice In many examples in books discussing Delegate patterns, you will probably find if/then/else and Switch-statements. While this seems like a good solution, you create a “plugin-lock”. Meaning that when you want to add new functionalities, you have to rebuild and recompile your base code. Object Maps Instead of using switches or if/then/else statements, you can choose to use Object Maps. In these object maps, you map the Delegate to an abstract key (a String value or number) and use and pass this abstract key to anything and anyone who needs it. Only when the Delegate is needed you resolve that key for the concrete Delegate. You Code Base can remain stable. Libraries and frameworks When you build a one-time solution, this might not seem to relevant at all. However, when you create a Library or Framework, you want the code-base of that library and framework to remain stable. Meaning that any change in any specific implementation does not affect the code of the Library.

Page 536: Re Factoring and Design Patterns

536 Peter Kaptein

BASE CLASS DIAGRAM OF THE DELEGATE PATTERN ::Tag: PAT-DEL-DIA-000

Delegator A

+ delegateMethodA()

+ someMethodA( )

Concrete Delegate A.a

2.a: «implements»

Client

+ delegateMethodA( )

«interface»Base Delegator A

«delegate.someMethodA()»

1: «addresses object of type»

- delegate2.b: «contains object of type»

+ someMethodA( )

«interface»Base Delegate A

+ someMethodA( )

Concrete Delegate A.b

3: «implements»

NOTES:

Page 537: Re Factoring and Design Patterns

Refactoring and Design Patterns 537

BASIC DIAGRAM OF A DELEGATE ::Tag: PAT-DEL-DIA-001

Delegate A

Class A / Object X

YourClass1: «uses»

2: «instantiates / contains / wraps / uses / executes via»

DEPENDENCIES: Your class 1: Uses Delegate A to execute an action Delegate A 2: Instantiates, contains, wraps, uses and executes actions via Class A / Object B

NOTES: A Wrapper to execute actions The Delegate is a wrapper like many other of the Patterns in this chapter. The main goal of the Delegate is to delegate the execution of Actions. Can delegate to a single object The Delegate can use one single object to delegate the actions to. Can delegate to an object from one ore more classes The Delegate can use multiple classes to select from (see next page) Can offer multiple actions to be executed via Delegation The Delegate can expose one or more Methods to be executed by Delegation via another object.

Page 538: Re Factoring and Design Patterns

538 Peter Kaptein

CHOOSING A DELEGATE OBJECT FROM A SET OF CLASSES ::Tag: PAT-DEL-DIA-002

Delegate A

Object X

YourClass1: «uses»

2.c: «instantiates / contains / wraps / uses / executes via»

Factory B / Strategy C

2.b: «uses»

2.a: «has a»

Context

3.b: «produces»

Class A

Class B

Class c

3.a: «uses»

Interface A / BaseCLass B

4: «implement / extend»

5: «implements / extends»

DEPENDENCIES: Your Class 1: Uses Delegate A Delegate A 2.a: Has a context 2.b: Uses Factory B / Strategy C 2.c: Instantiates / contains / wraps / uses / executes via Object X Factory B / Strategy C 3.a: Uses Class A, B or C 3.b: Produces Object X Class A, B and C 4: Implement / extend Interface A / BaseClass B Object X 5: Implements / extends Interface A / BaseClass B

NOTES: The Context is usually offered by Your Code The Context in which the Delegate chooses the Product or Strategy to execute your request is usually offered by your code.

Page 539: Re Factoring and Design Patterns

Refactoring and Design Patterns 539

A Delegate can also work with only one class A Delegate can be using just one single Class it wraps to abstract the way yo work and access the concrete object that executes the actions. All classes share the same Interface or Base Class To offer the same Interface on each object from each separate Class, the Classes either implement the same Interface, or extend the same Base Class. This way, the code for the Delegate can be kept simple as there is only one type of base-object and one way to call for a specific method.

Page 540: Re Factoring and Design Patterns

540 Peter Kaptein

DELEGATING ACTIONS ::Tag: PAT-DEL-DIA-003

Delegate A

Methods A, B, C

1.a: «exposes»

Methods A, B, C

1.b: «passes calls through to»

Object X2: «exposed by»

DEPENDENCIES: Delegate A 1.a: Exposes Methods A, B and C 1.b: Passes calls on Methods A, B and C through to Methods A, B and C of Object X Mehtods A, B and C 2: Are exposed by Object X

NOTES: The Delegate as a simple pass-through station Like the Adapter, the Delegate operates mostly as a Pass Through Station. The Delegate can be completely void of any intelligence in this, performing no actions on its own. The Delegate as a Façade-like pass through station It is possible that the Classes that execute your actions are not performing all, but are part of a bigger process and subsystem managed by the Delegate: very similar to the Façade. ::Link: PAT-FCD Can offer multiple actions to be executed via Delegation As stated before, the Delegate can expose one or more Methods to be executed by Delegation via another object.

Page 541: Re Factoring and Design Patterns

Refactoring and Design Patterns 541

EXAMPLE OF A BASIC IMPLEMENTATION OF THE DELEGATE PATTERN ::Tag: PAT-DEL-DIA-004

Methods A, B, C

Delegate A 1.a: «has a»

variable

2.b: «contains»1.b: «has»

Object B from Class N

3: «addresses»

Methods D, E, F

4: «inside»

Interface A / BaseClass B

2.a: «is of type»

3: «implements / extends»

DEPENDENCIES: Delegate A 1.a: Has a variable 1.b: Addresses Object X from Class N to execute the actions The Variable 2.a: Is of type Interface A / BaseClass B 2.b: Contains Object X from Class N Object B from Class N 3: Implements / extends Interface A / BaseClass B

NOTES: Using an Interface or Base Class You can use an Interface or Base Class when you have multiple Classes to choose from, to delegate the actions to. Using Injection Some implementations of the Delegate use Injection to inject the Concrete object that will execute the actual actions. The object as put in the Variable can be anything that uses either the Base Class or the Interface as stated in the Variable. Delegating actions to a wrapped object The basis of the Delegate Pattern is that the concrete execution of one or more actions is delegated to another object. This object can use a shared Base Class or a shared Interface and a context-specific implementation. Similarities to Bridge, Command and Façade The Delegate has some similarities in this to the Bridge, the Command Pattern and the Façade. Each of these Patterns, like the Delegate, use other objects to execute the requested actions.

Page 542: Re Factoring and Design Patterns

542 Peter Kaptein

Page 543: Re Factoring and Design Patterns

Refactoring and Design Patterns 543

WHEN DO YOU USE THE DELEGATE PATTERN?

::Tag: PAT-DEL-USE When you need to make one or more Classes compatible with your Project Like any wrapper, the Delegate is first of all used to wrap adapt existing Code and Classes to the specific needs and expectations within your Project. When you want to clarify your intent The Delegate is used when you are explicitly using an object or Class as a delegate for your actions and requests. Wrapping them within a Delegate makes clear what you inted to do with the Class or object the Delegate wraps. To delegate actions to another object, using one single Interface The Delegate is used when you want to Delegate actions to another object, using one single Interface and a clear Pattern to do so. To Abstract the execution of an Action, to allow alternations without changing your code You can use the Delegate to Abstract the execution of an action, meaning that – while using one single object to call and request these actions, any other object can be used to do the actual work. This means that you can alternate the workings of your Applications by changing the object that executes the code, without having to change the objects that are used by your Code.

Page 544: Re Factoring and Design Patterns

544 Peter Kaptein

COMPARISONS AND DIFFERENCES

::Tag: PAT-DEL-CDF

WHAT DIFFERENTIATES THE DELEGATE? ::Tag: PAT-DEL-DFFR Clarification of intent: explicitly used for the Delegation of actions While the Adapter, Bridge, Command and Decorator can be used to delegate actions to the objects they contain (and they do), the Delegate is explicitly used for that one action. This clarifies the Intent of the objects and Classes you create: “to delegate the execution of an action”.

PATTERNS WITH SIMILARITIES ::Tag: PAT-DEL-SIM

ADAPTER, DECORATOR, PROXY, BRIDGE ::Tag: PAT-DEL-SIM-ADPB Similarities: wrapping another object to perform actions Like the Adapter, Decorator, Bridge and proxy, the Delegate wraps another object to perform actions on. Adapter: adapts an object to conform to another Interface, can extend that object The Adapter adapts an object to conform to another Interface. The Delegate limits itself to the execution of a process, using the object it delegates the actions to. The Adapter can Adapt an object by Extending it. The Delegate uses an internal object stored in a variable. Decorator: wraps an object to add functionalities The Decorator wraps an object to add functionalities that object did not have yet. The purpose of the Decorator is to offer an alternative for subclassing. The Delegate does not add new functionalities, but rather uses the object(s) it wraps to execute actions. Proxy: used to represent the actual object and buffer values and calls The main purpose of the proxy is to represent an object that is not there yet. Depending on the implementation the Proxy can store values to be set on that object and even buffer calls to that object, to execute code once the Represented object is there.

FAÇADE, MANAGER, MEDIATOR ::Tag: PAT-DEL-SIM-FMM Similarities: can delegate to a subsystem The Façade, Mediator and the Manager delegate actions to a subsystem. The Delegate is not limited to one single object, but – like the Façade, Mediator and Manager – can use an entire subsystem to delegate the actions to.

BRIDGE ::Tag: PAT-DEL-SIM-BRI Similarities: delegation, possible use of an internal Factory or Data Map

Page 545: Re Factoring and Design Patterns

Refactoring and Design Patterns 545

Like the Delegate, the Bridge Pattern relies heavily on Delegation of actions to another object. Like the Bridge, the Delegate can use an internal Factory or Data Map to get and instantiate the object it will work with. Offering a single, polymorphic, Class The Bridge offers itself as one single Class which can have different specific Implementations. The Bridge does this internally: by instantiating a object via a Factory or Strategy. The Delegate simply delegates actions to an object instantiated inside itself.

COMMAND ::Tag: PAT-DEL-SIM-COM Similarities: performing a specific action on another object Like the Delegate, the Command encapsulates an object and performs specific actions on that object. Sent elsewhere to have the action performed Where the Delegate is usually used where it is instantiated, the Command is usually sent elsewhere, to have someone else perform the call for action.

COOPERATION WITH OTHER PATTERNS ::Tag: PAT-DEL-COP

FACTORY ::Tag: PAT-DEL-COP-FCT Producing the objects to delegate to The (Simple) Factory can be used to produce / create the obejcts you use to delegate the actions to

OBJECT MAP ::Tag: PAT-DEL-COP-OMP Retrieving the objects to delegate to When you use am Object Map, you can store the Delegates under specific Keys, to be retrieved whenever needed. This promotes approaches like Inversion of Control, where the Delegates can be mapped under specific keys and then retrieved by your Delegate.

Page 546: Re Factoring and Design Patterns

546 Peter Kaptein

SUMMARY

::Tag: PAT-DEL-SHS Wrapper to Execute Actions delegated to the encapsulated object The Delegate is a Wrapper with the explicit intent to execute actions on the object it encapsulates. Delegating actions to a wrapped object The basis of the Delegate Pattern is that the concrete execution of one or more actions is delegated to another object. This object can use a shared Base Class or a shared Interface and a context-specific implementation. Using a Context and Context specific solutions The Delegate can be given a specific Context which it will use to select and create a specific object from a specific Class to execute the required Action. Using Injection Some implementations of the Delegate use Injection to inject the Concrete object that will execute the actual actions. The object as put in the Variable can be anything that uses either the Base Class or the Interface as stated in the Variable. Similarities to- and differences from the Bridge Pattern Like the Bridge Pattern, the Delegate can use multiple Classes to do the same thing in different ways. The Delegate differs from the Bridge in the fact that the Bridge is used to wrap an object and provide a Dynamic Base Class. The Delegate is used to execute actions on the object it Encapsulates. Using a Factory The Delegate can use a Factory to get and Instantiate the object that will do the actual work. Using a Object Map to re-use persistent objects It is possible to use the Delegate together with a Object Map to save resources and instantiation time on the concrete object that will be used to perform and execute the required Action.

Page 547: Re Factoring and Design Patterns

Refactoring and Design Patterns 547

SEE ALSO

::Tag: PAT-DEL-SEE Overview of the Patterns based on type and use There are many ways to look at the Patterns in this book. In the overview on Patterns based on type and use you will find the patterns sorted on type and use. ::Link:PAT-TYP Overview of the Creational, Structural and Behavioral patterns Design Patterns have a basic classification in three different groups: Creational, Structural and Behavioral Patterns. ::Link:PAT-CLASS The Wrapper family tree The Wrapper Family Tree shows the various variation on the Wrapper theme and the relationships and differences for each Wrapper. ::Link: WRIA-REL-001 Command: sending your Delegate away so other can call for action If you need someone else to call for action instead of the Class and object that instantiated your Delegate, consider the Command. Like the Delegate it encapsulates the object on which the methods are called. The Command explicitly is used to execute those commands elsewhere. ::Link: PAT-COM The Visitor: similar to the Delegate, travelling inside object trees The Visitor is used as a “Delegate” sent into and inside an object Tree to perform specific actions within that Tree. These actions can vary from collecting data to changing values and performing actions on the Tree itself. ::Link:PAT-VIS Bridge: similar pattern as the Delegate, but used as a Base Class The Bridge is a very similar Pattern to the Delegate, but with a different use. Where Delegate is usually used as an object to perform a specific task via the enclosed object, the Bridge is used as the Base Class for other Classes. ::Link: PAT-BRI Adapter: wrapping an object to adapt the Interface The Adapter might be the simplest base form to start with to understand the wrappers in general. It simply does what it says: adapting the Interface of the object it envelops. In some senses the Delegate can be seen as a specialized Adapter: abstracting the Interface of the actual object and acting as the man in the middle to delegate the actual execution to another object. ::Link: PAT-ADP State: replacing the object you delegate to from within The State Pattern, like the Delegate, delegates the execution of specific Processes to an enclosed object: the State object. Where the Delegate might allow you to use a Context to choose the actual implementation of the actions, the State Pattern does something different and very special related to the other Patterns in this book. Based on the next step (or State), the State object injects another State object in the variable that the Context object uses to call on the State. ::Link: PAT-STT

Page 548: Re Factoring and Design Patterns

548 Peter Kaptein

BONUS MATERIAL

::Tag: PAT-DEL-BNS

IMPLEMENTING A FACTORY OR STRATEGY WITHIN THE DELEGATE PATTERN ::Tag: PAT-DEL-DIA-005

Delegate AInterface A /BaseClass B

4: «is of type»

4.b: «implements / extends»

3.a: «is put into»

1.d: «contains /calls methods on»

1.c: «uses»

1.e: «can implement /extend»

Factory A /Strategy B

2.a: «uses»

Variable A

2.b: «produces»

3.b: «implements /extends»

Object X

Class C

Class A

Class B

1.a: «exposes»

Methods A, B, C

Context

1.b: «has a» 1.f: «delegates to»

DEPENDENCIES: Delegate A 1.a: Exposes Methods A, B and C 1.b: Has a Context 1.c: uses Factory A / Strategy B 1.d: Contains and calls methods on Variable A 1.e: Can implement / extend Interface A / BaseClass B 1.f: Delegates actions/execution of a request to Object X Factory A / Strategy B 2.a: Uses Class A, B or C 2.b: Produces Object X Object X 3.a: Is put into Variable A 3.b: Implements / extends Interface A / BaseClass B Variabe A

Page 549: Re Factoring and Design Patterns

Refactoring and Design Patterns 549

4: Is of type Interface A / BaseClass B Class A, B and C 5: Implement / extend Interface A / BaseClass B

NOTES: Using a Factory or Strategy Provider When the Delegate has to be able to offer different implementations to perform a specific action, you can use a Factory or Strategy Provider to instantiate the right object based on the Context the Delegate is given. Strategy if you need to choose Processes, Factory if it is a more general object If your Delegate delegates the execution of a Process, use the Strategy Pattern. If the object you use is more generic, use one of the Factory Patterns (Simple Factory, Factory Method, Abstract Factory).

Page 550: Re Factoring and Design Patterns

550 Peter Kaptein

FAÇADE ::Tag: PAT-FCD ::includesubchapters

Page 551: Re Factoring and Design Patterns

Refactoring and Design Patterns 551

INTENT (GOF)

::Tag: PAT-FCD-INT 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.

FAÇADE BASICS

::Tag: PAT-FCD-DIA-BAS

Façade A

Class A

Class C

YourClass1: «uses»

«subsystem A»

Class B

Class D

ClassE

2: «wraps / adapts / addresses»

WHEN/WHAT? ::Tag: PAT-FCD-DIA-BAS-001 When you want to wrap a subsystem The Façade wraps a subsystem by offering a simplified interface to the actions in that subsystem. It deals internally with alle the actions you would otherwise have to code each time you access those functionalties. Simplification of the use of that subsystem The simplification can happen, for instance, by gathering a sequence of specific actions into one or two Methods and do all the hard stuff inside these Methods.

OTHER INFO ::Tag: PAT-FCD-DIA-BAS-002 Delegation The Façade operates by delegating all tasks to the objects in the subsystem it addresses. Multiple Façades for multiple tasks The Façade can be implemented many times to perform specific and completely different tasks on that and other subsystems in your project.

Page 552: Re Factoring and Design Patterns

552 Peter Kaptein

Inversion of Control As the Façade abstracts the access to the functionalities in the subsystem and delegates the tasks to the objects it has and receives, you can use the Façade to implement Inversion of Control by either injecting the objects the Façade works with from the outside, or by mapping the Concrete objects it will use onto astract keys in an Object Map.

Page 553: Re Factoring and Design Patterns

Refactoring and Design Patterns 553

DIAGRAMS

::Tag: PAT-FCD-DIA

VISUAL SUMMARY OF THE FAÇADE PATTERN ::Tag: PAT-FCD-VSM

1: «execute actions on»

4: «does stuff inside»

2: «refer to objects within»

Simplification of calls to- and actions on the subsystem

5: «leading to»

Façade

+ operationA()+ operationB(parameter)+ operationC()

- objectReferenceA- objectReferenceB- objectReferenceC

«subsystem»

Object from Class A

Object from Class B

Object from Class C

3: «delegate actions to»

NOTES: Delegating actions to the subsystem The Façade delegates close to all actions you request from the Façade to the subsystem. Adding actions where needed Where needed, the Façade will allow you to add extra actions in order to comply to the needs of your system. An adapter of a subsystem In some ways the Façade can be seen as an Adapter for a subsystem. Where the direct call to that subsystem might be too complex or simply does not comply to the needs of your code, the Façade helps solving this problem by wrapping all actions into the Façade class and offering a simplified interface to your code. To simplify the use of a subsystem The goal of the Façade is to simplify the use of the subsystem. The Façade does this by taking all relevant actions on all relevant objects in the subsystem and bundling the actions you would otherwise have to hardcode each time you need them into methods in the Façade.

Page 554: Re Factoring and Design Patterns

554 Peter Kaptein

BASIC CLASS DIAGRAM ::Tag: PAT-FCD-DIA-000

Façade

+ operationA()+ operationB(parameter)+ operationC()

- objectReferenceA- objectReferenceB- objectReferenceC

«result=objectReferenceA .operationA()

resultB=objectReferenceB.operationY( result )

»

Class A

+ operationA()+ operationX(parameter)

Class B

+ operationB()+ operationY(parameter)

Class C

+ operationC()

1: «contains object from»

«subsystem»

2: «contains object from»

3: «contains object from»

NOTES: Delegating actions to the subsystem The Façade delegates Actions to the Subsystem, using object references to objects within that subsystem. To simplify the use of that subsystem The goal of the Façade is to simplify the use of that subsystem.

Page 555: Re Factoring and Design Patterns

Refactoring and Design Patterns 555

SIMPLE DIAGRAM OF THE FAÇADE

::Tag: PAT-FCD-DIA-001

Façade A

Class A

Class C

YourClass1: «uses»

«subsystem A»

Class B

Class D

ClassE

2: «wraps / adapts / addresses»

DEPENDENCIES: Your Class 1: Uses Facade A Façade A 2: Wraps, adapts, addresses Subsystem A

NOTES: Wrapping a subsystem Unlike all the previous Patterns: Bridge, Adapter, Decorator and proxy, the Façade wraps an entire Subsystem. Simplification of the use of that subsystem The main goal of the Façade is to simplify the use of that subsystem, for instance, by gathering a sequence of specific actions into one or two Methods and do all the hard stuff inside these Methods.

Page 556: Re Factoring and Design Patterns

556 Peter Kaptein

IMPLEMENTATING THE FAÇADE PATTERN ::Tag: PAT-FCD-DIA-002

FaçadeA

Object X fromClass A

Object N from Class C

1: «has»

«subsystem A»

Object Y from Class B

Object Z from Class D

Object M from Class E

Methods A, B, C

2: «uses / calls methods on»

«works with»

«depends on»«works with»

The Subsystem as given here is just a random example to show possible relationships between objects within that subsystem. As the Subsystem can be anything, doing anything, we will not cover this in our steps.

DEPENDENCIES: Façade A 1: Has/exposes Methods A, B and C Methods A, B and C 2: Uses and call methods on Classes and objects in Subsystem A

NOTES: Exposing methods to work with the subsystem The Façade exposes the methods it offers you to communicate to and work with the Subsystem One exposed method can use multiple objects and call multiple Methods To perform the actions the exposed Methods in the Façade is requested to do, the Façade can call and use multiple methods on multiple objects.

Page 557: Re Factoring and Design Patterns

Refactoring and Design Patterns 557

ADDING THE VARIABLES AND RELATIONSHIPS ::Tag: PAT-FCD-DIA-003

Façade A

Object X fromClass A

Object N from Class C

1.a: «has»

«subsystem A»

Object Y from Class B

Object Z from Class D

Object M from Class E

Methods A, B, C

«works with»

«depends on»«works with»

Variables X, Y, Z

2: «uses / calls»1.b: «contains»

4: «contain»

Methods D, E, F, G, H

3: «exposed by»

RELATIONSHIPS: Façade A: 1.a: Has methods A, B ans C 1.b: Contains variables A, B and C Methods A, B and C: 2: Uses / calls Methods D, E, F, G and H Methods D, E, F, G and H: 3: Are exposed by the objects in Variables A, B and C Variables X, Y and Z: 4: Contain Object X, Object Y and Object Z

Page 558: Re Factoring and Design Patterns

558 Peter Kaptein

NOTES:

Page 559: Re Factoring and Design Patterns

Refactoring and Design Patterns 559

AN EXAMPLE OF MULTIPLE FACADES USING TWO SUBSYSTEMS ::Tag: PAT-FCD-DIA-004

Façade A

Class A

Class C

Your Class1.a: «uses»

«subsystem A»

2: «wraps / adapts / addresses»

Class B

Class D

Class E

Façade B

Class F

Class G

3: «wraps / adapts»

«subsystem B»

1.b: «can use»

DEPENDENCIES: Your Class 1.a: Uses Façade A 1.b: Can use Façade B Façade A 2: Wraps / adapts / addresses Subsystem A Façade B 3: Wraps / adapts / addresses Subsystem B

NOTES: Class E: used by both Facades Since Classes do not have to be bound to a specific subsystem, both Façade A (suing Subsystem A) and Façade B (using Subsystem B) can be in a situation using the same Class or Classes to perform their job.

Page 560: Re Factoring and Design Patterns

560 Peter Kaptein

NOTES: Mediator: part of the process, Façade is Top Down Façade might seem a lot of commonalities with Mediator. The main differences are that the Façade uses a Top Down approasch where the Façade requests information and directs the process, where the Mediator is more a man in the middle, Mediating between objects and Classes in the Subsystem it Mediates. Goal: interface for the subsystem The goal of the Façade is to create an Interface for and over an entire Subsystem, to provide one simple and stable Interface to Your Code, regardless of how complex that Subsystem might be. Handle processes, instantiate objects from the subsystem, call methods on the subsystem The Façade, according to the examples in “Design Patterns” by the Gang of Four, can handle specific processes within the Facade: that involve multiple Classes and objects of the subsystem. The Façade will do that by instantiation of required objects from that subsystem, calling Methods on these objects in the subsystem and passing the Results through to other Classes and objects in that subsystem until the process is finished.

Page 561: Re Factoring and Design Patterns

Refactoring and Design Patterns 561

WHEN DO YOU USE THE FAÇADE?

::Tag: PAT-FCD-USE Simplify the use of a (sub)system When your Classes use several Classes from one or more specific (sub)systems in a specific pattern and the pattern of that usage is always the same Abstracting the access to one or more (sub) systems When you want to offer one specific point of entry to perform specific actions on one or more specific (sub) systems

COMPARISONS AND DIFFERENCES

::Tag: PAT-FCD-CDF

WHAT DIFFERENTIATES THE FAÇADE? ::Tag: PAT-FCD-DFF Wrapping of- and delegation to multiple objects The Façade wraps a subsystem and delegates the actions to that subsystem, using any object and any code it needs. Top-down approach, no dependencies within the subsystem Unlike the Mediator, the Façade has no relationships with the objects in the subsystem. There are no dependencies from the subsystem towards the Façade. The Façade can be replaced by any other Façade, without disrupting that subsystem.

PATTERNS WITH SIMILARITIES ::Tag: PAT-FCD-SIM

ADAPTER ::Tag: PAT-FCD-SIM-ADP Similarities: wrapping existing functionalities Like the Adapter, the Facade “wraps” existing functionalities into – in the case of the Façade – simplified Interface to adapt these functionalities to the local needs in that specific Application Wraps only one Class and one main object Where the Adapter only wraps one Class and one object, the Façade wraps multiple objects and Classes

BRIDGE ::Tag: PAT-FCD-SIM-BRI Similarities: pretending to be something else Like the Bridge, the Façade pretends, in a way, to be something else. In the case of the Façade, that is the actions in the subsystem it uses and simplifies. Wraps only one object, offers choice

Page 562: Re Factoring and Design Patterns

562 Peter Kaptein

The Façade only represents one subsystem and can not dynamically change or choose which implementation it will take, as the Façade is the implementation. The Bridge can choose the implementation of the actual functionalities and (when it is built into the Bridge) is able to change that during runtime. The Bridge also addresses only one single object where the Façade addresses an entire subsystem.

DECORATOR ::Tag: PAT-FCD-SIM-DEC Similarities: extension by adding functionalities to an existing system Like the Decorator, the Façade allows you to “extend” an existing system by wrapping it and adding extra functionalities to it. Like the Decorator, you can create a set of Facades, each doing something else with the Subsystem, or using another aspect, while roughly supporting the same processes. In a way, the Decorator is the equivalent for the Façade for single objects. Injecting the object, does not work with a subsystem The Decorator acts only on one single object, not a subsystem. Another difference between the Façade and the Decorator is that the Façade has internal code interacting with the subsystem, while the Decorator works only on one single object.

DELEGATE ::Tag: PAT-FCD-SIM-DEL Similarities: delegating the execution of actions to a subsystem, multiple calls possible Like the Façade, the Delegate delegates the execution of actions to a subsystem. Like the Façade, the Delegate can call multiple methods on the object or wraps to perform the request made to the Delegate. Delegates, does not wrap or simplifies per se The Delegate Delegates actions and has no prime intent to simplify a system.

MEDIATOR, MANAGER ::Tag: PAT-FCD-SIM-MM Similarities: wrapping a subsystem, making it easier to use Like the Façade, the Mediator and the Manager wraps an entire subsystem to make the use and the process easier. Mediator: simplifying subsystem interaction, adding functionalities The Mediator simplifies a different aspect of the subsystem than the Façade. Where the Façade takes a set of actions on the subsystem and centralizes them and simplifies the use, the Mediator simplifies the interaction between the different elements within that subsystem. Unlike the Façade, the Mediator can add extra functionalities.

Replacing the Observer and Command Patterns If the Mediator is used to replace another Design Pattern, it is more the Observer and Command Patterns than anything else, as it is used to centralize actions and responses between objects and Classes within the subsystem.

Page 563: Re Factoring and Design Patterns

Refactoring and Design Patterns 563

Manager: explicitly includes business logic Unlike the Façade, the Manager explicitly includes Business Logic, having awareness of the system as a bigger whole, able to make decisions based on additional information from other sources.

STATE ::Tag: PAT-FCD-SIM-STT Similarities: using subsystems While the State Pattern itself might be a set of Implementations of different States, each State Class uses one or more subsystems to perform the actions it needs to perform. This makes it very similar to the Façade, but also to the Mediator Pattern. State: can replace itself, has knowledge of the placeholder it is in, can Inject upwards Unlike the Façade, the State can change itself during Runtime by injecting another State object in the placeholder it is used by, Injecting itself upwards. In this way, the State can deliberately change the way processes are executed within the placeholder. The Façade does not have this knowledge of the Placeholder that holds the Façade. Nor is the Façade capable of replacing itself when another Façade is needed to deal with the Process as it is at that point.

COOPERATION WITH OTHER PATTERNS ::Tag: PAT-FCD-COP

OBJECT MAP ::Tag: PAT-FCD-COP-OMP Using mapped objects and Inversion of Control Using Object Maps, you can map the objects of the subsystem you use inside the Façade and alter the Concrete objects in a different place, making it easier to change implementations and do unit testing as a consequence.

MEDIATOR ::Tag: PAT-FCD-COP-OMP Creating objects that can centralize communication and delegate actions The Façade itself helps to simplify the use of a subsystem, but sometimes you want more with that subsystem. For instance: Observe specific actions within that subsystem and respond to events or messages that are sent from that subsystem. The Mediator allows just that.

MANAGER, OPERATOR ::Tag: PAT-FCD-COP-MO Combining the Mediator and Façade Patterns The Manager and Operator use aspects of the Façade and the Mediator to create an object that can both simplify the access to a subsystem and respond to requests form that and other subsystems as well.

Page 564: Re Factoring and Design Patterns

564 Peter Kaptein

SUMMARY

::Tag: PAT-FCD-SHS One single Interface to an entire Subsystem The Façade offers one single interface to access and use functionalities of several Classes and objects in a subsystem Simplification of that Subsystem The intent of the Façade is to simplify the use of the subsystem by wrapping specific processes on that subsystem in Methods inside the Façade. Façade as a Wrapper / Adapter for an entire subsystem The Façade can be compared with an Wrapper or Adapter for an entire (sub) system Top Down, directive alternative for the Mediator The Façade is the Top Down variant of a solution where you want to centralize the command over a subsystem. The Mediator is more “part of the crew” and Mediates rather than Commands Top Down what needs to be done next. One exposed Method using multiple objects and Methods of the Subsystem One exposed Method from the Façade can call and use multiple objects and Methods of the Subsystem. Façade can implement additional code to provide the interface The Façade can implement additional code to make the Interface work as required by your code and your project. This additional code can be code that is not part of that Subsystem, but specifically implemented within and for the Façade.

Page 565: Re Factoring and Design Patterns

Refactoring and Design Patterns 565

SEE ALSO

::Tag: PAT-FCD-SEE Overview of the Patterns based on type and use There are many ways to look at the Patterns in this book. In the overview on Patterns based on type and use you will find the patterns sorted on type and use. ::Link:PAT-TYP Overview of the Creational, Structural and Behavioral patterns Design Patterns have a basic classification in three different groups: Creational, Structural and Behavioral Patterns. ::Link:PAT-CLASS The Mediator The Mediator Pattern has some similarities to the Façade, in the sense that it tries to simplify and centralize the command on a subsystem. ::Link: PAT-MED The Manager: more specific role, adding business logic The Manager is a Pattern very similar to the Façade, with the main difference that its main intent is to act as a manage for the processes that happen in the subsystem. ::Link: PAT-MGR The Wrapper Family Tree: showing the relationships and differences The Wrapper Family Tree shows the various variation on the Wrapper theme and the relationships and differences for each Wrapper. ::Link: WRIA-REL-001 The Delegate Pattern: delegating actions to a single object The Delegate Pattern delegates actions to a single object, to perform the actual actions. ::Link: PAT-DEL The Adapter: adapting a Class or object The Façade can be seen as the more versatile version of the Adapter. Where the Adapter adapts only a single Class or object, the Façade adapts an entire subsystem. ::Link: PAT-ADP

Page 566: Re Factoring and Design Patterns

566 Peter Kaptein

ASPECTS FROM “DESIGN PATTERNS”

::Tag: PAT-FCD-ASP From: Participants […] Subsystem Classes have no knowledge of the facade; that is, they keep no references to it. From: Collaborations […] Clients communicate with the subsystem by sending requests to Facade, which forwards them to the appropriate subsystem object(s) […] Although the subsystem objects perform the actual work, the facade may have to do work of its own to translate its interface to subsystem interfaces. From: Implementation […] An alternative to subclassing is to configure a Facade object with different subsystem objects. To customize the facade, simply replace one or more of its subsystem objects. From: Related Patterns […] Madiator is similar to Facade in that it abstracts functionality of existing classes. However, Mediator's purpose is to abstract arbitrary communication between colleague objects, often centralizing functionality that doesn't belong in any one of them. […] A mediator's colleagues are aware of and communicate with the mediator instead of communicating with each other directly. In contrast, a facade merely abstracts the interface to subsystem objects to make them easier to use; it doesn't define new functionality, and subsystem classes don't know about it.

Page 567: Re Factoring and Design Patterns

Refactoring and Design Patterns 567

FACTORY METHOD ::Tag: PAT-FAC: Discussing the Factory Method ::includesubchapters

Page 568: Re Factoring and Design Patterns

568 Peter Kaptein

INTENT(GOF)

::Tag: PAT-FAC-INT Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.

FACTORY METHOD BASICS

::Tag: PAT-FAC-DIA-BAS

Class A

Class B

Class C

Factory Method

1.b: «uses / requests»

2: «instantiates either/or»

4: «is returned to»

1.a: «has a»

Context

3: «produces»

1.c: «can be used by»

Your Code

Product X

WHEN/WHAT? ::Tag: PAT-FAC-DIA-BAS-001 When you need to define a blueprint for Factory Methods The Factory Method is mostly a way to define the blueprint with which you will create Factory Methods within your own Classes.

ADDITIONAL INFO ::Tag: PAT-FAC-DIA-BAS-002 Simple Factory is more to the point If you do not need to create blueprints for your Factory Methods, but simply want to implement them, use the Simple Factory instead. Starting point for Abstract Factory As you will find when you study the Abstract Factory Pattern, the Factory Method Pattern is almost completely implemented there as well. The main difference is that the Factory Method assumes you will implement the Factory Methods in your own Concrete Classes, while the Abstract Factory assumes you will extract and abstract these Factory Methods into separate Concrete Factories.

Page 569: Re Factoring and Design Patterns

Refactoring and Design Patterns 569

DIAGRAMS

::Tag: PAT-FAC-DIA

VISUAL SUMMARY OF THE FACTORY METHOD ::Tag: PAT-FAC-VSM

1: «are implemented in»

Concrete Creator B

+ produceProductA()+ produceProductB()

Factory Method Definitions 3: «uses»

Concrete Product A.b

Concrete Creator A

«classes»

4: «produces / return»

Concrete Product A.a

Concrete Product B.b

Concrete Product B.a3: «are extended / implemented by»

«concrete products»

«abstract definitions»

Re-usable definitions for factory methods to produce concrete products in several classes

5: «leading to»

Base Product A

Base Product B

«base product definitions»

2: «will produce producs of type»

NOTES: Abstract definitions for Methods and products The Factory Method Pattern delivers an abstract structure to create Factory Methods. Client implements the Factory Methods The Client (the Concrete Creator) implements the Factory methods. Produce products using pre-defined methods With the Factory Method Pattern you produce (instantiate) products (objects) from an existing set of Classes using pre-defined methods. From abstract to concrete

Page 570: Re Factoring and Design Patterns

570 Peter Kaptein

The Factory Method explicitly assumes you go from abstract definitions (either as Interface or Abstract Classes) of your Factory Methods to a concrete implementation. Assumes re-use The use of Interfaces or base-classes assumes you will re-use and implement the Factory methods in two or more derived classes. Extract the Factory Methods from the Concrete Creator to create the Abstract Factory When you look at the Factory Method, the biggest difference is the addition of the Client. This is similar to extracting the Factory Methods from your Concrete Creators and placing them in specific “Creation” or “Factory” classes. Simple Factory The Simple Factory is a simplified variation of the Factory Method, assuming you will only produce specific products of a specific type in one place.

Page 571: Re Factoring and Design Patterns

Refactoring and Design Patterns 571

BASE CLASS DIAGRAM ::Tag: PAT-FAC-DIA-000: Base class diagram of the Factory Method Pattern

«interface / base class»Product A

+ someMethod()+ anotherMethod()

Concrete Creator B

+ produceProductA()+ produceProductB()

«base class / interface»Creator

2.b: «extends / implements»

Concrete Product A.a3: «uses»

+ someMethod()+ anotherMethod()

+ doSomethingElse()Override:+ produceProductA()+ produceProductB()

Concrete Product A.b

+ someMethod()+ anotherMethod()

Concrete Creator A

+ doSomething()Override:+ produceProductA()+ produceProductB()

«return new Concrete Product»

2.a: «produces»

1.b: «implements»

2.a: «produces»

NOTES: As true as possible to implementation in “Design Patterns” You will find a very similar diagram in “Design Patterns”. What I focused on are the relationships between the Classes. Concrete Creator is not a Factory The Concrete Creator is a Class you define and which will implement specific creational methods as defined in the Base Class or Interface you use. As most current OOP languages do not allow multiple inheritance, you might like to use an Interface by default. Why not use a Product Base Class? If your Base Product contains code you want to re-use, you can choose to use a Product Base Class. No explicit rules on implementation Following the rules of the basic class diagram given here, the Factory Method can be implemented in many ways and with many variations. I only present two in this section on “The Base Diagram”. Producing more products of a different type The Factory Method Pattern does not limit you to implement just one creation-method. Instead, you can have several creation methods for many different products in once Class, including Products A, B and C. Implementing several Interfaces on one Class

Page 572: Re Factoring and Design Patterns

572 Peter Kaptein

Using Interfaces for the Creator, you can choose (if relevant) to combine several Creator Interfaces (A, B and C) on one Class, making these creators more versatile, also creating the risk of obscuring the roles and responsibilities of your Creators as a possible risk. Why it differs from the Abstract Factory The Factory Method is almost the same as the Abstract Factory. The main difference is that the Factory Method assumes you create the Products within your Class, while Abstract Factory aims at a clean structure for Delegation of these tasks. The Concrete Creators become Clients. ::Link: PAT-AFC-DIA-000 Conditional creation Within the Implementation of the Factory Method you will find a conditional creation of products. Based on the Product Type, the creation-method either returns a product of Sub-type A.a, A.b or A.c. This is displayed in the image below:

«interface / base class»Product A

+ someMethod()+ anotherMethod()

+ produceProductA()

«base class / interface»Creator

2.b: «extends / implements»

Concrete Product A.a

+ someMethod()+ anotherMethod()

Concrete Product A.b

+ someMethod()+ anotherMethod()

Concrete Creator A

+ yourMethodA()+ yourMethodB()Override:+ produceProductA( productType )

1: «implements / extends»

2.a: «produces either»

«case productTypeA: return new

Concrete Product A»

What about the Simple Factory? The Simple Factory follows very much the same lines as the Factory Method. Main difference is that the Simple Factory does not assume re-use of the Creator-Interface. It simply implements a set of conditions to create specific Products without implementing an Interface or extending a Class to build the Concrete Creator. ::Link: PAT-SFC What about the Abstract Factory? The Abstract Factory is a meta-pattern that acts like a blueprint for complete and more complex Factories. As discussed above, it (re)uses many of the same principles of the Factory Method, extracting the creational methods into separate classes instead. ::Link: PAT-AFC

Page 573: Re Factoring and Design Patterns

Refactoring and Design Patterns 573

SIMPLE DIAGRAM ::Tag: PAT-FAC-DIA-001

Class A

Class B

Class C

Factory Method

1.b: «uses / requests»

2: «instantiates either/or»

4: «is returned to»

1.a: «has a»

Context

3: «produces»

1.c: «can be used by»

Your Code

Product X

DEPENDENCIES: Your Code: 1.a: Has a Context 1.b: Uses / requests a Factory Method 1.c: the context can be used by the Factory Method The Factory Method: 2: Instantiates either/or Class A, B, C (based on the Context given by your code) Class A, B, C: 3: Produces Product X Product X: 4: Is returned to Your Code

NOTES: The Factory Method lives inside your code The Factory Method lives inside of your code and is the implementation of either an Interface implemented by your code, or an overridden method from a Base Class.

Page 574: Re Factoring and Design Patterns

574 Peter Kaptein

IMPLEMENTING THE FACTORY METHOD FROM A BASE CLASS ::Tag: PAT-FAC-DIA-002

Your Class

Class B

Interface A /Abstract Class B

Class C

4: «implements»

3.c: «instantiates /Returns object from either»

Class A

Base Creator Class

2.a: «extends»

2.b: «implements»3.b: «is of type»

1: «implements»

Abstract Method A

3.a: «overrides»

Concrete Method A

DEPENDENCIES: Base Creator Class: 1: Implements Abstract Method A Your Class: 2.a: Extends the Base Creator Class 2.b: Implements a Concrete version of Method A (the Factory Method) Concrete Method A: 3.a: Overrides Abstract Method A 3.b: Is of type Interface A or AbstractClass B 3.c: Instantiates and returns an object (called Product in the Factory Pattern) based on either Class A, B, C: 4: Implement Interface A or extend Abstract Class B.

Page 575: Re Factoring and Design Patterns

Refactoring and Design Patterns 575

NOTES: Using a common class/Interface provides a common fingerprint The use of a common Interface or Abstract Class makes Classes A, B and C interchangeable. As each uses the same Base Class or Interface, the returned Products from any of these Classes all have the same fingerprint to be used by your code. Using a Base Factory Class might be too much for your needs The use of a Base Factory Class is the official way to go for this Pattern, but only proves useful when you want to create multiple variations of the same Factory Method, for instance on several Factory objects. See the Simple Factory on the next pages. ::Link: PAT-SFC

WHY WOULD YOU USE THE FACTORY METHOD?

::Tag: PAT-FAC-USE Re-use of specific Factory Methods / Classes you can exchange for others The use of Abstract classes or Interfaces to define the Factory Methods smells like re-use. Two or more Classes will implement the same Factory Methods and when you need to, you can switch one Class for the other, making it possible to get different results from the same Call. Abstraction of object Creation By letting the Factory Method decide which Class will be used to create the concrete object When you parse data or Abstract Structures into object Trees The Simple Factory is a very handy tool to produce the Concrete objects to build the required object Tree (or Composite object).

COMPARISONS AND DIFFERENCES

::Tag: PAT-FAC-CDF

PATTERNS WITH SIMILARITIES ::Tag: PAT-FAC-SIM

SIMPLE FACTORY ::Tag: PAT-FAC-SIM-SF Similarities: methods to produce products The Simple Factory produces Explicitly produces several variations of a product type, does not require Abstract Definition The Simple Factory is the simplified version of the Factory Method Pattern. It takes away the hard requirement of Abstract definitions that the Factory Method Pattern has. The Simple Factory might be the most used Factory Pattern of all, simply because it makes more sense in most situations where you need that specific implementation only once.

Page 576: Re Factoring and Design Patterns

576 Peter Kaptein

ABSTRACT FACTORY ::Tag: PAT-FAC-SIM-AFC Similarities: same principles, next step The Abstract Factory uses the exact same principles as the Factory Method, but takes it one step further: by extracting and encapsulating the methods into separate Classes (the Concrete Factories). This makes it possible to vary the Concrete Implementation of the Factory Methods while your own code and Class can remain stable. Is a blueprint for many different Concrete Factories producing similar products Where the Factory Method is a pattern that describes what your Factory Methods should comply to, the Abstract Factory is a blueprint that describes what your Classes should look like. Where the Factory Method assumes you will implement these in your code, the Abstract Factory assumes you will put these methods into a separate Concrete Factory Class.

COOPERATION WITH OTHER PATTERNS ::Tag: PAT-FAC-COP

ABSTRACT FACTORY ::Tag: PAT-FAC-COP-AFC Factory Method is part of the blueprint The Factory Method is part of the blueprint that makes the Abstract Factory. You will find the exact principles of the Factory Method back in the Abstract Factory, but instead of applying them on your Concrete Class, you apply them to a specific Factory Class (the Concrete Factory).

SIMPLE FACTORY HAS TAKEN OVER THE SCENE ::Tag: PAT-AFC-COP-SF Implemented most Due to its simple appeal and the fact that many situations where you need and use a Factory do not justify the use of Abstract definitions, the Simple Factory has taken over the world like counterfeit Rolexes. Simple Factory is not an “official” pattern, but does exactly what is needed and with less paperwork. Factory Method and Abstract Factory nice for the records In this book I consider Factory Method and Abstract Factory two patterns which are nice for the records. Anywhere where you would use a Factory I assume the Simple Factory as the first choice.

Page 577: Re Factoring and Design Patterns

Refactoring and Design Patterns 577

SUMMARY

::Tag: PAT-FAC-SHS Factory Method: focus on the method itself The Factory Method does not focus on a Class or object, but on a Method within the Class or object, hence Factory Method Factory Method Pattern: includes the use of a Superclass or Abstract Class The Factory Method Pattern includes the use of a Superclass or Abstract Class (or interface) and the Concrete Implementation by Your Class of the Abstract version of the Factory Method. Factory Method Pattern: two approaches The Factory Method allows you to do and mix two different things: Create multiple creation-methods to produce completely different Products You can create several creation-Methods in one Class to produce completely different Products. Provide a variable to select a subtype of a specific product When you provide a variable to the creation-Method, the code within the Method can select a specific Class to produce a subtype of a product, that still shares the same Interface as all other products expected from that Method. Using a Context If you want to abstract the specific choice of the subtype of a product, you can choose to go for a Context in which the Concrete Product will be selected and produced by the Factory Method. Simple Factory: what you get when you keep the principle and cut away all the fluff The Simple Factory as described in this document seems like an implementation of the Abstract Factory, but is not, due to the lack of use of a Superclass and the lack of an Abstract version of the Factory Method.

Page 578: Re Factoring and Design Patterns

578 Peter Kaptein

SEE ALSO

::Tag: PAT-FAC-CNT Overview of the Patterns based on type and use There are many ways to look at the Patterns in this book. In the overview on Patterns based on type and use you will find the patterns sorted on type and use. ::Link:PAT-TYP Overview of the Creational, Structural and Behavioral patterns Design Patterns have a basic classification in three different groups: Creational, Structural and Behavioral Patterns. ::Link:PAT-CLASS The Strategy Pattern: focuses on processes (Strategies) instead of Products The Strategy Pattern follows very much the sampe principles as the Factory, but instead of returning Products it returns Strategies (or ways to deal with a specific process). ::Link: PAT-STRA Abstract Factory: a completely different approach and implementation The Abstract Factory may be offering some of the same principles as the Factory Method and Simple Factory, but the implementation and use is completely different. ::Link: PAT-AFC The Bridge and Delegate: might use a Factory to choose the concrete object The Bridge Pattern might use the Factory to choose and produce the concrete object it Delegates its actions and requests to. ::Link: PAT-BRIDC|PAT-DEL The Builder, Parser and Interpreter: using the Factory to create Composite objects Builder, Parser and Interpreter can use a Factory to produce the objects they need to create a Composite object. Both the Parser and Interpreter use an Abstract Description (or another object Tree) to build the new Structure. ::Link:PAT-INPR|PAT-PARS|PAT-BLD Where the Factory Method can be used The Factory Method can be used in many places. ::Link:MHOPUDO-MGR

ASPECTS FROM DESIGN PATTERNS

::Tag: PAT-FAC-ASP To be added.

Page 579: Re Factoring and Design Patterns

Refactoring and Design Patterns 579

FACTORY, ABSTRACT ::Tag: PAT-AFC : Discussing the Abstract Factory Pattern ::includesubchapters

Page 580: Re Factoring and Design Patterns

580 Peter Kaptein

INTENT (GOF)

::Tag: PAT-AFC-INT Provide an interface for creating families of related or dependent objects without specifying their concrete classes.

ABSTRACT FACTORY BASICS

::Tag: PAT-AFC-DIA-BAS

3.b: «instantiates /returns»

2.b: «instantiates /returns»

Your Code

Product A.1

Product B.1

Pruduct C.1

Factory A

1.b: «uses»

Product A.2

Product B.2

Pruduct C.2

Factory B

1.c: «or uses»

Interface A

«2.a: implements»

«3.a: implements»

1.a: «has a»

Context

WHEN/WHAT? ::Tag: PAT-AFC-DIA-BAS-001 When you need to create a line of different factories The Abstract Factory is a Pattern that describes how you can define the interfaces for a set of factories you can interchange for any of the other, to produce very specific products. Blueprint for Concrete Factories

Page 581: Re Factoring and Design Patterns

Refactoring and Design Patterns 581

The Abstract Factory is basically a Blueprint for Concrete Factories. The Abstract Factory Pattern uses this principle to create multiple Concrete Factories based on the Abstract Factory and to allow you to freely choose between any of these Concrete Factories to produce specific Products (“A.1” or “A.2”, “B.1” or “B.2” and so on)

OTHER INFO ::Tag: PAT-AFC-DIA-BAS-002 Different implementations of a Factory per context The Abstract Factory Pattern becomes useful when your code works within one or more specific Contexts, use the same basic Products to perform its actions, but needs a different Implementation for each specific Context.

Page 582: Re Factoring and Design Patterns

582 Peter Kaptein

DIAGRAMS

::Tag: PAT-AFC-DIA

VISUAL SUMMARY OF THE ABSTRACT FACTORY ::Tag: PAT-AFC-VSM

A: «are implemented in»

Concrete Factory B

+ produceProductA()+ produceProductB()

Abstract Factory Definition 3: «uses»

Concrete Product A.b

Concrete Factory A

«classes»

D: «produces / return»

Concrete Product A.a

Concrete Product B.b

Concrete Product B.aC: «are extended / implemented by»

«concrete products»

«abstract definitions»

Blueprints for interchangeable factories with very specific production lines producing specific products

3: «leading to»

Base Product A

Base Product B

«base product definitions»

B: «will produce producs of type»

Client A1: «can use any factory of»

2: «uses any of»

NOTES: Abstract factory is what happens when you extract Factory Methods The Abstract Factory is (in a way) what happens when you extract the Factory Metjods from the Concrete Creators (Clients). Blueprints for concrete factories More than anything, the Abstract Factory is a blueprint for one or more Concrete Factories all following the same base setup but allowing you to create very specific implementations.

Page 583: Re Factoring and Design Patterns

Refactoring and Design Patterns 583

Each Concrete Factory produces products of one specific subtype As far as I understand “Desing Patterns”, each Concrete Factory should only produce one subtype of a specific type of Product (so Concrete Factory A can only produce Products: “A.a” and “B.a” but not “A.b” and “B.b” as well. Change the Concrete Factory if you want products of another subtype If you want to have products of another subtype (“A.b” instead of “A.a”) you change the Concrete Factory itself. As all Concrete Factories of a specific type share the same Base Class or Interface, this is simply a matter of choosing and implementing a different Concrete Factory.

BASE CLASS DIAGRAM OF THE ABSTRACT FACTORY ::Tag: PAT-AFC-DIA-000: Base class diagram of the Abstract Factory

«interface / base class»Abstract Product A

+ someMethod()+ anotherMethod()

Concrete Factory A.b

+ produceProductA()+ produceProductB()

«base class»Abstract Factory A

2.b: «extends»

Concrete Product A.a 3: «uses»

+ someMethod()+ anotherMethod()

Override:+ produceProductA()+ produceProductB()

Concrete Product A.b

+ someMethod()+ anotherMethod()

Concrete Factory A.a

Override:+ produceProductA()+ produceProductB()

«return new Concrete Product»

2.a: «produces»

3: «extends / implements»

2.a: «produces»

«interface / base class»Abstract Product B

+ someMethod()+ anotherMethod()

Concrete Product B.b4: «extends / implements»

+ someMethod()+ anotherMethod()

Client A2.b: «requests products of type»

1.a: «uses a factory of type»

NOTES: As true as possible to implementation in “Design Patterns” You will find a very similar diagram in “Design Patterns”. What I focused on are the relationships between the Classes. Differences and similarities to the Factory Method

Page 584: Re Factoring and Design Patterns

584 Peter Kaptein

At first sight, there seems to be close to no difference between the Abstract Factory and the Factory Method. Both Patterns can produce different types of Products (A, B and C). Both can produce Products based on Interfaces or Base Classes. Abstract Factory adds the “Client” object and the “Concrete Creator” is now called “Concrete Factory”. Differences to the Factory Method: Delegation of the creation process Within the Factory Method Pattern, the class that requires products implements the code that will produce these products. Within the Abstract Factory, that production process is delegated by the Client to the Concrete Factory. In other words: the “Concrete Creator” in the Factory Method Pattern becomes the “Client”. What about Conditional Creation? It is not entirely clear to me whether the Abstract Factory Pattern allows for conditional creation of Products. Based on the examples in “Design Patterns” and the text on the Abstract Factory I assume there is no such thing as Conditional Creation of Products within each Factory. The approach seems to be: Concrete Factory A produces Concrete Products A.a, B.a, C.a while Concrete Factory B produces Concrete Products A.b, B.b and C.b. Concrete Factory A can not produce Products A.b, A.c or B.b and B.c. ::Link: PAT-FAC-DIA-000 Conditional Creation by switching to another Factory The Abstract Factory Pattern seems to promote the Conditional Creation of Products by switching the entire Factory. So if you need Concrete Product A.b, you switch to Concrete Factory B. If you need Concrete Product B.c you switch to Factory C. The next diagrams In the next diagrams I will zoom into specific aspects of the Abstract Factory, showing a generic implementation and then highlighting each specific part of the Abstract Factory.

Page 585: Re Factoring and Design Patterns

Refactoring and Design Patterns 585

SIMPLIFIED DIAGRAM OF THE ABSTRACT FACTORY ::Tag: PAT-AFC-DIA-001

3.b: «instantiates /returns»

2.b: «instantiates /returns»

Your Code

Product A.1

Product B.1

Pruduct C.1

Factory A

1.b: «uses»

Product A.2

Product B.2

Pruduct C.2

Factory B

1.c: «or uses»

Interface A

«2.a: implements»

«3.a: implements»

1.a: «has a»

Context

DEPENDENCIES: Your Code: 1.a: Has a (or works witin) a Context 1.b: Uses FactoryA 1.c: Or uses FactoryB Factory A: 2.a: Implements InterfaceA 2.b: Instantiates and returns Product A.1, B.1 or C.1 Factory B: 3.a: Implements Interface A 3.b: Instantiates and returns Product A.1, B.1 or C.1

Page 586: Re Factoring and Design Patterns

586 Peter Kaptein

THREE PARTS To understand the Abstract Factory, we cut it in three parts: Part 1: An example of the Abstract Classes that make an Abstract Factory In this example we focus on the Abstract Classes (which can also be Interfaces if you like) Part 2: An example of the Concrete implementation of a Abstract Factory Where we see how the Abstract Factory is implemented. Part 3: An example in code To show you how an Abstract Factory can be implemented I show brief code

PART 1: AN EXAMPLE OF THE ABSTRACT CLASSES THAT MAKE AN ABSTRACT FACTORY ::Tag: PAT-AFC-DIA-002

Your Abstract Factory /Your Factory Interface

Abstract Product B / Product B Interface

Abstract Product C /Product C Interface

2.b: «returns objects of type»

Abstract Product A / Product A Interface

YourClass1: «refers to» 2.a: «has»

Production lines (Methods) A, B, C

DEPENDENCIES: Your Class: 1: Refers to Your Abstract Factory / Your Factory Interface Your Abstract Factory / Your Factory Interface: 2.a: Has Production Lines (Methods) A, B, C 2.b: Returns objects of type: Abstract Product A, B, C / Product A, B, C Interface

Page 587: Re Factoring and Design Patterns

Refactoring and Design Patterns 587

NOTES: First: Create an Abstract Factory You start implementing the Abstract Factory Pattern by creating your Abstract Factory. The Abstract Factory (as mentioned before) is the blueprint for your Concrete Factories. This blueprint states:

1. The Methods – Stating which Products can and will be produced 2. The Return types – Of the Products that will be created

You can use either Abstract Classes or Interfaces The Abstract Factory can either be created USING Abstract Classes (which usually have no code of their own, but just the Methods that you will use as your blueprint) or Interfaces, which are very similar to Abstract Classes (as they do not contain code) but which are not Extended like the Abstract Classes, but Implemented. Purpose: standardized Factories and standardized Production Lines The sole purpose of this approach is to create a set of standardized Factories with standardized Production Lines. So that the Production Lines A, B, C in Factory A and work exactly the same as the production lines in Factory B and Factory C. Defining the standardized interface for each Product Once you have a standardized Factory with standardized Production Lines (the methods), you can start defining the standards for the Products: using an Interface or Abstract Product Class. Using any Factory Since you are using either a common Class (the Abstract Factory and the Abstract Products) or a common Interface (the Factory Interface and the Product Interfaces) your code can now use any version of your Abstract Factory and Abstract Products.

Page 588: Re Factoring and Design Patterns

588 Peter Kaptein

PART 2: AN EXAMPLE OF THE CONCRETE IMPLEMENTATION OF AN ABSTRACT FACTORY ::Tag: PAT-AFC-DIA-003

2.b: «implements»

Your Concrete Factory A

Concrete Product B.1

Concrete Product C.1

Concrete Product A.1

YourClass1: «instantiates»

Your Abstract Factory /Your Factory Interface

Abstract Product B / Product B Interface

Abstract Product C /Product C Interface

Abstract Product A / Product A Interface

4: «implements»

2.a: «has / exposes»

Production lines (Methods) A, B, C

3.a: «creates either»

3.b: «returns result to»

4: «implements»

4: «implements»

DEPENDENCIES: Your Class: 1: Instantiates YourConcreteFactoryA, which is one of the many Concrete Factories you can base on AbstractFactory / FactoryInterface A Your Concrete Factory: 2.a: Implements Abstract Factory / Factory Interface A 2.b: Has / exposes Productions Lines (Methods) A, B, C Productions Lines (Methods) A, B, C: 3.a: Creates / returns either Concrete Product A.1, B.1 or C.1. Concrete Products A.1, B.1 and C.1: 4: implement Abstract Product / Product Interface A, B and C.

Page 589: Re Factoring and Design Patterns

Refactoring and Design Patterns 589

NOTES: Your Class and Your Code only have to use one type abstract reference to any of Your Concrete Factory, and the Concrete Products A, B and C.

PART 3: EXAMPLES IN CODE ::Tag: PAT-AFC-DIA-004 The best way to demonstrate this is in code: // Context A: creating the Concrete Factory: A YourFactoryInterface yourFactory = new YourConcreteFactoryA(); // Your Class, which handles the process Context specifically YourClass yourHandler=new YourClass(); // Passing the Concrete Factory to handle the Context yourHandler.handleContext(yourFactory , yourData); // Context B: creating the Concrete Facotory: B YourFactoryInterface yourFactory = new YourConcreteFactoryB(); // Your Class, which handles the process Context specifically YourClass yourHandler=new YourClass(); // Passing the Concrete Factory to handle the Context yourHandler.handleContext(yourFactory, yourData); // Within your Class YourClass Public void function handleContext( YourFactoryInterface factory , Object yourObject ) {

// Creating Concrete Product A ProductAInterface productA = yourFactory.createProductA(); // Do something your yourObject productA.doSomething(yourObject); // Create Concrete Product B ProductBInterface productB= yourFactory.createProductB(); // Do something else using product B product.doSomethingElse(yourObject); // Done

}

Page 590: Re Factoring and Design Patterns

590 Peter Kaptein

WHY WOULD YOU USE AN ABSTRACT FACTORY?

::Tag: PAT-AFC-USE When you need several versions of a specific Factory Abstract Factory assumes you want and need several Concrete Factories you can visit and use to produce specific Products of a specific subtype. The Abstract Factory Pattern lets you vary these Concrete Factories and as a consequence receive different results when you call the specific Factory methods. Bundle the Construction Methods: offer one point of access to produce several Products The Factory Method produces only one type of Product (A), with different variations on that Product (A.1, A.2, A.3), but this might not always be convenient for your use. For instance, when you work with different Contexts and need a set of different and Context specific objects within that Context. The Abstract Factory Pattern helps you to bundle all these Construction Methods into one single instance of the Abstract Factory. Need a different implementation of your products per Context? When you need several different implementations of one or more Products to produce objects catered to very specific Contexts. For instance: different “brands” or different strategies to be implemented. Using the Abstract Factory Pattern, these Context Specific implementations of different Products are nicely bundled in one specific Concrete Factory.

COMPARISONS AND DIFFERENCES

::Tag: PAT-AFC-CDF

PATTERNS WITH SIMILARITIES ::Tag: PAT-AFC-SIM

FACTORY METHOD, SIMPLE FACTORY ::Tag: PAT-AFC-SIM-FMSF Similarities: producing Products Where Abstract Factory focuses on Context Specific Factories to produce Context Specific variations of different Products, Factory Method produces different variations of one single Product. Factory Method: implemented on your class The Abstract Factory extracts and encapsulates the Factory Methods into separate Concrete Factories, while the Factory Method assumes you will implement this within your Classes. Simple Factory: one implementation, no abstract definition The Simple Factory does not require an Abstract definition of the Factory and Factory Methods. You can simply implement your Factory Methods without having to implement an Abstract Class or Interface with them, as both Abstract Factory and Factory Method explicitly do dictate.

COOPERATION WITH OTHER PATTERNS ::Tag: PAT-AFC-COP

Page 591: Re Factoring and Design Patterns

Refactoring and Design Patterns 591

SIMPLE FACTORY HAS TAKEN OVER THE SCENE ::Tag: PAT-AFC-COP-SF Implemented most Due to its simple appeal and the fact that many situations where you need and use a Factory do not justify the use of Abstract definitions, the Simple Factory has taken over the world like counterfeit Rolexes. Simple Factory is not an “official” pattern, but does exactly what is needed and with less paperwork. Factory Method and Abstract Factory nice for the records In this book I consider Factory Method and Abstract Factory two patterns which are nice for the records. Anywhere where you would use a Factory I assume the Simple Factory as the first choice.

Page 592: Re Factoring and Design Patterns

592 Peter Kaptein

SUMMARY

::Tag: PAT-AFC-SHS Two abstract classes: Abstract Factory and Abstract Product. Abstract Classes are Classes without any concrete Code. They only contain the Methods you want to implement in your Concrete facotries. There are two Abstract Classes: the Abstract Factory and the Abstract Product. Concrete Factory Classes The Concrete Factory is any Class implementing the Abstract Classes making the Abstract Factory. Where the Abstract Factory Classes (or Interfaces) only define the Methods, the Concrete Classes and Concrete Factory contain the concrete code to produce the Products from the Classes that specific Factory uses. Concrete Product Classes The Concrete Classes that will be used to create the Concrete Factory and the Concrete objects produced in that Factory A blueprint for standardized factories with standardized production lines The Abstract Factory is more than anything a blueprint to create a series of standardized factories with standardized production lines, so you can exchange one for another and still perform the same actions to get the products. One blueprint, many factories One blueprint or Abstract Factory can be implemented in many Concrete Factories Standardizing the production lines By offering standardized production lines (the Construction Methods) you can use any Concrete Factory from the same family. One factory constructs two or more different types of Products The objects produced in one Factory can be of several different types, like “Car”, “Boat” and “Radio” Need similar products but from a different factory? To get another Product from one of the Production lines, you need to change or replace the Concrete Factory itself. You will still be producing a “Car”, “Boat” and “Radio”, but they will be made from a different set of Classes, by a different Concrete Factory. Need to simplify things? Use a Object Map to get the appropriate factory One way to catalog and retrieve Concrete Factories is by using a Object Map and map each Concrete Factory Class to a specific key. Want to go even further? Create a polymorphic Factory Using a Object Map and the Context, you can go one step further and create one single Polymorphic Factory that represents and uses all factories of one specific family.

Page 593: Re Factoring and Design Patterns

Refactoring and Design Patterns 593

SEE ALSO

::Tag: PAT-AFC-SEE Overview of the Patterns based on type and use There are many ways to look at the Patterns in this book. In the overview on Patterns based on type and use you will find the patterns sorted on type and use. ::Link:PAT-TYP Overview of the Creational, Structural and Behavioral patterns Design Patterns have a basic classification in three different groups: Creational, Structural and Behavioral Patterns. ::Link:PAT-CLASS Simple Factory / Factory Pattern: for lesser demands The Abstract Factory is quite demanding in its implementation. When you need something more simple, very likely you are looking for either the Factory Method or even simpler: the Simple Factory. ::Link: PAT-FAC Strategy: producing results focused on processes Where any Factory produces a Product, the Strategy Pattern focuses on processes and how they are dealt with. The Strategy in its most basic implementation is very much like the Simple Factory. ::Link: PAT-STRA Object Map: helping you choose the appropriate Concrete Factory via a Context When you store your Concrete Factories against the Context Keys in a Object Map, you can use that Object Map and a Context to retrieve the appropriate Concrete Factory for that Context. Use ::Link:MHOPUDO-MGR

Page 594: Re Factoring and Design Patterns

594 Peter Kaptein

BONUS MATERIAL

::Tag: PAT-AFC-BNS

USING A OBJECT MAP TO RETRIEVE A FACTORY ::Tag: PAT-AFC-DIA-004

Your CodeYour Factory

Provider

1.b: «uses»

1.a: «has a»

Context

Product X

2.b: «is passed to»

Concrete Factory A

Concrete Factory B

Concrete Factory B

3.a: «uses either»

3.b: «produces»

4: «is returned to»

2.a: «relates to»

DEPENDENCIES: Your Code: 1.a: Has a Context 1.b: Uses Your Factory Provider The Context: 2.a: Relates to Concrete Factory A, B or C 2.b: Is passed to Your Factory Provider Your Factory Provider: 3.a: Uses either Concrete Factory A, B or C 3.b: Produces Product X Product X: 4: Is returned to Your Code

NOTES: Storing and retrieving Factories under a Context or key The main trick in this implementation of a Factory Retriever is to store the Concrete Factories under specific keys.

Page 595: Re Factoring and Design Patterns

Refactoring and Design Patterns 595

Using the same Interface: making your Factory Provider the main point of entry When Your Factory Provider and your Concrete Factory use the same Interface, your Factory Provider can become the main point of entry to request and create the required Products.

CONCRETE IMPLEMENTATION OF A FACTORY PROVIDER USING A OBJECT MAP ::Tag: PAT-AFC-DIA-005

Concrete Factory Class A

Your DataMap

Concrete Factory Class B

Concrete Factory Class B

4.a: «contains / accesses»

«key» «value»Concrete Factory Class X /

Concrete Factory X

2: «is passed to»

4.b: «returns»

«DataMap Contents»

Your Factory Provider

1.a: «uses»3: «exposed by»

Retrieval-Method B

Context A

5: «exposes»

Construction method A, B, C

1.b: «receives / instantiates»

1.c: «uses / calls / receives result from»

Concrete Product X

6: «produces»

1.d: «receives»

DEPENDENCIES: Your Factory Provider: 1.a: (Has received and) uses Context A 1.b: Receives / instantiates Concrete Factory Class X / Concrete Factory X 1.c: Uses / calls / receives results (products) from Construction Method A, B, C 1.d: Receives Concrete Product X Context A: 2: Is passed to Retrieval Method B Retrieval Method B:

Page 596: Re Factoring and Design Patterns

596 Peter Kaptein

3: Is exposed by Your Object Map Your Object Map: 4.a: Contains Concrete Factory Classes / Concrete Factories A, B, C 4.b: Returns Concrete Factory Class X / Concrete Factory X Concrete Factory Class X / Concrete Factory X: 5: Exposes Construction Method A, B, C Construction Method A, B, C: 6: Produces Concrete Product X

NOTES: HashMaps and Key/Value pairs The simplest way to implement this pattern is by using a HasMap and Key/Value pairs, where the Key can be a String value and the Value either the Class (for late instantiation) or a Concrete Factory already instantiated. Encapsulation of the complexity to retrieve a Specific Concrete Factory By using a Factory Provider, you encapsulate the complexity needed to retrieve a specific Concrete Factory. Polymorphic like the Bridge and Delegate, using the Context to retrieve a specific Build of Product The Factory Provider can be implemented as a polymorphic Factory. When your external code requests for a specific Product, it can provide a Context to the Construction Method. Your Factory Provider will retrieve the appropriate Factory and produce the type of Product that is associated to the Method that was called. Implement the same Interface on your Factory Provider, set the context separately When you use the same Interface you use on the Concrete Factories, your Factory Provider becomes the ideal pass-through station. The Interface forces you to update the Factory Provider when new Construction Methods are added. To inform your Factory Provider which Context is required, you can set the Context separately.

Page 597: Re Factoring and Design Patterns

Refactoring and Design Patterns 597

FACTORY, SIMPLE ::Tag: PAT-SFC: Discussing the Simple Factory ::includesubchapters

Page 598: Re Factoring and Design Patterns

598 Peter Kaptein

INTENT

::Tag: PAT-SFC-INT Implement an interface to create an object based on specific parameters (the Context or product type). The Simple Factory chooses and instantiates the according Class and returns the result object to the caller.

SIMPLE FACTORY BASICS

::Tag: PAT-SFC-DIA-BAS

Class A

Class B

Class C

Simple Factory

1.b: «uses / requests»

2: «instantiates either/or»

4: «is returned to»

1.a: «has a»

Context

3: «produces»

1.c: «can be used by»

Your Code

Product X

WHEN/WHAT? ::Tag: PAT-SFC-DIA-BAS-001 To create a simple factory without the boilerplate code You use the Simple Factory to create a factory without the boilerplate-code of the Abstract Factory and Factory Method. Instantiates objects based on a context The Factory intantiates (produces) objects based on a specific context or type. For instance, cars of type “A”, “B” and “C” which all share the same interface, but each have a different implementation.

OTHER INFO ::Tag: PAT-SFC-DIA-BAS-002 Can be implemented in separate Class or in your code The Simple Factory can be implemented in your code or in a separate Factory Class. Returns products Like its bigger brothers the Simple Factory produces and returns products. Can have multiple factory methods The Simple Factory allows you to inplement multiple factory methods.

Page 599: Re Factoring and Design Patterns

Refactoring and Design Patterns 599

Each factory method has an object subtype Each method in the Simple Facotry produces one or more products of a specific subtype. Each of these products share the same Interface but comes from a differen Class and has a different implementation. Useful for Builder, Parser and Interpreter The Simple Factory is a very useful Pattern for the Builder, Parser and Interpreter as it can produce the objects these Patterns need to build a Composite structure.

Page 600: Re Factoring and Design Patterns

600 Peter Kaptein

DIAGRAMS

::Tag: PAT-SFC-DIA

VISUAL SUMMARY OF THE SIMPLE FACTORY ::Tag: PAT-SFC-VSM

+ produceProductA( subType )+ produceProductB( subType )

Simple Factory

Concrete Product A.b

1: «will produce producs of type»

Concrete Product A.a

Concrete Product B.b

Concrete Product B.a

2: «are implemented as»

«concrete products»

A very simple way to produce concrete products based on specific parameters

4: «leading to»

3: «produces / return»

Base Product B

Base Product A

«base product definition»

NOTES: No interface for the Factory Methods The Factory Methods producing the concrete products do not have an abstract definition. You do not need to create an abstract version but can simply implement what you need. Using a context to produce a specific subtype of a specific product The methods in a Simple Factory usually provide two or more variations or subtypes of a specific product. To achieve this, you can pass a specific parameter or “context” which helps the code withn the method to decide which Class to use and instantiate.

Page 601: Re Factoring and Design Patterns

Refactoring and Design Patterns 601

BASE CLASS DIAGRAM ::Tag: PAT-SFC-DIA-000

«interface»Product A

+ someMethod()+ anotherMethod()

Concrete Product A.a3: «uses»

+ someMethod()+ anotherMethod()

Concrete Product A.b

+ someMethod()+ anotherMethod()

Simple Factory A

+ produceProductA( productType )+ produceProductB( productType )

1.b: «implements»

2.a: «produces»

«case productTypeA: return new

Concrete Product A»

NOTES: Conditional creation of Product subtypes One of the main characteristics of the Simple Factory is that each creational Method expects at least one parameter defining the Product (sub) Type. This subtype will help the Simple Facotory decide which Class to instantiate to produce which specific subtype (A.a, A.b or A.c). No explicit rules on implementation The Simple Factory can be implemented in many ways and with many variations. You can implement the Simple Factory as a Method within your code and your Class (not to be confused with te Factory Method which requires you explicitly to implement either a Base Class or Interface for that Method). You can also implement it as a separate Class, producing the products on demand by Method calls. Producing more products of a different type The Simple Factory does not limit you to implement just one creation-method. Instead, you can have several creation methods for many different products in once Class, including Products A, B and C.

Page 602: Re Factoring and Design Patterns

602 Peter Kaptein

SIMPLE DIAGRAM OF THE SIMPLE FACTORY ::Tag: PAT-SFC-DIA-001

Class A

Class B

Class C

Simple Factory

1.b: «uses / requests»

2: «instantiates either/or»

4: «is returned to»

1.a: «has a»

Context

3: «produces»

1.c: «can be used by»

Your Code

Product X

DEPENDENCIES: Your Code: 1.a: Has a Context 1.b: Uses / requests the Simple Factory 1.c: The Context can be used by the Simple Facotory The Simple Factory: 2: Instantiates either / or Class A, B or C Class A, B or C: 3: Produces Product X Product X: 4: Is returned to Your Code

Page 603: Re Factoring and Design Patterns

Refactoring and Design Patterns 603

IMPLEMENTING THE SIMPLE FACTORY ::Tag: PAT-SFC-DIA-002

Simple Factory A

Class B

Interface A /Abstract Class B

Class C

5: «implement»3.b: «instantiates / uses either»

Class A

2: «implements / uses context on»

Construction Method A

3.a: «has return-type»

Your Class1.b: «receives» 4: «implements / extends»

ProductX

3.c: «produces / returns»1.a: «uses /offers context to»

1.a: «has a»

Context

Your Class: 1.a: Uses Simple Factory A 1.b: Receives ProductX, which is produced by SimpleFactoryA Simple Factory A: 2: Implements Construction Method A Construction Method A: 3.a: Has a return type of Interface A / Abstract Class B 3.b: Instantiates / uses either Class A, B, C 3.c: Produces / returns ProductX Product X: 4: Extends or Implements InterfaceA or AbstractClassB Class A, B, C: 5: Implement Interface A / Abstract Class B

Page 604: Re Factoring and Design Patterns

604 Peter Kaptein

NOTES: Simple Factory is not “the Factory Pattern” The Simple Factory is very likely what you associate to be the “Factory Pattern”. However, in “Design Patterns”, this most common implementation of a “Factory” is mentioned or shown nowhere. Since its use is almost anywhere and everywhere, it is silly to ignore it and it does have a clear reason for existence. That reason is its simplicity and lack of boilerplate code. Borrows elements from Abstract Factory and Factory Method The Simple Factory borrows important elements from the Abstract Factory and the Factory Method, but is neither Abstract Factory or Factory Method. Both Factory Method and Abstract Factory make explicit use of Superclasses and Abstract Methods to define the Concrete Factory Methods. The Simple Factory does no such a thing. Avoid using the Simple Factory? Should you then avoid using the Simple Factory? No. The Simple Factory as one possible seed that lead to the evolution of the Abstract Factory and Factory Method Patterns.

Page 605: Re Factoring and Design Patterns

Refactoring and Design Patterns 605

WHY WOULD YOU USE THE SIMPLE FACTORY?

::Tag: PAT-FAC-USE Choice, based on simple parameters To offer choice in the type of object you get in return Simplest form of a Factory Unlike the Factory Method and the Abstract Factory, the Simple Factory does not expect you to implement an Interface or Base Class for the methods you use to produce and create the Products. Abstraction of object Creation By letting the Factory Method decide which Class will be used to creare the concrete object When you parse data or Abstract Structures into object Trees The Simple Factory is a very handy tool to produce the Concrete objects to build the required object Tree (or Composite object).

Page 606: Re Factoring and Design Patterns

606 Peter Kaptein

COMPARISONS AND DIFFERENCES

::Tag: PAT-FAC-CDF

PATTERNS WITH SIMILARITIES ::Tag: PAT-FAC-SIM

ABSTRACT FACTORY, FACTORY METHOD ::Tag: PAT-FAC-SIM-001 Similarities: offering choice, producing Products The Abstract Factory produces objects (Products) and returns them as a result Factory Method: a blueprint for methods The Factory Method describes a way to blueprint your Factory Methods dso you can implement them multiple times in other places as well, while keeping the same fingerprint. Abstract Factory: a blueprint for multiple factories The Abstract Factory is – more than anything – a blueprint for the Concrete Factories. The Factory Method only focuses on (abstracting) the Factory Method. The Simple Factory hardly uses Abstract Classes or Interfaces.

COOPERATION WITH OTHER PATTERNS ::Tag: PAT-FAC-COP

BRIDGE, STATE, DELEGATE, STRATEGY ::Tag: PAT-FAC-COP-BRI Producing the concrete inplementor The Simple Factory can be used to produce the Concrete Implementor and/or Strategy to delegate the actions against.

OBJECT MAP ::Tag: PAT-FAC-COP-OMP Producing the concrete object When the Object Map is defined as a Map that will produce the objects the code requests, the Simple Factory can be used to do so. Used to deliver different classes: Inverison of control When the Factory is used in a setup where you implement and rely on Inversion of Control, you might want to create more choice in which Concrete Classes will be implemented to produce a specific product. The Object Map Can map Classes to be used by the Factory. Wjile you map the Concrete Classes against specific keys, the Factory can retrieve those elsewhere using these same keys in the process.

BUILDER, PARSER, INTERPRETER ::Tag: PAT-FAC-COP-BPI Producing the objects for the composite

Page 607: Re Factoring and Design Patterns

Refactoring and Design Patterns 607

The Builder, Parser and Interpreter will very likely use a Simple Factory to produce the objects needed in the Composite they will create form the building instructions.

ALTERNATIVES ::Tag: PAT-FAC-ALT

OBJECT MAP ::Tag: PAT-FAC-ALT-OMP Inversion of control, instead of a factory Instead of using a Factory for the Bridge, Delegate, State and Strategy, you might want to use an Object Map and only a small collection of objects produced when needed.

FACTORY OBJECT MAP ::Tag: PAT-FAC-ALT-FOMP Producing when needed, retrieving when available The Factory Object Map is a specialized verison of the Object Map, which will first try to retrieve the required object from the Map, then produce it by instantiation and map it when it is not vailable yet. The Factory Object Map takes better care of memory use and object instantiation than the (Simple) Factory and – unlike the Object Map – is specifically used to produce objects. ::Link: PAT-FAC-BNS-FOMP

Page 608: Re Factoring and Design Patterns

608 Peter Kaptein

SUMMARY

::Tag: PAT-FAC-SHS Choice by Context The Factory Method and Simple Factory offer choice in what kind of implementation is used for that product, based on a Context. The Simple Factory: what remains without the fluff The Simple Factory is the most simple form to build a Factory. It has one method or more methods to produce the Product, no Base Classes to extend and no Template Class to apply. Useful when you want to collect all variations on a product in one construction method The Simple Factory is useful when you want to collect all variation on a Product into one Construction Method. For instance, because your code might have to deal with several different contexts, each requiring a slightly different implementation.

SEE ALSO

::Tag: PAT-FAC-CNT Overview of the Patterns based on type and use There are many ways to look at the Patterns in this book. In the overview on Patterns based on type and use you will find the patterns sorted on type and use. ::Link:PAT-TYP Overview of the Creational, Structural and Behavioral patterns Design Patterns have a basic classification in three different groups: Creational, Structural and Behavioral Patterns. ::Link:PAT-CLASS Abstract Factory: a more extensive approach and implementation If you need something bigger and more elaborate, the Abstract Factory is your friend. ::Link: PAT-AFC Abstract Factory using a Object Map: back to square one When you need the versatility and structure of the Abstract Factory, but also the ease of use of a Context to produce a specific variant on a Product, consider variation on the Abstract Factory that uses a Object Map to store and resolve specific implementations under a specific Context. ::Link: PAT-AFC-DIA-004 The Bridge and Delegate: might use a Factory to choose the concrete Object The Bridge Pattern might use the Factory to choose and produce the concrete object it delegates its actions and requests to. ::Link: PAT-BRIDC| PAT-DEL The Builder, Parser and Interpreter: using the (Simple) Factory to create Composite objects Builder, Parser and Interpreter can use a Factory to produce the objects they need to create a Composite object. Both the Parser and Interpreter use an Abstract Description (or another object Tree) to build the new Structure. ::Link:PAT-INPR|PAT-PARS|PAT-BLD Use ::Link:MHOPUDO-MGR

Page 609: Re Factoring and Design Patterns

Refactoring and Design Patterns 609

BONUS MATERIAL

::Tag: PAT-FAC-BNS

THE FACTORY OBJECT MAP ::Tag: PAT-FAC-BNS-FOMP

Page 610: Re Factoring and Design Patterns

610 Peter Kaptein

FLYWEIGHT * ::Tag:PAT-FLYWT ::includesubchapters

Page 611: Re Factoring and Design Patterns

Refactoring and Design Patterns 611

INJECTOR * ::Tag:PAT-INJ ::includesubchapters

Page 612: Re Factoring and Design Patterns

612 Peter Kaptein

INTERPRETER ** ::Tag:PAT-INPR : Discussing the Interpreter Pattern ::includesubchapters

Page 613: Re Factoring and Design Patterns

Refactoring and Design Patterns 613

INTENT (GOF)

::Tag: PAT-INPR-INT Given a language, define a represention for its grammar along with an interpreter that uses the representation to interpret sentences in the language.

Page 614: Re Factoring and Design Patterns

614 Peter Kaptein

DIAGRAMS

::Tag: PAT-INPR-DIA

VISUAL SUMMARY OF THE INTERPRETER PATTERN ::Tag: PAT-INPR-INT

Non-terminal Expression A

Non-terminal Expression B

Object Structure AClient A2: «parses context into»

«non-terminal expressions»

5: «can be child of»

An object structure representing the semantic relationships as present within the Semantic Context Object

6: «leading to»

Terminal Expression A

Terminal Expression B

«terminal expressions»

5: «can be child of»

3: «can contain»

Semantic Context

2: «has or receives a»

NOTES: Semantic relationships The Interpreter is specifically to translate the Semantic Context in a language to an object structure Visiting and traversing the object structure Once the object structure is created, it can be traversed through and used by a Visitor or Parser to perform actions with that object structure. Terminal and non-terminal expressions: do we need them? “Design Patterns” explicitly mentions “terminal” and “non-terminal” expressions like the Nodes and Leafs in the Composite Pattern. Question is if this is an explicit requirement as a Terminal node can also be represented by a non-terminal node without children. It surely reduces the amount of required Classes if the Terminal and Non-terminal nodes can share the same logic and hardly differ. What do we use this for?

Page 615: Re Factoring and Design Patterns

Refactoring and Design Patterns 615

In “Design Patterns” the Interpreter Pattern is used for two examples: a compiler (for program code) and a parser for regular expressions. In most cases you will probably use the Parser Pattern which is the more generic-use relative of the Interpreter.

Page 616: Re Factoring and Design Patterns

616 Peter Kaptein

BASIC CLASS DIAGRAM ::Tag: PAT-INPR-DIA-000 : Basic class diagram of the Interpreter Pattern

«base / abstract class»Abstract Expression A

+ interpret( context )

Terminal Expression A Nonterminal Expression A

2: «extends»

Client Context1.a: «has a»

Override:+ interpret( context )

Override: + interpret( context )

- parentExpression

1.a: «uses / injects Context into»

«can create child elements based on Context»

«is the terminal node on a branch in the interpreted Context»

- childExpressions

3: «are of type»

NOTES: To be filled in

Page 617: Re Factoring and Design Patterns

Refactoring and Design Patterns 617

COMPARISONS AND DIFFERENCES

::Tag: PAT-INPR-CDF

WHAT DIFFERENTIATES THE INTERPRETER? ::Tag: PAT-INPR-DIFF Very specific use: interpreting semantics The Interpreter interprets semantics within the (clear text) structure it is provided. These semantics consist of the relationships between words and characters and the actions they (might) represent in a specific order and context.

PATTERNS WITH SIMILARITIES ::Tag: PAT-INPR-SIM

BUILDER, PARSER ::Tag: PAT-INPR-SIM-BP Similarities: creating (complex) structures Like the Builder and the Parser the Interpreter can create complex structures stored in a Composite object. Builder: more limited, not on linguistics Unlike the Interpreter (and the ParseR) the Builder has a very limited scope of creation. In the basic definition of the Builder, the building instructions are hardcoded into the Director. The Builder also does not deal with linguistics or semantics. Parser: no semantics The parser simply parses one structure into another. Unlike the Interpreter it does not focus on semantics.

COOPERATION WITH OTHER PATTERNS ::Tag: PAT-INPR-COP

ABSTRACT FACTORY, FACTORY METHOD, SIMPLE FACTORY ::Tag: PAT-INPR-COP-FCT Produces the objects for the Concrete Builders In most cases you will use a (Simple) Factory to produce the objects you need in the Concrete Builder.

Page 618: Re Factoring and Design Patterns

618 Peter Kaptein

SUMMARY

::Tag: PAT-INPT-SHS To be filled in.

SEE ALSO

::Tag: PAT-INPR-SEE Overview of the Patterns based on type and use There are many ways to look at the Patterns in this book. In the overview on Patterns based on type and use you will find the patterns sorted on type and use. ::Link:PAT-TYP Overview of the Creational, Structural and Behavioral patterns Design Patterns have a basic classification in three different groups: Creational, Structural and Behavioral Patterns. ::Link:PAT-CLASS The Parser: a more generic variant with similar principles as the Interpreter The Parser is a more generic implementation of the same principles: translating one structure into another, including an object Tree or Composite object. ::Link:PAT-PARS The Visitor: can be used to perform specific actions with the parsed data The Visitor can be sent out into the Composite object to perform specific actions on that data. ::Link:PAT-VIS

Page 619: Re Factoring and Design Patterns

Refactoring and Design Patterns 619

ASPECTS FROM DESIGN PATTERNS

::Tag: PAT-INPR-ASP From: Applicability Use the Interpreter pattern when there is a language to interpret, and you can represent statements in the language as abstract syntax trees.

Page 620: Re Factoring and Design Patterns

620 Peter Kaptein

MANAGER ::Tag: PAT-MGR ::includesubchapters

Page 621: Re Factoring and Design Patterns

Refactoring and Design Patterns 621

INTENT

::Tag: PAT-MGG-INT Define an object that encapsulates and centralizes Business Logic for a specific set of actions and acts as a manager for the processes that happen in the subsystem. Make these actions easily available to any object or Class that needs it.

MANAGER BASICS

::Tag: PAT-MGG-DIA-BAS

Manager A Subsystem B

Your Class

1: «uses»

2.a: «addresses»

Business Logic

2.b: «uses»

3: «can address»

WHEN/WHAT? ::Tag: PAT-MGG-DIA-BAS-001 Centralizing Business Logic The Manager Pattern centralizes the business logic that otherwise would be scattered over your sybsystem. It uses and addresses the subsystem in a similar way as the Façade. Façade and Mediator patterns combined The manager can be seen as a merge of the Mediator and Façade pattern, combining the aspects of both Patterns to create an object that allows you for more control over your application. Solve issues with Observer Pattern Sometimes the use of the Observer Pattern can lead to a loss of control: who dispatched what and why? Managers help centralize the communication from different systems and create several hubs with specific scopes of events and dispatches.

OTHER INFO ::Tag: PAT-MGG-DIA-BAS-002 The Business Logic: in the Manager or in separate classes? The Business Logic can be put into separate classes as well within the Manager itself.

Page 622: Re Factoring and Design Patterns

622 Peter Kaptein

Page 623: Re Factoring and Design Patterns

Refactoring and Design Patterns 623

DIAGRAMS

::Tag: PAT-MGG-DIA

SIMPLE DIAGRAM OF THE MANAGER PATTERN ::Tag: PAT-MGG-DIA-001

Manager A Subsystem B

Your Class

1: «uses»

2.a: «addresses»

Business Logic

2.b: «uses»

3: «can address»

DEPENDENCIES: Your Class: 1: Uses Manager A Manager A: 2.a: Addresses subsystem B 2.b: Uses business Logic Subsystem B: 3: Can address Manager A

NOTES: Centralizing Business Logic The Manager Pattern centralizes the business logic that otherwise would be scattered over your sybsystem. It uses and addresses the subsystem in a similar way as the Façade. The Business Logic: in the Manager or in separate classes? The Business Logic can be put into separate classes as well within the Manager itself.

Page 624: Re Factoring and Design Patterns

624 Peter Kaptein

IMPLEMENTING A MANAGER ::Tag: PAT-MGG-DIA-002

Manager A

Business Rules Behaviors

«business logic»

Handler A

2.b: «uses»Service B

Data Store C

«subsystem»

2.a: «addresses / uses / can observe»

Your Code

1: «addresses»

DEPENDENCIES: Your code: 1: Addresses and uses Manager A Manager A 1.a: Addresses / uses / can observe Handler A, Service B and Data Store C 1.b: Uses Business Rules and Behaviors

NOTES: Using business rules on the Subsystem The Manager uses the Business Rules on the subsystem. These can be (but are not limited to) general Business Rules or Behaviors. Simplification of processes Like the Façade Pattern, the Manager is a man in the middle to simplify the actions you have to perform to get something done within and by the Subsystem. Your Code does not communicate directly to the Subsystem The Manager shields the subsystem from your code. Injection of the Manager inside the Subsystem Like the Mediator, the Manager can inject itself into the Subsystem, so that elements in the Subsystem can communicate directly to the Manager.

Page 625: Re Factoring and Design Patterns

Refactoring and Design Patterns 625

Observing the subsystem Like with the Façade, you can choose to keep the Manager completely separated from the Subsystem. Instead, when the subsystem has to inform the Manager on some event, the Observer Pattern can be used.

IMPLEMENTING A MANAGER THAT INJECTS ITSELF IN THE SUBSYSTEM ::Tag: PAT-MGG-DIA-003

Manager A Subsystem Class

2.a: «has / calls»

Interface B

3.a: «can be of type»

1.b: «injects itself into»

1.a: «can implement»

3.b: «can be of type»

Variable C

2.b: «uses methods exposed by»

DEPENDENCIES: Mananger A 1.a: Can extend or implement Base Class A or Interface B 1.b: Injects itself into Variable C Sysbsystem Class: 2.a: Has / calls Variable C 2.b: Uses methods exposed by Interface B Variable C: 3.a: Can be of Type: Interface B 3.b: Can be of Type: Manager A

NOTES: Using the Manager Class as variable Type When your implementation has only one Manager, the simplest solution is to use the Manager Class as the Variable Type. Multiple Managers? Use an Interface If you implement multiple Managers, you can use and implement an Interface for both the Manager and the Variable.

Page 626: Re Factoring and Design Patterns

626 Peter Kaptein

IMPLEMENTING A MANAGER THAT OBSERVES THE SUBSYSTEM ::Tag: PAT-MGG-DIA-004

Manager A Subsystem Object1.a: «register to / observes»

2: «notifies»

Business Logic

1.b: «takes action using»

DEPENDENCIES: Manager A: 1.a: Registers Observer to Subsystem Object 1.b: Takes action on notification from Subsystem using the Business Logic Subsystem Object: 2: Notifies Manager A

NOTES: Manager registers to objects in Subsystem The Manager registers itself to objects in the Subsystem objects in subsystem notify the Manager When an event happens that is relevant to the Manager (see the Observer Pattern on events and Event Handles) the Manager is notified via the Using the Business Logic The Manager will use the Business Logic to decide what to do with the Notification and the underlying event. Asynchronous processes This construction is very common with Asynchronous systems, where the Manager (or any other Observer) sets out a request that can take some time to be fulfilled. Instead of moving into a Halt State, the Manager can continue to do other things while the process is handled and take appropriate action once the requested process is done. This process can be anything form loading data or images from an external source or delegating a processor intensive process to another processing unit (or processor or thread) in your system.

Page 627: Re Factoring and Design Patterns

Refactoring and Design Patterns 627

USING A MANAGER WITH STATIC METHODS ::Tag: PAT-MGG-DIA-005

Manager A Subsystem Objects

Business Logic

1.b: «takes action using»

Static Methods A, B, C

Your Code

1.a: «exposes»

2: «use / invoke»

3: «invoke private methods on»

DEPENDENCIES: Manager A: 1.a: Exposes Static Methods A, B and C 1.b: Takes action using Business Logic Your Code and Sybsystem objects: 2: Use and invoked Static Methods A, B and C Static Methods A, B and C: 3: Invoke private methods on Manager A

Page 628: Re Factoring and Design Patterns

628 Peter Kaptein

NOTES: Complete decoupling of your Concrete Manager By using a Manager with Static Methods, you can completely decouple your Concrete Manager from the rest of your code. As the Static Methods shield your concrete Implementation, you can decouple your Concrete Implementation, decreasing the Dependencies of your code to the Concrete Manager. Easy access through Static Methods, internal resolve The Manager with Static Methods is accessed through Static Methods, which use the internal logic of the Manager to resolve the exact objects (including the Manager) to execute the requested Actions. Shielding complexity and implementation form the users The Manager with Static Methods shields all complexity form the users (the other Classes and objects) as the “how” and “which” related to the Manager is no longer relevant. More agile As all the resolving (which Instantiated Manager for what situation?) is done internally, behind the public Static Methods, you can change the inner workings of the Manager completely if you need to, without too much impact on the rest of your project Unit Testing and Static Methods The misunderstanding related to Static Methods is that they are bad for unit testing. But as your Manager is shieling the internals from the outside world using Static Methods, the internals of the Manager can be set up in any way, including making use of Injection of Mockup Managers that help Unit Testing of other parts of your code that use the Manager. Using the Manager with Static Methods as a wrapper To support Unit Testing even more, the Manager with Static Methods can be implemented as a wrapper of the Concrete Manager, where this Concrete Manager is a replaceable/injectable object resolved and used by the Static Methods.

Page 629: Re Factoring and Design Patterns

Refactoring and Design Patterns 629

USING A DATA MAP TO RESOLVE THE MANAGER ::Tag: PAT-MGG-DIA-006

Manager X

Your Code Data Map

1.a: «uses / requests»

2: «resolves / returns»1.b: «uses»

DEPENDENCIES: Your Code: 1.a: Uses / requests a Data Map 1.b: Uses Manager X as it is resolved / retruned by the Data Map Data Map A: 2: Resolves and returns Manager X

NOTES: On demand / lazy instanitation Using Data Maps to resolve Managers is most useful when you use and need Lazy Instantiation, meaning that you will only instantiate the Manager when you need it. The reason to do this is mainly to avoid overhead when your application starts. Instead of all objects (including your Manager(s) beign created at the very beginning, you do it when needed. Resolving Managers by using logical keys You can resolve any Manager in your Project by using logical keys. The simplest keys are String Values or Constants. Storing Managers in Constants An alternative way is to store Managers in the Constants you would otherwise use to refer to the Managers. Using Maps and Managers When you move towards more Declarative Programming, Data Maps become more and more essential to your implementations of the Manager Pattern and other Patterns in your application. One example of using Declarations is loading an XML definition that states which Manager is bound to which keyword, to be used and addressed by other objects also created from XML definitions.

Page 630: Re Factoring and Design Patterns

630 Peter Kaptein

WHEN DO YOU USE THE MANAGER?

::Tag: PAT-MGG-USE To centralize Business Processes and Business Logic The Manager is used when you want to explicitly centralize the point of access to Business Logic and Business Processes. When you need aspects from both Mediator and Façade The Manager combines both aspects from the Façade and the Mediator. Its main purpose is to encapsulate and centralize Business Logic in any way possible. It can Inject itself into the Subsystem when needed and can use the more directive approach of the Façade when needed as well.

COMPARISONS AND DIFFERENCES

::Tag: PAT-MGG-CMP

PATTERNS WITH SIMILARITIES ::Tag: PAT-MGG-SIM

FAÇADE ::Tag: PAT-MGG-SIM-FAC Wrapping and simplifying a subsystem The Manager is closely related to the Façade, as it uses a lot of the same principles: wrapping and simplifying a subsystem. Manager implements the Façade as part of the Manager Pattern The Manager implements the Façade as part of the Manager Pattern

MEDIATOR ::Tag: PAT-MGG-SIM-MED Centralizing decision-making code, allowing interaction from the subsystem Like the Mediator, the Manager centralizes decision-making code and allows direct interaction from the subsystem. Like the Mediator, the Manager can Inject itself into the Subsystem (or can be resolved via a Data Map or Constant) and the Subsystem can call Methods directly on the Manager to get things done. Manager implements the mediator The Manager implements all the aspects of the Mediator, increasing the range and scope of the objects and making it a more versatile pattern to control and manage specific aspects of your application.

OPERATOR ::Tag: PAT-MGG-SIM-OPR Manager with limted and specific scope The Operator is a “Manager” between different domains or systems. It deals with access and connecting different Domains like the View and the Model.

Page 631: Re Factoring and Design Patterns

Refactoring and Design Patterns 631

COOPERATION WITH OTHER PATTERNS ::Tag: PAT-MGG-COP

DELEGATE ::Tag: PAT-MGG-COP-DEL Delegating the real work to other objects The Manager delegates the actual actions to other objects and Classes.

BRIDGE ::Tag: PAT-MGG-COP-BRI Abstracting the concrete implementation from your code The Manager, as discussed in the diagrams, can abstract the concrete implementation of the Concrete Manager from your code, allowing you – like the Bridge – to change and choose the appropriate Manager on runtime.

OBSERVER ::Tag: PAT-MGG-COP-BRI Observing the subsystem The Observer Pattern can be used by the Manager to observe the subsystem.

Page 632: Re Factoring and Design Patterns

632 Peter Kaptein

SUMMARY

::Tag: PAT-MGG-SHS Centralization of Business Logic If and when your (sub)system has many places where decisions are made and (business)rules are applied, the Manager helps you to centralize them. Managing the subsystem Using the centralized Business Logic, the Manager can manage the Subsystem and make (complex) decisions on what should happen when. Separated from the Subsystem or not? The way your system uses and needs the Manager decides whether it should be separated from your subsystem (no dependencies from the subsystem to the Manager) or injected into that subsystem. Using the Observer Pattern or Injection for notifications from the subsystem Depending on your choice of separation from the subsystem, or injection into that subsystem, you can use the Observer Pattern or injection of the Manager into the subsystem. Façade and Mediator: a bit of both The Manager is a bit of both Façade and Mediator. The main role of the Manager is, as discussed, to centralize the actions related to the Business Logic and make those actions easily available. Both Mediator and Façade Patterns can provide in this, depending on your implementation. Tightly coupled to the subsystem? Inject it If your Manager is tightly coupled to the subsystem by nature, simply inject the Manager into your subsystem and let your subsystem communicate directly to that subsystem. This heavily simplifies your code. Using Data Maps and Static Methods To reach your Manager, two approaches are possible: using a Data Map with one or more Managers and using static Methods on the Manager Class. Both approaches are valid, depending on your use of the Manager and the number of separate Instances you need of that one Manager. The subsystem is allowed to call methods on the Manager Like the Mediator, the Manager allows the subsystem to call methods directly on the Manager, or on the Static Methods of the Manager Class: resolving the concrete execution of these calls internally.

Page 633: Re Factoring and Design Patterns

Refactoring and Design Patterns 633

SEE ALSO

::Tag: PAT-MGG-SEE Overview of the Patterns based on type and use There are many ways to look at the Patterns in this book. In the overview on Patterns based on type and use you will find the patterns sorted on type and use. ::Link:PAT-TYP Overview of the Creational, Structural and Behavioral patterns Design Patterns have a basic classification in three different groups: Creational, Structural and Behavioral Patterns. ::Link:PAT-CLASS Façade: similar approach, more restricted The Façade has a similar approach to use and delegate actions to a Subsystem as the Manager, but is more restricted in its influence. Unlike the Manager, though, the Façade is hardly allowed to make decisions on its own and is much more a pass-through for requests. ::Link: PAT-FCD Mediator: making decisions, one of the guys The Mediator is in some senses the opposite of the Façade. Where the Façade only delegates actions, the Mediator is part of the subsystem it “wraps” and the Mediator is able to make decisions on what to do with the requests it gets from both your code and the subsystem it mediates. Objects in the subsystem are allowed to call the Mediator and execute methods on that Mediator. ::Link: PAT-MED Delegate: delegating actions to other objects Like the Delegate (and the Façade), the Manager delegates most of the requests to other objects. ::Link: PAT-DEL

Page 634: Re Factoring and Design Patterns

634 Peter Kaptein

ASPECTS FROM “DESIGN PATTERNS” HIGHLIGHTED IN THIS

CHAPTER

::Tag: PAT-MGG-ASP This pattern does not appear in “Design Patterns”.

Page 635: Re Factoring and Design Patterns

Refactoring and Design Patterns 635

MEDIATOR ::Tag: PAT-MED ::includesubchapters

Page 636: Re Factoring and Design Patterns

636 Peter Kaptein

INTENT (GOF)

::Tag: PAT-MED-INT Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.

MEDIATOR BASICS

::Tag: PAT-MED-DIA-BAS

Madiator A

Class A

Class C

Your Class«uses»

«subsystems»

Class B

Class D

Class E

«interacts with / allows interaction between»

WHEN/WHAT? ::Tag: PAT-MED-DIA-BAS-001 Centralition of communication between objects More than wrapping the Classes and objects it “wraps” the communication that takes place between them, by centralizing and managing the communication that is needed for these Processes within the Mediator Hub or man in the middle The Mediator acts as a Hub or “Man in the Middle” for the Communication between separate objects and Subsystems Abstracts and decouples the dependencies between objects in the subsystem The Mediator allows objects in a Subsystem to communicate between each other, without the need for these objects to have knowledge of the other objects in the Subsystem, or the need to know how to communicate with them

Page 637: Re Factoring and Design Patterns

Refactoring and Design Patterns 637

OTHER INFO ::Tag: PAT-MED-DIA-BAS-002 Using Inversion of Control and Dependency Injection The Mediator is another Pattern that applies the principles of Inversion of Control. Instead of objects deciding who should be created and who will be communicated to (the wiring), the Mediator takes over creation and the wiring and successively Injects itself into each player. Can Inject itself into the subsystem In one of the possible implementations of the Mediator, the Mediator can inject itself into the subsystem to be addressed directly by that Subsystem. The benefits of this injection is simplification of the code and your processes. De disadvantage is a tight coupling between the subsystem and the (Interface of) the Mediator that is Injected.

Page 638: Re Factoring and Design Patterns

638 Peter Kaptein

DIAGRAMS

::Tag: PAT-MED-DIA

VISUAL SUMMARY OF THE MEDIATOR PATTERN ::Tag: PAT-MED-VSM

3: «has references to»Concrete Mediator

+ yourMethodA(): do something+ yourMethodB() do something else

Centralization of communication between objects in your subsystem

5: «leading to»

«colleagues in subsystem»

Concrete Collegue A

Concrete Collegue B

2: «have references to»

4: «communicate to»

5: «delegates actions to specific»

Client

1: «uses»

NOTES: Centralizing communication in your subsystem

Page 639: Re Factoring and Design Patterns

Refactoring and Design Patterns 639

BASIC CLASS DIAGRAM ::Tag: PAT-MED-DIA-000

Base Mediator A

Concrete Collegue A

+ operationA()+ operationB(parameter)

«base class»Base Collegue

1: «contains a reference to»

- mediator

Concrete Collegue B

3: «extends»Concrete Mediator A

+ someOperationD()+ operationE(parameter)

+ operationF()+ operationG(parameter)

+ requestA()+ requestB()+ requestC()

«collegueA .someOperationD()collegueB .operationF()»

Concrete Mediator B

+ operationD()

- collegueA- collegueB

2: «extends»

4: «contains a reference to»

5: «contains a reference to»

- collegueC- collegueD

NOTES:

Page 640: Re Factoring and Design Patterns

640 Peter Kaptein

SIMPLE DIAGRAM OF THE MEDIATOR ::Tag: PAT-MED-DIA-001

Madiator A

Class A

Class C

Your Class«uses»

«subsystems»

Class B

Class D

Class E

«interacts with / allows interaction between»

Page 641: Re Factoring and Design Patterns

Refactoring and Design Patterns 641

MORE ELABORATE: IMPLEMENTATION OF MEDIATOR ::Tag: PAT-MED-DIA-002

Madiator A

Class A

Your Class«uses»

Class B

Class E

«addresses»

«addresses»

«addresses»

«addresses»

«addresses»

«addresses»

DEPENDENCIES: Mediator A: Is addressed by objects instantiated from Class A, B and E Classes A, B and E: Are addressed by Mediator A

NOTES: The Mediator as a Hub All possible communication between Class A, B and C goes through the Mediator The Mediator as Man in the Middle Within the Mediator Pattern, objects never address each other directly, but always via the Mediator Abstraction of communication The Subsystems Class A, B and E do not need to have any knowledge of each other. Whatever communication is happening place between the objects is happening thanks to the role and position of Mediator A

Page 642: Re Factoring and Design Patterns

642 Peter Kaptein

USING OBSERVERS IN THE MEDIATOR PATTERN ::Tag: PAT-MED-DIA-004

Madiator A

Class A

Your Class«uses»

Class B

Class E«Observes / addresses»

«Observes / addresses»

«Observes / addresses»

DEPENDENCIES: Your Class: Uses Mediator A Mediator A: Observes / addresses Class A, B and E

NOTES: Reduction of Dependencies Where the Mediator on the previous pages injected itself in the Collegues, in this implementation the Colleagues have no need to know the Mediator. Instead they use Events to notify the Mediator of any change or to request the Mediator a specific action. Mediator still addresses the Colleagues directly What still remains is that the Mediator still addresses the Coleagues directly.

Page 643: Re Factoring and Design Patterns

Refactoring and Design Patterns 643

BASIC EXAMPLE OF AN IMPLEMENTATION OF THE MEDIATOR ::Tag: PAT-MED-DIA-003

Page 644: Re Factoring and Design Patterns

644 Peter Kaptein

USING INVERSION OF CONTROL ::Tag: PAT-MED-DIA-005

Madiator A

Your ClassObject from

Class A

Object from Class B

Object from Class E

1.b: «injects objects into»

1.a: «instantiates»

2: «mediates interactions»

DEPENDENCIES: Your Class: 1.a: Instantiates Object from Class A, B and E 1.b: Injects these Objects into Mediator A Mediator A: 2: Mediates the communications and interactions between objects from Class A, B and E and Your Code

NOTES: Tight Coupling reduces re-usability of your Mediator The main weakness of the previous example is that the Mediator itself is supposed to have knowledge of the system it manages. This binds that specific Mediator to that specific code and reduces the immediate re-usability of that code to zero. Re-use of the Mediator in other places When your code evolves, your Mediators (or Patterns that are similar to a Mediator) might- and will be re-usable within your projects, without the need to change any line of code, due to a set of tricks using sets of rules instead of hardcoded lines to handle your processes. Injection of the Colleagues With Inversion of Control, something or someone else instantiates the objects your Mediator will use and then Injects those objects (the Colleagues) into your Mediator. Re-use in other places The main advantage of this approach is that your Mediator can be used in many places: dramatically reducing your need to Copy & Paste your own coding.

Page 645: Re Factoring and Design Patterns

Refactoring and Design Patterns 645

WHEN DO YOU USE THE MEDIATOR?

::Tag: PAT-MED-USE To create flexible ways for subsystems to interact with each other Instead of making parts of a subsystem communicate directly with each other, you “wrap” them with a Mediator and let the Mediator manage the interactions To manage processes and communication between objects within a subsystem You use the Mediator when you need more control over what is happening between objects in a subsystem. To centralize communication of objects in your Subsystems You can use the Mediator to gain more transparency and control over what happens when you need elements from the wrapped sub-systems to communicate with each other. As a hardwired alternative for the Observer Pattern The Observer Pattern is great to decouple objects and Systems, as everything goes via Events or Messages and none of the receivers have to be known to the sender. The disadvantage in more complex systems is that you can lose control over the Process Flow as anyone can be sending any message in any order to anyone else. And there is no gate-keeper keeping an eye on the process itself. The Mediator does the same as the Observer Pattern: decoupling objects from others and providing a means of communication between them.

Mediator: adding a management layer What the Observer Pattern cannot provide, due to its nature, the Mediator can: add a management layer over the communication that takes place. Mediator: acting as a gate keeper and filter The Mediator can interfere as a gate-keeper. It can translate messages or re-package them. It can decide not to pass specific messages to specific objects. It can apply business rules and filters.

Page 646: Re Factoring and Design Patterns

646 Peter Kaptein

COMPARISONS AND DIFFERENCES

::Tag: PAT-MED-CDF

PATTERNS WITH SIMILARITIES ::Tag: PAT- MED-SIM

FAÇADE ::Tag: PAT- MED-SIM-FAC Wrapping and simplifying a subsystem The Manager is closely related to the Façade, as it uses a lot of the same principles: wrapping and simplifying a subsystem. Top Down, invisible for the subsystem, not part of “the gang” Unlike the more social Mediator, the Façade is very much a Top Down Manager. The Façade talks and everyone in the subsystem has to listen and respond. Nobody in that subsystem is allowed to call or contact the Façade or even knows it exists. Instead the Mediator is “one of the guys” and passes its number to anyone and anything it works with. objects within the Mediated process can call the Mediator and ask for help or information. As the “man in the middle”, the Mediator will then take care of the process and the passing of messages.

MANAGER ::Tag: PAT- MED-SIM-MED Centralizing decision-making code, allowing interaction from the subsystem Like the Mediator, the Manager centralizes decision-making code and allows direct interaction from the subsystem. Like the Mediator, the Manager can Inject itself into the Subsystem (or can be resolved via a Data Map or Constant) and the Subsystem can call Methods directly on the Manager to get things done. Manager implements the mediator pattern The Manager implements all the aspects of the Mediator, increasing the range and scope of the objects and making it a more versatile pattern to control and manage specific aspects of your application.

OPERATOR ::Tag: PAT- MED-SIM-OPR Manager with limted and specific scope The Operator is a “Manager” between different domains or systems. It deals with access and connecting different Domains like the View and the Model. Operator implements the mediator pattern The Operator implements all the aspects of the Mediator, increasing the range and scope of the objects and making it a more versatile pattern to control and manage specific aspects of your application.

COOPERATION WITH OTHER PATTERNS ::Tag: PAT- MED-COP

Page 647: Re Factoring and Design Patterns

Refactoring and Design Patterns 647

DELEGATE ::Tag: PAT- MED-COP-DEL Delegating the real work to other objects The Manager delegates the actual actions to other objects and Classes.

BRIDGE ::Tag: PAT- MED-COP-BRI Abstracting the concrete implementation from your code The Manager, as discussed in the diagrams, can abstract the concrete implementation of the Concrete Manager from your code, allowing you – like the Bridge – to change and choose the appropriate Manager on runtime.

OBSERVER ::Tag: PAT- MED-COP-BRI Observing the subsystem The Observer Pattern can be used by the Manager to observe the subsystem.

Page 648: Re Factoring and Design Patterns

648 Peter Kaptein

SUMMARY

::Tag: PAT-MED-SHS Hub or man in the middle The Mediator acts as a Hub or “Man in the Middle” for the Communication between separate objects and Subsystems Wraps and centralizes the communication between objects More than wrapping the Classes and objects it “wraps” the communication that takes place between them, by centralizing and managing the communication that is needed for these Processes within the Mediator Abstracts and decouples the dependencies between objects in the subsystem The Mediator allows objects in a Subsystem to communicate between each other, without the need for these objects to have knowledge of the other objects in the Subsystem, or the need to know how to communicate with them Using Inversion of Control and Dependency Injection The Mediator is another Pattern that applies the principles of Inversion of Control. Instead of objects deciding who should be created and who will be communicated to (the wiring), the Mediator takes over creation and the wiring and successively Injects itself into each player. Can Inject itself into the subsystem In one of the possible implementations of the Mediator, the Mediator can inject itself into the subsystem to be addressed directly by that Subsystem. The benefits of this injection is simplification of the code and your processes. De disadvantage is a tight coupling between the subsystem and the (Interface of) the Mediator that is Injected. Promotes loose coupling between these objects The Mediator promotes loose coupling by keeping objects from referring to each other explicitly Can be used as an alternative to the Observer Pattern ,to gain more control over what happens when, where, when an object wants to communicate to others that something happened or should happen The Mediator manages the processes between different objects and plays an active role in deciding what should happen when. Using Observers instead of Injection The Mediator Pattern can be implemented using the Observer Pattern to communicate between the Mediator and the Collegues. Differences and similarities with the Façade: decisions and simplification of working with subsystems Unlike the Mediator, the Façade takes a Top Down approach. The objects and Classes “wrapped” by the Façade cannot- and do not interact with or get access to that Façade and do not know the Façade exists at all. Like the Façade, however, the Mediator is designed to simplify working with Subsystems. In this case by centralizing the processes that take place within those Subsystems. Centralization of communication: another form of control

Page 649: Re Factoring and Design Patterns

Refactoring and Design Patterns 649

What the Mediator does is using another way to take control of the processes within the subsystem. Instead of letting the objects and Classes in the subsystem communicating directly to each other, the Mediator only allows that communication to happen via itself. Any decision made on who should to talk to who and with what kind of information is decided and managed by the Mediator.

SEE ALSO

::Tag: PAT-MED-SEE Overview of the Patterns based on type and use There are many ways to look at the Patterns in this book. In the overview on Patterns based on type and use you will find the patterns sorted on type and use. ::Link:PAT-TYP Overview of the Creational, Structural and Behavioral patterns Design Patterns have a basic classification in three different groups: Creational, Structural and Behavioral Patterns. ::Link:PAT-CLASS The State Pattern: when you deal with processes In some cases, you need something that responds differently when it is in a different State. The Mediator only knows one way to deal with things. ::Link: PAT-STT The Observer Pattern: when you need to decouple everything Instead of Decoupling objects via the Mediator and instead of managing Processes via a “Man in the Middle”, you can decouple everything by using Events and the Observer Pattern. See for more information the Observer Pattern in the section “Working with Events”. ::Link: PAT-OBS Façade: when you do not want the dependencies from the Subsystem to the Mediator One of the possible disadvantages of the Mediator is that your subsystems needs to have knowledge of at least the Interface it uses. This works perfectly when you are the creator of the system, but fails when that system is already created by someone else, or needs to be more versatile than just this one Implementation. The Mediator can really obstruct the re-usability of your Components when – in order to use them – they also have to implement some Pattern that they do not like or do not use: your Mediator. ::Link: PAT-FCD The Manager: when you need a smart Façade The Mediator can be a bit too friendly with the subsystem it is part of to be useful. Where the Façade might be a better choice in some case because it has a more top-down approach, the Façade Pattern is much more a more elaborate Delegate Pattern than it is a close relative to the Mediator. The Façade Pattern simply focuses on offering an Interface to a Subsystem and does not include elaborate or complex decision making in the way the Mediator does. The Manager takes all the elements of the Façade and everything you can do with the Mediator and combines it into one Class. ::Link: PAT-MGR

Page 650: Re Factoring and Design Patterns

650 Peter Kaptein

ASPECTS FROM “DESIGN PATTERNS”

::Tag: PAT-MED-ASP From: Motivation [..] Object-oriented design encourages the distribution of behavior among objects. Such distribution can result in an object structure with many connections between objects; in the worst case, every object ends up knowing about every other. [..] You can avoid these problems by encapsulating collective behavior in a separate mediator object. A mediator is responsible for controlling and coordinating the interactions of a group of objects. The mediator serves as an intermediary that keeps objects in the group from referring to each other explicitly. The objects only know the mediator, thereby reducing the number of interconnections. From: Collaborations [..] Colleagues send and receive requests from a Mediator object. The mediator implements the cooperative behavior by routing requests between the appropriate colleague(s). From: Consequences [..] A mediator localizes behavior that otherwise would be distributed among several objects. [..] A mediator promotes loose coupling between colleagues. You can vary and reuse Colleague and Mediator classes independently. [..] A mediator replaces many-to-many interactions with one-to-many interactions between the mediator and its colleagues. [..] Making mediation an independent concept and encapsulating it in an object lets you focus on how objects interact apart from their individual behavior. That can help clarify how objects interact in a system. [..] It centralizes control. From: Implementation [..] One approach is to implement the Mediator as an Observer using the Observer pattern. [..] Another approach defines a specialized notification interface in Mediator that lets colleagues be more direct in their communication. Smalltalk/V for Windows uses a form of delegation: When communicating with the mediator, a colleague passes itself as an argument, allowing the mediator to identify the sender. From: Related Patterns Facade differs from Mediator in that it abstracts a subsystem of objects to provide a more convenient interface. Its protocol is unidirectional; that is, Facade objects make requests of the subsystem classes but not vice versa. In contrast, Mediator enables cooperative behavior that colleague objects don't or can't provide, and the protocol is multidirectional. Colleagues can communicate with the mediator using the Observer (293) pattern.

Page 651: Re Factoring and Design Patterns

Refactoring and Design Patterns 651

MULTITON * ::Tag:PAT-MULT ::includesubchapters

Page 652: Re Factoring and Design Patterns

652 Peter Kaptein

OBJECT MAP ** ::Tag: PAT-DTMP ::includesubchapters

Page 653: Re Factoring and Design Patterns

Refactoring and Design Patterns 653

INTENT

::Tag: PAT-DTMP-INT Store objects in memory and retrieve them using a unique identifier. Assure that only one instance of an object exists for each specific data-item.

THE BASIS OF THE OBJECT MAP

::Tag: PAT-DTMP-BAS

3: «contains objects based on»

Object Map

Your Code

2: «injects objects into / requests objects from»

Some Code

1: «injects objects into / requests objects from»

Class A

Class B

Class C

WHEN/WHAT? ::Tag: PAT-DTMP-BAS-001 Storing objects in memory using two keys The Object Map store objects in memory using two keys: the Object Key (or ID) and a reference to the Class the object is derived from. Retrieving, re-using objects and allowing for data-persistence The main goal of the Object Map is to make it easier to store objects in such a way that you can retrieve them easily from anywhere. This promotes re-use of objects and makes it easier to create persistent objects with only one instance for data that comes from the outside.

OTHER INFO ::Tag: PAT-DTMP-BAS-002 A pattern to de-couple dependencies The Object Map has a second use, which is the de-coupling of dependencies from objects and within your structure. Instead of sending specific objects down a chain of objects, you can use abstract keys or identifiers(for instance based on Constants or identifiers in XML or JSON data) that refer to the specific objects you want and need. Storing lists instead of objects In some cases, instead of storing objects you might want to store lists of objects, which you can access and modify anywhere in your application.

Page 654: Re Factoring and Design Patterns

654 Peter Kaptein

DIAGRAMS

::Tag: PAT-DTMP-DIA

VISUAL SUMMARY OF THE OBJECT MAP ::Tag: PAT-DTMP-DIA-001

3: «maps»ObjectMap

+ static getObject( key, classRef )+ static removeObject( key, classRef )+ static addObject( key, classRef )

5: «returns instance of object to» - static _objectMap

1: «calls, using a key and class reference to identify the specific object»

Client

2: «uses»

Mapping one instance of a specific object of any typeto be retrieved and used anywhere

6: «leading to»

Class A

Class B

Class C

«objects of type»

NOTES: Who provides the objects? You can choose for two scenarios to provide the objects stored in the Object Map.

The Object Map provides the (new) Objects In this scenario the Object Map will create new Objects when the requested Objects are not yet stored in the Object Map. Your code provides the (new) Objects In this case your code will receive a null-object from the Object Map when the object does not (yet) exists in the Object Map. In that case, your code will create the object and store it in the Object Map.

Page 655: Re Factoring and Design Patterns

Refactoring and Design Patterns 655

CLASS DIAGRAM ::Tag: PAT-DTMP-DIA-000

Class A

Class B

Class C

«objects of type»

ObjectMap

- static objectMap1: «contains»

+ static getObject( key, classRef )+ static removeObject( key, classRef )+ static addObject( key, classRef )

«static getObject( key:String , classReference ): Get object of type and key from map When not there yet: create and store object return object;»

NOTES: Object Map The Object Map has two keys to store and retrieve objects:

The Class Reference – The Class Reference refers to the Class to which the object belongs. It helps to separate objects from different classes with the same ID. The Object ID – Referred to as “key” in the diagram. The Object ID is a unique Identifier of the object that is shared, consistent and available within the separate places in your application.

Using (String) Constants as object Identifiers When the objects are created within your application, the most logical choice for your Idnetifiers would be the use of (String) Constants. Using record-IDs as object Identifiers When the objects in the Object Map represent data objects from a database (or comparable data source) the logical ID would the the unique Identifier in which it is stored in the database. Three static methods The Object Map uses three static methods to do the basics:

getObject Get Object will attempt to retrieve the object that complies to the Class Reference and the Object ID (Key). If it does not find the object, it can do two things: Create a new object, store it under the given keys and return that new object or return a null value. addObject Add Object will add the given object under the keys you provide the Object Map via the method call. It is possible to retrieve the Class Reference from the object itself. Most OOP languages allow you to retrieve the Class type from the object itself, using Reflection.

Page 656: Re Factoring and Design Patterns

656 Peter Kaptein

removeObjects Remove object will remove the object stored under the given keys.

THE BASIS OF THE OBJECT MAP ::Tag: PAT-DTMP-BAS

3: «contains objects based on»

Object Map

Your Code

2: «injects objects into / requests objects from»

Some Code

1: «injects objects into / requests objects from»

Class A

Class B

Class C

NOTES: Storing objects in memory using two keys The Object Map store objects in memory using two keys: the Object Key (or ID) and a reference to the Class the object is derived from. Retrieving, re-using objects and data-persistence The main goal of the Object Map is to make it easier to store objects in such a way that you can retrieve them easily from anywhere. This promotes re-use of objects and makes it easier to create persistent objects with only one instance for data that comes from the outside. A tool to de-couple dependencies The Object Map has a second use, which is the de-coupling of dependencies from objects and within your structure. Instead of sending specific objects down a chain of objects, you can use abstract keys or identifiers(for instance based on Constants or identifiers in XML or JSON data) that refer to the specific objects you want and need. Storing lists instead of objects In some cases, instead of storing objects you might want to store lists of objects, which you can access and modify anywhere in your application.

COMPARISONS AND DIFFERENCES

::Tag: PAT-OMP-CDF

PATTERNS WITH SIMILARITIES ::Tag: PAT-OMP-SIM

Page 657: Re Factoring and Design Patterns

Refactoring and Design Patterns 657

MULTITON ::Tag: PAT-OMP-SIM-001 Similarities: mapping objects against a key Like the Object Map, the multiton mapes objects against a key you can pas to retrieve an instant of that specific object. Only one layer The Multiton usually has only one layer (the key or reference ID) to store the objects against, where the Object Map can have two or more (the key or reference ID and the Class Reference).

COOPERATION WITH OTHER PATTERNS ::Tag: PAT-OMP-COP

BRIDGE, STATE, DELEGATE, STRATEGY ::Tag: PAT-OMP-COP-BRI Producing the concrete inplementor The Object Map can be used to produce the Concrete Implementor and/or Strategy to delegate the actions against.

FACTORY OBJECT MAP ::Tag: PAT-OMP-COP-FOMP Producing when needed, retrieving when available The Factory Object Map is a specialized verison of the Object Map, which will first try to retrieve the required object from the Map, then produce it by instantiation and map it when it is not vailable yet. The Factory Object Map takes better care of memory use and object instantiation than the (Simple) Factory and – unlike the Object Map – is specifically used to produce objects. ::Link: PAT-OMP-COP-FOMP Inversion of Control: used to deliver different classes When the Factory is used in a setup where you implement and rely on Inversion of Control, you might want to create more choice in which Concrete Classes will be implemented to produce a specific product. The Object Map Can map Classes to be used by the Factory. Wjile you map the Concrete Classes against specific keys, the Factory can retrieve those elsewhere using these same keys in the process.

BUILDER, PARSER, INTERPRETER ::Tag: PAT-FAC-OMP-BPI Inversion of Control: Producing the factories or concrete classes for the composite objects The Builder, Parser and Interpreter can use the Object Map to retrieve the concrete Classes that will be used to produce the concrete objects that will form the Composite objects.

ALTERNATIVES ::Tag: PAT-OMP-ALT

MULTITON ::Tag: PAT-OMP-ALT-

Page 658: Re Factoring and Design Patterns

658 Peter Kaptein

Simpler verison The Multiton is a simpler implementation of the same principle: storing and retrieving concrete objects into some sort of map.

FACTORY OBJECT MAP ::Tag: PAT-FAC-ALT-FOMP Producing when needed, retrieving when available The Factory Object Map is a specialized verison of the Object Map, which will first try to retrieve the required object from the Map, then produce it by instantiation and map it when it is not vailable yet. The Factory Object Map takes better care of memory use and object instantiation than the (Simple) Factory and – unlike the Object Map – is specifically used to produce objects. ::Link: PAT-FAC-BNS-FOMP

Page 659: Re Factoring and Design Patterns

Refactoring and Design Patterns 659

SUMMARY

::Tag: PAT-DTMP-SHS Storing objects in memory The Object Map / Simple Repository stores Objects in memory, using a List, Dictionary or Hash map. Retrieving them via an unique identifier Each object is stored under a unique identifier. To retrieve them, that same identifier can be used. Assuring that only one instance exists When you handle data from external sources, like a database or XML list, each re-load and parsing of that data would normally lead to the creation of new objects. By mapping each data-object to its ID, the Object Map can be used to retrieve the existing object that contains a previous instance of that data. Simple in-memory database The Object Map can be seen as a simple in-memory database.

SEE ALSO

::Tag: PAT-DTMP-SEE

Page 660: Re Factoring and Design Patterns

660 Peter Kaptein

OBJECT POOL * ::Tag: PAT-OBJP ::includesubchapters

Page 661: Re Factoring and Design Patterns

Refactoring and Design Patterns 661

OBSERVER ::Tag: PAT-OBS ::includesubchapters

Page 662: Re Factoring and Design Patterns

662 Peter Kaptein

INTENT (GOF)

::Tag: PAT-OBS-INT Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

THE BASIS OF THE OBSERVER PATTERN ::Tag: PAT-OBS-DIA-BAS

Some ObjectYour Objects

1: «observes»

2: «notifies»

WHEN/WHAT? ::Tag: PAT-OBS-DIA-BAS-001 One object, Multiple Observers One object can be Observed by many Observers. Decoupling of Dependencies The Observer object (or Subject) does not have to have any relationship with the Observer, or has to know of the existence of an of the (possible) Observers that will “Observe” the changes or Events from the Subject

OTHER INFO ::Tag: PAT-OBS-DIA-BAS-002 Events and Messages The Observer Pattern can be used for two main types of notification: Events and Messages. As discussed elsewhere, Messages can represent anything, including Events, Requests, Updates and Instructions. Events are only dispatched when something happened. Events can not be used to send requests or instructions. Event and Message Bus: routing the Events and Messages through a specific bus Instead of implementing the Obseerver Pattern directly on the object that is to be observed, an alternative approach can be to use and refer to an Event Bus. This Bus is an object to which Observers are bound and Events are dispatched. ::Link: PAT-OBS-DIA-005

Page 663: Re Factoring and Design Patterns

Refactoring and Design Patterns 663

DIAGRAMS

::Tag: PAT-OBS-DIA

BASIC CLASS DIAGRAM ::Tag: PAT-OBS-DIA-000

«base class»Subject

+ attach( observer )+ detach( observer )+ notify()

Concrete Subject Concrete Observer

+ update()

- observerState- subject

3.a: «observes»

+ update()

«interface»Observer

2: «extends»

+ setState()+ getState()

- subjectState

1: «notifies»

3.b: «implements»

«for all observers in list … notify»

- observerList

NOTES: As true as possible to implementation in “Design Patterns” You will find a very similar diagram in “Design Patterns”. What I focused on are the relationships between the Classes. More current: “dirty” implementations The Observer Pattern as described here has been replaced by several different approaches. While these newer implementations of the Observer Pattern are true to the original intent, the approach is in some ways completely different from what you will find in “Design Patterns”. No reference to Subject in Observer In the implementation above you will find a hard reference to the Subject in the Concrete Observer. In more recent implementations of the Observer Pattern, you will hardly find any reference to the Subject. Subject returns itself in the Callback In most cases the Subject returns itself as a parameter in the Callback to the Observer. This is how we will approach and describe the Observer Pattern in the next diagrams. “Observer” in the Observer list can also be Command or Method call When you register an Observer to the Subject, the “Observer” can also be a Method or a Command. In C# and ActionScript you will find the first approach (registering a Method). In Java and JavaScript registering a Command might be a more logical choice.

Page 664: Re Factoring and Design Patterns

664 Peter Kaptein

THE BASIS OF THE OBSERVER PATTERN ::Tag: PAT-OBS-DIA-001

Some ObjectYour Objects

1: «observes»

2: «notifies»

DEPENDENCIES: Your Object: 1: Observes Some Object for a specific Event. Some Object: 2: Notifies your object when that Event took place

NOTES: One object, Multiple Observers One object can be Observed by many Observers. Decoupling of Dependencies The Observer object (or Subject) does not have to have any relationship with the Observer, or has to know of the existence of an of the (possible) Observers that will “Observe” the changes or Events from the Subject Events and Messages The Observer Pattern can be used for two main types of notification: Events and Messages. As discussed elsewhere, Messages can represent anything, including Events, Requests, Updates and Instructions. Events are only dispatched when something happened. Events can not be used to send requests or instructions. Event and Message Bus: routing the Events and Messages through a specific bus Instead of implementing the Obseerver Pattern directly on the object that is to be observed, an alternative approach can be to use and refer to an Event Bus. This Bus is an object to which Observers are bound and Events are dispatched. ::Link: PAT-OBS-DIA-005

Page 665: Re Factoring and Design Patterns

Refactoring and Design Patterns 665

A CONCEPTUAL EXAMPLE OF THE OBSERVER PATTERN ::Tag: PAT-OBS-DIA-002

Some ObjectYour Object1: «registers to»

Observerlist A

2.a: «has / uses»

Some Event

2.b: «dispatches»

3.a: «relates to non, one or more observers in»

3.b: «when observed by.., is passed to»

DEPENDENCIES: Your Object: 1: Registers to Observer list A of Some Object, for a specific Event of a specific Type Some Object: 2.a: Has / uses Observer list A 2.b: Dispatches Some Event Some Event: 3.a: Relates to none, one or more Observers in Observer list A in Some Object 3.b: When Observed by Your Object, is passed to your Object

NOTES: Observer list Observers are registered in an Observer list, used to resolve in a later point in time (when an Event happens) which Observer should be notified. Relationship of the Event to the Observer The Event that is dispatched has a relationship of none, one or more Observers in the Observer list. This principle is also translated to the Publicize / Subscribe or Pub/Sub Pattern. The object Publicizes an Event. It will then be sent to the registered Subscribers to that Event. Handling the Event The object (the Observer) that receives the Event will then handle the Event it receives. Usually by executing a Method or lines of Code related to that Event. Pointcasting

Page 666: Re Factoring and Design Patterns

666 Peter Kaptein

This approach allows you to cast specifically to the Observers of a specific object, making the multi-cast of Events and Messages limited to some. In this book, this cast to a limited set of Observers is referred to as “pointcasting” ::Link: PAT-EVTS-BAS-006 Callback objects in the Observer list Instead of using the Observer and calling back to the Observer, implementations of the Observer in languages like C# and ActionScript use Methods as Callback Objects. In Java and JavaScript (as discussed later) Commands can be used to overcome certain limitations in JavaScript and allow for a more Agile solution for Observers in Java. ::Link: PAT-OBS-DIA-005 More detail in next diagram In the Next diagram we will go into deeper detail on this.

Page 667: Re Factoring and Design Patterns

Refactoring and Design Patterns 667

IMPLEMENTING THE OBSERVER PATTERN ::Tag: PAT-OBS-DIA-003

Some ObjectYour Object

Observerlist A

3: «has / uses»

Some Event

2.b: «dispatches»

4.c: «when handle matches, is passed to»

Subject A / EventDispatcher B

2.a: «extends / registers observers to»

4.a: «is dispatched on»

1.b: «is registered to»

1.a: «registers to»

«using»

Event Handle B

4.b «using»

DEPENDENCIES: Your Object: 1.a: Registers to Some Object, using Event Handle B. 1.b: Is registerd to Observerlist A in Subject A / EventDispatcher B. Some Object: 2.a: Extends and registers Observers to Subject A / EventDispatcher B. 2.b: Dispatches Some Event. Subject A / Event Dispatcher B: 3: Has / uses Observerlist A to Dispatch the Event to the Observers listed there Some Event: 4.a: Is Dispatched on Subject A / EventDispatcher B 4.b: Is using Event Handle B for reference to the correct Observer in Observerlist A 4.c: When the Handle maches, the Event is passed to Your Object

NOTES: Event Handles: who should receive which Event Dispatch? Each Observer also sends the Event Handle on which it wants to be notified. This usually is a String Value encapsulated in a Constant Same Observer Pattern everywhere: using a Base Class

Page 668: Re Factoring and Design Patterns

668 Peter Kaptein

In most cases the Observer / Dispatcher (Subject) Pattern is the same all over the Application and can be dealt with by one generic Event Dispatcher or Subject class that is either Extended by- or Instantiated within the Classes that can be Observed. What do we put in the Observer List: Methods, Commands or Objects? What will you register in the Observer List? What will you call back on when the Event is Dispatched? Will it be a Method, a Command or an object? Each has benefits and disadvantages. And in some languages like Java and JavaScript cannot be used at all, or only with a certain price (more complexity).

USING THE CALLBACK OBJECT ::Tag: PAT-OBS-DIA-005

Callback Object AEvent Dispatcher

A

2: «lives inside»Callback Interface

B

3.b: «implements»

Callback Method A

1.c: «invokes»

4: «includes»

Command / Observer Object

3.a: «can be»1.b: «resolves»

Event Handle

1.a: «receives»

DEPENDENCIES: Event Dispatcher A: 1.a: Receives an Event Handle 1.b: Resolves Callback Object A based on the Event Handle 1.c: Invokes Callback Method A Callback Method A: 2: Lives inside Callback Object A Callback Object A: 3.a: Can Be a Command / Observer Object 3.b: Implements Callback Interface B Callback Interface B: 4: Includes Callback Method A

Page 669: Re Factoring and Design Patterns

Refactoring and Design Patterns 669

Page 670: Re Factoring and Design Patterns

670 Peter Kaptein

USING EVENT HANDLES TO SEPARATE SPECIFIC OBSERVER LISTS ::Tag: PAT-OBS-DIA-004

Observer Map

Add ObserverKey: the Event HandleObserver: Object or CallBack Method

Dictionary / HashMapKey = Event Handle

1: «is added to»

«Observer / Callback Method»

4: «contains»

«Observer / Callback Method»

Key/Value Pair: «event handle 1»

2: «contains»

Key/Value Pair: «event handle 2»

List / Array / Collection

3: «contains»

Observer List

DEPENDENCIES: The Observer and Event Handle 1: Are added to the Observer Map. The Observer Map: 2: Contains Key/Value Pairs. The Key/Value Pair: 3: Contains an Observer List of type List, Array, Collection The Observer List: 4: Contains the Observer / Callback Method

Page 671: Re Factoring and Design Patterns

Refactoring and Design Patterns 671

NOTES: Storing the Observer / Callback in a Map By storing an Observer into a Map, you can create separate Observer / Callback Lists for each specific Event. This is how most (if not all) current Observer Patterns are implemented. ::Link: PAT-DTMP Making sure you register each Observer for a specific Event or Message only once When your Observer registers itself to the Subject, it can be (due to sloppy coding) that this is done more than once. As the Event (or Message) only needs to dispatched once to each Observer for each time it occurs, you do not want double registrations. To avoid these double-registrations, you need to check if the Callback object / Observer that is registered, is only registered once. If this Callback object is a Command, one way to simplify this process is to make sure that the Command itself is created once in your Observer object and passed by reference to the Subject.

Page 672: Re Factoring and Design Patterns

672 Peter Kaptein

IMPLEMENTING COMMANDS IN THE OBSERVER PATTERN ::Tag: PAT-OBS-ALT-001

Some ObjectYour Object

Observerlist A

4: «has / uses»

Some Event

3.b: «dispatches»

5.c: «when handle matches, executes»

Subject A / EventDispatcher B

3.a: «extends / registers observers to»

5.a: «is dispatched on»

2.a: «is registered to»

1.b: «registers command to»

«using»

Event Handle B

5.b «using»1.a: «creates»

2.b: «executes method on»

CommandA

STEPS:

1. Your Object a. Creates CommandA b. Registers CommandA to Some Object, using Event Handle B. CommandA will deal with

the Callback when Some Event with Event Handle B happens 2. Command A

a. Is registered to Observerlist A in Subject A / EventDispatcher B b. Will execute the stated Method on Your Object when the Event Handle matches Event

Handle B under which CommandA is registered 3. Some Object

a. Extends, registers Observers to Subject A / EventDispatcher B b. Dispatches Some Event

4. Subject A / EventDispatcher B – has / uses Observerlist A 5. Some Event

a. Is dispatched on Subhject A / EventDispatcher B b. Using Event Handle B to define which Observers should be notified c. When the Event Handle matches that of the Command, Executes the Command

Page 673: Re Factoring and Design Patterns

Refactoring and Design Patterns 673

BASIC PROBLEM: WHEN METHODS CAN NOT BE PASSED ActionScript, C#: Methods are Objects you can pass Programming Languages like C# and ActionScript allow you to call back on a specific Method when the Event is Dispatched. The benefit is that you can specifically tell your Dispatcher what to do and Call when the Event occurs. Another benefit is that handling the Events requires less code on the Receiving side, to sort out what the Event was and who or what should handle is.

Basic problem of Java: Methods cannot be passed Not all programming languages provide for such a versatile approach. Java is one example, as passing a Method to another part of the Application is not allowed (until Java 5). Basic problem of JavaScript: Methods become part of the Scope you pass them to JavaScript is another example where passing a Method to handle the Callback will not work, as the Method will automatically become part of the Scope of the Subject or EventDispatcher the moment it is received and added to the Observer list. Workaround: implement and send a Command object as the Observer A simple workaround for this problem is by implementing and sending a Command object to handle the Callback. On the next page you will find an example of a Concrete implementation of a Command in the Observer Pattern.

Page 674: Re Factoring and Design Patterns

674 Peter Kaptein

USING AN EVENT / MESSAGE BUS ::Tag: PAT-OBS-DIA-005

Object A Object B

2: «has knowledge of / dispatches events /

messages on»

1: «has knowledge of / registers observers on»

3: «sends callback to»

Event Bus X / Message Bus Y

DEPENDENCIES: Object A: 1: Has knowledge of / registers Observers on Event Bus X / Message Bus Y Object B: 2: Has knowledge of / dispatches Events / Messages on Event Bus X / Message Bus Y Event Bus X / Message Bus Y: 3: Sends callback to Object A

NOTES: Advantage: centralizing event- and message dispatches The big advantage of the Message / Event Bus is that you can use it to centralize the dispatches of Events and Messages and the registration of Observers to these Messages and Events. Meaning that you can receive and dispatch them from anywhere in your Application without having to jump through complicated sets of hoops. Complete decoupling between Subject and Observer The Event / Message Bus allows for a complete decoupling between Observer and Subject. Neither need to know about the other and neither will create a direct reference to the other. Storing and retrieving specific Message / Event busses You can instantiate and store multiple Message / Event Busses using a “man in the middle” dealing with the creation and retrieval of these Busses. This “man in the middle” might be a Object Map or Multiton using String based references to store and retrieve the specific busses. ::Link: PAT-DTMP Disadvantage: shoutcasting and loss of control The Event Bus can become a Shoutcasting system: shouting each and all Events and Messages to all registered objects, while only being relevant to some. For instance: when specific objects are updated and only a few Observers of all registered on the: “Updated” event need to know. ::Link: PAT-EVTS-BAS-006

Page 675: Re Factoring and Design Patterns

Refactoring and Design Patterns 675

WHEN DO YOU USE THE OBSERVER PATTERN?

::Tag: PAT-OBS-WHN Calling back the caller When your Callee (the object you use to perform an action) needs to call back the caller (your object). Multiple observers When multiple Objects need to be informed on a change in the object that is observed. Decoupling dependencies You use the Observer Pattern to decouple the dependencies between two objects. By using a more open approach to which you can register any object to be called back, you can also reduce the need of the Objects to know of each others existence. To create Event and Message Driven systems Event and Message Driven Systems do no longer rely on explicit connections between objects. Instead, you use Events and Messages to notify other systems, send data, request a response and send instructions.

Page 676: Re Factoring and Design Patterns

676 Peter Kaptein

COMPARISONS AND DIFFERENCES

::Tag: PAT-OBS-CDF

PATTERNS WITH SIMILARITIES ::Tag: PAT-OBS-SIM

CHAIN OR RESPONSIBILITY ::Tag: PAT-OBS-SIM-COR Leaving the decision on what is handled where to another object The Chain of Responsibilities is another way to deal with events. Instead of registering Observers, you create a chain of objects who can bubble an event to others in that chain.

COMMAND ::Tag: PAT-OBS-SIM-COM Abstraction and normalization of the action all, Observer Pattern turned inside out Like the Command Pattern, the Observer Pattern abstracts and normalizes the actual Methods and Calls, so that the Dispatcher can call any and all Commands it holds, using just one Method. The Command uses a similar pattern as the Observer, but instead of registering a lot of Observers to the Subject, we encapsulate the actual object with a single set of added Actions we can execute somewhere else. Other way around: sent into the world Where the Observer Pattern assumes the Observer will register a callback object to the subject, the Command Pattern turns this around and assumes who-ever needs to notify someone else, will use one or more Commands for that. Message driven more than event The Command Pattern has more commonalities with the Message Driven (to specific listeners: “do something”) approach of the Observer Pattern than the Event driven (to anyone: “something has happened”) models you can implement.

Page 677: Re Factoring and Design Patterns

Refactoring and Design Patterns 677

COOPERATION WITH OTHER PATTERNS ::Tag: PAT-OBS-COP

OBJECT MAP ::Tag: PAT-OBS-COP-COM Registering the Observers The Observer Pattern registers the Observers in some type of map, that usually represents the type of event (or message) and contains a list of all the Observers. As each Observer – by preference – should only be mapped once (to avoid multiple callbacks when only one is expected) the Observer itself might be the key for the Observer object to be stored.

COMMAND ::Tag: PAT-OBS-COP-COM Delegating the callback to Commands instead of methods Not all languages and situations allow for a direct callback to a method like is the case with C# and ActionScript (Flash). Instead you need to do some very “weird” actions to gain the same result. To solve these issues you can send and set a Command as a Observer. The Command will handle the callback to your object and your methods without compromising your code.

MEDIATOR, MANAGER, OPERATOR ::Tag: PAT-OBS-COP-MMO Responding to events Mediator, Manager and Operator can all implement the Observer Pattern to respond to events in one or more subsystems. Decoupling of dependencies Instead of registering the Mediator, Manager and Operator within the subsystem, you can choose to set and register Observers instead.

PROXY ::Tag: PAT-OBS-COP-PRX Notifications of the state of the proxy Wihtin the Proxy Pattern, the subject can be instantiated any time. To notify anything and anyone that is dependent of that object, you can use and implement the Observer Pattern on the Proxy, dispatching different events per State the Proxy is in.

Page 678: Re Factoring and Design Patterns

678 Peter Kaptein

ALTERNATIVES ::Tag: PAT-OBS-ALT

MEDIATOR, MANAGER, OPERATOR ::Tag: PAT-OBS-ALT-MMO Centralizing communication The Observer Pattern has one major dropback when your projects become bigger: there are no clearly defined central points of command. You might use some kind of Event Bus and might define multiple of these busses, but who takes care of more complex issues and decision making when events happen? The Mediator, Manager and Operator Pattern can all perform the same role: mediating when what action is taken next in a centralized place in your application. Operator and Manager: adding all qualities of the Façade The Operator and the Manager add all the qualities of the Façade to that pattern, allowing you to use subsystems to perform additional actions and create an ever tighter sphere of control around your objects.

COMMAND ::Tag: PAT-OBS-ALT-COM Inverting control The Command Pattern inverts the model created by the Observer Pattern. Instead of broadcasting an event or message to all who listen, you spread objects (Commands) around that will focus any specific call to one specific object that is wrapped and represented by that Command.

Page 679: Re Factoring and Design Patterns

Refactoring and Design Patterns 679

SUMMARY

::Tag: PAT-OBS-SHS Observer: Observing an object Within the Observer Pattern, the Observer observes an object. One Subject, many Observers One Subject (the Observed object) can be Observed by many Observers. Observers register to the Subject Within the Observer Pattern, the Observers register to the Observed object (or Subject). Distinguishing Messages, Events and Callbacks The Observer Pattern can be implemented for a Message Based System or a Event Based System. Messages allow for any information you want to send, whether it is an Update, a Notification of something that has happened, a Request for something to happen or an Instruction for something to be done by something else. An Event is limited to the notification of something that happened. Within all Observer Patterns I know, some sort of Callback is involved to a Method on an object defined by the Observer. Callback #1: registering and using Methods In languages like C# and ActionScript you can register Methods on the Subject. These Methods will be called directly when the Event is dispatched on and from the Subject. Each of these Methods will have to implement a specific default fingerprint that is the same for all these Method. Callback #2: registering and using Commands Instead, with languages like Java and JavaScript, you might like to use Command Objects. In that way it does not matter what specific Method needs to be called on the Observer as the Command object takes care of that specific implementation. Both Java and JavaScript allow you to define that Command object within the code of your Class, keeping your project and your code relatively simple. Another important advantage is the scalability of your code due to the use of a simplified and standardized Interface. You simply pass back whatever you want to pass back on an Event in the Event Bus. Callback #3: registering and using specific Objects / Interfaces When you choose to skip the Method and Command approach, you can choose the third option for callback, which is by using an Interface or Base Class for the Callback object. You see this specifically in Java, where either a Callback is done on an Interface and Methods in that Interface, or directly on a Base-Class that has to be implemented by the Objects you register as an Observer. The advantage is that you can use specific Callback Methods and that you can Strong-type the values sent back. The disadvantage is a different type of Dependencies in your code: to Interfaces implemented in your callbacks. If you can and if the project allows, Commands are a good second option for the implementation of Observers in Java. Major benefit of the Observer Pattern: promotes Loose Coupling The Subject has no knowledge of the Objects that live in your Project, until they register themselves to the Subject. When implemented with a Command or by passing the Method, there is no need to know what type of Objects the Observers are or from what Class they are derived.

Page 680: Re Factoring and Design Patterns

680 Peter Kaptein

Using a standardized Event and Message Bus Instead of creating a specific call-back loop per Subject: with dependencies to specific Interfaces (as in the implementation in “Design Patterns”) you can also choose to go for a more generic implementation as you will find in, for instance, C# and ActionScript. Your Event Bus on which you dispatch your Events, implement only one very specific Interface that is standard throughout your Application. Regardless of what and where you use the Observer Pattern on your Objects, you only implement one type of callback and one type if callback Interface. Using Methods/Callbacks instead of Objects Where Java implements the Observer Pattern quite true to the original design, offering only one Callback Method to be called by the Dispatcher, languages like C# and ActionScript (Flash) allow you to register the Method you want to use for the Callback.

Benefits of Callback Methods The benefit of Callback Methods is that you can use and add any Event Handler to your Code and use them for specific Events. Additional, there is no need for your code to decipher the Event and take decisions in your Callback Method which action to take. The Method is the Action to be taken when the Event is dispatched.

Event Handles: listening to a specific Event Most, if not all current Observer Patterns add an Event Handle when they register themselves to a Subject. This Handle is in most case a String Value also used when the Subject Dispatches the Event.

Page 681: Re Factoring and Design Patterns

Refactoring and Design Patterns 681

SEE ALSO

::Tag: PAT-OBS-SEE Overview of the Patterns based on type and use There are many ways to look at the Patterns in this book. In the overview on Patterns based on type and use you will find the patterns sorted on type and use. ::Link:PAT-TYP Overview of the Creational, Structural and Behavioral patterns Design Patterns have a basic classification in three different groups: Creational, Structural and Behavioral Patterns. ::Link:PAT-CLASS Event Driven Systems: specific use of the Observer Pattern You can use the Observer to create Event Driven Systems. These systems have some advantages, including the possibility to completely decouple all dependencies between Objects and Subsystems in your project. Event Driven Systems also harbor some dangers. ::Link: PAT-EVTS-BAS-004 Message Driven Systems: more versatile than Event Driven Systems Message Driven Systems are similar to Event Driven Systems in their implementation. The difference is that where Event Driven System only respond to things that have happened, Message Driven Systems can also send Updates and Instructions to other players in the project. ::Link: PAT-EVTS-BAS-005 Mediator: centralizing and managing interaction Instead of using the Observer Pattern in a Event or Message Driven system, you might like to consider centralizing actions and Events into specific Handlers like the Mediator. The Mediator can make decisions on what needs to happen next on a specific Event and offering its own specific Event Bus, increasing your level of Control on what happens when, where and why. ::Link: PAT-MED Manager: centralizing interaction and increasing the scope of Control Where the Mediator mainly mediates communication between different objects, the Manager also involves elements from the Façade Pattern, allowing you a bigger scope of control. ::Tag: PAT-MGR Object Map: storing observers The Object Map can be used to store the Observers in your dispatcher. ::Link: PAT-DTMP

Page 682: Re Factoring and Design Patterns

682 Peter Kaptein

PARSER ::Tag:PAT-PARS : Discussing the Parser Pattern Keywords::Parser,Parser Design Pattern, Parser explained, Parser Examples, Parser variations ::includesubchapters

Page 683: Re Factoring and Design Patterns

Refactoring and Design Patterns 683

INTENT

::Tag:PAT-PARS-INT To convert or parse one structure into another structure: containing similar, or the same, data.

PARSER BASICS

::Tag:PAT-PARS-DIA-BAS

Abstract Definition / Object Tree

Object Tree / Composite Object

Abstract Definition

1: «parsed to» 2: «can be parsed to» 2: «can be parsed to»

WHEN/WHAT? ::Tag:PAT-PARS-DIA-BAS-001 To parse/convert one structure into another To read and use the contents of a structure

OTHER INFO ::Tag:PAT-PARS-DIA-BAS-002 Any direction The Parser is by default a Pattern that can Parse anything to anything as long as it is available and possible. So you can Parse one Abstract Definition to another (XML to JSON, XML to a Custom Structure, XML to a Custom Structure to an Object Tree, XML to an Object Tree, back to XML). Results can be fed back to a Parser In principle, a Parser result can be Parsed into yet another structure. An object structure can be parsed into an Abstract Definition and then into another Abstract Definition and then into an object Tree. Use in real life The Parser is used in almost any case where Data from an external Source is used within an Application. Word Parses files into object structures. Your web browser parses HTML into Visual Content.

Page 684: Re Factoring and Design Patterns

684 Peter Kaptein

DIAGRAMS

::Tag:PAT-PARS-DIA

VISUAL SUMMARY OF THE PARSER PATTERN ::Tag:PAT-PARS-VSM To be added

Page 685: Re Factoring and Design Patterns

Refactoring and Design Patterns 685

CLASS DIAGRAM ::Tag:PAT-PARS-000 To be added

Page 686: Re Factoring and Design Patterns

686 Peter Kaptein

TWO DIRECTIONS TO PARSE AN ABSTRACT DEFINITION OR OBJECT TREE ::Tag:PAT-PARS-DIA00

Abstract Definition / Object Tree

Object Tree / Composite Object

Abstract Definition

1: «parsed to» 2: «can be parsed to» 2: «can be parsed to»

RELATIONSHIPS: Abstract Definition / Object Tree 1: Can be Parsed to an Object Tree / Composite Object or to an Abstract Definition Abstract Definition / Object Tree / Composite Object: 2: Can be parsed to Abstract Definition / Object Tree

NOTES: Any direction The Parser is by default a Pattern that can Parse anything to anything as long as it is available and possible. So you can Parse one Abstract Definition to another (XML to JSON, XML to a Custom Structure, XML to a Custom Structure to an Object Tree, XML to an Object Tree, back to XML). Results can be fed back to a Parser In principle, a Parser result can be Parsed into yet another structure. An object structure can be parsed into an Abstract Definition and then into another Abstract Definition and then into an object Tree. Use in real life The Parser is used in almost any case where Data from an external Source is used within an Application. Word Parses files into object structures. Your web browser parses HTML into Visual Content.

SIMPLIFIED INTERNALS OF A PARSER ::Tag:PAT-PARS-DIA-007

Page 687: Re Factoring and Design Patterns

Refactoring and Design Patterns 687

Parser A Simple Factory B2.b: «uses /

requires build actions from »

Concrete Product

3: «constructs / returns»

Your Code

1.b: «uses»

Composite C4: «is injected as child into»

2.a: «constructs / returns»

2.c: «injects values in»

Abstract Description A

1.a: «uses»

DEPENDENCIES: Your Code: 1.a: Uses Abstract Description A 1.b: Uses Parser A Parser A: 2.a: Constructs and returns Composite C 2.b: Uses Simple Factory B 2.c: Inject Values in Concrete Product Simple Factory B: 3: constructs and returns Concrete Product Concrete Product: 4: Is injected as a Child into Composite C

Page 688: Re Factoring and Design Patterns

688 Peter Kaptein

NOTES: Parsing the Abstract Description The Abstract Description is the description of the object Tree as it should be, but put down in a portable form, like XML, JSON or Clear Text. Using specific Hooks, like object Names, from the Abstract Description, the object Tree can be built: represented by Composite C. Creating the Objects via a Simple Factory The Simple Factory in a Parser is used to produce any object of any Type that is stated in the Abstract Description. When Parsing HTML that could be: A Paragraph, an Image, a Div or a loader and container for JavaScript. Same basis, but not the same type of Product In most cases the Products used to build the Composite Structure share the same basic Interface to allow Nesting and to Remove and Retrieve Children from the Hierarchic Structure. Based on this basis, any object of any Type can be used to create the Composite Structure. Injecting values into the Product Each Product that is produced by the Simple Factory is usually an empty shell waiting for further instructions. For instance: when the object is a Text Field, the text itself still needs to be passed to it. Other values that can be injected are usually the settings, like X and Y position, color, thickness of edges and rounding of corners.

Page 689: Re Factoring and Design Patterns

Refactoring and Design Patterns 689

ZOOMING INTO THE DIFFERENT PLAYERS IN THE PARSING PROCESS ::Tag:PAT-PARS-DIA-008

Parser A Simple Factory B

2.b: «sends required object type to»

Concrete Product

3.b: «produces / returns» 5.b: «is returned to»

Interface C

5.a: «implements»

Class A

Class B

Class C

3.a: «uses»

4: «implement»

2.a: «has»

Parse Method

2.c: «calls»

Your Code

1: «calls»

Base methods:addChild()removeChild()getChildren()

RELATIONSHIPS: Your code: 1: Calls the Parse Method on Parser A Parser A: 2.a: Has a Parse Method 2.b: Sends the object type of the object to Simple Factory B Calls the Parse Method on itself when there are- and for each Child Nodes to Parse Simple Factory B: 3.a: Uses Class A, B and C to create Product X: based on the object Type it received from Parser A 3.b: Produces and returns Concrete Product Class A, B and C: 4: Implement Interface C Concrete Product:

Page 690: Re Factoring and Design Patterns

690 Peter Kaptein

5.a: Implements Interface C 5.b: Is returned to Parser A Interface C: 6: Implements the base methods: addChild, removeChild, getChildren

Page 691: Re Factoring and Design Patterns

Refactoring and Design Patterns 691

PARSING PROCESS: FROM ABSTRACT TO CONCRETE STRUCTURE ::Tag:PAT-PARS-DIA-009

Do we have Children?

Read Node

Simple Factory BDoes it

represent an Object?

Method:Parse Structure

«use» Get Object

Add object as child to Parent Object /

Inject values

«no»

«yes»

For each Child Node

«yes»

Done

«no»

Call Method

CallParameters:Parent Object = «Root Object» Structure = «Root Node»

Values:Values, Settings, NameNode Type / Object type

We create the Composite Structure here, by invoking something like “addChild” on the Parent Object

We use the Object Type and a Simple Factory to resolve and create the Object that represents the Node

When there are no children left, we are done parsing in this branche of the Tree

Parameters:Parent Object = «Current Object» Structure = «Child Node»

«loop»

BRIEF: Recursion The Parsing Process is a recursive process. Each node in the Abstract Structure can have one or more children. Using a factory or Strategy The Parser usually uses a (simple) Factory or Strategy Provider to translate Abstract definitions into a concrete object.

Page 692: Re Factoring and Design Patterns

692 Peter Kaptein

SIMPLIFIED EXAMPLE: PARSING AN ABSTRACT DESCRIPTION TO AN OBJECT MODEL ::Tag:PAT-PARS-DIA-008

Root ObjectRoot Node

Child Node

Child Node Node Object

Node Object

«are added as child to»

«accompanies»

«has»

«produces»

«has»

«is added as child to»

«is passed as parent to»

«produces / sets values on»

Parsing the Abstract Description The resulting Object Structure or Composite Object

Child Node Node Object

«is passed as parent to»

«produces / sets values on»

NOTES: Root Node and Root object The Root Node and Root object are the starting points for your Parsing. Both are passed to the Parser to start the Parsing Process Child Nodes and Node Objects Each Child Node in your Abstract Description can represent an object in your object Tree or Composite Structure. If that is the case, the Node object is created and added to the Parent as passed to the Child Node. Similar structures The Parsing Process in this example creates a similar “mirrored” model between the Abstract Structure and the object Tree. No hard limit to the depth of the Abstract Structure The Abstract Structure can be of any Depth, from three Nodes to thousands and hundred thousands of Nodes and Child Nodes. The only limits and limiting factors to the depth of your Structure are: the available Memory and your Parsing Speed. Not always similar: Converting a Model from Structure A to B A Parser can also be used to Convert a Model from Structure A to Structure B. For instance, when

Page 693: Re Factoring and Design Patterns

Refactoring and Design Patterns 693

WHEN DO YOU USE THE PARSER?

::Tag:PAT-PARS-USE To be written

Page 694: Re Factoring and Design Patterns

694 Peter Kaptein

COMPARISONS AND DIFFERENCES

::Tag:PAT-PARS-CDF

WHAT DIFFERENTIATES THE PARSER? ::Tag:PAT-PARS-DIFF More freedom than Builder The Parser takes all the good things from the Builder: creating Composite Objects and adds an almost unlimited freedom to it. Two way street The Parser can be used to create both object Trees from an Abstract Definition and an Abstract Definition from an object Tree. Same basis, but more generic in use than Interpreter The Parser uses the same basis as the Interpreter: translating or parsing a almost semantic structure into an object Tree. However, the Interpreter is specifically designed to represent the grammer of a language and interpret sentences. The Parser simply parses one structure into another, whether that is from an Abstract Definition to an object Tree, from an object Tree to an Abstract Definition, or from one Abstract Definition to another. Four types of Parsing: A to A.1, B to B.1, A to B and B to A The Parser can be used to Parse an Abstract Definition to another Abstract Definition (A to A.1), an object Tree to another object Tree (B to B.1), an Abstract definition to an object Tree (A to B) or to parse an object Tree to an Abstract Definition (B to A) Merging Abstract Definitions from other Sources A Parser can be used to Merge Data and Structures from other Sources

Page 695: Re Factoring and Design Patterns

Refactoring and Design Patterns 695

PATTERNS WITH SIMILARITIES ::Tag:PAT-PARS-SIM

BUILDER, INTERPRETER ::Tag:PAT-PARS-SIM-BI Similarities : creating composite Objects The Builder and the Interpreter, like the Parser, creates Composite Objects based on Building Instructions. Interpreter: same level of freedom, language specific Like the Parser, the Interpreter can create any Composite object possible with your Code and tour Classes, based on an Abstract Definition (the semantic description). The Interpreter Pattern is specifically created to build Compositie Objects to interpret a semantic description. This can be a Regular Expression, but also the words and sentences you write in a text-editor, or the code in your programming environment. Builder: fixed instructions, only one way The Builder Pattern uses fixed instructions, embedded in the Director, to create the Composite Objects. This makes the Builder more rigid, but also simpler to implement than the Parser. The Builder Pattern also works only one way: it creates the Composite object. The Parser is able to create a Composite object and Parse that (or another) Composite into yet another Composite object.

COOPERATION WITH OTHER PATTERNS ::Tag:PAT-PARS-COP

COMPOSITE ::Tag:PAT-PARS-COP-COM Building the object structure The Composite Pattern is the pattern that describes how you create objcts that can be nested into other objects. It is a typical Pattern used by the Parser.

FACTORY METHOD, ABSTRACT FACTORY, SIMPLE FACTORY ::Tag:PAT-PARS-COP-FAC Producing the objects The Parser needs some kind of producer to create the objects it uses to build the resulting object structure. This role is typically taken by some sort of Factory.

Page 696: Re Factoring and Design Patterns

696 Peter Kaptein

BONUS MATERIAL

::Tag:PAT-PARS-BNS

MAPPING AN ABSTRACT DEFINITION TO AN ALTERNATIVE STRUCTURE ::Tag:PAT-PARS-DIA-001

Abstract Definition / Object Tree

Object Tree / Composite Object

1.a: «via / using»

Alternative Mapping Structure

1.b: «parsed to»

Abstract Definition

2: «can be parsed to» 2: «can be parsed to»

RELATIONSHIPS: Abstract Definition: 1.a: Is parsed to an object Tree, using an Alternative Mapping Structure 1.b: Is parsed to an Abstract Definition, using an Alternative Mapping Structure Object Tree / Composite Structure: 2: Can be parsed to an Abstract Definition

NOTES: Alternative Mapping Structure The Alternative Mapping Structure can be both Code (the easiest to build) or a Mapping File in XML or another easy-to-read structure. The idea behind the Alternative Mapping Structure is to change the organization or structure of the Abstract Definition. Simpler put: when you receive data in a Structure you can not use, you pull it apart and put it together again in a new structure. Parsing and Conversion The moment you parse one Structure into another, you perform a Conversion. This Conversion can be from a structure where – for instance – People are grouped to a Country, to a structure where People are grouped by Occupation.

Page 697: Re Factoring and Design Patterns

Refactoring and Design Patterns 697

MERGING DATA SETS ::Tag:PAT-PARS-DIA-002

Abstract Definition / Object Tree

Object Tree / Composite Object

1.a: «via / using»

Alternative Mapping Structure

1.b: «parsed to»

Abstract Definition

Alternative Mapping Structure

1.c: «using»

Abstract Definition / Object Tree

2: «using» Data Merger

Abstract Definition B / Object Tree C2: «can be parsed to»

2: «can be parsed to»

DEPENDENCIES: Abstract Definition / Object Tree: 1.a: Is parsed using an Alternative Mapping Structure 1.b: Is parsed into an Abstract Definition or Object Tree / Composite Object 1.c: Using a Data Merger Data Merger 2: Uses Abstract Definition B / Object Tree C Abstract Definition / Object Tree: 3: Can be parsed to an Abstract Definition / Object Tree

NOTES: Merging Data In some cases, the required Data Set is based on data from two or more Data Sources from two or more Sources. For instance: Database A holds all people and photos these people made, while System B on another Server holds the links to the actual photos. By calling both Sources and Merging the Data with the Parser, your System can offer the links to the photos and the additional meta-data as if they are from one single system.

Page 698: Re Factoring and Design Patterns

698 Peter Kaptein

MERGING DATA SETS FROM A DATA MAP ::Tag:PAT-PARS-DIA-003

Abstract Definition / Object Tree

Object Tree / Composite Object

1.a: «via / using»

Alternative Mapping Structure

1.b: «parsed to»

Abstract Definition

Alternative Mapping Structure

1.c: «using»

Abstract Definition / Object Tree

2: «using» Data Merger

Abstract Definition B / Object Tree C

Data Map / Simple Repository

3: «from»

DEPENDENCIES: Abstract Definition / Object Tree: 1.a: Is parsed using an Alternative Mapping Structure 1.b: Is parsed into an Abstract Definition or Object Tree / Composite Object 1.c: Using a Data Merger Data Merger: 2: Uses Abstract Definition B / Object Tree C Abstract Definition B / Object Tree C: 3: Can be derived from a Data Map / Simple Repository

NOTES: Using a Data Map or Simple Repository In most cases you will use a Simple Data Map to find and match the data. This can be the structure itself (XML, Object Tree, whatever is received) or something stored in a Data Map / Simple Repository.

Page 699: Re Factoring and Design Patterns

Refactoring and Design Patterns 699

LOSSLESS AND LOSSFUL PARSING ::Tag:PAT-PARS-DIA-004

Structure A Structure B Structure A.1

3: «A.1 should be 100% identical to A»

1: «parsed to»

2: «parsed to»

Lossless Parsing

Structure A Structure B Structure A.1

3: «A.1 is not identical to A»

1: «parsed to»

2: «parsed to»

Lossfull Parsing

NOTES: Lossless Parsing When you receive Structure A and Parse it to Structure B, Structure B also will be Parsed back to Structure A, to be stored or passed to elsewhere. In this case, you want to perform a lossless Parsing. Each and all items should be there when you run a simple test from A to B to A. As a result, when you parse Structure B to Structure A.1, A.1 should be completely identical to A.

Memento: making the perfect copy for later use The Memento Pattern is used to make a copy of the content of an and any object.

Lossful Parsing When you receive A, it might be that A has more data than you need. For instance, out of all data per item you only need “first name” and “last name”. For many reasons, including a more efficient memory use, you decide to drop all other information. As a result, when you parse Structure B to Structure A.1, A.1 is no longer identical to A. Which one is the “right” way? Both Lossless and Lossful Parsing are deliberate choices, so both are right in their specific context.

Editing persistent Data You use Lossless Parsing mainly when dealing with Data that is sent to your Application to be edited and modified and then sent back to the Source to be used in that same exact fashion over and over again. Data Corruption

Page 700: Re Factoring and Design Patterns

700 Peter Kaptein

Any loss in your Parsing process means that the Data you receive and send back becomes corrupted: a change happened without an explicit action by a user (editing that Data).

Unit testing the Lossless Parsing process WITHOUT modification, the result (after Parsing to A to B and back to Structure A as A.1) A.1 should be completely Identical to the original in A. This is something you can Unit-test by simply parsing A to B to A.1 and compare A and A.1.

Presenting data When you present data, for instance in a dropdown list, you will not send that data back to your Source. As a result it does not matter much what happens with that Data in the Parsing Process, as long as the results meet the requirements.

Losing irrelevant data for performance and efficiency When you only need a small subset of data, for instance: to present a list that can contain over 10.000 items, you only want to deal with the data that is relevant. Anything else is ballast, waste.

USING REFLECTION IN THE PARSING PROCESS ::Tag:PAT-PARS-DIA-005

Abstract DefinitionObject Structure / Composite Object

Reflection on Fields

2: «using»

1: «parsed to»

Source Object Destination Object

3.a: «getting Fields / getting values from»

3.b: «matching Fields / putting

values into»

RELATIONSHIPS: Abstract Definition 1: Is parsed to Object Tree . Composite object Parser: 2: Is using Reflection on Fields per object Reflection on Fields: 3.a: Gets Fields and the Values in the Fields from the Source object 3.b: Matches each Field with the Fields in the Destination object and tries to insert the Values when the match is made

NOTES:

Page 701: Re Factoring and Design Patterns

Refactoring and Design Patterns 701

Parsing and Reflection: making it easy by using less code One of the ways to achieve Lossless Parsing is by using Reflection. Reflection is a solution in most OOP based languages to treat your Objects as complete Black Boxes and assuming they will have the same structure and Fields as your Source. In other words: when your Source has the Field “firstName”, you assume your Black Box object will also have a field (or setter) “firstName”. Benefits of Reflection The main benefit of Reflection is that you only need to create and have the object Description right: the Fields you want to Parse from A to B, the Fields that “A” mirrors in “B”. The code required to pass values from “A” to “B” is replaced by a generic script that simply iterates through the fields of “A” and tries to Map these to the fields on “B”. Disadvantages of Reflection: cost and performance Reflection is costly. For each Field in A, your code has to verify if the counterpart exists in B. If not, you need to do something with the Error or Exception that occurs. This has a Cost: the number of extra Code that needs to be and will be executed to make Reflection possible and deal with your Error Trapping. A second consequence of this is a drop in Performance. Where this is hardly noticeable for 100 or 1000 items, when you do this for 1.000.000 items every second, the Parsing Process in your application might drive your CPU to 100%

Mapping Fields from A to B: Solving the issue of non-matching Field Names When the Source object has a similar structure as the Destination object, but different Field Names per item, this can be solved by using the principle of Mapping. Simply put: “Map: firstname<==>personFirstName”. So when “firstname” is received, the Mapper will map this to “personFirstName” in the Destination object.

Page 702: Re Factoring and Design Patterns

702 Peter Kaptein

USING GENERATED OBJECTS IN THE PARSING PROCESS ::Tag:PAT-PARS-DIA-005

Abstract DefinitionObject Structure / Composite Object

Objects from Generated Code

2: «using»

1: «parsed to»

Source Object

3: «copying values from»

DEPENDENCIES: Abstract Definition: 1: Is parsed to an object Tree / Composite object. Object Tree / Composite Structure 2: Uses Objects from Generated Code. Objects from Generated Code: 3: Copy values from the Source Objects they represent, get values from Source object injected.

NOTES: Parsing and auto-generated Data Objects: making it fast and more fail-safe The first alternative for Reflection is using Auto Generated (Data) Objects. These Objects are created by a Script, that outputs Code and Classes that can be used and Compiled in your Project. These Objects are Disposable and should not be used for any custom coding, as each next Generation Cycle will destroy any code you added to these classes. Benefits of Auto Generated Code: more optimized for performance Auto Generated Code is more optimized than Reflection. It simply passes Values from the Source object into itself (in most cases) and that’s it. As the Code is Auto Generated, all sanity checks can be done by Auto Generated Code, again, reducing overhead you would otherwise have from Error Trapping. Disadvantages of Auto Generated Code: added complexity to your project This is a debatable issue. Here is my point. When you Generate Code, the first step is to find a Code Generator that delivers the kind of code you need and the kind of code that conforms to your internal Quality Standards. Secondly, the Code that is Generated can not be blindly integrated into your Project. It is “non-editable”. So if and when you need to do stuff with that code, you will need a second object, accessing the Generated object to do the actual work. This is no problem when you use a way of building where Data is strictly separated from Actions. Solving Data Incompatibilities by adding Getters and Setters

Page 703: Re Factoring and Design Patterns

Refactoring and Design Patterns 703

When the Field names or Data Structures of System A are not conform those of System B you can add extra getters and setters to your Data Transfer object. The main goal is to bridge the incompatibilities of these Objects and conform the External Data to the naming conventions and Data Types of your Local System. Using (Auto Generated) Decorators to solve incompatibilities When your Source Data does not match your Destination Objects, due to differences in the systems, or because you receive Data from more than one Source, one way to solve the gap is by using (auto Generated) Decorators as a second layer in your Data Transfer Process, to do the Mapping from system A to system B. While the Internal object is matching the Source Objects, the Decorator “decorates” that object to expose and translate the values and possible Methods to comply to the local needs. These Decorators can be generated by the same code that generates the Data Transfer objects.

Page 704: Re Factoring and Design Patterns

704 Peter Kaptein

PARSING AND USING DATA MAPS / SIMPLE REPOSITORIES IN YOUR SYSTEM ::Tag:PAT-PARS-DIA-006

Abstract Definition ParserDisposable

Objects

2: «resulting in» 1: «read by»

Source Objects

Objects in Data Map / Simple

Repository

3.b: «compared with / updates/ when new: stored into»

Object Structure / Composite Object

4: «used to create»

3.a: «copying values from»

DEPENDENCIES: Abstract Definition: 1: Is read by the Parser. The Parser: 2: Creates Disposable objects. Disposable objects: 3.a: Copy values from the Source objects. 3.b: Are compared with the objects in the Data Map / Simple Repository and used to update the objects in the Data Map or are inserted into the Data Map / Simple Repository when their Persistent Representative does not exist yet. Objects in the Data Map / Simple Repository: 4.a: Are used to create the object Tree / Composite Object. 4.b: Uses objects from Data Map to create the object Tree.

Page 705: Re Factoring and Design Patterns

Refactoring and Design Patterns 705

SUMMARY

::Tag:PAT-PARS-SHS Creating an object Tree from an Abstract Description The Parser can be used to create an object Tree from an Abstract Description, based on XML , clear text, JSON or your own format. HTML HTML is one example where an Abstract Description (the HTML and CSS files) are translated into another Structure (the Web Page you see in your browser). Creating an Abstract Description from an object Tree Parsing is a two way process: using the object Tree, you can use a Parser to move through the structure and create an Abstract Description from that Structure. Using Parsing to Serialize and Deserialize Objects The Parser is the most used tool to Serialize and Deserialize Objects. Serialization / Deserialization is used in most cases to communicate between two separate systems. XML, JSON and SOAP are three examples of Serialized Data. But this data can also be Serialized into Binary Format, where it is no longer readable for humans. Simple Factories and Factory Methods The simplest way to build a Parser is by using a Simple Factory or Factory Method. Using the object Type from the Serialized Data or Abstract Description as a key, you can let the Factory return the object that corresponds that key.

Page 706: Re Factoring and Design Patterns

706 Peter Kaptein

SEE ALSO

::Tag:PAT-PARS-SEE Overview of the Patterns based on type and use There are many ways to look at the Patterns in this book. In the overview on Patterns based on type and use you will find the patterns sorted on type and use. ::Link:PAT-TYP Overview of the Creational, Structural and Behavioral patterns Design Patterns have a basic classification in three different groups: Creational, Structural and Behavioral Patterns. ::Link:PAT-CLASS The Injector: a specialized form of the Parser Where the Parser is a generic solution to parse one structure to another, the Injector has one specific role and intent: to Inject data from one object into another. ::Link:PAT-INJ The Memento Pattern The Parser is a perfect aid to the Memento Pattern. Using the possibilities of the Parser to take an existing Composite object and run through that structure, then to extract the contents of that object is exactly what the Memento can use. The Builder Pattern: similar to the Parser, but with fixed instructions The Builder is very similar to the Parser in creating Composite Objects with a dynamic structure: using Building Instructions. What differs the Builder from the Parser is two things: the Builder only works one way: to create a Composite object, while the Parser can work two ways: also parsing the Composite object into a base or Abstract Definition. The second difference is that the Builder works with fixed Building Instructions hardcoded into the Director. ::Link: PAT-BLD The Factory Pattern: a very valuable aid The Factory Pattern is a very important aid to the Parder: to instantiate and provide Concrete Objects that represent the Objects or tags we are trying to parse. ::Link: PAT-FAC The Strategy Pattern: when you need Strategies instead of Products When you parse an Abstract Definition that represents a Process, you use a Strategy Provider instead of a Factory. ::Link: PAT-STRA The Visitor Pattern: getting or constructing something from the Composite object It is possible you use the Builder to create an object structure to be translated into something else. For instance: the HTML code for a HTML page. The Visitor can visit each object in the Composite and extract the data or information you need to create another type of object. ::Link:PAT-VIS Traversing a Composite object inside-out and outside in: a short story There are two ways to travers an object Tree (or Composite object): outside in and inside out. The Visitor does this from the inside, the Parser from the outside. ::Link: PAT-DSTR-TRV

Page 707: Re Factoring and Design Patterns

Refactoring and Design Patterns 707

PROTOTYPE *

Page 708: Re Factoring and Design Patterns

708 Peter Kaptein

PROXY ::Tag: PAT-PRX ::includesubchapters

Page 709: Re Factoring and Design Patterns

Refactoring and Design Patterns 709

INTENT (GOF)

::Tag: PAT-PRX-INT Provide a surrogate or placeholder for another object to control access to it.

PROXY BASICS

::Tag: PAT-PRX-DIA-BAS

Proxy A

Object B

Your Class1: «uses»

2: «instantiates / represents / will contain / will address»

WHEN/WHAT? ::Tag: PAT-PRX-DIA-BAS-001 Representing something that might not be there yet The object we represent with the Proxy is usually not yet there when we instantiate the Proxy. Can be used immediately, even if the object is not there With the Proxy you do not have to wait for the Actual object to arrive. Whatever you want to do with the object can be done immediately on the Proxy. The Remote Proxy: representing an object from somewhere else The Remote Proxy pretends to be an object running somewhere else. This can be in another local system, but also in a system on another physical location. The Virtual Proxy: creating the object when needed The Virtual Proxy represents the actual object until it is needed. Only then it will instantiate the actual object. When actions are called for and variables have been set on the Proxy, the Proxy will pass these through to the object. The protection Proxy: enveloping and protecting the original object The protection Proxy adds a set of additional layers to the original object, to restrict access to that original object. For instance: restricted read and write rights based on the identity of the user, or restricted read and write rights based on the current state of the object. The Smart Reference: man in the middle when accessing an object The Smart Reference acts as a man in the middle when you want to access an object. It can be that it resolves that object from a Object Map, a Multiton or a Singleton, or that it uses a Factory or Strategy Provider.

Page 710: Re Factoring and Design Patterns

710 Peter Kaptein

OTHER INFO ::Tag: PAT-PRX-DIA-BAS-002 Pretends to be, with additional features Like the Adapter and the Bridge, the Proxy Pretends to be the object it represents. But where Bridge and Adapter rely on the actual object to be there, for the Proxy it does not matter if the object it represents arrives later or not at all Buffering the values and method calls The Proxy – in most cases – will act as a buffer for all the method calls and value settings on the actual object. While the actual object is not there, the Proxy will store these settings and queue the calls internally. Passes all your requests when the object is there Once the object arrives, the Proxy passes all your requests and executes your settings on the object (B)

Page 711: Re Factoring and Design Patterns

Refactoring and Design Patterns 711

DIAGRAMS

::Tag: PAT-PRX-DIA

VISUAL SUMMARY OF THE PROXY PATTERN ::Tag: PAT-PRX-VSM

Real Subject A

Proxy

- realSubject+ variableA+ variableB

Client

- proxy

+ doSomething()+ doSomethingElse()

1: «contains»

+ methodA( )+ methodB( )

+ methodA( )+ methodB( )

+ variableA+ variableB

2: «will contain»3: «execute»

5: «will be delegated to»

4: «will be passed to»

NOTES:

Page 712: Re Factoring and Design Patterns

712 Peter Kaptein

BASE CLASS DIAGRAM OF THE PROXY PATTERN ::Tag: PAT-PRX-DIA-000

Real Subject A

+ executeA( )+ executeB( )

«interface»Subject A

Proxy A

- realSubject+ variableA+ variableB

2.a: «implements»

Client

- proxy

+ doSomething()+ doSomethingElse()

1: «is of type»

+ executeA( )+ executeB( )

+ executeA( )+ executeB( )

«if realSubject != null: realSubject.executeA()»

3: «instanitates /passes values to /

delegates actions to»

«proxy.executeA() proxy.executeB()»

+ variableA+ variableB

NOTES:

Page 713: Re Factoring and Design Patterns

Refactoring and Design Patterns 713

SIMPLE DIAGRAM OF THE PROXY ::Tag: PAT-PRX-DIA-001

Proxy A

Object B

Your Class1: «uses»

2: «instantiates / represents / will contain / will address»

DEPENDENCIES: Your Class: 1: Uses Proxy A Proxy A: 2: Instantiates / represents / will contain / will address Object B

NOTES: Late instantiation The proxy allow objects to be instantiated later, while offering all (or most of all) variables and methods to your code as if that object is already there. Representing an object that might not be there yet The Proxy Represents an object that might not be there yet. The big benefit is that you can perform actions and set values to that object, even if it does not exist.

Page 714: Re Factoring and Design Patterns

714 Peter Kaptein

IMPLEMENTING THE BASIC PROXY PATTERN ::Tag: PAT-PRX-DIA-002

Methods A, B, CVariables L, L, M

Proxy A1.a: «has a»

variable

2: «will contain»

1.b: «has»

Object X from Class N3: «will

address / set»Methods D, E, FVariables O, P, Q

4: «inside»

1.c: «instantiates / represents / pretends to be»

DEPENDENCIES: Proxy A: 1.a: Has a variable that will contain the Object (B) 1.b: Has Methods A, B, C and variables K, L, M 1.c: Instantiates / represents / pretends to be / will address Object B The variable: 2: Will contain Object B Methods A, B and C and Variables K, L and M: 3: Will address / set Methods D, E, F and variables O, P, Q Methods D, E, F and variables O, P, Q: 4: Live inside Object X from Class N

NOTES: Simplification of Asynchronous processes Proxies are very handy to simplify Asynchronous processes. For instance when you load an image or instantiate an object when it is needed. In both cases you can already perform all settings and requests, even when the object is not there yet. The Proxy will buffer these settings and requests and execute them for you once the object is instantiated. In this, the Proxy removes the need for you to add Event Listeners to the process of creating that object and finding some kind of mechanism to solve these issues. Images and late instantiation As mentioned, Images and Late Instantiation are two examples of the use of the Proxy. You can set the height, width and rotation of the Image and be done with it and only instantiate an object (in most cases expensive in Memory and Instantiation) when you need it, while your Application thinks it is already there.

Page 715: Re Factoring and Design Patterns

Refactoring and Design Patterns 715

AN IMPRESSION OF THE COMPLETE PICTURE ::Tag: PAT-PRX-DIA-004

Proxy A

2.a: «has»

variableA

4.b: «will contain»

Object B

System C3.a: «will get and return»

Interface A / (Base)Class B

4.a: «is of type»

Your Code

1: «uses / calls methods on / sets values on»

2.c: «will set values/call

methods on»

5: «imple-ments»

3.b: «will notify»

2.b: «uses / observes»

DEPENDENCIES:

1. Your Code – Instantiates, uses, calls methods on and sets values on ProxyA 2. Proxy A

a. Has Variable A b. Uses and Observes System C (to load the object we want to address) c. Will set values on- and will call methods on Object B

3. System C a. Will get and return Object B b. Will notify Proxy A

4. Variable A a. Is of type Interface A or (Base)Class B b. Will contain Object B

5. Object B – Implements Interface A or extends (Base)Class B

Page 716: Re Factoring and Design Patterns

716 Peter Kaptein

NOTES: All major players In this example of the complete picture of an implementation of the Proxy Pattern, we see all major players in the game. Object B can be anything, obtained from anywhere How System C obtains Object B and what Object B is, is not relevant for this overview. It can be an Parsed object from an XML source, or a file loaded from some location. Calling back to notify the Proxy Since the Proxy represents an object that might not necessarily be there, you need some kind of mechanism to tell the Proxy object that it can perform the buffered actions and set the buffered values on the object that has been created, loaded or retrieved. The Proxy can observe the System To be notified, Proxy A can use an Observer on System C, receiving a notification when System C is done obtaining Object B. These notifications (in general) can be Event Dispatches. The Proxy can inject itself or Callback Methods into the System The Proxy can also inject itself or Callback Methods into the System that deals with the instantiation of the object the Proxy represents. When the System has retrieved or created the object that is represented by the Proxy, the System can use these references to do generic or specific callbacks.

Page 717: Re Factoring and Design Patterns

Refactoring and Design Patterns 717

WHEN DO YOU USE WHICH PROXY?

::Tag: PAT-PRX-USE The Virtual Proxy: to perform actions on an object that is not there yet You use a Virtual Proxy when you want to perform actions to an object that is not there yet. For instance: an image that is not loaded yet The Remote Proxy: to access Remote objects as if they are local You use Remote Proxies when you want to access objects from a Remote system as if they are local. This can include the call and execution of Methods and requests for information. The Protection Proxy: to restrict access You use the Protection Proxy when you want to apply specific rules for access on an object or parts of (specific actions on) that object. Think of systems in which some users are allowed to remove specific data and others are not. While the object itself has no knowledge of these rules, or how to deal with them, your Protection Proxy does. Smart References: to add a mediation layer to the reference of an object The Smart Reference adds a mediation layer between your system and the actual object. This layer can request additional data about the object it shields, can block access when the object is in use (think databases).

Page 718: Re Factoring and Design Patterns

718 Peter Kaptein

COMPARISONS AND DIFFERENCES

::Tag: PAT-PRX-CDF

WHAT DIFFERENTIATES THE PROXY PATTERN? ::Tag: PAT-PRX-DFF Late instantiation of the object without consequences The Proxy allows you to Instantiate the actual object only when you need it, without adding extra complexity to your code. You can set values on the Proxy, call methods to perform actions (as long as you do not expect an immediate response) and once the Concrete object is there, the Proxy will pass all these actions to the object to assure your wishes are indeed fulfilled. All complexity related to asynchronous systems and late binding is resolved inside the Proxy The Proxy is created to take care of all the complexity of dealing with objects which are not there yet. The Proxy does this by offering all methods and variables you are allowed to set, buffering these actions, listening to callbacks if remote and external data is loaded and performing these actions and settings on the object: once it is there.

PATTERNS WITH SIMILARITIES ::Tag: PAT-PRX-SIM

ADAPTER, DELEGATE ::Tag: PAT-PRX-SIM-AD Acting as a man in the middle, offering an Interface adapted to your needs Like the Adapter and Delegate, the Proxy acts as a man in the middle, providing a specific Interface for an object and Class, by “wrapping” it and disallowing direct access. Delegate: wrapping an object, delegating actions, choosing the object based on context Like the Delegate, the Proxy wraps the object it uses, to have actions executed by that object. Like the Delegate (and the Bridge) the Proxy can choose the object it uses to perform the actual actions by Context. For instance to load data from a File or from a Database.

DECORATOR ::Tag: PAT-PRX-SIM-DEC Adding functionalities Especially the Protection Proxy and the Smart Reference are very similar to the Decorator in the fact that they extend the encapsulated object with extra functionalities. The Protection Proxy does this by adding a Security Layer. The Smart Reference does this by adding extra methods allowing you, for instance, to find out how many references exist to the object, or to act as a man in the middle for Observers.

BRIDGE ::Tag: PAT-PRX-SIM-BRI Abstracting the concrete implementation of the functionalities and the object

Page 719: Re Factoring and Design Patterns

Refactoring and Design Patterns 719

The Proxy abstracts the Concrete Implementation of the object it wraps, making that Concrete Implementation less relevant for your code. Like the Bridge, the proxy can choose which type of object it will implement to perform the actual actions.

COOPERATION WITH OTHER PATTERNS ::Tag: PAT-PRX-COP

OBSERVER ::Tag: PAT-PRX-COP-OBS Notifying observers on the Proxy what the Proxy State is When the Proxy changes state (for instance because the object is instantiated or loaded) you want and need some way to notify the observers onthe Proxy what the Proxy State is. The Observer Pattern helsp you do this.

DELEGATE ::Tag: PAT-PRX-COP-DEL Delegating the execution to the encapulated object Once the encapsulated object is there, the Proxy can delegate all calls to the object. To do so it implements (a part of) the Delegate Pattern.

MANAGER, OPERATOR ::Tag: PAT-PRX-COP-MO wrap multiple objects and Classes, work with subsystems, do not include late instantiation Unlike the Façade and the Manager, the Proxy wraps only a single object. The Façade and the Manager wrap multiple objects. The Façade and the Manager also add extra logic, allowing them to compose a chain of actions by using multiple objects and Methods from the subsystem to achieve the results it is requested to produce. The Proxy is much more like the Adapter, Decorator and Delegate, passing through the values and requests it receives to the object it envelops and represents. The Façade Pattern does not include Late Instantiation.

Page 720: Re Factoring and Design Patterns

720 Peter Kaptein

BONUS MATERIAL

::Tag: PAT-PRX-BNS

TAKING CARE OF THE CREATION OR RETRIEVAL OF THE PROXIED OBJECT ::Tag: PAT-PRX-DIA-003

Proxy A

1.b: «has a»

variable

2.b: «will contain»

1.a: «uses»

Object B from Class C

System C3.a: «will return»

1.c: «will address / set»

3.b: «will notify»

BRIEF: To give you more insight in the step by step process of the Proxy, we cut the implementation into pieces. In this case, we include SystemC which is used to Get and Return Object B. The complete picture is given in the next example.

DEPENDENCIES: Proxy A: 1.a: Uses System C to get or produce Object B 1.b: Has a variable 1.c: Will address / set Object B form Class C The Variable: 2: Will contain Object B System C: 3.a: Will return Object B form Class C 3.b: Will notify Proxy A that Object B is available

NOTES: Using another system to provide / create the object In most cases your Proxy will use another system to provide and return the actual object. Observing the subsystem or receiving a direct callback The Proxy can use two ways to be notified: by registering Observers to the subsystem, or by injecting a reference to itself or to callback methods into the subsystem.

Page 721: Re Factoring and Design Patterns

Refactoring and Design Patterns 721

Responsibility of the Proxy: creating and retrieving the actual object This process is the responsibility of the Proxy. Based on the internal rules the proxy decides when, where and how the actual object will be acquired and created. In this way the rest of your system remains unaware of the process and the dependencies of the object Creation is encapsulated by the Proxy or a Subsystem of the Proxy, making changes and expansions of that process simpler.

EXPLORING THE PROXY SUBSYSTEM ::Tag: PAT-PRX-DIA-004

System CFactory / Strategy

Provider / Data/file loader

DataMap / Multiton

Persistent / shared Objects

Context-specific Objects/StrategiesData / Data Objects

1.a: «can be / can use» 2.b: «returns»

3.b: «returns»

Business Rules

1.b: «can contain»

Connection / Communication

module

Data to/from external system

4.b: «communicates with / interprets»

4.a: «remote proxy»

3.a: «smart reference»

2.a: «virtual proxy»

5: «protection proxy / smart reference»

DEPENDENCIES: System C: 1.a: Can be / use a Factory / Strategy Provider / Data/File loader, a Object Map / Multiton, a Connection / Communiation moduel to an external system 1.b: Can contain / use Business Rules The Factory / Strategy Provider / Data/File Loader: 2.a: Can be used for the Virtual Proxy 2.b: Creates and returns a Context specific object or Strategy / an external object The Object Map / Multiton: 3.a: Can be used for the Smart Reference 3.b: Returns a Persistent or Shared object The Connection / Communication module: 4.a: Can be used for the Remote Proxy 4.b: Communicates with / interprets Data to/from an external system The Business Rules:

Page 722: Re Factoring and Design Patterns

722 Peter Kaptein

5: Can be used for the Protection Proxy and the Smart Reference

NOTES: Inside the Proxy or as separate Class? The subsystem (System C) can be created as a separate Class or be part of the code of the Proxy itself if the code is simple and the chances of re-use and changes in approach are slim. The Virtual Proxy: loading data or creating Objects when needed The Virtual Proxy can either load external data when needed. The main benefit is that expensive processes (memory use or CPU strain) can be postponed until the moment the object is really needed. These objects can be – for instance – heavy/expensive objects or Images and files from a file system. The Smart Reference: using your resources with more intelligence The Smart Reference allows you to manage and report on the objects it grants access to. It can be used to get objects from Object Maps and manage the amount and selection of those objects based on business rules you either store in the Proxy or access from an external Class The Remote Proxy: accessing an object living somewhere else The Remote Proxy represents an object that is living an a (completely) different system. In some senses it has a lot of commonalities with the Virtual Proxy. The difference from the Virtual Proxy is the use of- and focus on a (sometimes real time) communication protocol between your Proxy and the Remote object. This communication protocol is required to update the Remote object and receive updates from that object when another system changes and can be using any protocol that is available, form (but not limited to) Sockets, HTTP polling and parallel and serial communications via a hardware port. The Protection Proxy: adding a Business Layer to the object The Protection Proxy adds a business layer to the object that that object itself does not possess. This Business Layer can (for instance) take care of security and access rights.

Page 723: Re Factoring and Design Patterns

Refactoring and Design Patterns 723

IMPLEMENTING A PROXY THAT CAN CONTAIN OBJECTS OF DIFFERENT TYPES ::Tag: PAT-PRX-DIA-005

Methods A, B, CVariables K, L, M

Proxy A1.a: «has a»

variable

2.b: «will contain»1.b: «has / exposes»

Object X from Class N, O or P3: «will

address / set»Methods D, E, FVariables O, P, Q

4: «inside»

1.c: «instantiates / represents / pretends to be»

InterfaceA / (Base)ClassB

2.a: «is of type»

5: «implements/ extends»

DEPENDENCIES: Proxy A: 1.a: Has a variable 1.b: Has / exposes Mehtods A, B, C and variables K, L, M The Variable: 2.a: Is of type Interface A / Baseclass B 2.b: Will Contain Object X from Class N Methods A, B, C and Variables K, L, M: 3: Will address / set Methods D, E, F and variables O, P, Q Methods D, E, F and variables O, P, Q: 4: Live inside Object X from Class N Object X from Class N, O or P: 5: Implements / extends Interface A / BaseClass B

NOTES: Implementing an Interface or extending a BaseClass By implementing an Interface or extending a Baseclass, your Proxy can be used to envelop several different Classes. This can be useful when you have different sources or types of objects while you want to use the same Proxy Class to make your code less dependent of the concrete implementations of the actions and objects the Proxy might use. Bridge: similar setup, similar goal

Page 724: Re Factoring and Design Patterns

724 Peter Kaptein

This setup is very much like the Bridge Pattern, while you hace one single object and class to instantiatie, that same Class can choose the concrete implementation from several Classes which represent specific implementations of a specific process or object Type. Data: same structure, different sources One concrete example is a Remote proxy that retrieves and stores data from and to a remote source, where the Source can be either (but not limitet to) a Webservice with XML, a Database Layer returning Records or a local File returning binary data or clear text. While the data and the way the Proxy interacts with these Data Access objects is the same, the concrete implementation of each of these Data Access objects is different.

Page 725: Re Factoring and Design Patterns

Refactoring and Design Patterns 725

SUMMARY

::Tag: PAT-PRX-SHS Representative or surrogate The proxy provides a surrogate or placeholder to that object to control access to it. This is possible in several ways. Below are the different types as defined in “Design Patterns”. Buffering the values and method calls The Proxy – in most cases – will act as a buffer for all the method calls and value settings on the actual object. While the actual object is not there, the Proxy will store these settings and queue the calls internally. Passes all your requests when the object is there Once the object arrives, the Proxy passes all your requests and executes your settings on the object (B) Working with an object as if it is there The commonality between all the types mentioned in “Desing Patterns” is that the Proxy allows you to work with an object as if it is already there. Depending on the implementation, this can be simply setting variables and reserving space in a layout, or simple interaction with an object somewhere else. Protection Proxy: base the access to an object by adding a gate-keeper The Protection Proxy: “controls access to the original object”. According to “Design Patterns”, Protection proxies are useful when objects should have different access rights. You can do this by wrapping the original object in a Proxy and place a gate-keeper between the user (your code) and the actual object that is addressed. The gate-keeper can decide, based on rules and data, what your code (and your user) is allowed access and to what functionalities access will be denied. Remote Proxy: representing a Remote object The Remote proxy represents an object that is somewhere else. It allows you to work with that remote object as if it is there locally and, depending on the implementation, allows you to call methods, perform actions and get results from the remote system as if it is local. Virtual Proxy: representing an object that is not there yet The Virtual Proxy: “creates expensive objects on demand. The ImageProxy described in the Motivation is an example of such a proxy”. The use of Virtual Proxies is most common for files and heavy objects of which the instantiation on start would freeze the application. Smart References: doing additional work on, or with, the object they represent A Smart Reference is similar to the Protection Proxy as it allows you to add extra actions and validations to the process of accessing and using the actual object. The main goal of the Smart Reference is to provide you tools and information on the actual object while that object can be simple and straight forward.

Page 726: Re Factoring and Design Patterns

726 Peter Kaptein

SEE ALSO

::Tag: PAT-PRX-SEE Overview of the Patterns based on type and use There are many ways to look at the Patterns in this book. In the overview on Patterns based on type and use you will find the patterns sorted on type and use. ::Link:PAT-TYP Overview of the Creational, Structural and Behavioral patterns Design Patterns have a basic classification in three different groups: Creational, Structural and Behavioral Patterns. ::Link:PAT-CLASS The Wrapper Family Tree The Wrapper Family Tree shows the various variation on the Wrapper theme and the relationships and differences for each Wrapper. ::Link: WRIA-REL-001 The Decorator: extending an object like the Protection Proxy and Smart Reference The Protection Proxy and the Smart Reference add an extra layer to the object it encapsulates consisting of functionalities the original object does not possess. This makes the Protection Proxy a close relative to the Decorator. ::Link: PAT-DEC The Adapter: close relative to the Virtual Proxy? The Virtual Proxy either exposes the same Interface as the object it encapsulates, but can also adapt the object it envelops. What the Virtual Proxy does not add new functionalities. In this sense the Virtual Proxy can be seen as an Adapter with the ability to instantiate the wrapped object on demand. ::Link: PAT-ADP

Page 727: Re Factoring and Design Patterns

Refactoring and Design Patterns 727

ASPECTS FROM “DESIGN PATTERNS”

::Tag: PAT-PRX-ASP From: Also known as Surrogate From: Motivation [..] One reason for controlling access to an object is to defer the full cost of its creation and initialization until we actually need to use it. [..] But what do we put in the document in place of the image? And how can we hide the fact that the image is created on demand so that we don't complicate the editor's implementation? [..] The solution is to use another object, an image proxy, that acts as a stand-in for the real image. The proxy acts just like the image and takes care of instantiating it when it's required. From: Applicability [..] A remote proxy provides a local representative for an object in a different address space. [..] A virtual proxy creates expensive objects on demand. The ImageProxy described in the Motivation is an example of such a proxy. [..] A protection proxy controls access to the original object. Protection proxies are useful when objects should have different access rights. [..] A smart reference is a replacement for a bare pointer that performs additional actions when an object is accessed. [..] for instance: counting the number of references to the real object so that it can be freed automatically when there are no more references (also called smart pointers) From: Implementation Proxy [..] provides an interface identical to Subject's so that a proxy can by substituted for the real subject. Proxy [..] controls access to the real subject and may be responsible for creating and deleting it. From: Collaborations [..] Proxy forwards requests to RealSubject when appropriate, depending on the kind of proxy. From: Consequences [..] A remote proxy can hide the fact that an object resides in a different address space. [..] A virtual proxy can perform optimizations such as creating an object on demand. [..] Both protection proxies and smart references allow additional housekeeping tasks when an object is accessed. From: Related Patterns [..] An adapter provides a different interface to the object it adapts. [..] Although decorators can have similar implementations as proxies, decorators have a different purpose. A decorator adds one or more responsibilities to an object, whereas a proxy controls access to an object. [..] Proxies vary in the degree to which they are implemented like a decorator. A protection proxy might be implemented exactly like a decorator. On the other hand, a remote proxy will not contain a direct reference to its real subject but only an indirect reference, such as "host ID and local address on host." A

Page 728: Re Factoring and Design Patterns

728 Peter Kaptein

virtual proxy will start off with an indirect reference such as a file name but will eventually obtain and use a direct reference.

Page 729: Re Factoring and Design Patterns

Refactoring and Design Patterns 729

REFLECTION * ::Tag: PAT-REFL ::includesubchapters

Page 730: Re Factoring and Design Patterns

730 Peter Kaptein

SINGLETON * ::Tag:PAT-SING ::includesubchapters Diagrams

Singleton

+ static instance()+ someMethod()+ anotherMethod()

4: «returns instance of object to» - static _instance

3: «contains instance of»

1: «calls»Client

2: «uses»

One single instance of an object that can be retrieved and used anywhere

5: «leading to»

Page 731: Re Factoring and Design Patterns

Refactoring and Design Patterns 731

STATE ::Tag: PAT-STT: Discussing the State Pattern ::includesubchapters

Page 732: Re Factoring and Design Patterns

732 Peter Kaptein

INTENT (GOF)

::Tag: PAT-STT-INT Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.

STATE BASICS

::Tag: PAT-STT-DIA-BAS

State Object A

State Object B

State Object C

State Object X

2: «has a / addresses»

State Context A

State container vatiable

3: «contains»

4.a: «changes»

4.b: «is either / has knowledge of»

Your Class 1: «uses»

5: «is put inside»

WHAT/WHEN? ::Tag: PAT-STT-DIA-BAS-001 When you need a self-organizing delegator to handle processes Due to its setup, the State can be seen as a self-organizing Delegator. The Context delegates actions to the State object. The State object then defines which next State object will deal with the process state that follows. The State object changes the content of the State container The State Pattern is a closed universe. Your Code, using the State Pattern, has no knowledge on what State should or could be next. This is all dealt with by the State objects themselves.

Page 733: Re Factoring and Design Patterns

Refactoring and Design Patterns 733

OTHER INFO Each state object knows what next state will follow Each state object knows what next state will follow on a specific method call. Actions in the Context are delegated to the State object Most if not all actions in the Context are delegated to the State object. State objects have knowledge of other State objects State objects have knowledge of other State objects and which State object to choose when the State changes due to a method call.

DIAGRAMS

::Tag: PAT-STT-DIA

VISUAL SUMMARY OF THE STATE PATTERN ::Tag: PAT-STT-VSM

Context

+ request()

+ setState( stateOject )

Concrete State A

+ handleRequest()

- stateObject

Concrete State B

+ handleRequest()

A self-organizing delegator that defines internally which concrete implementation should handle the next state of the process

4: «leading to»

«state object»

1: «contains»

2: «is handled by current»

5: «sets next state object via»

3: «has reference to / can inject another state object into»

4: «has knowledge of other»

Concrete State C

+ handleRequest()

NOTES: State and behavior Each time you call a method within the State object, the State of the process, represented by the State object can change as a result. Due to that change in state, the behavior behind the methods in your Context object might have to change as well.

Page 734: Re Factoring and Design Patterns

734 Peter Kaptein

BASE CLASS DIAGRAM ::Tag: PAT-STT-DIA-000: State Base class diagram

Context

+ request()+ setState( stateOject )

Concrete State A

+ handle()

- stateObjectB

+ setContext( context )+ handle()

«base class»State

1: «contains object of type»

«stateObject.handle()»

- stateObject

Concrete State B

+ handle()

- stateObjectA

2.a: «extends»

- contextObject

«contextObject.setState( stateObjectB )»

2.b: «has reference to / sets next state object in»

NOTES: As true as possible to implementation in “Design Patterns” You will find a very similar diagram in “Design Patterns”. What I focused on are the relationships between the Classes. State Base Class or State Interface? In this Diagram I use a State Base Class. Within the State Pattern, the Concrete State sets the next state on the Context. To be able to do this, the State object needs a reference to the Context object. This reference is set using “setContext” on the State objects which are instantiated in and by the Context. Context is used by your code The context object is instantiated and used by your code. Request and handle: passing the request to the State object Within the State Pattern, like within the Delegate, the request from your code is passed to the State object. Using a Object Map instead of setting the State objects one by one Instead of setting the State objects one by one on each State object within the Context, you can use a Object Map with two keys: the Context ID and the ID per State object. This is presented below.

Page 735: Re Factoring and Design Patterns

Refactoring and Design Patterns 735

Context

+ request()+ setState( stateOject )

Concrete State A

+ handle()

- stateObjectB

+ setContext( context )+ handle()- getStateObject( stateID )

«base class»State

1.a: «contains object of type»

«stateObject.handle()»

- stateObject

Concrete State B

+ handle()

- stateObjectA

2.a: «extends»

- contextObject+ const stateAID+ const stateBID

«contextObject.setState( stateObjectB )»

«static class»StateContextMap

- stateContextMap

+ setStateContext( contextID, stateID, stateObject )+ getStateObject( contextID, stateID )

1.b: «uses / sets»

3: «uses»

Using (String) constants to identify the State objects To store and resolve the State objects from the Object Map, you can use (String) Constants as keys. Each time you implement the Pattern, the steps are exactly the same: you create the State objects, store them in the Object Map and recall them where needed using the Constants as the key to retrieve that specific State object. Do you need the Context ID? In “Design Patterns”, State Pattern, Consequences, the following is said:

[..] contexts can share a State object. When states are shared in this way, they are essentially flyweights with no intrinsic state, only behavior.

In that case, the State object can be stored under State object ID only. When each Context has its own State objects and each State object maintains some kind of state (meaning it holds certain values related to that specific Context) you need to instantiate and store State objects per Context. What about the Flyweight? “Design Patterns” makes mention of the Flyweight in cases of re-use of objects. The Flyweight is very similar to the Object Map in the result it produces. What differs between the Flyweight and the Object Map is the way the objects are mapped and retrieved.

Page 736: Re Factoring and Design Patterns

736 Peter Kaptein

SIMPLE DIAGRAM ::Tag: PAT-STT-DIA-001

State Object A

State Object B

State Object C

State Object X

2: «has a / addresses»

State Context A

State container vatiable

3: «contains»

4.a: «changes»

4.b: «is either / has knowledge of»

Your Class 1: «uses»

5: «is put inside»

DEPENCENCIES: Your Code: 1.a: Instantiates / addresses State Context A State context A 2: Has / addresses a State Container The State container variable: 3: Contains State Object X State Object X: 4.a: Changes the State Object within the State container 4.b: Is either / has knowledge of State Object A, B, C State Object A, B, C: 5: Is put inside the State container variable

NOTES: Method call on State object: new state? When you call a Method on a State object, this can lead to a new State. State object changes the State Container The State Pattern is a closed universe. Your Code, using the State Pattern, has no knowledge on what State should or could be next. This is all dealt with by the State objects themselves. State objects have knowledge of other State objects

Page 737: Re Factoring and Design Patterns

Refactoring and Design Patterns 737

State objects have knowledge of other State objects and which State object to choose when the State changes due to a method call.

Page 738: Re Factoring and Design Patterns

738 Peter Kaptein

IMPLEMENTING THE STATE PATTERN ::Tag: PAT-STT-DIA-002

4.a: «uses either / or»

State Context A

State Object A

State Object B

1.a: «has a»

State Container variable

Abstract Class A / Interface B

2.c: «contains»

1.b: «addresses /pretends to be»

Your State Class B

Your State Class A

Your State Class C

6: «implement / extend»

Methods A, B, C

3: «contains»

2.a: «is of type»

5: «

insta

ntia

ted fro

4.b: «sets»

State Object X

State Object C

2.b: «is either / or»

1.c: «can implement»

DEPENDENCIES: State context A: 1.a: Has a (variable for a) State Object 1.b: Addresses / pretends to be the State Object (“State Object X”) 1.c: Can implement Abstract Class A / Interface B State Container: 2.a: Is of Type AbstractClassA or InterfaceB 2.b: Is either / or StateObject A, B or C 2.c: Contains StateObject A, B or C State Object X: 3: Contains Methods A, B and C Methods A, B and C: 4.a: Uses either or State Object A, B or C 4.b: Sets the State Object Variable Your State Objects A, B and C: 5: Are Instantiated from Your State Class A, B and C Your State Class A, B, C: 6: Implement or extend Abstract Class A or Interface B

Page 739: Re Factoring and Design Patterns

Refactoring and Design Patterns 739

NOTES: State Container (variable) The State Container is a variable that contains the current State object. It is initially set by your Code, but once the State Pattern is set in action, it will be changed by the State object into each next State that is the result of your calls to action on the State object. The process of Changing State Each State object has the same set of Base Methods, compliant to either the Abstract Class or Interface. Each Method contains two elements:

1. The actions that have to take change for that State 2. The Next State object that has to be set when these actions have taken place.

When you call a method on the State object within the State Container: 1. The Actions for that state, for that Method will be executed 2. The Current State object injects the appropriate next State object into the State Container.

Interfaces and State objects The State objects and State Classes can each be completely different, but each inherit or Implement the same Abstract Class or Interface. This makes each State object interchangeable with each other State object in the same family. States and dead-end actions Not all methods in a State object lead to a concrete action. Some calls in some State objects can be “dead ends” as the called for actions might be: “not allowed” or irrelevant in that state. Think of a button being clicked to start a process, while the process is already running. Pretending to be the State object: Delegation of actions Your Code uses the State object to perform the actions requested to Your Code. The requested actions are delegated to the State object.

Page 740: Re Factoring and Design Patterns

740 Peter Kaptein

WHEN WOULD YOU USE STATE PATTERN?

::Tag: PAT-STT-USE To bundle State-specific actions The State Pattern allows you to collect all State specific actions into State specific Classes. While each Class in the family exposes the same Methods, the execution will be State-specific. Polymorphic objects: to change internal behavior when the State changes The State Pattern allows you to change the internal behavior of your object when the State (of the data) changes. When you need to perform different actions per specific When your application and parts of your Application have clearly defined States with clearly defined actions per State, instead of using conditional execution, you can use the State Pattern instead. When you need a self-managing solution The State Pattern is self-managing. Each State object decides which State object will be used next when a Method is called.

Page 741: Re Factoring and Design Patterns

Refactoring and Design Patterns 741

COMPARISONS AND DIFFERENCES

::Tag: PAT-STT-USE

PATTERNS WITH SIMILARITIES ::Tag: PAT-STT-SIM

BRIDGE ::Tag: PAT-STT-SIM-BRI Similarities: Polymorphic, pretends to be, encapsulates Like the Bridge Pattern, the State Pattern pretends to be something else by wrapping the object that does the actual work. Both Bridge and State use encapsulation within a wrapper to abstract the situation specific solutions to enable Choice in the concrete implementation of specific actions. Both State and Bridge are polymorphic objects. Changes the internal object, polymorphic Class The Bridge object implements the object it represents when it is instatiated. Where the State Context object is – in most cases – a passive player in the State Pattern, the Bridge object is an active player and changes the object it wraps. Where the State Pattern delivers a polymorphic object changing itself from the inside out, the Bridge creates a polymorphic Class. The Bridge object is the one changing the encapsulated object.

DELEGATE ::Tag: PAT-STT-SIM-DEL Similarities: Delegation to other objects,chan change delegator The Delegate, like the State Pattern delegates all actions to another object. And like the State Pattern, this delegation is not fixed to one single object. Delegate does not allow for the Delegate to choose the next Delegate Where the State Pattern allows a State Object to choose the next State Object, the Delegatre does not. Delegate is not state-driven The Delegate does not focus on states, but simply on the delegation of actiosn to other objects.

Page 742: Re Factoring and Design Patterns

742 Peter Kaptein

COOPERATION WITH OTHER PATTERNS ::Tag: PAT-STT-COP

SIMPLE FACTORY, ABSTRACT FACTORY, FACTORY METHOD ::Tag: PAT-STT-COP-FAC Instantiating the State Objects The State Pattern can use a Factory to instantiate the specific State Object when and where needed.

OBJECT MAP ::Tag: PAT-STT-COP-OBM Mapping the State Objects You can use the Object Map (together with the Factory) to map the State Objects within a State Handler so switching between the State Objects can be done via the Object Map and abstract keys. Inversion of Control: Mapping the State Objects somewhere else Instead of producing them when needed, you can choose to map the State Objects somehere else, using a shared key also known to your State Handler.

Page 743: Re Factoring and Design Patterns

Refactoring and Design Patterns 743

BONUS MATERIAL

::Tag: PAT-STT-BNS

CREATING A STATE-BRIDGE ::Tag: PAT-STT-DIA-003

State Object A

State Object B

State Object C

State Object X

2: «has a / addresses»

State Context A

State container vatiable

3: «contains»

4.a: «changes»

4.b: «is either / has knowledge of»

Your Code1: «extends»

DEPENDENCIES: Your Code: 1: Extends State Context A State Context A: 2: Has / addresses a State container Variable The State Container variable: 3: Contains State Object X State Object X: 4.a: Changes the State container variable 4.b: Is either/ has knowledge of State Object A, B, C

NOTES: Creating a Polymorphic class that changes its behavior when the state changes Using the State-Bridge construction, you can create a Class that changes its behavior when the State changes.

Page 744: Re Factoring and Design Patterns

744 Peter Kaptein

SUMMARY

::Tag: PAT-STT-SHS Deals with States in your Code The State Pattern is used to deal with the specific States in your Code. One Context, many states One Context object can have many internal States. One State object for one Specific State Each State object is created for a specific State in (a part of) your Application and has all internal knowledge of what needs to happen how. Two parties can decide the next state Two parties can define what the next state will be.

1: The State object The State object can decide what is next state when a method is executes. 2: The Context Instead, when the criteria for a State are fixed, the Context object can decide what the next state will be once an action is executed.

Same Interface, same methods, different implementation Each State object shares the same public methods, but each State Class implements these methods differently, according to the State it represents. These methods are defined in either an Interface or Abstract / Base Class Using the same interface also for the Context object Since the Context object acts as a Delegate to the actions you can perform on the State object, you can choose to use the same Interface on the Context object if there is no further abstraction is required. Most in common with Bridge and Delegate Like the Bridge and Delegate, the State acts as a man in the middle between your code and the object that executes the concrete actions. Each call to the wrapper (the Context object) is delegated to the State object. A pretender Like the Bridge and Delegate Patterns, the State Pattern is a pretender. It pretends to be the State object it envelops. Method Call on a State object leads to next State When a method is called on a State object, this automatically leads to a next State and the injection of the according State object into the Context object. When a new request is done to the Context object, this request will be delegate to- and dealt with the new State object. Inside out: the State object changes the State object

Page 745: Re Factoring and Design Patterns

Refactoring and Design Patterns 745

The State object itself injects another State object into the Container (the Context) it is contained by. By doing this, it replaces itself by another State object that is more fit to deal with the new State. Dependencies: each State object has knowledge of the other State objects All State objects within a specific Scope are linked to one or more other State objects and thus have knowledge of each other. Persistent State objects State objects are usually Persistent and created only one per State within the Scope they operated

SEE ALSO

::Tag: PAT-STT-SEE Overview of the Patterns based on type and use There are many ways to look at the Patterns in this book. In the overview on Patterns based on type and use you will find the patterns sorted on type and use. ::Link:PAT-TYP Overview of the Creational, Structural and Behavioral patterns Design Patterns have a basic classification in three different groups: Creational, Structural and Behavioral Patterns. ::Link:PAT-CLASS A short piece on change from inside out / outside in The State Pattern changes the behavior of an object from the inside out. It is the State object that replaces itself for another State object ::Link: PAT-CHC-OV-REL003 Relationships with other wrappers The State Pattern uses the same internal setup as most of the Wrappers described in “Wrapping, Interfacing and Abstraction”. In “Relationships between the patterns” the State is compared to the object Wrappers. ::Link: WRIA-REL The Delegate: delegating actions to an embedded object The State can be considered a specific variation on the Delegate Pattern. Both delegate the execution of the actions to a sub-object. The Delegate (like the Bridge) can use internal logic to choose and decide which object from which Class will be used to execute the next phase in the cycle. ::Link: PAT-DEL The Bridge: polymorphic, delegating actions in the form of a Base Class Like the Delegate, the Bridge is polymorphic and delegates the requests for actions to an embedded object. Like the State Pattern, the Bridge is able to change the embedded object on demand, based on the business rules in the Bridge Class / object. ::Link: PAT-BRIDC State-Bridge: a dynamic Class The Bridge, like the State Pattern, addresses an internal object that does the actual work. When you need a more dynamic Class than the Bridge provides, you might consider a State-Bridge. The difference between a normal State Pattern and the State-Bridge is that you use the Context Class as a Base Class instead of an object you instantiate within your Code. ::Link: PAT-STT-DIA-003 See the Bridge Pattern for more info on the Bridge itself. ::Link: PAT-BRI The Visitor: working from the inside out

Page 746: Re Factoring and Design Patterns

746 Peter Kaptein

Like the State Pattern, the Visitor turns everything you take for granted inside out. Instead of traversing an object tree from the outside, using information provided by each individual object, the Visitor is injected into the object Tree (or Composite object) and passed through to all child elements by the internal logic of those objects. ::Link:PAT-VIS

Page 747: Re Factoring and Design Patterns

Refactoring and Design Patterns 747

ASPECTS FROM DESIGN PATTERNS

::Tag: PAT-STT-ASP From: Applicability Use the State pattern [when..] An object's behavior depends on its state, and it must change its behavior at run-time depending on that state. Operations have large, multipart conditional statements that depend on the object's state. [..] The State pattern puts each branch of the conditional in a separate class. This lets you treat the object's state as an object in its own right that can vary independently from other objects. From: Participants Context [..]defines the interface of interest to clients. [..] maintains an instance of a ConcreteState subclass that defines the current state. State [..] defines an interface for encapsulating the behavior associated with a particular state of the Context. ConcreteState subclasses [..] each subclass implements a behavior associated with a [specific] state of the Context. Form: Collaborations Context delegates state-specific requests to the current ConcreteState object. A context may pass itself as an argument to the State object handling the request. This lets the State object access the context if necessary. Context is the primary interface for clients. Clients can configure a context with State objects. Once a context is configured, its clients don't have to deal with the State objects directly. Either Context or the ConcreteState subclasses can decide which state succeeds another and under what circumstances. From: Consequences [..] The State pattern puts all behavior associated with a particular state into one object. [..], new states and transitions can be added easily by defining new subclasses. [..] It makes state transitions explicit. [..] Introducing separate objects for different states makes the transitions more explicit. Also, State objects can protect the Context from inconsistent internal states [..] [..] contexts can share a State object. When states are shared in this way, they are essentially flyweights with no intrinsic state, only behavior. From: Implementation [..] The State pattern does not specify which participant defines the criteria for state transitions. If the criteria are fixed, then they can be implemented entirely in the Context. It is generally more flexible and appropriate, however, to let the State subclasses themselves specify their successor state and when to make the transition. [..] A table-based alternative. [..] For each state, a table maps every possible input to a succeeding state. In effect, this approach converts conditional code [..] into a table look-up.

Page 748: Re Factoring and Design Patterns

748 Peter Kaptein

STRATEGY ::Tag: PAT-STRA: Discussing the Strategy Pattern ::includesubchapters

Page 749: Re Factoring and Design Patterns

Refactoring and Design Patterns 749

INTENT (GOF)

::Tag: PAT-STRA-INT Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.

STRATEGY BASICS

::Tag: PAT-STRA-DIA-BAS

Context Object A

Class X / Strategy Y

Your Class

1.a: «uses / addresses / inject strategy into»

1.b: «instantiates»

Code inContext Object A

3: «uses / addresses»

2: «contains»4: «is injected into»

WHAT/WHEN? ::Tag: PAT-STRA-DIA-BAS-001 When only a part of the process changes in a specific Context The Strategy Pattern is used when only a part of the process in your Class changes in a specific Context. When you want to extract Context specific code into a separate Class To cater a more dynamic implementation of specific routines, only the context-specific code is externalized (extracted) into a Strategy Class. Depending on the Context of the situation, a different Strategy can be injected into the Context object by your code, leading to a different execution of specific actions. Delegating actions Like the Brisge and the Delegate Pattern, the Strategy Pattern delegates actions to another object. In the case of Strategy, this is the Strategy Object or Concrete implementation of the Strategy per Context. A handy alternative for conditional execution in your code Instead of cluttering your Methods with conditions, you can simply extract that conditional code into separate Classes, select the one you need and delegate the concrete execution to it.

OTHER INFO ::Tag: PAT-STRA-DIA-BAS-002 Similar to Delegate and Bridge The Strategy Pattern is very similar to the Delegate Pattern and the Bridge. Like the Delegate and Bridge, it uses another object (the Strategy object) to execute the actual actions.

Page 750: Re Factoring and Design Patterns

750 Peter Kaptein

DIAGRAMS

::Tag: PAT-STRA-DIA

VISUAL SUMMARY: EXTRACTING CODE TO A STRATEGY ::Tag: PAT-STRA-VSM

Your Class

+ yourMethodA(): if A: do Approach A if B: do Approach B+ yourMethodB()

variables

procedures Concrete Strategy A.a

+ yourMethodA: do Approach A

Concrete Strategy A.b

+ yourMethodA: do Approach B

1: «extract and split conditional code into separate classes»

2: «injected into / replacement for: code inside yourMethodA»

Classes and Objects that can change part of their behavior

3: «leading to»

NOTES: One separate Strategy Class per approach Each separate approach in your code (A and B in the example) is translated to a separate Class or Strategy. Several types of strategies possible One Class can use several different types of Strategies (A, B and C) with several varations (A.a, A.b and A.c). Re-use and scalability Once extracted, Strategies can be re-used. As each Strategy is clearly separated, you can add any number without cluttering your code.

Page 751: Re Factoring and Design Patterns

Refactoring and Design Patterns 751

BASE CLASS DIAGRAM ::Tag: PAT-STRA-DIA-001: Strattegy Base class diagram

Context

+/- executeA()+ setStrategyA( strategy )+ doSomethingElse()

Concrete Strategy A.a

+ executeA()

+ executeA( )

«interface»Strategy A

2.a: «contains object of type»

«strategyA.executeA()»

- strategyA

Concrete Strategy A.b

+ executeA()

2.a: «implements»

Client

- context

- setStrategy( contextID)

1: «uses / can set strategy»

2.b: «uses»

NOTES: As true as possible to implementation in “Design Patterns” You will find a very similar diagram in “Design Patterns”. What I focused on are the relationships between the Classes. Concrete Strategies only cover variable part of Context In contrary to patterns like the Bridge and the Adapter, the Strategy in the Strategy Pattern covers only a specific part of the code in the Context. The main goal of the Strategy Pattern is to allow you to change the implementation of a specific algorithm within your code. The Client sets the Strategy In general, the Client sets the Strategy. This can be done by injecting a new Strategy object Into the Context object, or by passing a Context ID and let the Context choose the associated Strategy. The Context uses the Concrete Strategy The Context uses the Concrete Strategy that is held in the Strategy variable (named: “strategyA” in the diagram). A Context can implement Strategies for several processes The Context is not limited in using one Strategy. You can extract and encapsulate several Strategies for several parts of your code, for instance to deal with Context specific strategies for two or more processes in your code. (Strategy A, B and C for processes A, B and C). Using a Object Map or Factory to create and retrieve the strategies You can use either a Object Map or Factory to create and retrieve the specific Strategies. We discuss this in the next pages.

Page 752: Re Factoring and Design Patterns

752 Peter Kaptein

What about the Flyweight? “Design Patterns” makes mention of the Flyweight in cases of re-use of objects. The Flyweight is very similar to the Object Map in the result it produces. What differs between the Flyweight and the Object Map is the way the objects are mapped and retrieved.

SIMPLE DIAGRAM ::Tag: PAT-STRA-DIA-001

Context Object A

Class X / Strategy Y

Your Class

1.a: «uses / addresses / inject strategy into»

1.b: «instantiates»

Code inContext Object A

3: «uses / addresses»

2: «contains»4: «is injected into»

DEPENDENCIES: Your Class: 1.a: Selects a Class and instantiates a Strategy Object 1.b: Uses / addresses / injects Strategy Object into Context Object A Context Object A: 2: Contains programming code Code in Context Object A: 3: Uses and addresses Strategy Y Class X / Strategy Y: 4: Is injected into Context Object A

NOTES: Similar to Delegate Pattern and Bridge The Strategy Pattern is very similar to the Delegate Pattern and the Bridge. Like the Delegate and Bridge, it uses another object (the Strategy object) to execute the actual actions. Context object A already consists code The Context object contains code to execute specific actions. Context specific code is extracted into a Strategy Class To cater a more dynamic implementation of specific routines, only the context-specific code is externalized (extracted) into a Strategy Class. Depending on the Context of the situation, a different Strategy can be injected into the Context object by your code, leading to a different execution of specific actions.

Page 753: Re Factoring and Design Patterns

Refactoring and Design Patterns 753

IMPLEMENTING THE STRATEGY PATTERN ::Tag: PAT-STRA-DIA-002

Context Object A1.a: «uses»

2.a: «has / addresses / delegates to Strategy in»

Variable A

Strategy A Strategy B Strategy C

Interface A / BaseCLass B

4: «implement / extend»

1.b: «injects Strategy into»

1.c: «instantiates either»

3: «is of type»

2.b: «receives / uses either»

Factory A / DataMap B

1.d: «can use»

YourClass

DEPENDENCIES: Your Class: 1.a: Instantiates and uses Strategy A 1.b: Injects Strategy into Variable A 1.c: Instantiates either Strategy A, B or C Context Object A: 2.a: Has / addresses / delegates to the Strategy in Variable A 2.b: Receives / uses either Strategy A, B or C Variable A: 3: Is of type Interface A / BaseClass B Implementation A, B and C: 4: Implement / extend Interface A / BlaseClass B

NOTES: Injection of strategy via method on Content Object A In what is considered a proper Abstraction and Encapsulation, the Context object will never allow Your Class to inject their Strategy directly into Variable A. Instead, the Context object will expose either a parameter or an extra method to allow Your Class to inject the concrete Strategy. Implementing the same Interface / abstract Class on the Strategies

Page 754: Re Factoring and Design Patterns

754 Peter Kaptein

All Strategies have to be “of the same family” somehow, so that the Context object can treat them as if there is no difference between Strategy A, Bo or C. for this we either implement the same Interface or the same Base Class on each Strategy Class. Using a Factory or Object Map to create or retrieve the Strategy Depending on your implementation of the Strategy Pattern, you can use either a Factory to create a new Strategy object every time you need it, or re-use existing Strategy objects from a Object Map, to control and limit the object Creation process and reduce the risks of memory leaks. Not the only way to implement Strategy Pattern While this is the basic implementation as described in “Design Patterns” it is not the only way in which you can make the Strategy Pattern work. ::Link: PAT-STRA-DIA-003

Page 755: Re Factoring and Design Patterns

Refactoring and Design Patterns 755

USING A CONTEXT TO INSTANTIATE THE STRATEGY WITHIN THE CONTEXT OBJECT ::Tag: PAT-STRA-DIA-003

Context Object AYourClass1.a: «uses»

Variable A

Strategy A Strategy B Strategy C

Interface A / BaseCLass B

4: «implement / extend»

1.b: «has a»

3: «is of type»

2.b: «instantiates / uses»

Context

2.a: «has / addresses / delegates to Strategy in»

1.c: «is passed to»

Factory A / DataMap B

2.c: «can use»

DEPENDENCIES: Your Class: 1.a: Uses Context Object A 1.b: Has a Context 1.c: Passes the context to Context Object A Context Object A: 2.a: Has / addresses / delegates to Strategy in Variable A 2.b: Can instantiate / uses either Strategy A, B or C 2.c: Can use Factory A / Object Map B to instantiate / retrieve Strategy A, B or C Variable A: 3: Is of type Interface A / BaseClass B Strategy A, B, C: 4: Implement / extend Interface A, BaseClass B

NOTES: Abstracting the creation / instantiation of the Strategy

Page 756: Re Factoring and Design Patterns

756 Peter Kaptein

Instead of Your Code, the Context Object itself instantiates the Strategy object. The Big benefit of this implementation is that only your Context object needs to have knowledge of the classes that lead to the Concrete Strategies, while Your Code only needs to know which String value to pass as the Context in which the Context object needs to operate. Easier to implement within a broader scope Let’s assume you implement the Strategy Pattern on multiple places, in different Context Classes and different types of circumstances. When each of these Context objects need to mirror the same type of context-related behavior it is easier to do this via a String value (or any abstract representation of that context) and by letting the Context object choose the accompanying Strategy than your own Code having to know and decide which Strategy should go with what context. Not explicitly mentioned in “Design Patterns” The implementation as described here is not explicitly mentioned in “Design Patterns”. When looking at the Intent, this implementation seems to fit within the Strategy Pattern.

Page 757: Re Factoring and Design Patterns

Refactoring and Design Patterns 757

WHEN WOULD YOU USE THE STRATEGY PATTERN?

::Tag: PAT-STRA-USE Choice in the way to handle a specific process If you want to have choice in handling a specific process. For instance: to deal with a call to a Server (is it a request for an HTTP connection, a WebSocket connection, FTP or TCP Socket?). To abstract and separate context-specific implementions The different ways you can solve one specific problem or request. See also the chapter “Extraction, Encapsulation and Abstraction”. To reduce the need for subclassing If only parts of your implementation of a Class vary, you can choose to only extract and implement these variations. Like the Decorator, the Strategy Pattern is designed to help you find alternative solutions to create a more versatile solution when you need specific variations on a theme. To delegate specific actions From a more generic point of view, the Strategy Pattern helps you by providing a standard solution to delegate specific actions within your Classes to other objects.

Page 758: Re Factoring and Design Patterns

758 Peter Kaptein

COMPARISONS AND DIFFERENCES

::Tag: PAT-STRA-CDF

PATTERNS WITH SIMILARITIES ::Tag: PAT-STRA-SIM

DECORATOR, BRIDGE, DELEGATE, STATE ::Tag: PAT-STRA-SIM-APDB Similarities: wrapping and abstracting the functionalities The Decorator, Bridge, Delegate and State wrap and abstract the functionalities of the concrete object that will perform the requested actions. They all use the same basic structure in which the wrapper exposes the concrete methods with which the wrapped object will be called and addressed.They also abstract the actual methods and actions performed on the wrapped object, making it possible to vary and combine specific calls on that object. Context specific execution Like the Strategy, each of these patterns allows for Context-specific executon of actions. Bridge: internal creation of the object, extendable polymorphic base class Where a Bridge object offers direct access to the functionalities of a chosen Strategy, Strategy Pattern produces objects to be used to execute the Strategy for a specific Process State: changing internal object, not just part The State can change its internal State object and does this every time the State of the object changes due to a method call on that State object. The State Pattern also assumes all actions to be done by the State object, not just a part as is the case with the Strategy Pattern.

DELEGATE ::Tag: PAT-STRA-SIM-DPBS Similarities: delegating actions to an embedded object The Delegate, Proxy and Bridge follows a similar process as the Strategy: delegating actions to another object referred to by the Delegate, Bridge or Proxy.

Page 759: Re Factoring and Design Patterns

Refactoring and Design Patterns 759

COOPERATION WITH OTHER PATTERNS ::Tag: PAT-STRA-COP

SIMPLE FACTORY, ABSTRACT FACTORY, FACTORY METHOD ::Tag: PAT-STRA-COP-FAC Instantiating the State Objects The State Pattern can use a Factory to instantiate the specific State Object when and where needed.

OBJECT MAP ::Tag: PAT-STRA-COP-OBM Mapping the State Objects You can use the Object Map (together with the Factory) to map the State Objects within a State Handler so switching between the State Objects can be done via the Object Map and abstract keys. Inversion of Control: Mapping the State Objects somewhere else Instead of producing them when needed, you can choose to map the State Objects somehere else, using a shared key also known to your State Handler.

Page 760: Re Factoring and Design Patterns

760 Peter Kaptein

SUMMARY

::Tag: PAT-STRA-SHS Injecting the behavior you want an object to implement With the Strategy Pattern, you inject the behavior you want an object (the Context) to implement. This allows you to address one single object with one single interface and have you decide later on what explicit behavior should be implemented when called. The Context-object can choose the Strategy Based on a context passed by Your Code, the Context object can choose the Concrete Strategy to perform the actual actions. Your code can choose the Strategy If you want to place the responsibility of instantiation of the appropriate Strategy in Your Code, Your Code can instantiate the Strategy and pass it to the Context object. The consequernce of this implementation is that Your Code (and any other location where the Context object is used) needs explicit knowledge of the available Strategies and which context is linked to each. Using separate Classes for specific implementations of processes The Strategy Pattern extract and places different implementations for a process (the strategy) into separate Classes. Using a context instead of injecting the Strategy “Design Patterns” is not explicitly clear on the use of a context to resolve the specific Strategy within the Context object. But as far as I understand the Pattern as described in “Design Patterns”, Strategy Pattern does not forbid to Dynamic implementation of a part of the code inside the Context object Iti s possible a lot of things take place within the Context object of which only a part has to be executed by the Strategy object or Concrete Strategy. The Strategy object you inject into the Context object can be used to perform the required actions in a very specific way, as implemented within the Strategy. What about the Delegate and Bridge? The Strategy Pattern is very similar in its working and purpose to the Delegate and Bridge. Bridge, Delegate and Strategy all explicitly delegate specific actions to the object they wrap. As mentioned before, the Context object in the Strategy Pattern depends on external code to Inject the Strategy object. Delegate and Bridge can use a Context (in the shape of a String value) and a Simple Factory to select and resolve the concrete implementation of a process internally. Another main difference is that the Strategy you inject into the Context object only takes care of the actions in the Context object that need to be variable in their implementation. The rest of the code in the Context object is native to the Context object. What about the Decorator? The Decorator Pattern uses a similar injection mechanism as the Strategy Pattern. In general neither Decorator or Strategy decide by themselves which classes or objects to implement to execute the actions. The Decorator, however, adds extra functionalities to the Base object while the Strategy Pattern

Page 761: Re Factoring and Design Patterns

Refactoring and Design Patterns 761

allows you to change the way specific actions within the Context object are executed by injecting a specific Strategy object.

SEE ALSO

::Tag: PAT-STRA-SEE Overview of the Patterns based on type and use There are many ways to look at the Patterns in this book. In the overview on Patterns based on type and use you will find the patterns sorted on type and use. ::Link:PAT-TYP Overview of the Creational, Structural and Behavioral patterns Design Patterns have a basic classification in three different groups: Creational, Structural and Behavioral Patterns. ::Link:PAT-CLASS Delegate, Bridge, Decorator: similar but not the same As described in “Summary”, there are a lot of commonalities between the Decorator, Delegate, Bridge and Strategy Pattern. All delegate the concrete execution of (specific) actions to the- or an object they encapsulate. Where the Delegate and Bridge can select and instantiate that object internally, the intent of the Decorator is to add extra functionalities to the object you inject. ::Link: PAT-DEL|PAT-DEC|PAT-BRI Simple Factory: produce Strategies using a Context If you need a Strategy Provider that uses a simple input (the Context) to decide which Strategy to return, you might like to consider the Simple Factory. ::Link: PAT-SFC Context I use the word “context” a lot in relationship to patterns where a Factory is used. ::Link: PAT-WRP-CONT Using a Object Map to store and select Strategies? When your State objects instantiate or choose the next State object to take over the actions to, you can choose to use a Object Map instead of hardcoded access to the State objects you might want to use. The Object Map can store concrete objects to specific keys you can offer as a context to your Context object. ::Link: PAT-DTMP Execution of actions only: use Handlers or Utils? The strategies you execute are usually stateless objects. When you use Strategies to simply execute specific implementations of a process or action, these Strategies do not / should not remember previous states. Instead this is a task for your Context object. ::Link:MHOPUDO-UTIL|MHOPUDO-HNDLR

Page 762: Re Factoring and Design Patterns

762 Peter Kaptein

ASPECTS FROM DESIGN PATTERNS

::Tag: PAT-STRA-ASP From: Motivation [..] We can avoid these problems by defining classes that encapsulate different linebreaking algorithms. An algorithm that's encapsulated in this way is called a strategy. [..] A Composition maintains a reference to a Compositor object. [..] it forwards this responsibility to its Compositor object. The client of Composition specifies which Compositor should be used by installing the Compositor it desires into the Composition.

From: Applicability [..] when: [..] many related classes differ only in their behavior. Strategies provide a way to configure a class with one of many behaviors. [..] you need different variants of an algorithm. [..] Strategies can be used when these variants are implemented as a class hierarchy of algorithms. [..] an algorithm uses data that clients shouldn't know about. Use the Strategy pattern to avoid exposing complex, algorithm-specific data structures. [..] a class defines many behaviors [..] Instead of many conditionals, move related conditional branches into their own Strategy class. From: Collaborations [..] A context may pass all data [..] to the strategy when the algorithm is called. Alternatively, the context can pass itself as an argument to Strategy operations. That lets the strategy call back on the context as required. A context forwards requests from its clients to its strategy. Clients usually create and pass a ConcreteStrategy object to the context; thereafter, clients interact with the context From: Consequences An alternative to subclassing. Inheritance offers another way to support a variety of algorithms or Behaviors [..]Encapsulating the algorithm in separate Strategy classes lets you vary the algorithm independently of its context, making it easier to switch, understand, and extend. [..] The Strategy pattern offers an alternative to conditional statements for selecting desired behavior. [..] Encapsulating the behavior in separate Strategy classes eliminates these conditional statements. [..] [..] Strategies can provide different implementations of the same behavior. The client can choose among strategies [..]. [..] The pattern has a potential drawback in that a client must understand how Strategies differ before it can select the appropriate one. [..] Communication overhead between Strategy and Context. The Strategy interface is shared by all ConcreteStrategy classes whether the algorithms they implement are trivial or complex. [..] That means there will be times when the context creates and initializes parameters that never get used. [..]

Page 763: Re Factoring and Design Patterns

Refactoring and Design Patterns 763

[..] Strategies increase the number of objects in an application. Sometimes you can reduce this overhead by implementing strategies as stateless objects that contexts can share. [..] Shared strategies should not maintain state across invocations. The Flyweight pattern describes this approach in more detail. From: Implementation One approach is to have Context pass data in parameters to Strategy operations—in other words, take the data to the strategy. [..] Another technique has a context pass itself as an argument, and the strategy requests data from the context explicitly. Alternatively, the strategy can store a reference to its context, eliminating the need to pass anything at all. [..] [..] The Context class may be simplified if it's meaningful not to have a Strategy object. Context checks to see if it has a Strategy object before accessing it. If there is one, then Context uses it normally. If there isn't a strategy, then Context carries out default behavior. The benefit of this approach is that clients don't have to deal with Strategy objects at all unless they don't like the default behavior.

Page 764: Re Factoring and Design Patterns

764 Peter Kaptein

TEMPLATE METHOD *

Page 765: Re Factoring and Design Patterns

Refactoring and Design Patterns 765

VISITOR ::Tag:PAT-VIS : Discussing the Visitor Pattern ::includesubchapters

Page 766: Re Factoring and Design Patterns

766 Peter Kaptein

INTENT (GOF)

::Tag:PAT-VIS-INT 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.

VISITOR BASICS

::Tag:PAT-VIS-DIA-BAS

Composite Object B

Visitor AYourClass

1.b: «injects visitor into» 2: «visits / travels through / uses / performs operations with or to»

1.a: «instantiates»

WHAT/WHEN? ::Tag:PAT-VIS-DIA-BAS-001 When you need to traverse through a composite object The Visitor can be used to travers through a Composite object and either do something with the object,s or simply read the contents. As an alternative for the Parser You could use the Visitor pattern as an alternative for the Parser as both can accomplish the same results. The Visitor requires a bit more within the objects you traverse. Many different Visitors, one traversing process The benefit of the Visitor is that you can use many different Visitors in the same traversing process, each delivering a completely different result in that process.

OTHER INFO ::Tag:PAT-VIS-DIA-BAS-002 Can require specific setup of the objects in the tree In the basic implementation of the Visitor Pattern, the objects pass the Visitor. This includes an “accept” method on each object: accepting the visitor. Visitor can pass itself to the next object There are workarounds possible in which the Visitor can pass itself to each next object and deal with the content there. One workaround is to use an Object Adapter for the objects which are not implementing the Visitor Pattern.

Page 767: Re Factoring and Design Patterns

Refactoring and Design Patterns 767

Inverted approach related to the Parser Like the Command and Observer patterns, the Visitor and Parser are two different approaches to the same problem: how do I work with data and objects in a structure? Like the Command, the Visitor inverts the approach from an outside-in to inside out. You send an object into a composite structure and let that object do the work.

Page 768: Re Factoring and Design Patterns

768 Peter Kaptein

DIAGRAMS

::Tag:PAT-VIS-DIA

VISUAL SUMMARY OF THE VISITOR PATTERN ::Tag:PAT-VIS-INT

Concrete Element A

Concrete Element B

Concrete Visitor A

Object Structure A

Concrete Visitor B

Client A

«visitors»

1: «selects a concrete visitor based on» 2: «has / sends selected visitor into»

«elements»

3: «consists of elements based on»

4: «visits / is sent through / can perform operations on»

5: «can be child of»

A dynamic solution to run through- and perform actions on an Object Structure from the inside using different type of “visitors”

6: «leading to»

NOTES: Running through an object structure form the inside Where the Parser runs through an object structure from the outside, inspecting the object and the existing children in that object, the Visitor iterates through the object structure from the inside. Passed either by the object structure or by itself The Visitor object is passed through the object structure either by a method in the object structure or by the Visitor itself Elements can be children of other Elements Elements in the object structure can be children of other Elements. Requires the objects in the object structure to implement a specific Interface

Page 769: Re Factoring and Design Patterns

Refactoring and Design Patterns 769

Unlike the Parser, which just needs to understand the objects in the structure it parses, the Visitor requires the objects in your Structure to explicitly implement either a Base Class or an Interface. The dynamics lies in the use of different Visitors What you do and can do with the object structure depends on the Visitor. This means that whatever you need, is translated into a separate Visitor and then injected into the object structure to perform its actions.

BASE CLASS DIAGRAM ::Tag:PAT-VIS-DIA-000 : Base class diagram of the Visitor Pattern

«interface / base class»Base Visitor A

Concrete Element A

+ acceptVisitor( visitor )

+ acceptVisitor( visitor )

«base class»Base Element A

Concrete Element B

3.a: «extends»

Concrete Visitor A

3: «consists of elements based on»

+ acceptVisitor( visitor )

Object Structure A

- childElementList

Overrides / Implements:+ handleElementA( elementA )+ handleElementB( elementB )

Concrete Visitor B

«visitor.handleElementA( this )»

«visitor.handleElementB( this )»

+ handleElementA( elementA )+ handleElementB( elementB )

2: «extends / implements»

Client A

1.a: «selects a concrete visitor based on» 1.a: «sends selected visitor into»

Overrides / Implements:+ handleElementA( elementA )+ handleElementB( elementB )

3.b: «contains elements based on»

NOTES: Visiting the object structure The Visitor is explicitly used to traverse through an object structure and do stuff with the objects witin that structure. Traversing from the inside Unlike the more commonly used Parser Pattern, the Visitor traverses the object structure from the inside. It is passed to an object in the structure, does its work from within that structure and then gives back the result in some way.

Page 770: Re Factoring and Design Patterns

770 Peter Kaptein

Visiting different objects from a different type Within that structure, each object can be from a different type, with a different implementation and different processes to be handled by the Visitor. For this, the Visitor can have explicit methods to handle objects from type A, B and C. Who passes the Visitor? The Visitor can be passed by both the Concrete Element and the Concrete Visitor. This is all up to the designer of the specific implementation of the Visitor Pattern for that specific case. Multiple types of Visitors, same process, different results The Visitor Pattern can be used to traverse the same object structure and get completely different results out of that process. These results are defined by the Concrete Implementation of these Visitors. No scope to the possible result from a Visit Within the same implementation, one Concrete Visitor can collect data and save it to an outside source. Another Visitor can traverse the object structure and change specific values (based on Business rules) in specific (or all) objects in that structure. Yet another Visitor can collect that data, apply specific filters and return it in a different structure. Differences in naming In “Design Patterns” the “handle Element” methods are named “visit Element”. I explicitly identify Base Classes by calling: “Visitor” and: “Element” : “Base Visitor” and: “Base Element”.

Page 771: Re Factoring and Design Patterns

Refactoring and Design Patterns 771

SIMPLE DIAGRAM OF THE VISITOR PATTERN ::Tag:PAT-VIS-DIA-001

Composite Object B

Visitor AYourClass

1.b: «injects visitor into» 2: «visits / travels through / uses / performs operations with or to»

1.a: «instantiates»

DEPENDENCIES: Your Class: 1.a: Instantiates Visitor A 1.b: Injects Visitor A into Composite Object B Visitor A: 2: Visits / travels through / uses / performs operations with or to the objects within Composite Object B

NOTES: Visitor A can spawn new Visitor objects When you need, your Visitor can spawn new Instances to take care of parts of sub-processes or sub-parts.

Page 772: Re Factoring and Design Patterns

772 Peter Kaptein

EXAMPLE OF AN IMPLEMENTATION OF THE VISITOR PATTERN ::Tag:PAT-VIS-DIA-002

1.a: «has / creates»

Object X from Class N

Visitor A

Method A, B, C

3: «are executed by / receive Object X via »

1.b: «passes visitor into»

Accept-Method A

4.b: «lives inside»

Object Y from Class M

5: «can contain»

Accept-Method B

4.a: «executes / passes visitor to »

6: «lives inside»

Your Code

2: «has / exposes»

Repeat

DEPENDENCIES: Your Code: 1.a: Has / creates Visitor A 1.b: Passes Visitor A into Accept-Method A Visitor A: 2: Has / exposes Methods A, B and C Methods A, B, C: 3: Are executed by Accept-method A / B Accept-Method A: 4.a: Executes / passes Object X to Method A, B or C 4.b: Lives insode Object X from Class N Object X from Class N: 5: Can contain Object Y from Class M Accept-Method B: 6: Lives inside Object Y from Class M

Page 773: Re Factoring and Design Patterns

Refactoring and Design Patterns 773

NOTES: Endless nesting The object-tree that the Visitor is injected in can be “endlessly deep”. Spawning more Visitors as they go It is possible that your application needs to “split” the visitors as they pass, for instance, to take care of the child-elements inside a new and separate Visitor object. One interface or Base Class, many different Visitors The Visitor Pattern allows you to send many different Visitors down the tree, as long as they all implement the same Interface or Base Class. One type of Visitor can store the content of the objects to a file or database. Another Implementation of the Visitor can extract data into a serialization object.

Page 774: Re Factoring and Design Patterns

774 Peter Kaptein

PASSING VARIABLES AND DEPENDENCIES WITHIN THE VISITOR PATTERN ::Tag:PAT-VIS-DIA-003

4: «lives inside»

3: «lives inside»

Object Y from Class M

Accept-Method B

2.a: «lives inside»

Visitor A

1: «is passed to»

Method A for Class M

2.b: «calls / injects Object Y into» 2.c: «can inject Visitor in»

List of elements

DEPENDENCIES: Visitor A: 1: Is passed to Accept-method B Accept Method B: 2.a: Lives inside Object Y from Class M 2.b: Injects Object Y into Method A for Class M 2.c: Can inject Visitor A into the List of Elements living inside Object Y Method A for Class M: 3: Lives inside Visitor A The list of Elements: 4: Lives inside Object Y from class M

NOTES: Visitor can inject itself into each sub-element The Visitor can use the injected object to retrieve the sub-elements and inject itself into each sub-element by using the Accept-method on each Element. See the next diagram. Using the Element to perform actions and retrieve data The Visitor can use the entire Element (Object Y) to perform actions on and retrieve data from. The benefit of this approach is that the Visitor is in full control on what happens with the Element (Object Y). Passing only the required values into the Visitor: not the official way

Page 775: Re Factoring and Design Patterns

Refactoring and Design Patterns 775

A simpler approach (in some cases) is where your Accept Method injects specific data into the Visitor to be processed in specific ways. This is more limiting to the possibilities and levels of freedom you have with the Visitor. It will only be able to do stuff with the data it receives and if this data is insufficient, you will have to extend or refactor/rewrite your code and the implemented pattern. You pass the responsibility of knowing what is needed by the Visitor to the object it visits. Something you might want to avoid.

INJECTING THE VISITOR INTO SUB-ELEMENTS FROM WITHIN THE VISITOR ::Tag:PAT-VIS-DIA-004

4: «lives inside»

Object Y from Class M

Accept-Method B

2.a: «lives inside»

Visitor A

1: «is passed to»Method A for Class M

List of elements

3.b: «can inject Visitor in»

3.a: «lives inside»

2.b: «calls / injects Object Y into»

DEPENDENCIES: Visitor A: 1: Is passed to Accept-Method B Accept-Method B: 2.a: Lives inside Object Y from Class M 2.b: Calls / injects Object Y into Method A fro Class M Method A for Class M: 3.a: Lives inside Visitor A 3.b: Can inject the Visitor into the List of elements The List of Elements: 4: Lives inside Object Y from Class M

Page 776: Re Factoring and Design Patterns

776 Peter Kaptein

NOTES:

Page 777: Re Factoring and Design Patterns

Refactoring and Design Patterns 777

WHEN DO YOU USE THE VISITOR?

::Tag:PAT-VIS-USE Avoiding the code for an external traversal process You can use the Visitor when you want to limit the amount of Classes to deal with the object Tree. By moving the code to traverse the object Tree (Composite object) inside the objects, you remove the need for external classes and code to do that same job. Bundle (“localize”) actions distributed over several Classes The Visitor allows you to bundle Actions that would otherwise be distributed over components in an object Tree. This makes it easier to maintain specific related actions over several Classes.

Page 778: Re Factoring and Design Patterns

778 Peter Kaptein

COMPARISONS AND DIFFERENCES

::Tag:PAT-VIS-CDF

WHAT DIFFERENTIATES THE VISITOR? ::Tag:PAT-VIS-DIFFT Created to be sent on a mission into unknown territory The Visitor is the explorer of all Patterns. It is sent out into the unknown to fulfill a specific task. Most, if not all, other Patterns stay where they are and either traverse a structure from the outside, using the information the object and object structure provides (the Parser). Working inside-out instead of outside-in The Visitor Pattern takes a very different approach to “doing stuff” than most other Patterns in this book. Adding functionalities, working from the inside While Patterns like the Delegate allow you to add functionalities by wrapping the object and becoming the main in the middle: adding new functionalities, the Visitor goes inside the object and does its work from there. No need to write external code The Visitor Pattern moves all code to traverse the object Tree (or Composite object) inside the objects of the object Tree. This means that you do not need additional classes and code to traverse that Tree. Deals with the traversion of (complex) structures The Visitor is made to deal with (complex) structures. It can be used for one single object, but as the intent states: “Represent an operation to be performed on the elements of an object structure”.

PATTERNS WITH SIMILARITIES ::Tag:PAT-VIS-SIM

PARSER ::Tag:PAT-VIS-SIM-PARS Similarities: traversing structures Like the Visitor, the Parser travers through a structure to read objects and perform actions. Building and traversing structures from the outside, knowledge of the structure The Parser uses the existing structure (whether it is in clear text or as an object structure) to create something new. Unlike the Visitor, that travers within the structure. The Parser travels outside of the Structure and uses information from each object to find out what the next steps are within the object structure. The Visitor relies on the object it is injected into to be passed further on into the structure. The Visitor has no knowledge of the structure it travels through while the Parser uses the information on the structure it gets from the Composite object to decide what to do next.

Page 779: Re Factoring and Design Patterns

Refactoring and Design Patterns 779

COOPERATION WITH OTHER PATTERNS ::Tag:PAT-VIS-COP

ADAPTER ::Tag:PAT-VIS-COP-ADP Adapting objects which do not implement the Visitor Pattern The Decorator works from the outside in. objects to be handled are injected into the Decorator and actions on the injected object are executed from the outside, on the Decorator.

COMPOSITE ::Tag:PAT-VIS-COP-COM Using the visitor to travers the composite structure When you work a lot with Composite objects and composite structures, you might like to use the Visitor as one of the preferred ways to deal with the information and the objects within that composite structure.

Page 780: Re Factoring and Design Patterns

780 Peter Kaptein

SUMMARY

::Tag:PAT-VIS-SHS Accepting a visitor An object explicitly accepts the Visitor via an Accept-method Three approaches to visit the objects in a structure The Visitor has three possible approaches. These will be described below. 1: Handling the next line of Visits inside the Accept Method When an object has children or internal lists, the Accept Method can run through these lists and call the Accept method for each element, passing the Visitor to perform its actions. 2: Handling the next line of visits inside the Visitor The Visitor can use the object it visits to find out what the next line of visits is. For this, the object has to expose the list the Visitor requires. 3: Handling the (next line) of visits inside an Iterator An iterator can be setup in such a way that it accepts a Visitor and calls the Accept-method on each object it iterates through. Injecting values into the Visitor Your Accept-class can inject values in the Visitor. This limits the amount of dependencies between the Visitor and the Elements it visits. However: this approach is not the official approach for a visitor. Injecting the visited element into the Visitor “Design Patterns” assumes you inject the visited Element into the Visitor when that Element accepts the visitor and then use the Class and Element specific code to extract the information (or perform the actions) on that Visitor. The main benefit of this approach is that each Visitor can do completely different things with the information and methods each Element exposes, making your solution as open as possible. A specific type of Decorator In one way, the Visitor acts as a specific type of Decorator: “Instead of binding operations statically into the Element interface, you can consolidate the operations in a Visitor and use Accept to do the binding at run-time” (from “Design Patterns”, the Visitor Pattern, “Implementation”). This is very much like the Decorator, where you externalize Methods from a Class and an object into the Decorator, to be executed on the object you Inject into that Decorator. Distinguishing aspect of the Visitor: Travelling inside the objects The Visitor Pattern distinguishes itself from most of the other Patterns in this book by travelling through the objects it traverses or is traversed through. Most other Patterns stay on the outside or inject the specific object inside itself instead.

Page 781: Re Factoring and Design Patterns

Refactoring and Design Patterns 781

SEE ALSO

::Tag:PAT-VIS-SEE Overview of the Patterns based on type and use There are many ways to look at the Patterns in this book. In the overview on Patterns based on type and use you will find the patterns sorted on type and use. ::Link:PAT-TYP Overview of the Creational, Structural and Behavioral patterns Design Patterns have a basic classification in three different groups: Creational, Structural and Behavioral Patterns. ::Link:PAT-CLASS Composite: what the Visitor usually will travers through The Composite object is the most common pattern the Visitor will travers through. ::Link: PAT-CMP Builder, Parser: can be the one who provided the structure The Builder or Parser can be the Pattern that created the Composite object. ::Link: PAT-BLD|PAT-PARS Command, Delegate: using one single interface for many possible implementations The Visitor can be seen as a Command or Delegate sent inside an object Tree to execute their actions while travelling through the Tree. You will find some commonalities with the Command and Delegate Pattern in how an Abstract Interface is used to perform Context-specific actions. The difference with the Visitor is that the Command and Delegate patterns are wrappers by definition. The Visitor Pattern can be implemented using a Command or Delegate, but can also execute the actions immediately with the code inside. ::Link: PAT-COM|PAT-DEL Decorator: adding functionalities to existing objects Like the Visitor, the Decorator adds functionalities to existing objects without the need to change them. Like the Decorator, the Visitor Pattern can be used to vary the actions taken when you change the concrete Visitor you inject into the structure. ::Link: PAT-DEC State: working from the inside Like the Visitor, the State Pattern turns things upside down. The State Pattern can be seen as a specific variation on the Delegate Pattern, but instead of letting the enveloping object decide which State object will be used to execute the requested Actions, the State object itself takes care of that process, by injecting a new reference to another State object in the variable (State Container) it lives in. ::Link: PAT-STT Mediator: also handing over control to the subsystem Like the Visitor, the Mediator hands over (a part of the) Control to the outside world. Where the Visitor hands over the decision to the path it will travel through an object Tree to that object Tree, the Mediator hands over the control of what object will do what when: only mediating which objects and actions will be called next when one of these objects addresses the Mediator. ::Link: PAT-MED Traversing a Composite object inside-out and outside in: a short story There are two ways to travers an object Tree (or Composite object): outside in and inside out. The Visitor does this from the inside, the Parser from the outside. ::Link: PAT-DSTR-TRV

Page 782: Re Factoring and Design Patterns

782 Peter Kaptein

ASPECTS FROM DESIGN PATTERNS

::Tag:PAT-VIS-ASP From: Motivation [..] adding a new operation usually requires recompiling all of these classes. 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.

[..] 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. From: Applicability Use the Visitor pattern when [..] an object structure contains many classes of objects with differing interfaces, and you want to perform operations on these objects that depend on their concrete classes. [..] many distinct and unrelated operations need to be performed on objects in an object structure, and you want to avoid "polluting" their classes with these operations. Visitor lets you keep related operations together by defining them in one class. When the object structure is shared by many applications, use From: Participants [..] Visitor [..]declares a Visit operation for each class of ConcreteElement in the object structure. ConcreteVisitor [..] implements each operation declared by Visitor. [..] ConcreteVisitor provides the context for the algorithm and stores its local state. This state often accumulates results during the traversal of the structure. Element [..] defines an Accept operation that takes a visitor as an argument. ConcreteElement [..] implements an Accept operation that takes a visitor as an argument. [..] ObjectStructure - may provide a high-level interface to allow the visitor to visit its elements. - may either be a composite [..] or a collection such as a list or a set. From: Consequences [..]Visitors make it easy to add operations that depend on the components of complex objects. You can define a new operation over an object structure simply by adding a new visitor. [..] Visitor's approach assumes that the ConcreteElement interface is powerful enough to let visitors do their job. [..] the pattern often forces you to provide public operations that access an element's internal state, which may compromise its encapsulation. From: Implementation

Page 783: Re Factoring and Design Patterns

Refactoring and Design Patterns 783

[..] A visitor must visit each element of the object structure. The question is, how does it get there? We can put responsibility for traversal in any of three places: in the object structure, in the visitor, or in a separate iterator object [..] Often the object structure is responsible for iteration. A collection will simply iterate over its elements, calling the Accept operation on each. A composite will commonly traverse itself by having each Accept operation traverse the element's children and call Accept on each of them recursively. [..] Another solution is to use an iterator to visit the elements. [..] You could even put the traversal algorithm in the visitor, although you'll end up duplicating the traversal code in each ConcreteVisitor for each aggregate ConcreteElement. [..] This is the key to the Visitor pattern: The operation that gets executed depends on both the type of Visitor and the type of Element it visits. Instead of binding operations statically into the Element interface, you can consolidate the operations in a Visitor and use Accept to do the binding at run-time.