Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
SOFTWARE
DEVELOPMENT
AND
DESIGN PATTERNS
A book-sized thesis on software design
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}
::Bookname}
::Filename}
::Versions}
::Current}
::Authors}
::ePubauthor}
::Creation date}
::Publication date}
::Content width}
::Print width}
::Copyright}
Peter Kaptein
Kaptien, Peter
Created: December 17, 2011
Last update: April 22, 2012
700 pixels
700 pixels
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.
See:
Peter Kaptein
::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;
PART 1: INTRODUCTION
14
15
20
30
34
66
69
70
79
115
116
Basics
Refactoring step by step
Elements of Refactoring **
117
129
136
176
177
178
196
197
198
201
240
244
276
290
300
301
302
304
406
427
Adapter
33
428
Peter Kaptein
Bridge
Builder
Chain of Responsibility *
Command
Composite **
Data Access Object *
Decorator
Delegate
Faade
Factory Method
Factory, Abstract
Factory, Simple
Flyweight *
Injector *
Interpreter **
Manager
Mediator
Multiton *
Object Map **
Object Pool *
Observer
Parser
Prototype *
Proxy
Reflection *
Singleton *
State
Strategy
Template Method *
Visitor
443
468
489
490
502
512
513
532
550
567
579
597
610
611
612
620
635
651
652
660
661
682
707
708
729
730
731
748
764
765
PART 1: INTRODUCTION
14
15
16
16
16
17
18
18
19
20
21
21
21
22
24
26
26
26
27
27
27
27
28
Downloadable Content **
Download and share
eBooks
OOP Principles
The refactoring process
Design Patterns
presentations
30
31
31
31
31
32
32
33
34
35
39
48
55
66
67
67
68
69
Introduction to OOP
Learning curve
70
71
Peter Kaptein
Productivity curves
Why do we use it?
What is it?
72
76
78
OOP principles
A visual summary
Classes and objects
Strong Typing
Scoping methods and variables: static, local, private, protected, public, and final
Extraction, Encapsulation and Abstraction
Base classes
Specialization
Interfaces
Using Composition
Overloading and overriding Methods
79
80
83
85
87
91
95
96
106
111
114
115
116
Basics
What is it?
To refactor or not at all?
When will you Refactor?
When will you not Refactor?
Why is Refactoring beneficial?
Why is it relevant?
Why will Refactoring become one of your most valued assets?
Refactoring and Design Patterns
117
118
120
124
124
125
125
126
127
129
130
134
135
Elements of Refactoring **
Three main types of refactoring
Maintaining a stable project structure
Creating an Design Pattern agnostic Code Base
Promoting and Demoting your code
Using MVC and separation of responsibilities
Constants and remarks
136
137
155
155
156
159
172
176
177
178
179
181
182
187
189
191
191
192
194
194
195
196
197
Basics
Macro and Macro Patterns
Design Principles
Design Principles and Macro Patterns
Overview of Macro-Patterns and Design Principles
198
199
199
199
199
201
202
203
207
215
221
237
3-Tier
Diagrams
240
241
244
245
245
247
250
255
260
267
269
273
276
277
278
284
Inversion of Control
Diagrams
Basic definition
See also
Benefits of Dependency Injection
Inversion of Control and Design Patterns
Bonus material
290
291
293
293
293
294
298
Peter Kaptein
300
301
302
303
303
303
304
306
309
328
342
356
379
384
399
406
407
409
410
412
413
415
417
420
427
Adapter
Intent (GoF)
Adapter basics
Diagrams
Comparisons and differences
Summary
See also
Aspects from Design Patterns
428
429
429
430
437
440
441
442
Bridge
Intent (GoF)
Bridge basics
Diagrams
When do you use Bridge?
Comparisons and differences
Summary
See also
Bonus material
Aspects from Design Patterns
443
444
444
446
454
455
458
459
460
467
Builder
Intent (GoF)
Builder basics
Diagrams
Summary
See also
Comparisons and differences
Bonus Material
Aspects from Design Patterns
468
469
469
471
477
478
479
482
488
Chain of Responsibility *
Command
Intent (GoF)
Command basics
Diagrams
When do you use the Command Pattern
Comparisons and differences
Summary
See also
489
490
491
491
493
498
499
500
500
Composite **
Intent (GoF)
Diagrams
Comparisons and differences
Summary
See also
Aspects from Design Patterns
502
503
504
508
509
509
511
512
513
514
514
515
524
525
528
529
529
530
Delegate
Intent
Delegate basics
Diagrams
When do you use the Delegate Pattern?
Comparisons and differences
Summary
See also
Bonus material
532
533
533
534
543
544
546
547
548
Faade
Intent (GoF)
Faade basics
550
551
551
10
Peter Kaptein
Diagrams
Simple diagram of the Faade
When do you use the Faade?
Comparisons and differences
Summary
See also
Aspects from Design Patterns
553
555
561
561
564
565
566
Factory Method
Intent(GoF)
Factory Method basics
Diagrams
Why would you use the Factory Method?
Comparisons and differences
Summary
See also
Aspects from Design Patterns
567
568
568
569
575
575
577
578
578
Factory, Abstract
Intent (GoF)
Abstract Factory basics
Diagrams
Why would you use an Abstract Factory?
Comparisons and differences
Summary
See also
Bonus material
579
580
580
582
590
590
592
593
594
Factory, Simple
Intent
Simple Factory basics
Diagrams
Why would you use the Simple Factory?
Comparisons and differences
Summary
See also
Bonus material
597
598
598
600
605
606
608
608
609
Flyweight *
Injector *
Interpreter **
Intent (GoF)
Diagrams
Comparisons and differences
Summary
See also
Aspects from Design Patterns
610
611
612
613
614
617
618
618
619
Manager
Intent
Manager basics
Diagrams
When do you use the Manager?
620
621
621
623
630
11
630
632
633
634
Mediator
Intent (GoF)
Mediator basics
Diagrams
When do you use the Mediator?
Comparisons and differences
Summary
See also
Aspects from Design Patterns
635
636
636
638
645
646
648
649
650
Multiton *
Object Map **
Intent
The basis of the Object Map
Diagrams
Comparisons and differences
Summary
See also
651
652
653
653
654
656
659
659
Object Pool *
Observer
Intent (GoF)
The basis of the Observer Pattern
Diagrams
When do you use the Observer Pattern?
Comparisons and differences
Summary
See also
660
661
662
662
663
675
676
679
681
Parser
Intent
Parser basics
Diagrams
When do you use the Parser?
Comparisons and differences
Bonus material
Summary
See also
682
683
683
684
693
694
696
705
706
Prototype *
Proxy
Intent (GoF)
Proxy basics
Diagrams
When do you use which Proxy?
Comparisons and differences
Bonus material
Summary
707
708
709
709
711
717
718
720
725
12
Peter Kaptein
See also
Aspects from Design Patterns
726
727
Reflection *
Singleton *
State
Intent (GoF)
State basics
Diagrams
When would you use State Pattern?
Comparisons and differences
Bonus material
Summary
See also
Aspects from Design Patterns
729
730
731
732
732
733
740
741
743
744
745
747
Strategy
Intent (GoF)
Strategy basics
Diagrams
When would you use the Strategy Pattern?
Comparisons and differences
Summary
See also
Aspects from Design Patterns
748
749
749
750
757
758
760
761
762
Template Method *
Visitor
Intent (GoF)
Visitor basics
Diagrams
When do you use the Visitor?
Comparisons and differences
Summary
See also
Aspects from Design Patterns
764
765
766
766
768
777
778
780
781
782
13
PART 1: INTRODUCTION
::Tag:Part1
14
Peter Kaptein
15
16
Peter Kaptein
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
17
Peter Kaptein
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
19
20
Peter Kaptein
21
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.
22
Peter Kaptein
1: implements / extends
2: is of type
Concrete Component A
Override / implement:
+ someMethod()
+ anotherMethod()
Base Decorator A
- component
+ setComponent(
component )
Override / implement:
+ someMethod()
+ anotherMethod()
component.someMethod()
3: extends
Concrete Decorator A
Concrete Decorator B
Concrete Decorator C
- yourAddedMethodA()
- yourAddedMethodB()
Override:
+ anotherMethod()
- yourAddedMethodC()
- yourAddedMethodD()
Override:
+ someMethod()
+ anotherMethod()
Your Class
1: can be
wrapped by
variables
procedures
+ yourMethodA():
do something
+ yourMethodB()
do something else
2: can be
wrapped by
Decorator A
+ yourMethodA: extended
add extra functionalities
execute:
yourClass.yourMethodA()
+ yourMethodB: extended
do something extra
execute:
yourClass.yourMethodA()
Decorator B
+ yourMethodA(): extended
+ yourMethodB(): extended
::Link: PAT-DEC
23
24
Peter Kaptein
25
26
Peter Kaptein
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.
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
27
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
28
Peter Kaptein
29
DOWNLOADABLE CONTENT **
::Tag:DWNLD
::includesubchapters
30
Peter Kaptein
EBOOKS
::Tag:DWNLD-EBKS
OOP PRINCIPLES
::Tag:DWNLD-OOP
REFACTORING SUMMARY
::Tag:DWNLD-REF-001
English version
31
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
32
Peter Kaptein
33
34
Peter Kaptein
35
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.
36
Peter Kaptein
37
38
Peter Kaptein
Intention
Discovery
Scoping,
Budget
Approval
Design
Realization
Test /
Debug
Acceptation
Release
39
40
Peter Kaptein
Design
Build
Test
Release
Design
Build
Refactor
Test
Fix
Deliver
41
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 redesigning 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.
Design
Build
Refactor
Test
Fix
Deliver
Build,
Test
Revise,
Rename,
Repair,
Test
Test,
Register
bugs
Revise,
Repair,
Test
Working
proof of
concept
Improved
POC
Bug list,
issue list
Release
version
Paper
prototype
42
Peter Kaptein
1
Design
Build
Test /
Debug
Refactor
Fix
Refactor
Release
2
Test
43
Define
Focus
Design
Make it
work
Make it
better
Make it
awesome
Release
44
Peter Kaptein
Define
Focus
Design
Make it
work
Make it
better
Make it
awesome
Release
Build,
Test,
Revise,
Deliver
Build,
Test,
Revise,
Deliver
Build,
Test,
Revise,
Deliver
Working
proof of
concept
Betaversion
Release
version
Basic
requirements
Paper
prototype
45
Proto
type
Test / Fix
Refactor
Review
Release
46
Peter Kaptein
Proto
type
Test / Fix
Refactor
Review
Release
Build,
Test
Revise,
Repair,
Test
Revise,
Rename,
Repair,
Test
Show/
demo to
others/
client
Working
proof of
concept
Improved
POC
Clean POC
Go / no go
47
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.
48
Peter Kaptein
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.
49
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.
50
Peter Kaptein
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.
51
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.
52
Peter Kaptein
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
53
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.
54
Peter Kaptein
55
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.
56
Peter Kaptein
PHASE 1: INTENTION
::Tag:SCOPE-PH-001
Intention
Discovery
Scoping,
Budget
Approval
Design
Realization
Test /
Debug
Acceptation
Release
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.
57
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
Intention
Discovery
Scoping,
Budget
Approval
Design
Realization
Test /
Debug
Acceptation
Release
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
58
Peter Kaptein
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.
WATERFALL METHOD
Coding not started yet
In Waterfall Method, you as a coder very likely do not know this project even exists.
Intention
Discovery
Scoping,
Budget
Approval
Design
Realization
Test /
Debug
Acceptation
Release
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
59
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.
60
Peter Kaptein
Intention
Discovery
Scoping,
Budget
Approval
Design
Realization
Test /
Debug
Acceptation
Release
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.
61
Intention
Discovery
Scoping,
Budget
Approval
Design
Realization
Test /
Debug
Acceptation
Release
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 -
62
Peter Kaptein
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.
63
PHASE 6: REALIZATION **
::Tag:SCOPE-PH-006
Intention
Discovery
Scoping,
Budget
Approval
Design
Realization
Test /
Debug
Acceptation
Release
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
64
Peter Kaptein
Once the code and the application are to everyones 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.
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.
65
66
Peter Kaptein
67
3: Leaner
To do more stuff with less code. By Extracting and Encapsulating things otherwise done right at
that place.
68
Peter Kaptein
PART 3: BASICS OF
OBJECT ORIENTED
PROGRAMMING
::Tag:Part3
69
INTRODUCTION TO OOP
::Tag:OOP
::includesubchapters
70
Peter Kaptein
LEARNING CURVE
::Tag:OOP-LCRV
Hard to understand
Difficulty in understanding
Procedural programming
learning curve
Progress of time
71
PRODUCTIVITY CURVES
::Tag:OOP-PRDC
PROCEDURAL PROGRAMMING
::Tag:OOP-PRDC-PRC
Speed of progress
72
Peter Kaptein
Speed of progress
73
methods are and return objects of a very specific type), Extending classes, using Interfaces and using
Abstract Classes.
::Tag:OOP-PRDC-OOP
Speed of progress
Time spent on complexity
74
Peter Kaptein
75
76
Peter Kaptein
77
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
78
Peter Kaptein
OOP PRINCIPLES
::Tag:OOP-PRNC
79
A VISUAL SUMMARY
::Tag:OOP-PRNC-VSM
base classes
abstract classes
interfaces
D: can extend
or implement
Abstract Class A
Base Class B
other classes
and objects
Interface C
Class A
Class B
2: can contain
1: can extend or implement reference to object
from
Your Class
Class C
separate
actions and processes
- someObject
+ doSomething():
do process A.1
do process B
do process A.2
do process C
do process A.3
+ doSomethingElse()
+ doProcessA( object )
5: can be used to create
An Object
3: can be
extracted as
do process A.1
do process A.2
do process A.3
B: be placed into /
encapsulated by /
can refer to
do process B
do process C
4: can be encapsulated
into methods into
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
80
Peter Kaptein
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.
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
81
D: EXTENDING / IMPLEMENTING
::Tag:OOP-PRNC-VSM-00D
82
Peter Kaptein
83
6: Your code
The actual code within your methods
84
Peter Kaptein
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
85
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.
86
Peter Kaptein
STATIC VARIABLES
::Tag:OOP-PRNC-SCOP-002
Accessing them via the Class
Lets 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.
87
88
Peter Kaptein
89
90
Peter Kaptein
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.
91
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.
92
Peter Kaptein
Your Method
Methods: Encapsulated
Process 1
extract
Part 1 of Process 1
Part 1 of Process 1
Part 1 of Process 2
Part 2 of Process 1
Part 3 of Process 1
Part 2 of Process 2
Part 2 of Process 1
Part 3 of Process 1
abstraction1
Methods: Encapsulated
Process 2
Your Method
Part 1 of Process 2
Part 2 of Process 2
Methods: Encapsulated
Process 1
use
Part 3 of Process 1
Part 2 of Process 1
abstraction2
Your Method
Extraction, Encapsulation,
Abstraction
Part 1 of Process 2
Part 2 of Process 2
Methods: Encapsulated
Process 1
extract
Call Process 1
Part 1 of Process 1
Call Part 1 of Process 2
Part 2 of Process 1
Call Part 2 of Process 2
use
Part 3 of Process 1
Methods: Encapsulated
Process 2
Part 1 of Process 2
Part 2 of Process 2
93
94
Peter Kaptein
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
95
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
1: specializes into
ClassB
ClassC
ClassD
2: specializes into
ClassE
ClassF
BRIEF
Class A
1: Specializes into Class B, C and D
Class D
2: Specialized further into Class E and F
Peter Kaptein
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.
ClassA
1: inherit from
ClassB
ClassC
ClassD
2: inherit from
ClassE
ClassF
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
97
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
98
Peter Kaptein
POLYMORPHISM
::Tag:OOP-PRNC-SPC-004
From Wikipedia:
Subtype polymorphism, almost universally called just polymorphism in the context of objectoriented 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.
ClassA
1: creating multiple forms of / specializing into / extended by
ClassB
ClassC
ClassD
ClassE
ClassF
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.
99
100
Peter Kaptein
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.
ClassA
1: extend
ClassB
ClassC
ClassD
2: extend
ClassE
ClassF
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
101
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.
102
Peter Kaptein
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
103
104
Peter Kaptein
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.
105
INTERFACES
::Tag:OOP-PRNC-INTF
BASIS
::Tag:OOP-PRNC-INTF-001
1.a: exposes
ClassA
InterfaceA
Methods
1.b: is implemented by
2: must be implemented by
ClassB
ClassC
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
106
Peter Kaptein
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
InterfaceA
1: is implemented by
ClassA
ClassB
ClassC
Part of the
family now
107
InterfaceA
1.b: is implemented by
ClassA
ClassB
ClassC
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:
108
Peter Kaptein
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.
1.a: has
Your Class
3.a: implements
Concrete Product
2: is of type
InterfaceA
1.b: uses
ClassA
4.a: produces/
returns
Factory B
5: implements
ClassB
ClassC
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
109
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.
110
Peter Kaptein
USING COMPOSITION
::Tag:OOP-PRNC-CMP
BASIS
::Tag:OOP-PRNC-CMP-001
1.a: has
Variable A, B, C
Your Class
2: contain
1.b: uses functionalities
encapsulated in
ObjectA
3.a: is of
ClassA
3.b: is of
ObjectB
ClassB
3.c: is of
ObjectC
ClassC
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
111
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.
112
Peter Kaptein
BaseClass
extends
SubClass1
HelperClass1
Composition
When you use Composition, you
basically access the possibilities and
smartness of other Classes to reduce the
required code in your (Extended) Class.
uses
extends
SubClass2
HelperClass2
uses
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.
113
114
Peter Kaptein
PART 4: SOFTWARE
ARCHITECTURE
::Tag:PART4
This chapter needs to be written.
115
PART 5: REFACTORING
::Tag:PART5
116
Peter Kaptein
BASICS
::Tag:RFCT-BAS
::includesubchapters
117
WHAT IS IT?
::Tag:RFCT-BAS-WHT
REFACTORING
::Tag:RFCT-BAS-WHT-002
B
4
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.
118
Peter Kaptein
119
Productivity line
In d
r zo
e
g
n
Productivity
In d
a
ork
w
e
ctiv
E ffe
ne
nge
r zo
ne
E ffe
ctiv
ew
ork
Time
120
Peter Kaptein
Danger zone
Productivity
Refactoring
No refactoring
Time
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.
121
Refactorings
Danger zone
Productivity
Effective
work
Time
122
Peter Kaptein
COMPARISON
::Tag:RFCT-BAS-WHT-VSM-004
Danger zone
Productivity
No refactoring
Time
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.
123
124
Peter Kaptein
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 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.
125
126
Peter Kaptein
127
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.
128
Peter Kaptein
129
A VISUAL SUMMARY
::Tag:RFCT-BAS-WHT-VSM-STPS
Refactoring
MoSCoW /
Priorization
SandBoxing /
Deadline
Backup current
130
Shitlist
Refactor
1: What is wrong?
2: What can be improved?
1: Define MoSCoW:
a: Must-, Should-, Could- , Would have
2: 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 wins
4: 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?
Peter Kaptein
131
Peter Kaptein
133
134
Peter Kaptein
135
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?
136
Peter Kaptein
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
137
Improvement of
project structure
file structure /
class packages
Clarification
and reduction of
dependencies
Class B
Class C
Class C
# of layers
increased /
decreased
base classes
abstract classes
interfaces
organization
of classes and
files
Class A
Class A
interaction
between
elements
Class A
Class C
Abstract Class A
Class B
Base Class B
code
extracted and
promoted to
Interface C
classes
and objects
Class C
Class A
organized
structure put
back into
Class B
Class C
cleaner
code put
back into
A
B
clarificarion
of 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 )
code
extracted and
abstracted
do process A.1
do process A.2
do process A.3
To Methods
Cleaner code
Refactoring
of processes
::Link:RFCT-ELM-PROC|RFCT-ELM-STRU|DWNLD-REF
138
Peter Kaptein
do process B
do process C
To Classes
extraction
and abstraction of
code
clarification of
processes
extracted
actions and processes
Promotion of
code (to separate
methods)
Promotion of
code (to
classes)
139
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.
140
Peter Kaptein
141
142
Peter Kaptein
1: CLARIFICATION OF PROCESSES
::Tag:RFCT-ELM-REST-001
From messy
To clear
143
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
extracted
actions and processes
code
extracted and
abstracted
do process A.1
do process A.2
do process A.3
do process B
do process C
To Methods
144
Peter Kaptein
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
145
code
extracted and
abstracted
extracted
actions and processes
do process A.1
do process A.2
do process A.3
do process B
do process C
To Classes
146
Peter Kaptein
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
147
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.
148
Peter Kaptein
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
149
150
Peter Kaptein
An example: counting and reducing the steps from request (A) to concrete execution (B)
Refactoring and Design Patterns
151
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 )
code
extracted and
abstracted
do process A.1
do process A.2
do process A.3
Your Class
do process B
Class A
do process C
To Methods
To Classes
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
152
Peter Kaptein
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 C
Class B
Class C
Class A
Class B
Class C
153
154
Peter Kaptein
155
Manager
Operator
Hub
ViewModel Object
Promotion
Handler
Parser
Utility
Demotion
Code from
Your Object
Value Object
Data Object
Data Transfer
Object
Specialization
::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
156
Peter Kaptein
157
A promotion means that the code moves one or more steps up the ladder. So code inside your object
that is more than lets say 10 lines, does smart stuff or handles specific things and shows ambitions
to grow even more, will become a Handler or Manager.
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
158
Peter Kaptein
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
159
To be finished
160
Peter Kaptein
A VISUAL SUMMARY
::Tag:RFCT-ELM-SRSP-DIA
Model
MVC
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
161
Controller
Extended MVC
1: Presentation
View
Operator
Simulations,
Actors,
Rules,
Behaviors
Services
3: Data
Data Objects
Layers
Model
2: Business
Handlers,
Managers,
Utilities,
Parsers
::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.
162
Peter Kaptein
163
Manager
Operator
Hub
Promotion
ViewModel Object
Handler
Parser
Utility
Demotion
Code from
Your Object
Value Object
Data Object
Data Transfer
Object
Specialization
::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
164
Peter Kaptein
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.
Model
Business Rules
Services
1.a: apply
Data Services
Data Structures
Populator
2.a: apply
2.c: can
be
1.b: use
Managers
Handlers
2.b: use
5: is derived
from / parsed
into
Parser
Data Transfer
Handler
Data Objects
3: can be
Utility
Data Transfer
Objects
Operators
6.b: can
be
Hub
ViewModel
Object
::Link:EMVC-SR-OVV-MOD
165
Model
Business Rules
Services
1.a: apply
Data Services
Data
Structures
Populator
2.a: apply
2.c: can
be
1.b: use
Managers
Handlers
2.b: use
5: is derived
from / parsed
into
Parser
Data Transfer
Handler
Data Objects
3: can be
Utility
Data Transfer
Objects
Operators
6.b: can
be
Hub
ViewModel
Object
::Link:EMVC-SR-OVV-SER
Additional text to be written
166
Peter Kaptein
View
1.b: can
contain
Panel / Page /
Dialog / Popup
Container
2.c: can
be
List
Controller
1.c: can
contain / is a
Controller
View
Component
2.b: can
contain / is a
Tab sheet
3: can be addressed by
3: uses
Event
Dispatcher
Container
4: can be
observed by
View Code
7: work with
Operators
5.b: using
Injectors
State
Managers
6: working
with
View(Data)
Managers
ViewModel
5.b: can
be
Hub
ViewModel
Object
::Link:EMVC-SR-OVV-VW
Additional text to be written
167
Peter Kaptein
The Manager is responsible for Managing Processes and Actions. The Manager has some overlap with
the faade 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
169
170
Peter Kaptein
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
171
172
Peter Kaptein
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
173
}
// 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
174
Peter Kaptein
175
BOOK 2: DESIGN
PATTERNS
176
Peter Kaptein
PART 6: INTRODUCTION
TO DESIGN PATTERNS
AND DESIGN PRINCIPLES
::Tag:Part6
177
178
Peter Kaptein
179
Peter Kaptein
exclusive a thing. A Recurring Pattern is a Recurring Pattern and when normalized and re-usable, it
becomes a Design Pattern.
181
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
182
Peter Kaptein
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.
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.
183
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
184
Peter Kaptein
185
4: STRUCTURE
::Tag:INTRDP-MNEL-FLX-STRU
To be written
186
Peter Kaptein
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
187
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.
188
Peter Kaptein
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.
189
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
190
Peter Kaptein
191
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).
192
Peter Kaptein
193
194
Peter Kaptein
195
ANTI-PATTERNS
::Tag:INTRDP-ANTI
::includesubchapters
To be written, will contain a summary of anti-patterns as defined in the industry.
196
Peter Kaptein
197
BASICS
::Tag:INTRDP-MCRDP-BAS
::includesubchapters
198
Peter Kaptein
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.
199
200
Peter Kaptein
201
202
Peter Kaptein
DIAGRAMS
::Tag: MVC-PATT-001
Model
MVC
SmallTalk
View
Controller
2.b: notifies
1.b: triggers
1.a: uses
Actor
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
203
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.
204
Peter Kaptein
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.
205
[]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?).
206
Peter Kaptein
MODEL AS HUB
::Tag: MVC-PATT-HUB
Model
MVC
model as hub
1: pushes data to /
retrieves data from
3: notifies
View
Controller
2: notifies
Dependencies:
1. Model Pushes data to the View, retrieves data from View
2. View Notifies Controller
3. Controller Notifies Model
207
ViewModel
3: notifies
View
Controller
2: notifies
208
Peter Kaptein
CONTROLLER AS HUB
::Tag: MVC-PATT-CHUB
Model
MVC
controller as
hub
Controller
1.b: pushes
data to / gets
data from
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
209
Model
MVP
presenter as
hub
Model
2: pushes data to /
retrieves data from
Presenter
MVVM
viewmodel as
hub
2: pushes data to /
retrieves data from
ViewModel
1: passes data to /
receives data from
1: passes data to /
receives data from
View
View
210
Peter Kaptein
View A
Presenter /
ViewModel
Model
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.
211
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.
view
View A
Interpreter A
View B
Interpreter B
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 forand 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.
212
Peter Kaptein
VIEW AS HUB
::Tag: MVC-PATT-VHUB
VIEW AS A HUB
::Tag: MVC-PATT-VHUB-001
Model
MVC
model as hub
View
3: notifies /
pushes data to
1.b: notifies /
pushes data
to
Controller
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.
213
HTML
::Tag: MVC-PATT-VHUB-002
Model
MVC
model as hub
1: generates / pushes
data into
3: sends data to
View
Controller
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
214
Peter Kaptein
BASICS
::Tag: MVC-3TIER-BAS
Presentation Layer
contains
contains
Business rules
Data management
Data manipulation
contains
communicates with
Business Layer
communicates with
Data Layer
215
sends updates to
View
Controller
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
216
Peter Kaptein
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.
ViewModel
View
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)
217
uses
View
uses
uses
ViewModel
Model
Services
sends updates to
View
Services
Controller
notifies
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
218
Peter Kaptein
uses
View Model
uses
Application Model
sends updates to
View
Services
Controller
notifies
Part of
Business Layer
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.
219
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-PATTMVHI
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
220
Peter Kaptein
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.
221
Model
MVC
SmallTalk
View
Controller
2.b: notifies
1.b: triggers
1.a: uses
Actor
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.
222
Peter Kaptein
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
223
[]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.
224
Peter Kaptein
[]. 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.
225
Model
MVC
split up
3.b: notifies
View Logic
Controller Logic
2: triggers
View Presenter
Interface
view
controller
1.b: uses/triggers
1.a: percieves/uses
Actor
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
226
Peter Kaptein
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.
227
Model
MVC
re-arranged
3.b: notifies
View Logic
Controller Logic
View Renderer
Interface
1.a: percieves/uses
Actor
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
228
Peter Kaptein
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:
OReilly, 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?
229
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.
Model
Hub
2: triggers /
sends input to
View Renderer
Interface
1.a: percieves/uses
1.b: uses/triggers/
sends input to
Actor
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
230
Peter Kaptein
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.
231
Model
MVHI
MVC refactored
Controller Logic
set data on model
application behavior
3.c: uses
View Logic
get data from model
parse/massage data
push data to View
Hub
2: triggers /
sends input to
View Renderer
Interface
1.a: percieves/uses
1.b: uses/triggers/
sends input to
Actor
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
232
Peter Kaptein
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.
233
Model
4: gets / sets data
3.a: sends data to /
retrieves data from
Data Setter /
Data Getter
6: Defines which
Response should
follow from what user
Action
Application
Behavior
2: triggers /
sends input to
Data Pusher
View Renderer
Interface
1.a: percieves/uses
1.b: uses/triggers/
sends input to
Data Parser
3.c: uses
Hub
Actor
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
234
Peter Kaptein
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
235
RESULT
::Tag: MVC-PATT-MVHI-E006a
236
Peter Kaptein
237
238
Peter Kaptein
239
3-TIER
::Tag:INTRDP-MCRDP-3TR
::includesubchapters
240
Peter Kaptein
DIAGRAMS
::Tag:INTRDP-MCRDP-3TRD
Business Layer
Data Layer
Presentation Layer
Presentation Layer
Business Layer
Business Layer
Data Layer
Data Layer
241
Client
Server
Presentation Layer
Presentation Layer
Business Layer
Business Layer
Data Layer
pull
Data Layer
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.
Client
Server
Presentation Layer
Presentation Layer
Business Layer
Business Layer
Data Layer
push
Data Layer
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.
242
Peter Kaptein
243
244
Peter Kaptein
ORIGINS
::Tag:MHOPUDO-ORIG
This Design Principle emerged out of my own work and based on organizational principles.
DIAGRAMS
::Tag:MHOPUDO-DIA
Your Model
Manager
can access
can access
can access
Operator
Handler
can access
Parser
can access
Value Object
Data Objects
Data Transfer
Object
245
Controller
Extended MVC
1: Presentation
View
Operator
Simulations,
Actors,
Rules,
Behaviors
Services
3: Data
Data Objects
Layers
Model
2: Business
Handlers,
Managers,
Utilities,
Parsers
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 3Tier, this makes them part of the Data Layer.
246
Peter Kaptein
247
Manager
Operator
Hub
ViewModel Object
Promotion
Handler
Parser
Utility
Demotion
Code from
Your Object
Value Object
Data Object
Data Transfer
Object
Specialization
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
248
Peter Kaptein
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:
249
DIAGRAMS
::Tag:MHOPUDO-MGR-DIA
Business Rules
1.a: applies
Data Services
Populator
2.a: apply
2.c: can
be
1.b: uses
Manager
Handlers
2.b: use
Value Objects
1.e: can work with
Other Manager
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)
250
Parser
Peter Kaptein
Data Transfer
Handler
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)
251
Peter Kaptein
253
254
Peter Kaptein
DIAGRAMS
::Tag:MHOPUDO-HNDLR-DIA
Business Rules
1.a: applies
Data Services
Populator
2.a: apply
2.c: can
be
1.b: uses
Manager
Handlers
Parser
2.b: use
Value Objects
Data Transfer
Handler
Other Manager
255
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.
256
Peter Kaptein
257
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
258
Peter Kaptein
259
DIAGRAMS
::Tag:MHOPUDO-OPR-DIA
1: uses
2.a: addresses
Operator A
Subsystem B
3: can address
2.b: uses /
delegates to
Subsystem C
260
Peter Kaptein
Model
Business Rules
Services
1.a: apply
Data Services
2: apply
1.b: use
Managers
Handlers
3: granting access to
Operators
261
Data Handler
View Logic
The View
View Components
Connects to
Connector to View
Operator Model
Operator Logic
Connects to
Business Layer
The Operator
Presentation Layer
View Interface
Application Model
262
Peter Kaptein
SPLITTING THE OPERATOR INTO TWO PARTS: THE OPERATOR AND OPERATOR INTERFACE
::Tag:MHOPUDO-OPR-DIA-003
Data Handler
View Logic
The View
View Components
Connector to View
Operator Model
Operator Logic
Operator Interface
Connects to
The Interface
Business Layer
Connects to
The Operator
Presentation Layer
Connects to
View Interface
Application Model
263
BASICS
::Tag:MHOPUDO-OPR-BAS
264
Peter Kaptein
RELATED PATTERNS
::Tag:MHOPUDO-OPR-SEE
Faade: a simplified, single point of access to a subsystem
The Operator most resembles the Faade 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 Faade 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.
265
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
266
Peter Kaptein
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.
267
268
Peter Kaptein
DIAGRAM
::Tag:MHOPUDO-PARS-DIA
Data Services
Populator
2.a: apply
2.c: can
be
1.b: uses
Manager
Handlers
Parser
2.b: use
Data Objects
Data Transfer
Handler
Other Manager
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.
269
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
270
Peter Kaptein
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
271
272
Peter Kaptein
DATA OBJECTS
::Tag:MHOPUDO-DO
DIAGRAMS
CONCEPTUAL DIAGRAM INCLUDING THE DATA OBJECTS
Data Services
1.b: uses
Manager
Handlers
Value Objects
3.a: can be
Data Transfer
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
273
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.
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
274
Peter Kaptein
275
276
Peter Kaptein
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.
277
1.b: updates
View
Controller
Extended MVC
3.a: updates / gets values from
2.b: notifies/
updates
Operator
3.b: updates / gets values from
4.b: can
include
4.d can use
Simulations,
Actors,
Rules,
Behaviors
Layers
Model
2: Business
4.a:
includes
Handlers,
Managers,
Parsers
1: Presentation
2.a:
updates
4.c: includes
Services
3: Data
Data Objects
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.
278
Peter Kaptein
3-TIER
::Tag:EMVC-SR-VSM-002
Presentation Layer
contains
contains
Business rules
Data management
Data manipulation
contains
communicates with
Business Layer
communicates with
Data Layer
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
279
Model
Business Rules
Services
1.a: apply
Data Services
Data
Structures
Populator
2.a: apply
2.c: can
be
1.b: use
Managers
Handlers
2.b: use
5: is derived
from / parsed
into
Parser
Data Transfer
Handler
Data Objects
3: can be
Utility
Data Transfer
Objects
Operators
6.b: can
be
Hub
ViewModel
Object
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 Faade 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
280
Peter Kaptein
View
1.b: can
contain
Panel / Page /
Dialog / Popup
Container
2.c: can
be
List
Controller
1.c: can
contain / is a
Controller
View
Component
2.b: can
contain / is a
Tab sheet
3: can be addressed by
3: uses
Event
Dispatcher
Container
4: can be
observed by
View Code
7: work with
Operators
5.b: using
Injectors
State
Managers
6: working
with
View(Data)
Managers
ViewModel
5.b: can
be
Hub
ViewModel
Object
281
Manager
Operator
Hub
Promotion
ViewModel Object
Handler
Parser
Utility
Demotion
Code from
Your Object
Value Object
Data Object
Data Transfer
Object
Specialization
NOTES:
::Link:MHOPUDO|RFCT-ELM-SRSP-PRO-MHPDO
282
Peter Kaptein
Your Model
Manager
can access
can access
can access
Operator
Handler
can access
Parser
can access
Value Object
Data Objects
Data Transfer
Object
Notes:
::Link:MHOPUDO
283
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, Faade and Mediator combined
The Operator is basically a combination of a Faade 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, Faade 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.
284
Peter Kaptein
Model
Business Rules
Services
1.a: apply
Data Services
Data Structures
Populator
2.a: apply
2.c: can
be
1.b: use
Managers
Handlers
2.b: use
5: is derived
from / parsed
into
Parser
Data Transfer
Handler
Data Objects
3: can be
Utility
Data Transfer
Objects
Operators
6.b: can
be
Hub
ViewModel
Object
285
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
286
Peter Kaptein
Model
Business Rules
Services
1.a: apply
Data Services
Data
Structures
Populator
2.a: apply
2.c: can
be
1.b: use
Managers
Handlers
2.b: use
5: is derived
from / parsed
into
Parser
Data Transfer
Handler
Data Objects
3: can be
Utility
Data Transfer
Objects
Operators
6.b: can
be
Hub
ViewModel
Object
287
View
1.b: can
contain
Panel / Page /
Dialog / Popup
Container
2.c: can
be
List
Controller
1.c: can
contain / is a
Controller
View
Component
2.b: can
contain / is a
Tab sheet
3: can be addressed by
3: uses
Event
Dispatcher
Container
4: can be
observed by
View Code
7: work with
Operators
5.b: using
Injectors
State
Managers
6: working
with
View(Data)
Managers
5.b: can
be
Hub
ViewModel
Object
ViewModel
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.
288
Peter Kaptein
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 Faade 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.
289
INVERSION OF CONTROL
::Tag:INTRDP-IOC
::includesubchapters
290
Peter Kaptein
DIAGRAMS
::Tag:INTRDP-DIA
Object A
1: creates
2: creates
Object B
Handler A
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.
291
Handler A
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
292
Peter Kaptein
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
293
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.
294
Peter Kaptein
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
FAADE
::Tag: PAT-IOC-FCD
295
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
BUILDER
::Tag: PAT-IOC-BLDR
Factory and Inversion of Control
Factory using the Object Map
296
Peter Kaptein
CONCRETE FACTORIES
CONCRETE STRATEGIES
CONCRETE IMPLEMENTORS FOR BRIDGE AND DELEGATE
CONCRETE MANAGERS
CONCRETE OPERATORS
CONCRETE MEDIATORS
297
BONUS MATERIAL
::Tag:INTRDP-IOC-BNS
Object B
Object A
1.b: creates
3: instantiates
2.a: has a reference to
Object C
Handler A
Object X
4.b: is inserted in
Map B
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
298
Peter Kaptein
Interface D
4.a: implements
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.
299
300
Peter Kaptein
PART 8:
CLASSIFICATIONS OF
DESIGN PATTERNS
301
::Tag:CLSDP
302
Peter Kaptein
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
303
Peter Kaptein
305
306
Peter Kaptein
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.
307
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.
308
Peter Kaptein
309
1: ADAPTER
::Tag:PAT-TYP-WR-ADP : Adapter as wrapper
Client
1: addresses object of type
2: adapts
Adapter A
+ desiredMethodA( ):
do something
execute someMethodA()
do something else
class
Adaptee
3: delegates actions to
+ someMethodA( ):
do something
return result
4: leading to
Wrap and adapt the interface of existing Obejcts and Classes to your needs
310
Peter Kaptein
2: DECORATOR
::Tag:PAT-TYP-WR-DEC : Decorator as wrapper
3: share the same
Main Interface / Base Class
+ yourMethodA():
+ yourMethodB()
Your Class
1: can be
wrapped by any
variables
procedures
+ yourMethodA():
do something
+ yourMethodB()
do something else
2: can be
wrapped by any
Decorator A
+ yourMethodA: extended
add extra functionalities
execute:
yourClass.yourMethodA()
+ yourMethodB: extended
do something extra
execute:
yourClass.yourMethodA()
Decorator B
+ yourMethodA(): extended
+ yourMethodB(): extended
4: leading to
Extended functionalities
311
3: DELEGATE
::Tag:PAT-TYP-DEL-DEL : Delegate as wrapper
Client
1: addresses
+ someMethodA( ):
do something
return result
Delegator A
+ delegateMethodA( ):
do something
delegate.someMethodA()
do something else
Delegate A
3: delegates actions to
Delegate B
+ someMethodA( ):
do something else
return result
312
Peter Kaptein
4: STATE
::Tag:PAT-TYP-DEL-STT :State as wrapper
3: has reference to /
can inject another
state object into
state object
Context
1: contains
- stateObject
2: is handled by current
+ request()
+ setState( stateOject )
Concrete State A
+ handleRequest()
Concrete State B
4: has knowledge
of other
+ handleRequest()
Concrete State C
+ handleRequest()
4: leading to
A self-organizing delegator that defines internally which concrete
implementation should handle the next state of the process
::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
313
5: BRIDGE
::Tag:PAT-TYP-DEL-BRI : Bridge as wrapper
Bridge
1: can change
Base Abstraction
- implementor
2: contains
+ operationA()
+ operationB(parameter)
+ setContext(contextID)
3: delegates
actions to
class / object
Concrete Implementor
+ operationA()
+ operationB(parameter)
4: can be extended to
RefinedAbstraction
+ operationC()
314
Peter Kaptein
6: PROXY
::Tag:PAT-TYP-DEL-BRI : Proxy as wrapper
Client
- proxy
1: contains
+ doSomething()
+ doSomethingElse()
3: execute
Proxy
- realSubject
+ variableA
+ variableB
2: will contain
+ methodA( )
+ methodB( )
5: will be
delegated to
4: will be passed to
Real Subject A
+ variableA
+ variableB
+ methodA( )
+ methodB( )
315
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.
316
Peter Kaptein
1: FAADE
::Tag:PAT-TYP-WRSS-FCD : Faade as wrapper
Faade
2: refer to objects within
- objectReferenceA
- objectReferenceB
- objectReferenceC
1: execute actions on
+ operationA()
+ operationB(parameter)
+ operationC()
3: delegate actions to
subsystem
Object from Class A
5: leading to
Simplification of calls to- and actions on the subsystem
317
2: MEDIATOR
::Tag:PAT-TYP-WRSS-MED :Mediator as wrapper
Client
2: have references to
1: uses
colleagues
in subsystem
Concrete Mediator
+ yourMethodA():
do something
+ yourMethodB()
do something else
3: has references to
Concrete Collegue A
4: communicate to
Concrete Collegue B
5: delegates actions to specific
5: leading to
Centralization of communication between objects in your subsystem
318
Peter Kaptein
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
Your Class
1: uses
2.a: addresses
Manager A
Subsystem B
3: can address
2.b: uses
Business Logic
319
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
320
Peter Kaptein
4: OPERATOR
::Tag:PAT-TYP-WRSS-MG : Operator as wrapper
Your Class
1: uses
2.a: addresses
Operator A
Subsystem B
3: can address
2.b: uses /
delegates to
Subsystem C
321
su
Main
role?
In
ta ter
ke pr
s a ete
ct s a
Pa ion nd
in sse
st s
ru
ct
io
ns
Notifications from
subsystem?
W
r
bs aps
ys
te
m
In
j
th ect
es s
ub itse
sy lf
st in
em
St
su ay s
bs o
y s ut
te of
m
Us
e
Ob s
se
rv
er
s
Is
c
di al
re le
ct d
ly
Relationships with
subsystem?
Facade
Manager
Mediator
is based on
Functionality
Wrapper
is a spedcialization of
Wrapper
is a specialization of
is a specialization of
Class Wrapper
Object Wrapper
is based on
Factory/StrategyWrapper
is based on
can be either
Adapter
can be either
State
Proxy
Decorator
As a principle
Can add extra
functionalities
Can change internal
Object when needed
Represents /
pretends
Can do /use late
instantiation
Extended as
Base Class
Uses / can use
injected Objects
Interpretes /
takes action
322
Peter Kaptein
Command
Delegate
is based on
Bridge
323
324
Peter Kaptein
325
326
Peter Kaptein
Mediator: simplify operations, centralize crucial actions, access a Subsystem through one object
327
DELEGATION OF ACTIONS
::Tag:PAT-TYPDEL
INTRODUCTION
::Tag:PAT-TYP-INTR
328
Peter Kaptein
1: DELEGATE PATTERN
::Tag:PAT-TYP-DEL-DEL : Delegate to delegate all actions
Client
1: addresses
+ someMethodA( ):
do something
return result
Delegator A
+ delegateMethodA( ):
do something
delegate.someMethodA()
do something else
Delegate A
3: delegates actions to
Delegate B
+ someMethodA( ):
do something else
return result
4: leading to
A cleaner way to define who executes what, how, when
329
2: ADAPTER
::Tag:PAT-TYP-DEL-ADP : Adapter as delegator
Client
1: addresses object of type
2: adapts
Adapter A
+ desiredMethodA( ):
do something
execute someMethodA()
do something else
class
Adaptee
3: delegates actions to
+ someMethodA( ):
do something
return result
4: leading to
Wrap and adapt the interface of existing Obejcts and Classes to your needs
330
Peter Kaptein
3: COMMAND
::Tag:PAT-TYP-DEL-COM : Command as delegator
1: uses
Your Object
Some Command
2.a:
implements
Command
Interface
Some Object
331
4: STATE
::Tag:PAT-TYP-DEL-STT :State as delegator
3: has reference to /
can inject another
state object into
state object
Context
1: contains
- stateObject
Concrete State A
2: is handled by current
+ request()
+ setState( stateOject )
+ handleRequest()
Concrete State B
4: has knowledge
of other
+ handleRequest()
Concrete State C
+ handleRequest()
4: leading to
A self-organizing delegator that defines internally which concrete
implementation should handle the next state of the process
332
Peter Kaptein
5: PROXY
::Tag:PAT-TYP-DEL-PRO : Proxy as delegator
Client
- proxy
1: contains
+ doSomething()
+ doSomethingElse()
3: execute
Proxy
- realSubject
+ variableA
+ variableB
2: will contain
+ methodA( )
+ methodB( )
5: will be
delegated to
4: will be passed to
Real Subject A
+ variableA
+ variableB
+ methodA( )
+ methodB( )
333
6: BRIDGE
::Tag:PAT-TYP-DEL-BRI
Bridge
1: can select any of
Base Abstraction
- implementor
+ operationA()
+ operationB(parameter)
+ setContext(contextID)
implementation
Concrete Implementor A
2: contains selected
+ operationA()
+ operationB(parameter)
3: delegates actions
to selected
Concrete Implementor B
4: can be extended to
RefinedAbstraction
+ operationC()
5: leading to
A polymorphic class that can change its behavior and concrete implementation on runtime
::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 DelegateBridge 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.
334
Peter Kaptein
1: STRATEGY
::Tag:PAT-TYP-DE-STRA
Your Class
variables
procedures
+ yourMethodA():
if A:
do Approach A
if B:
do Approach B
+ yourMethodB()
+ yourMethodA:
do Approach A
1: extract and
split conditional
code into separate
classes
2: injected into /
replacement for: code
inside yourMethodA
3: leading to
Classes and Objects that can change part of their behavior
335
336
Peter Kaptein
1: FAADE
::Tag:PAT-TYP-WRSS-FCD : Faade as wrapper
Faade
2: refer to objects within
- objectReferenceA
- objectReferenceB
- objectReferenceC
1: execute actions on
+ operationA()
+ operationB(parameter)
+ operationC()
3: delegate actions to
subsystem
Object from Class A
5: leading to
Simplification of calls to- and actions on the subsystem
337
2: MEDIATOR
::Tag:PAT-TYP-WRSS-MED :Mediator as wrapper
Client
1: uses
2: have references to
colleagues
in subsystem
Concrete Mediator
+ yourMethodA():
do something
+ yourMethodB()
do something else
3: has references to
Concrete Collegue A
4: communicate to
Concrete Collegue B
5: delegates actions to specific
5: leading to
Centralization of communication between objects in your subsystem
338
Peter Kaptein
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
Your Class
1: uses
2.a: addresses
Manager A
Subsystem B
3: can address
2.b: uses
Business Logic
339
4: OPERATOR
::Tag:PAT-TYP-WRSS-MG : Operator as wrapper
Your Class
1: uses
2.a: addresses
Operator A
Subsystem B
3: can address
2.b: uses /
delegates to
Subsystem C
340
Peter Kaptein
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
341
342
Peter Kaptein
INTRODUCTION
::Tag: PAT-CHC-INT
??
Option A
use
Your Code
Option B
Option C
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.
343
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.
344
Peter Kaptein
1: BRIDGE
::Tag:PAT-TYP-DCL1-BRI : Bridge as a dynamic class
Bridge
1: can select any of
Base Abstraction
- implementor
+ operationA()
+ operationB(parameter)
+ setContext(contextID)
2: contains selected
implementation
Concrete Implementor A
+ operationA()
+ operationB(parameter)
3: delegates actions
to selected
Concrete Implementor B
4: can be extended to
RefinedAbstraction
+ operationC()
5: leading to
A polymorphic class that can change its behavior and concrete implementation on runtime
::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.
345
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
346
Peter Kaptein
1: DELEGATE
::Tag:PAT-TYP-DCL1-DLG : Delegate as a dynamic class
Client
1: addresses
+ someMethodA( ):
do something
return result
Delegator A
+ delegateMethodA( ):
do something
delegate.someMethodA()
do something else
Delegate A
3: delegates actions to
Delegate B
+ someMethodA( ):
do something else
return result
4: leading to
A cleaner way to define who executes what, how, when
347
2: STATE
::Tag:PAT-TYP-DCL1-STT : State as a dynamic class
3: has reference to /
can inject another
state object into
state object
Context
1: contains
- stateObject
Concrete State A
2: is handled by current
+ request()
+ setState( stateOject )
+ handleRequest()
Concrete State B
4: has knowledge
of other
+ handleRequest()
Concrete State C
+ handleRequest()
4: leading to
A self-organizing delegator that defines internally which concrete
implementation should handle the next state of the process
::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
348
Peter Kaptein
3: STRATEGY
::Tag:PAT-TYP-DCL1-STR : Strategy as a dynamic class
Your Class
variables
procedures
+ yourMethodA():
if A:
do Approach A
if B:
do Approach B
+ yourMethodB()
+ yourMethodA:
do Approach A
1: extract and
split conditional
code into separate
classes
2: injected into /
replacement for: code
inside yourMethodA
3: leading to
Classes and Objects that can change part of their behavior
349
1: DECORATOR
::Tag:PAT-TYP-DCL1-DEC : Decorator as a dynamic class
3: share the same
Main Interface / Base Class
+ yourMethodA():
+ yourMethodB()
Your Class
1: can be
wrapped by any
Decorator A
+ yourMethodA: extended
add extra functionalities
execute:
yourClass.yourMethodA()
+ yourMethodB: extended
do something extra
execute:
yourClass.yourMethodA()
variables
procedures
+ yourMethodA():
do something
+ yourMethodB()
do something else
2: can be
wrapped by any
Decorator B
+ yourMethodA(): extended
+ yourMethodB(): extended
4: leading to
Extended functionalities
350
Peter Kaptein
351
Pretends to be
Context specific
Bridge
State specific
Change
State
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
352
Peter Kaptein
Object A
Object A
changes
variableB
variableB
contains
contains
changes
Object C
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
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.
353
1.a:
uses
ObjectA
ObjectA
1.b:
changes
variableB
variableB
Factory A
3: contains
1: contains
2: returns
ObjectC
ObjectC
2.b:
changes
2.a: has
reference
to
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.
354
Peter Kaptein
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
355
356
Peter Kaptein
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.
357
358
Peter Kaptein
1: are
implemented in
classes
3:Concrete
uses Creator A
+ produceProductA()
+ produceProductB()
Concrete Creator B
concrete products
2: are
implemented in
4: leading to
Re-usable definitions for factory methods to produce concrete products in several classes
359
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.
360
Peter Kaptein
2: SIMPLE FACTORY
::Tag:PAT-TYP-CRI-SF : Simple Factory as a creator of objects
base product definition
Base Product A
Simple Factory
+ produceProductA( subType )
+ produceProductB( subType )
1: will produce
producs of type
Base Product B
3: produces / return
2: are implemented as
concrete products
Concrete Product A.a
4: leading to
361
3: ABSTRACT FACTORY
::Tag:PAT-TYP-CRI-AF : Abstract Factory as a creator of objects
Context
Product A.1
1.a: has a
1.b: uses
Your Code
Factory A
2.b:
instantiates /
returns
Product B.1
1.c: or uses
2.a: implements
Pruduct C.1
Interface A
3.a: implements
Factory B
Product A.2
3.b:
instantiates /
returns
Product B.2
Pruduct C.2
362
Peter Kaptein
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
363
1: PARSER
::Tag:PAT-TYP-CRCO-PAR : Parser as a creator of complex structures
Abstract
Definition /
Object Tree
2: can be parsed to
1: parsed to
Abstract Definition
3: can be parsed to
Object Tree /
Composite Object
364
Peter Kaptein
2: BUILDER
::Tag:PAT-TYP-CRCO-BLDR : Builder as a creator of complex structures
Client
1: uses
5: returns
composite
object to
Director
+ constructA():
buildPart ..
buildPart ..
buildPart ..
getResult()
2: uses
Concrete Builder
Overrides / implements:
+ buildPartA()
+ buildPartB()
+ buildPartC()
+ getResult()
3: construct
and returns
4: is returned to
Composite Object
::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
365
3: ITERATOR
::Tag:PAT-TYP-CRCO-ITR : Iterator as a creator of complex structures
To be written
366
Peter Kaptein
4: VISITOR
::Tag:PAT-TYP-CRCO-VIS : Visitor as a reader of complex structures
Client A
1: selects a concrete visitor based on
visitors
Object Structure A
Concrete Visitor A
Concrete Visitor B
elements
Concrete Element A
4: visits / is sent through /
can perform operations on
Concrete Element B
5: can be child of
6: leading to
A dynamic solution to run through- and perform actions on an Object
Structure from the inside using different type of visitors
367
5: COMPOSITE
::Tag:PAT-TYP-CRCO-COM : Composite as a holder of complex structures
Client A
Object Structure A
1: contains
2: can contain
non-terminal nodes
terminal nodes
Non-terminal node A
Terminal node A
Non-terminal node B
Terminal node B
3: can be child of
4: can be child of
5: leading to
An object tree with nodes and children, that can be of any depth
368
Peter Kaptein
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
B
369
6: REFLECTION
::Tag:PAT-TYP-CRCO-COM : Reflection to use in complex structures
To be written
370
Peter Kaptein
BONUS MATERIAL
::Tag: PAT-DSTR-REL
Prefab objects
Factory
uses
can
produce
uses
can
produce
receives
prefab
assembly
instructions
Your classes
Prefab parts + custom assembly
Parser /
Interpreter
uses
uses
can
produce
external /
custom
assembly
instructions
371
Full freedom
Parser
Interpreter
Results
creates
Simple
Composite
composition
Builder
Full freedom,
Specific use
Dynamic Builders
Composite
Full freedom
creates
372
creates
Peter Kaptein
Dynamic wrappers
creates
Decorator
Diagram
Composite Structure
production
Builder
assembly
Factory
Any Model
Hardcoded Model
Fixed Result
Parser
uses
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.
373
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.
374
Peter Kaptein
Factory
1.a: produces
Product
2.a: produces
Product
3: produces
Result
Builder
Parser /
Interpreter
375
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
376
Peter Kaptein
YourClass
Visitor A
YourClass
1.a: instantiates
Parser B
1.a: instantiates
1.b: passes
Composite Object
Composite Object
377
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.
378
Peter Kaptein
1: SINGLETON
::Tag:PAT-TYP-SH-STN
Client
1: calls
3: contains
instance of
Singleton
4: returns
instance of
object to - static _instance
2: uses
+ static instance()
+ someMethod()
+ anotherMethod()
5: leading to
One single instance of an object that can be retrieved and used anywhere
379
2: MULTITON
::Tag:PAT-TYP-SH-MTN
1: calls, using a key to
identify the specific object
Client
3: contains
instance of
Multiton
4: returns
instance of
object to - static _instanceMap
2: uses
+ static instance( key )
+ someMethod()
+ anotherMethod()
5: leading to
One or more specific instances of an object can be retrieved and used anywhere
Peter Kaptein
3: OBJECT MAP
::Tag:PAT-TYP-SH-DMP
1: calls, using a key and
class reference to identify
the specific object
Client
objects of type
ObjectMap
5: returns
instance of
object to - static _objectMap
3: maps
Class A
Class B
2: uses
+ static getObject( key, classRef )
+ static removeObject( key, classRef )
+ static addObject( key, classRef )
Class C
6: leading to
Mapping one instance of a specific object of any type
to be retrieved and used anywhere
381
382
Peter Kaptein
4: OBJECT POOL
::Tag:PAT-TYP-SH-OPL
To be written
5: STATIC METHODS
383
1: MEDIATOR
::Tag:PAT-TYP-EVTS-MED
Client
2: have references to
1: uses
colleagues
in subsystem
Concrete Mediator
+ yourMethodA():
do something
+ yourMethodB()
do something else
3: has references to
Concrete Collegue A
4: communicate to
Concrete Collegue B
5: delegates actions to specific
5: leading to
Centralization of communication between objects in your subsystem
384
Peter Kaptein
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
Your Class
1: uses
2.a: addresses
Manager A
Subsystem B
3: can address
2.b: uses
Business Logic
385
386
Peter Kaptein
3: OPERATOR
Your Class
1: uses
2.a: addresses
Operator A
Subsystem B
3: can address
2.b: uses /
delegates to
Subsystem C
387
Some Command
2.a:
implements
Command
Interface
Some Object
388
Peter Kaptein
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
389
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
has knowledge of
Object A
390
Object B
Peter Kaptein
Object B
has knowledge of
ASYNCHRONOUS SYSTEMS
::Tag: PAT-EVTS-BAS-003
391
Object A
Object B
performAction(paremeteX, callBackC)
Process A
Process B
callBackC()
::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.
392
Peter Kaptein
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.
has knowledge of /
registers observers on / calls
Object B
dispatches event on
including
Event listeners /
Observers X, Y ,Z
393
394
Peter Kaptein
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.
USING CALLBACKS
::Tag: PAT-EVTS-BAS-005a
The basis of a Callback
395
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
calls back on
Callbacks A, B, C
passed by / living inside
Can be Methods
or Commands
396
Peter Kaptein
397
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
398
Peter Kaptein
PARSER
::Tag:PAT-TYP-INJ-PARS
::Link:PAT-PARS
INJECTOR
::Tag:PAT-TYP-INJ-INJ
REFLECTION
::Tag:PAT-TYP-INJ-REF
MULTITON
::Tag:PAT-TYPDA-T3-MTT
OBJECT POOL
::Tag:PAT-TYPDA-T3-OBP
(REMOTE) PROXY
::Tag:PAT-TYPDA-T3-PRXY
399
BONUS MATERIAL
::Tag:PAT-TYPDA-BNS
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
400
Peter Kaptein
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.
401
402
Peter Kaptein
403
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:
404
Peter Kaptein
USING DATA MAPPING TO TRANSLATE ONE OBJECT AND ONE STRUCTURE TO ANOTHER
::Tag:PAT-TYPDA-BNS-005
See also
The Factory Pattern
The Parser
405
406
Peter Kaptein
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
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
Refactoring and Design Patterns
407
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
408
Peter Kaptein
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.
RELEVANT PATTERNS
::Tag:INTRDP-CLS-RPT
To be written
409
410
Peter Kaptein
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
411
412
Peter Kaptein
THIN CLIENTS
::Tag:INTRDP-THCL
413
RELEVANT PATTERNS
::Tag:INTRDP-THCL-RPT
To be written
414
Peter Kaptein
RICH CLIENTS
::Tag:INTRDP-RCL
415
RELEVANT PATTERNS
::Tag:INTRDP-RCL-RPT
To be written
416
Peter Kaptein
DESKTOP APPLICATIONS
::Tag:INTRDP-DSKTP
RELEVANT PATTERNS
::Tag:INTRDP-DSKTP-RPT
417
418
Peter Kaptein
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
419
GAME DEVELOPMENT
::Tag:INTRDP-GMDV
420
Peter Kaptein
RELEVANT PATTERNS
::Tag:INTRDP-GMDV-RPT
421
422
Peter Kaptein
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
423
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
424
Peter Kaptein
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 InGame 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.
Faade or Mediator?
Where the ViewModel object is implemented most as a Faade 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:
425
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 Webbased 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
426
Peter Kaptein
PART 9: DESIGN
PATTERNS
::Tag: PAT
427
ADAPTER
::Tag: PAT-ADP
::includesubchapters
428
Peter Kaptein
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
1.a: wants
to address
YourClass
Class A / Object B
1.b: uses
Adapter A
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.
429
DIAGRAMS
::Tag: PAT-ADP-DIA
2: adapts
Adapter A
+ desiredMethodA( ):
do something
execute someMethodA()
do something else
class
Adaptee
3: delegates actions to
+ someMethodA( ):
do something
return result
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)
430
Peter Kaptein
Client
1: addresses object
of type
1: addresses object
of type
interface
Target A
class
Adaptee
interface
Target A
class
Adaptee
+ desiredMethodA( )
+ someMethodA( )
+ desiredMethodA( )
+ someMethodA( )
2.a: implements
2.b: extends
2.a: implements
2.b: contains
Adapter A
Adapter A
+ desiredMethodA()
someMethodA()
- adaptee
+ desiredMethodA()
adaptee.someMethodA()
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.
431
Class A / Object B
1.b: uses
Adapter A
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
432
Peter Kaptein
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.
433
variable
2: contains
AdapterA
1.b: has
3: addresses
Methods A, B, C
4: inside
Object B from
Class A
Methods D, E, F
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.
434
Peter Kaptein
Interface B /
BaseClass C
Class A
1b: implements
1.a: extends
Adapter A
Methods A, B, C
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.
435
Class A / Object B
Adapter A
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
436
Peter Kaptein
The Adapter as used here can be an alternative for a Data Transfer object: converting one standard
into another.
437
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.
438
Peter Kaptein
439
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.
440
Peter Kaptein
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 Faade, 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 Faade, 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
441
442
Peter Kaptein
BRIDGE
::Tag: PAT-BRI : D
::includesubchapters
443
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
uses:
either / principle of
extends
Your Class
Bridge
pretends to be /
delegates actions to
Factory /
ObjectMap
returns
Product / Concrete
implementation
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.
444
Peter Kaptein
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.
445
DIAGRAMS
::Tag: PAT-BRI-DIA
implementation
Concrete Implementor A
2: contains selected
+ operationA()
+ operationB(parameter)
3: delegates actions
to selected
Concrete Implementor B
4: can be extended to
RefinedAbstraction
+ operationC()
5: leading to
A polymorphic class that can change its behavior and concrete implementation on runtime
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
446
Peter Kaptein
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.
2.a: extends
1.a: contains
object of type
implementor
.operationA()
interface
Implementor
+ operationA()
+ operationB(parameter)
2.a: implements
RefinedAbstraction
+ operationC()
Concrete Implementor A
Concrete Implementor B
+ operationA()
+ operationB(parameter)
+ operationA()
+ operationB(parameter)
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.
447
Bridge
1.b: can implement
Abstraction
- implementor
+ operationA()
+ operationB(parameter)
+ setContext(contextID)
1.a: contains
object of type
implementor
.operationA()
interface
Implementor
+ operationA()
+ operationB(parameter)
3: implements
2: extends
RefinedAbstraction
+ operationC()
Concrete Implementor A
Concrete Implementor B
+ operationA()
+ operationB(parameter)
+ operationA()
+ operationB(parameter)
448
Peter Kaptein
Bridge
uses:
either / principle of
pretends to be /
delegates actions to
Factory /
ObjectMap
returns
Product / Concrete
implementation
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.
449
1.a: has a
Your Code
InterfaceA
4: implements
3.a: instantiates /
retrieves
2.a: implements
1.b: uses /
extends
Bridge A
Option A
2.c: uses
Factory A /
DataMap B
Option B
2.b: pretends to be
3.b: returns
Product X
Option C
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.
450
Peter Kaptein
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.
451
Bridge A
Variable A
1.b: contains /
calls methods
on
1.a: instantiates /
Is bridge to /
pretends to be
2.a: is of
type
2.b: is
either
InterfaceA /
BaseClassB
3:
implements
ImplementationA
ImplementationB
ImplementationC
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
452
Peter Kaptein
WHEN YOU NEED TO ADAPT THE CLASSES YOU USE IN THE BRIDGE
Variable A
1.a: is of
type
InterfaceA /
BaseClassB
2: is not
compatible with
1.b: is
either
3.a: implements
3.b: adapts
Implementation A
Adapter A
3.b: adapts
Implementation B
Adapter B
3.b: adapts
Implementation C
Adapter C
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.
453
454
Peter Kaptein
DELEGATE, STATE
::Tag: PAT-BRI-SIM-DS
455
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.
ADAPTER
::Tag: PAT-BRI-COP-ADP
Adapting the Concrete Implementation
456
Peter Kaptein
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.
457
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
458
Peter Kaptein
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
Refactoring and Design Patterns
459
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
1.b: contains /
calls methods on
1.a: uses
3.a: is of
type
Interface A /
BaseClass B
3.b: is
either
4.a:
implements
Implementation A
Factory A /
Strategy B
2: returns
5.a: implements
Adapter A
Implementation B
5.b: extends / adapts
Implementation C
Class C
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:
460
Peter Kaptein
NOTES:
461
1.b: uses /
extends
Your Class
Bridge A
2.a: uses
either
Factory Method
Strategy
2.b: pretends to be
1.a: has a
Product X /
Strategy Y
Context
3: returns
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.
462
Peter Kaptein
Bridge A
Variable A
1.b: contains /
calls methods
on
1.a: uses
3.a: is of
type
3.b: is
either
InterfaceA /
BaseClassB
4:
implements
ImplementationA
FactoryA /
StrategyB
2: returns
ImplementationB
ImplementationC
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
463
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.
464
Peter Kaptein
Context
Variable A
1.b: contains /
calls methods
on
1.d: has a
Bridge A
3.a:
is of type
3.b: contains
either
1.a: uses
Interface A /
BaseClass B
4: implements
Implementation A
Object X
2.a: uses
Singleton A /
Multiton B /
DataMap C
2.b:
returns
Implementation B
ImplementationB
Object Y
Implementation C
Object Z
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
465
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.
466
Peter Kaptein
467
BUILDER
::Tag: PAT-BLD: Discussing the Builder Pattern
::includesubchapters
468
Peter Kaptein
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
Your Code
1.a: selects
Director A
2: uses /
requires build
actions from
either
Builder A
Builder B
Builder C
3: constructs /
returns
3: constructs /
returns
3: constructs /
returns
Product
Composition X.a
Product
Composition X.b
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
469
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.
Prefab parts + prefab assembly
Builder
uses
can
produce
receives
prefab
assembly
instructions
= Your classes
470
Peter Kaptein
DIAGRAMS
::Tag: PAT-BLD-DIA
6: returns
composite
object to
1: uses
Director
+ constructA():
cb.buildPart ..
cb.buildPart ..
cb.buildPart ..
result=cb.getResult()
return result
2: uses
3: addresses
Concrete Builder
Overrides / implements:
+ buildPartA()
+ buildPartB()
+ buildPartC()
+ getResult()
4: construct
and returns
5: is returned to
Composite Object
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.
471
3.b: is of type
+ setBuilder( builder )
+ construct()
base class/interface
Base Builder A
+ buildPartA()
+ buildPartB()
+ buildPartC()
+ getResult()
3.b: produces /
builds / returns
Composite Object
2: extends / implements
Concrete Builder A
Concrete Builder B
Override / implement:
+ buildPartA()
+ buildPartB()
+ buildPartC()
+ getResult()
Override / implement:
+ buildPartA()
+ buildPartB()
+ buildPartC()
+ 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
472
Peter Kaptein
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
473
1.a: selects
Director A
2: uses /
requires build
actions from
either
Builder A
Builder B
Builder C
3: constructs /
returns
3: constructs /
returns
3: constructs /
returns
Product
Composition X.a
Product
Composition X.b
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
474
Peter Kaptein
Your Code
1: uses / injects builder into /
asks to construct product
2.a:
uses
Director A
4.a: is
injected
into
BuilderX
Variable B
2.b: has
3: are invoked on
4.b: produces
5: is returned to
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
475
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.
476
Peter Kaptein
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.
477
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
478
Peter Kaptein
479
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.
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.
COMPOSITE
::Tag: PAT-BLD-COP-COM
A result of the Building Process
The Composite is one of the possible results the Builder can produce.
480
Peter Kaptein
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.
481
BONUS MATERIAL
::Tag: PAT-BLD-BNS
Your Code
Factory A /
DataMap B
1.a: uses
Builder B
BuilderX
4.a: is of type
Variable B
5.b: has
Builder C
4.c: produces
3: implement
Product X.n
6: is returned to
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
482
Builder A
2.b: produces
4.b: is
injected
into
5.a:
uses
Director A
2.a: chooses /
instantiates
Peter Kaptein
Interface B
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:
Prefab parts + prefab assembly
Builder
uses
can
produce
receives
prefab
assembly
instructions
= Your classes
483
1: uses
2.a: selects
Your Concrete
Factory
2.b: selects
Director A
3: is used
as
Director X
Builder A
5: uses
Builder B
Director B
Builder Y
Builder C
Director C
6: creates
Product Z.1
DEPENDENCIES:
Your Code:
484
4: is used
as
Peter Kaptein
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:
485
Your Concrete
Factory A
1.a: gets/uses
Your Concrete
Factory B
Builders of type A
1.b: uses
1.a: gets/uses
Builders of type B
1: uses
2: creates
Director 1
2: creates
Product 1.A
Director 1
Product 2.A
Director 2
Product 3.A
Director 3
2: creates
Director 2
2: creates
2: creates
Director 3
Product 1.B
Product 2.B
2: creates
Product 3.B
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
486
Peter Kaptein
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.
487
Peter Kaptein
CHAIN OF RESPONSIBILITY *
::Tag: PAT-CRS
::includesubchapters
To be done
489
COMMAND
::Tag: PAT-COM
::includesubchapters
490
Peter Kaptein
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 System
2.c: is passed to
Some Command
2.a:
implements
Command
Interface
Some Object
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
491
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()
492
Peter Kaptein
DIAGRAMS
::Tag: PAT-COM-DIA
Invoker
+ command(list)
+ doSomething()
+ undoSometing()
3: has reference to /
calls methods on
Concrete Command
+ receiver
+ execute()
+ undo
2.b: extends / implements
Base Command
+ execute()
+ undo()
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.
493
2.c: is passed to
Some Command
2.a:
implements
Command
Interface
Some Object
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
494
Peter Kaptein
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.
495
Some System
1.b: passes
command to
Object A
Your Object
Some Command
4.b: executes
actions on
Some Object
4.a: implements
Command
Interface
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.
496
Peter Kaptein
Object X
3: uses
Your Object
Command A
Command B
Command C
2.a: implement
Interface B
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.
Refactoring and Design Patterns
497
498
Peter Kaptein
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.
499
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.
500
Peter Kaptein
::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
501
COMPOSITE **
::Tag: PAT-CMP
::includesubchapters
502
Peter Kaptein
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.
503
DIAGRAMS
::Tag: PAT-CMP-DIA
Object Structure A
1: contains
2: can contain
non-terminal nodes
terminal nodes
Non-terminal node A
Terminal node A
Non-terminal node B
Terminal node B
3: can be child of
4: can be child of
5: leading to
An object tree with nodes and children, that can be of any depth
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.
504
Peter Kaptein
505
Composite A
- children
Override / implement:
+ someMethod()
+ add( component )
+ remove ( component )
+ getChild( index )
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.
506
Peter Kaptein
Client
- compositeObject
1.a: is of type
base class / interface
Base Node A
- children
3: are of type
+ someMethod( )
+ add( component )
+ remove( component )
+ getChild( index )
1.b: contains either
2: extends / implements
Node Type A
Node Type B
+ yourMethod()
Override / Implement:
+ someMethod()
+ myMethod()
Override / Implement:
+ someMethod()
for each item in children:
item.someMethod()
507
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.
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.
508
Peter Kaptein
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
Refactoring and Design Patterns
509
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
510
Peter Kaptein
511
512
Peter Kaptein
DECORATOR
::Tag: PAT-DEC : Discussing the Decorator Pattern
::includesubchapters
513
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
1.a: has
Your Class
Class A / Object B
Decorator C
3: extend
2.a: offers
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.
514
Peter Kaptein
DIAGRAMS
::Tag: PAT-DEC-DIA
Your Class
1: can be
wrapped by
variables
procedures
+ yourMethodA():
do something
+ yourMethodB()
do something else
2: can be
wrapped by
Decorator A
+ yourMethodA: extended
add extra functionalities
execute:
yourClass.yourMethodA()
+ yourMethodB: extended
do something extra
execute:
yourClass.yourMethodA()
Decorator B
+ yourMethodA(): extended
+ yourMethodB(): extended
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.
515
1: implements / extends
2: is of type
Concrete Component A
Override / implement:
+ someMethod()
+ anotherMethod()
Base Decorator A
- component
+ setComponent(
component )
Override / implement:
+ someMethod()
+ anotherMethod()
component.someMethod()
3: extends
Concrete Decorator A
Concrete Decorator B
Concrete Decorator C
- yourAddedMethodA()
- yourAddedMethodB()
Override:
+ anotherMethod()
- yourAddedMethodC()
- yourAddedMethodD()
Override:
+ someMethod()
+ anotherMethod()
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.
516
Peter Kaptein
517
Class A / Object B
Decorator C
3: extend
2.a: offers
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.
518
Peter Kaptein
Base/Abstract Class A /
Interface B
3: are derived
from
Base Methods
X, Y and Z
Base Decorator D
1.b: has
4.a: extend
4.b: add
Methods A, B
and C
Decorator A
4.b: add
Methods D, E
and F
Decorator B
Methods G, H
and I
4.b: add
Decorator C
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
519
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.
520
Peter Kaptein
GOING ALL THE WAY: USING THE DECORATOR PATTERN FOR MULTIPLE CLASSES
::Tag: PAT-DEC-DIA-002
Base/Abstract Class A /
Interface B
3: extends / implements
Concrete Classes
Decorators
Your Class A
Decorator A
2.a:
extends
Base Decorator D
1.b: can be
decorated by
Your Class B
Decorator B
Your Class C
Decorator C
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.
Refactoring and Design Patterns
521
Your Object
Variable A
2.a: is of
type
4.a: are
derived from
Base/Abstract Class A /
Interface B
Decorator X
3.b: has
6: can invoke
5: contains
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
522
Peter Kaptein
Added
functionalites
Base Methods
X, Y and Z
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.
523
524
Peter Kaptein
525
FAADE, MANAGER
::Tag: PAT-DEC-SIM-FM
Similarities: wrapping functionalities, allow for injection
Like the Faade 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 Faade 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.
Faade: wraps functionality, is not designed for nesting of Faades inside Faades
The main intent of the Faade 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.
526
Peter Kaptein
527
BONUS MATERIAL
::Tag: PAT-DEC-BNS
1.b: extends /
implements
Your Class
1.a: extraction of
4: extends /
implements
Actions A, B
and C
Actions D, E
and F
Base Decorator
2.a: encapsulation into
3.b extends
Decorator A
Decorator B
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
528
Peter Kaptein
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
529
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
Peter Kaptein
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 responsibilitiesit 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.
531
DELEGATE
::Tag: PAT-DEL
::includesubchapters
532
Peter Kaptein
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
1: uses
YourClass
Delegate A
2: instantiates / contains /
wraps / uses / executes via
Class A / Object X
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.
533
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
+ someMethodA( ):
do something
return result
Delegator A
+ delegateMethodA( ):
do something
delegate.someMethodA()
do something else
Delegate A
3: delegates actions to
Delegate B
+ someMethodA( ):
do something else
return result
4: leading to
Plug & play code: a cleaner way to define who executes what, how, when
534
Peter Kaptein
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.
535
+ someMethodA( )
+ someMethodA( )
2.a: implements
3: implements
Delegator A
- delegate
+ delegateMethodA()
2.b: contains
object of type
interface
Base Delegate A
+ someMethodA( )
delegate.someMethodA()
NOTES:
536
Peter Kaptein
Delegate A
2: instantiates / contains /
wraps / uses / executes via
Class A / Object X
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.
537
Class A
2.a: has a
1: uses
YourClass
2.b: uses
Delegate A
Factory B /
Strategy C
3.a: uses
Class B
3.b: produces
Class c
Object X
4: implement / extend
Interface A /
BaseCLass B
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.
538
Peter Kaptein
539
DELEGATING ACTIONS
::Tag: PAT-DEL-DIA-003
Methods A, B, C
1.a: exposes
Delegate A
Object X
2: exposed by
Methods A, B, C
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 Faade-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 Faade. ::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.
540
Peter Kaptein
2.a: is of type
1.a: has a
Interface A /
BaseClass B
2.b: contains
1.b: has
4: inside
3: addresses
Methods A, B, C
Object B from
Class N
3: implements /
extends
Methods D, E, F
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 Faade
The Delegate has some similarities in this to the Bridge, the Command Pattern and the Faade. Each of
these Patterns, like the Delegate, use other objects to execute the requested actions.
541
542
Peter Kaptein
543
BRIDGE
::Tag: PAT-DEL-SIM-BRI
Similarities: delegation, possible use of an internal Factory or Data Map
544
Peter Kaptein
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.
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.
545
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.
546
Peter Kaptein
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
547
BONUS MATERIAL
::Tag: PAT-DEL-BNS
Delegate A
1.d: contains /
calls methods on
4: is of type
1.a: exposes
1.b: has a
Context
1.c: uses
Factory A /
Strategy B
1.f: delegates to
2.b: produces
Interface A /
BaseClass B
4.b: implements /
extends
Object X
Class A
2.a: uses
Class B
Class C
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
548
Peter Kaptein
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).
549
FAADE
::Tag: PAT-FCD
::includesubchapters
550
Peter Kaptein
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.
FAADE BASICS
::Tag: PAT-FCD-DIA-BAS
1: uses
YourClass
Faade A
Class A
Class B
Class C
ClassE
Class D
WHEN/WHAT?
::Tag: PAT-FCD-DIA-BAS-001
When you want to wrap a subsystem
The Faade 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 Faade operates by delegating all tasks to the objects in the subsystem it addresses.
Multiple Faades for multiple tasks
The Faade can be implemented many times to perform specific and completely different tasks on that
and other subsystems in your project.
551
Inversion of Control
As the Faade abstracts the access to the functionalities in the subsystem and delegates the tasks to the
objects it has and receives, you can use the Faade to implement Inversion of Control by either injecting
the objects the Faade works with from the outside, or by mapping the Concrete objects it will use onto
astract keys in an Object Map.
552
Peter Kaptein
DIAGRAMS
::Tag: PAT-FCD-DIA
1: execute actions on
+ operationA()
+ operationB(parameter)
+ operationC()
3: delegate actions to
subsystem
Object from Class A
5: leading to
Simplification of calls to- and actions on the subsystem
NOTES:
Delegating actions to the subsystem
The Faade delegates close to all actions you request from the Faade to the subsystem.
Adding actions where needed
Where needed, the Faade 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 Faade 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 Faade helps
solving this problem by wrapping all actions into the Faade class and offering a simplified interface to
your code.
To simplify the use of a subsystem
The goal of the Faade is to simplify the use of the subsystem. The Faade 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 Faade.
553
result=objectReferenceA
.operationA()
resultB=objectReferenceB.
operationY( result )
Class A
Class B
+ operationA()
+ operationX(parameter)
+ operationB()
+ operationY(parameter)
Class C
+ operationC()
subsystem
NOTES:
Delegating actions to the subsystem
The Faade delegates Actions to the Subsystem, using object references to objects within that
subsystem.
To simplify the use of that subsystem
The goal of the Faade is to simplify the use of that subsystem.
554
Peter Kaptein
Faade A
Class A
Class B
Class C
ClassE
Class D
DEPENDENCIES:
Your Class
1: Uses Facade A
Faade A
2: Wraps, adapts, addresses Subsystem A
NOTES:
Wrapping a subsystem
Unlike all the previous Patterns: Bridge, Adapter, Decorator and proxy, the Faade wraps an entire
Subsystem.
Simplification of the use of that subsystem
The main goal of the Faade 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.
555
1: has
Object X from
Class A
Object Y from
Class B
works with
Object N from
Class C
Object M from
Class E
depends on
works with
Object Z from
Class D
subsystem A
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:
Faade 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 Faade 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 Faade is requested to do, the Faade can call and
use multiple methods on multiple objects.
556
Peter Kaptein
Faade A
1.b: contains
2: uses / calls
3: exposed by
Variables X, Y, Z
Methods D, E, F, G, H
4: contain
Object X from
Class A
Object Y from
Class B
works with
Object N from
Class C
Object M from
Class E
depends on
works with
Object Z from
Class D
subsystem A
RELATIONSHIPS:
Faade 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
557
NOTES:
558
Peter Kaptein
Faade A
Faade B
3: wraps / adapts
subsystem B
subsystem A
Class A
Class B
Class C
Class D
Class E
Class F
Class G
DEPENDENCIES:
Your Class
1.a: Uses Faade A
1.b: Can use Faade B
Faade A
2: Wraps / adapts / addresses Subsystem A
Faade 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 Faade A (suing Subsystem A) and
Faade B (using Subsystem B) can be in a situation using the same Class or Classes to perform their job.
559
NOTES:
Mediator: part of the process, Faade is Top Down
Faade might seem a lot of commonalities with Mediator. The main differences are that the Faade
uses a Top Down approasch where the Faade 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 Faade 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 Faade, 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 Faade 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.
560
Peter Kaptein
ADAPTER
::Tag: PAT-FCD-SIM-ADP
Similarities: wrapping existing functionalities
Like the Adapter, the Facade wraps existing functionalities into in the case of the Faade 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 Faade wraps multiple objects and Classes
BRIDGE
::Tag: PAT-FCD-SIM-BRI
Similarities: pretending to be something else
Like the Bridge, the Faade pretends, in a way, to be something else. In the case of the Faade, that is
the actions in the subsystem it uses and simplifies.
Wraps only one object, offers choice
561
The Faade only represents one subsystem and can not dynamically change or choose which
implementation it will take, as the Faade 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 Faade addresses an entire
subsystem.
DECORATOR
::Tag: PAT-FCD-SIM-DEC
Similarities: extension by adding functionalities to an existing system
Like the Decorator, the Faade 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 Faade 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 Faade
and the Decorator is that the Faade 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 Faade, the Delegate delegates the execution of actions to a subsystem. Like the Faade, 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 Faade, 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 Faade. Where the Faade 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 Faade, 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.
562
Peter Kaptein
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 Faade, but also to the Mediator Pattern.
State: can replace itself, has knowledge of the placeholder it is in, can Inject upwards
Unlike the Faade, 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 Faade does not have this knowledge of the Placeholder that holds the Faade. Nor is the Faade
capable of replacing itself when another Faade is needed to deal with the Process as it is at that point.
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 Faade 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 Faade 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 Faade Patterns
The Manager and Operator use aspects of the Faade 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.
563
SUMMARY
::Tag: PAT-FCD-SHS
One single Interface to an entire Subsystem
The Faade 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 Faade is to simplify the use of the subsystem by wrapping specific processes on that
subsystem in Methods inside the Faade.
Faade as a Wrapper / Adapter for an entire subsystem
The Faade can be compared with an Wrapper or Adapter for an entire (sub) system
Top Down, directive alternative for the Mediator
The Faade 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 Faade can call and use multiple objects and Methods of the Subsystem.
Faade can implement additional code to provide the interface
The Faade 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 Faade.
564
Peter Kaptein
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 Faade, 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 Faade, 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 Faade can be seen as the more versatile version of the Adapter. Where the Adapter adapts only a
single Class or object, the Faade adapts an entire subsystem.
::Link: PAT-ADP
565
566
Peter Kaptein
FACTORY METHOD
::Tag: PAT-FAC: Discussing the Factory Method
::includesubchapters
567
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.
Your Code
Factory Method
4: is returned to
2: instantiates
either/or
3: produces
Class B
Class C
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.
568
Peter Kaptein
DIAGRAMS
::Tag: PAT-FAC-DIA
1: are
implemented in
classes
3:Concrete
uses Creator A
+ produceProductA()
+ produceProductB()
Concrete Creator B
2: will produce
producs of type
base product definitions
4: produces / return
Base Product B
Base Product A
concrete products
3: are extended /
implemented by
5: leading to
Re-usable definitions for factory methods to produce concrete products in several classes
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
569
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.
570
Peter Kaptein
+ someMethod()
+ anotherMethod()
+ produceProductA()
+ produceProductB()
1.b: implements
2.a: produces
Concrete Creator B
+ doSomething()
Override:
+ produceProductA()
+ produceProductB()
2.a: produces
+ doSomethingElse()
Override:
+ produceProductA()
+ produceProductB()
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
571
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()
1: implements / extends
Concrete Creator A
+ someMethod()
+ anotherMethod()
2.a: produces
either
+ someMethod()
+ anotherMethod()
+ yourMethodA()
+ yourMethodB()
Override:
+ produceProductA(
productType )
case productTypeA:
return new
Concrete Product A
572
Peter Kaptein
SIMPLE DIAGRAM
::Tag: PAT-FAC-DIA-001
Context
Class A
1.a: has a
Your Code
Factory Method
4: is returned to
2: instantiates
either/or
3: produces
Class B
Class C
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.
573
Abstract
Method A
2.a: extends
3.a: overrides
2.b: implements
Your Class
Concrete
Method A
3.b: is of type
3.c: instantiates /
Returns object
from either
Interface A /
Abstract Class B
4: implements
Class A
Class B
Class C
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.
574
Peter Kaptein
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
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.
575
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.
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).
576
Peter Kaptein
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.
577
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
578
Peter Kaptein
FACTORY, ABSTRACT
::Tag: PAT-AFC : Discussing the Abstract Factory Pattern
::includesubchapters
579
INTENT (GOF)
::Tag: PAT-AFC-INT
Provide an interface for creating families of related or dependent objects without specifying their
concrete classes.
Factory A
2.b:
instantiates /
returns
Product B.1
1.c: or uses
2.a: implements
Pruduct C.1
Interface A
3.a: implements
Factory B
Product A.2
3.b:
instantiates /
returns
Product B.2
Pruduct C.2
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
580
Peter Kaptein
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.
581
DIAGRAMS
::Tag: PAT-AFC-DIA
Client A
2: uses any of
abstract definitions
Abstract Factory Definition
A: are
implemented in
classes
3:Concrete
uses Factory A
+ produceProductA()
+ produceProductB()
Concrete Factory B
B: will produce
producs of type
base product definitions
D: produces / return
Base Product B
Base Product A
concrete products
C: are extended /
implemented by
3: leading to
Blueprints for interchangeable factories with very specific production lines
producing specific products
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.
582
Peter Kaptein
Client A
base class
Abstract Factory A
+ someMethod()
+ anotherMethod()
+ produceProductA()
+ produceProductB()
3: extends / implements
Concrete Product A.a
+ someMethod()
+ anotherMethod()
2.b: extends
3:
uses Factory A.a
Concrete
2.a: produces Override:
+ produceProductA()
+ produceProductB()
Concrete Factory A.b
2.a: produces Override:
+ produceProductA()
+ produceProductB()
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
583
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.
584
Peter Kaptein
Factory A
2.b:
instantiates /
returns
Product B.1
1.c: or uses
2.a: implements
Pruduct C.1
Interface A
3.a: implements
Factory B
Product A.2
3.b:
instantiates /
returns
Product B.2
Pruduct C.2
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
585
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
2.a: has
Production lines
(Methods) A, B, C
2.b: returns
objects of type
Abstract Product A /
Product A Interface
Abstract Product B /
Product B Interface
Abstract Product C /
Product C Interface
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
586
Peter Kaptein
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.
587
1: instantiates
YourClass
4: implements
Concrete Product A.1
4: implements
Concrete Product B.1
4: implements
Concrete Product C.1
Abstract Product A /
Product A Interface
Abstract Product B /
Product B Interface
Abstract Product C /
Product C Interface
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.
588
Peter Kaptein
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.
589
590
Peter Kaptein
591
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.
592
Peter Kaptein
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
593
BONUS MATERIAL
::Tag: PAT-AFC-BNS
2.b: is passed to
1.a: has a
1.b: uses
Your Factory
Provider
Your Code
3.b: produces
Product X
3.a: uses
either
Concrete Factory A
Concrete Factory B
Concrete Factory B
4: is returned 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.
594
Peter Kaptein
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.
Context A
2: is passed to
3: exposed by
1.a: uses
Your Factory
Provider
Your DataMap
4.a: contains /
accesses
4.b: returns
1.b: receives /
instantiates
DataMap Contents
key
5: exposes
value
6: produces
Concrete Factory Class B
1.d: receives
Concrete Product X
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:
595
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.
596
Peter Kaptein
FACTORY, SIMPLE
::Tag: PAT-SFC: Discussing the Simple Factory
::includesubchapters
597
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.
Your Code
Simple Factory
4: is returned to
2: instantiates
either/or
3: produces
Class B
Class C
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.
598
Peter Kaptein
599
DIAGRAMS
::Tag: PAT-SFC-DIA
1: will produce
producs of type
Base Product B
3: produces / return
2: are implemented as
concrete products
Concrete Product A.a
4: leading to
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.
600
Peter Kaptein
1.b: implements
3: uses
Simple Factory A
2.a: produces
+ produceProductA( productType )
+ produceProductB( productType )
case productTypeA:
return new
Concrete Product A
+ someMethod()
+ anotherMethod()
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.
601
Your Code
Simple Factory
4: is returned to
2: instantiates
either/or
3: produces
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
602
Peter Kaptein
Class B
Class C
1.a: has a
1.b: receives
4: implements / extends
Your Class
ProductX
Simple Factory A
2: implements / uses
context on
Construction
Method A
Interface A /
Abstract Class B
5: implement
3.b: instantiates /
uses either
Class A
Class B
Class C
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
603
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.
604
Peter Kaptein
605
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.
606
Peter Kaptein
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.
607
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
608
Peter Kaptein
BONUS MATERIAL
::Tag: PAT-FAC-BNS
609
FLYWEIGHT *
::Tag:PAT-FLYWT
::includesubchapters
610
Peter Kaptein
INJECTOR *
::Tag:PAT-INJ
::includesubchapters
611
INTERPRETER **
::Tag:PAT-INPR : Discussing the Interpreter Pattern
::includesubchapters
612
Peter Kaptein
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.
613
DIAGRAMS
::Tag: PAT-INPR-DIA
Object Structure A
2: parses
context into
2: has or receives a
3: can contain
Semantic Context
non-terminal expressions
terminal expressions
Non-terminal Expression A
Terminal Expression A
Non-terminal Expression B
Terminal Expression B
5: can be child of
5: can be child of
6: leading to
An object structure representing the semantic relationships as present
within the Semantic Context Object
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?
614
Peter Kaptein
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.
615
1.a: has a
Context
2: extends
3: are of type
Terminal Expression A
Override:
+ interpret( context )
Nonterminal Expression A
- childExpressions
Override:
+ interpret( context )
NOTES:
To be filled in
616
Peter Kaptein
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.
617
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
618
Peter Kaptein
619
MANAGER
::Tag: PAT-MGR
::includesubchapters
620
Peter Kaptein
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
Your Class
1: uses
2.a: addresses
Manager A
Subsystem B
3: can address
2.b: uses
Business Logic
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 Faade.
Faade and Mediator patterns combined
The manager can be seen as a merge of the Mediator and Faade 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.
621
622
Peter Kaptein
DIAGRAMS
::Tag: PAT-MGG-DIA
1: uses
2.a: addresses
Manager A
Subsystem B
3: can address
2.b: uses
Business Logic
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 Faade.
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.
623
IMPLEMENTING A MANAGER
::Tag: PAT-MGG-DIA-002
Your Code
1: addresses
Manager A
subsystem
2.a: addresses /
uses / can observe
Handler A
2.b: uses
Business Rules
Service B
Data Store C
Behaviors
business logic
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 Faade 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.
624
Peter Kaptein
Manager A
2.a: has /
calls
Subsystem Class
Variable C
3.b: can be of type
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.
625
Manager A
1.a: register
to / observes
Subsystem Object
Business Logic
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.
626
Peter Kaptein
3: invoke private
methods on
Your Code
1.a: exposes
Manager A
Subsystem Objects
Business Logic
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
627
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.
628
Peter Kaptein
1.b: uses
1.a: uses /
requests
Data Map
2: resolves / returns
Manager X
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.
629
FAADE
::Tag: PAT-MGG-SIM-FAC
Wrapping and simplifying a subsystem
The Manager is closely related to the Faade, as it uses a lot of the same principles: wrapping and
simplifying a subsystem.
Manager implements the Faade as part of the Manager Pattern
The Manager implements the Faade 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.
630
Peter Kaptein
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.
631
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.
Faade and Mediator: a bit of both
The Manager is a bit of both Faade 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 Faade 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.
632
Peter Kaptein
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
Faade: similar approach, more restricted
The Faade 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 Faade 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 Faade. Where the Faade 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 Faade), the Manager delegates most of the requests to other objects.
::Link: PAT-DEL
633
634
Peter Kaptein
MEDIATOR
::Tag: PAT-MED
::includesubchapters
635
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
uses
Your Class
Madiator A
Class A
Class B
Class C
Class E
Class D
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
636
Peter Kaptein
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.
637
DIAGRAMS
::Tag: PAT-MED-DIA
2: have references to
colleagues
in subsystem
Concrete Mediator
+ yourMethodA():
do something
+ yourMethodB()
do something else
3: has references to
Concrete Collegue A
4: communicate to
Concrete Collegue B
5: delegates actions to specific
5: leading to
Centralization of communication between objects in your subsystem
NOTES:
Centralizing communication in your subsystem
638
Peter Kaptein
1: contains a
reference to
- mediator
+ operationA()
+ operationB(parameter)
2: extends
Concrete Mediator A
4: contains a
reference to
- collegueA
- collegueB
+ requestA()
+ requestB()
+ requestC()
Concrete Mediator B
- collegueC
- collegueD
3: extends
Concrete Collegue A
5: contains a
reference to
collegueA
.someOperationD()
collegueB
.operationF()
+ someOperationD()
+ operationE(parameter)
Concrete Collegue B
+ operationF()
+ operationG(parameter)
+ operationD()
NOTES:
639
Madiator A
Class A
Class B
Class C
640
Class E
Class D
Peter Kaptein
uses
Your Class
Madiator A
Class E
addresses
addresses
addresses
addresses
addresses
Class A
Class B
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
641
Madiator A
Observes /
addresses
Class A
Observes /
addresses
Class E
Observes /
addresses
Class B
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.
642
Peter Kaptein
643
Your Class
1.a: instantiates
Madiator A
Object from
Class A
Object from
Class B
Object from
Class E
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.
644
Peter Kaptein
645
FAADE
::Tag: PAT- MED-SIM-FAC
Wrapping and simplifying a subsystem
The Manager is closely related to the Faade, 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 Faade is very much a Top Down Manager. The Faade talks and
everyone in the subsystem has to listen and respond. Nobody in that subsystem is allowed to call or
contact the Faade 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.
646
Peter Kaptein
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.
647
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 Faade: decisions and simplification of working with subsystems
Unlike the Mediator, the Faade takes a Top Down approach. The objects and Classes wrapped by the
Faade cannot- and do not interact with or get access to that Faade and do not know the Faade exists
at all.
Like the Faade, 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
648
Peter Kaptein
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
Faade: 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 Faade
The Mediator can be a bit too friendly with the subsystem it is part of to be useful. Where the Faade
might be a better choice in some case because it has a more top-down approach, the Faade Pattern is
much more a more elaborate Delegate Pattern than it is a close relative to the Mediator. The Faade
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
Faade and everything you can do with the Mediator and combines it into one Class.
::Link: PAT-MGR
649
650
Peter Kaptein
MULTITON *
::Tag:PAT-MULT
::includesubchapters
651
OBJECT MAP **
::Tag: PAT-DTMP
::includesubchapters
652
Peter Kaptein
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.
Your Code
Class A
3: contains
objects based on
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.
653
DIAGRAMS
::Tag: PAT-DTMP-DIA
Client
objects of type
ObjectMap
5: returns
instance of
object to - static _objectMap
3: maps
Class A
Class B
2: uses
+ static getObject( key, classRef )
+ static removeObject( key, classRef )
+ static addObject( key, classRef )
Class C
6: leading to
Mapping one instance of a specific object of any type
to be retrieved and used anywhere
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.
654
Peter Kaptein
CLASS DIAGRAM
::Tag: PAT-DTMP-DIA-000
objects of type
ObjectMap
- static objectMap
1: contains
Class A
Class B
Class C
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.
655
removeObjects
Remove object will remove the object stored under the given keys.
Your Code
Class A
3: contains
objects based on
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.
656
Peter Kaptein
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).
ALTERNATIVES
::Tag: PAT-OMP-ALT
MULTITON
::Tag: PAT-OMP-ALT-
657
Simpler verison
The Multiton is a simpler implementation of the same principle: storing and retrieving concrete objects
into some sort of map.
658
Peter Kaptein
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
659
OBJECT POOL *
::Tag: PAT-OBJP
::includesubchapters
660
Peter Kaptein
OBSERVER
::Tag: PAT-OBS
::includesubchapters
661
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.
Some Object
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
662
Peter Kaptein
DIAGRAMS
::Tag: PAT-OBS-DIA
1: notifies
- observerList
interface
Observer
+ update()
+ attach( observer )
+ detach( observer )
+ notify()
2: extends
Concrete Subject
- subjectState
+ setState()
+ getState()
3.b: implements
Concrete Observer
3.a: observes
- observerState
- subject
+ update()
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.
663
Some Object
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
664
Peter Kaptein
1: registers to
Some Object
2.b: dispatches
3.a: relates to non, one or more
observers in
Some Event
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
665
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.
666
Peter Kaptein
Subject A /
EventDispatcher B
1.b: is registered to
2.a: extends / registers observers to
Your Object
1.a: registers to
Some Object
using
2.b: dispatches
Event Handle B
4.a: is dispatched on
4.b using
Some Event
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
Refactoring and Design Patterns
667
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).
1.a: receives
Event Dispatcher
A
1.b: resolves
1.c: invokes
Callback
Method A
3.a: can be
Callback Object A
3.b: implements
2: lives inside
Callback Interface
B
4: includes
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
668
Peter Kaptein
Command /
Observer Object
669
Dictionary / HashMap
Key = Event Handle
Observer Map
2: contains
Key/Value Pair: event handle 1
Key/Value Pair: event handle 2
3: contains
Observer List
4: contains
Observer / Callback Method
Observer / Callback Method
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
670
Peter Kaptein
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.
671
2.a: is registered to
Subject A /
EventDispatcher B
Your Object
1.b: registers
command to
Some Object
using
2.b: executes
method on
3.b: dispatches
5.a: is dispatched on
1.a: creates
5.b using
CommandA
Some Event
Event Handle B
5.c: when handle matches, executes
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
672
Peter Kaptein
673
1: has knowledge of /
registers observers on
Object B
3: sends
callback to
2: has knowledge of /
dispatches events /
messages on
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
674
Peter Kaptein
675
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.
676
Peter Kaptein
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.
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.
677
ALTERNATIVES
::Tag: PAT-OBS-ALT
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.
678
Peter Kaptein
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.
679
680
Peter Kaptein
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 Faade 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
681
PARSER
::Tag:PAT-PARS : Discussing the Parser Pattern
Keywords::Parser,Parser Design Pattern, Parser explained, Parser Examples, Parser variations
::includesubchapters
682
Peter Kaptein
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
2: can be parsed to
1: parsed to
2: can be parsed to
Object Tree /
Composite Object
Abstract Definition
WHEN/WHAT?
::Tag:PAT-PARS-DIA-BAS-001
To parse/convert one structure into another
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.
683
DIAGRAMS
::Tag:PAT-PARS-DIA
684
Peter Kaptein
CLASS DIAGRAM
::Tag:PAT-PARS-000
To be added
685
1: parsed to
2: can be parsed to
Object Tree /
Composite Object
Abstract Definition
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.
686
Peter Kaptein
1.a: uses
Abstract
Description A
Your Code
1.b: uses
Parser A
2.a: constructs /
returns
Composite C
2.b: uses /
requires build
actions from
2.c: injects
values in
Simple Factory B
3: constructs / returns
Concrete Product
4: is injected
as child into
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
687
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.
688
Peter Kaptein
Your Code
1: calls
Parse Method
2.c: calls
2.a: has
Parser A
2.b: sends
required object
type to
5.b: is returned to
Simple Factory B
3.a:
uses
Class A
5.a: implements
Base methods:
addChild()
removeChild()
getChildren()
Interface C
Class C
4: implement
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:
689
690
Peter Kaptein
Parameters:
Parent Object = Root Object
Structure = Root Node
Method:
Parse Structure
Read Node
Does it
represent an
Object?
Values:
Values, Settings, Name
Node Type / Object type
yes
no
Get Object
use
Simple Factory B
loop
Do we have
Children?
no
Done
yes
For each
Child Node
Call Method
Parameters:
Parent Object = Current Object
Structure = Child Node
When there are no children left, we are
done parsing in this branche of the Tree
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.
691
Root Node
accompanies
is passed as parent to
has
Root Object
are added as
child to
Child Node
Node Object
Child Node
Node Object
has
Child Node
produces
Node Object
is added as
child to
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
692
Peter Kaptein
693
694
Peter Kaptein
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 texteditor, 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.
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.
695
BONUS MATERIAL
::Tag:PAT-PARS-BNS
2: can be parsed to
2: can be parsed to
1.b: parsed to
Abstract Definition
Object Tree /
Composite Object
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.
696
Peter Kaptein
2: can be parsed to
1.c: using
1.b: parsed to
Abstract Definition
2: using
Data Merger
Abstract
Definition B /
Object Tree C
2: can be parsed to
Object Tree /
Composite Object
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.
697
Data Map /
Simple Repository
3: from
Alternative
Mapping
Structure
1.c: using
2: using
Data Merger
Abstract
Definition B /
Object Tree C
1.b: parsed to
Abstract Definition
Object Tree /
Composite Object
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.
698
Peter Kaptein
Structure A
1: parsed
to
Structure B
2: parsed
to
Structure A.1
Lossfull Parsing
Structure A
1: parsed
to
Structure B
2: parsed
to
Structure A.1
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
699
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.
Object Structure /
Composite Object
2: using
Source Object
3.a: getting
Fields / getting
values from
Reflection on
Fields
3.b: matching
Fields / putting
values into
Destination Object
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:
700
Peter Kaptein
701
Object Structure /
Composite Object
2: using
3: copying values
from
Source Object
Objects from
Generated Code
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 thats 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
702
Peter Kaptein
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.
703
Source Objects
2: resulting in
Parser
Disposable
Objects
Object Structure /
Composite Object
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.
704
Peter Kaptein
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.
705
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
706
Peter Kaptein
PROTOTYPE *
707
PROXY
::Tag: PAT-PRX
::includesubchapters
708
Peter Kaptein
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
1: uses
Your Class
Proxy A
Object B
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.
709
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)
710
Peter Kaptein
DIAGRAMS
::Tag: PAT-PRX-DIA
1: contains
+ doSomething()
+ doSomethingElse()
3: execute
Proxy
- realSubject
+ variableA
+ variableB
2: will contain
+ methodA( )
+ methodB( )
5: will be
delegated to
4: will be passed to
Real Subject A
+ variableA
+ variableB
+ methodA( )
+ methodB( )
NOTES:
711
1: is of type
+ doSomething()
+ doSomethingElse()
interface
Subject A
+ executeA( )
+ executeB( )
proxy.executeA()
proxy.executeB()
Real Subject A
+ variableA
+ variableB
+ executeA( )
+ executeB( )
2.a: implements
3: instanitates /
passes values to /
delegates actions to
Proxy A
- realSubject
+ variableA
+ variableB
+ executeA( )
+ executeB( )
NOTES:
712
Peter Kaptein
if realSubject != null:
realSubject.executeA()
Proxy A
Object B
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.
713
2: will contain
Proxy A
1.c: instantiates /
represents / pretends to be
1.b: has
Methods A, B, C
Variables L, L, M
3: will
address / set
4: inside
Object X from
Class N
Methods D, E, F
Variables O, P, Q
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.
714
Peter Kaptein
4.a: is of type
4.b: will contain
System C
Object B
5: implements
Interface A /
(Base)Class B
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
715
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.
716
Peter Kaptein
717
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
718
Peter Kaptein
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.
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 Faade and the Manager, the Proxy wraps only a single object. The Faade and the Manager
wrap multiple objects. The Faade 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 Faade Pattern does not include Late
Instantiation.
719
BONUS MATERIAL
::Tag: PAT-PRX-BNS
1.c: will
address / set
System C
Object B from
Class C
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.
720
Peter Kaptein
System C
Factory / Strategy
Provider /
Data/file loader
2.b: returns
Context-specific
Objects/Strategies
Data / Data Objects
3.b: returns
Persistent / shared
Objects
Business Rules
4.a: remote proxy
5: protection proxy /
smart reference
Connection /
Communication
module
4.b: communicates
with / interprets Data to/from
external system
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:
721
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 ofand 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.
722
Peter Kaptein
2.a: is of type
1.c: instantiates /
represents / pretends to be
InterfaceA /
(Base)ClassB
Methods A, B, C
Variables K, L, M
3: will
address / set
4: inside
Object X from
Class N, O or P
5: implements/
extends
Methods D, E, F
Variables O, P, Q
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
723
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.
724
Peter Kaptein
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.
725
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
726
Peter Kaptein
727
virtual proxy will start off with an indirect reference such as a file name but will eventually obtain and
use a direct reference.
728
Peter Kaptein
REFLECTION *
::Tag: PAT-REFL
::includesubchapters
729
SINGLETON *
::Tag:PAT-SING
::includesubchapters
Diagrams
Client
1: calls
3: contains
instance of
Singleton
4: returns
instance of
object to - static _instance
2: uses
+ static instance()
+ someMethod()
+ anotherMethod()
5: leading to
One single instance of an object that can be retrieved and used anywhere
730
Peter Kaptein
STATE
::Tag: PAT-STT: Discussing the State Pattern
::includesubchapters
731
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
Your Class
1: uses
State Context A
State Object A
2: has a / addresses
State container
vatiable
5: is put inside
State Object B
3: contains
4.a: changes
State Object C
State Object X
4.b: is either /
has knowledge of
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.
732
Peter Kaptein
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
- stateObject
2: is handled by current
+ request()
+ setState( stateOject )
Concrete State A
+ handleRequest()
Concrete State B
4: has knowledge
of other
+ handleRequest()
Concrete State C
+ handleRequest()
4: leading to
A self-organizing delegator that defines internally which concrete
implementation should handle the next state of the process
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.
733
1: contains
object of type
base class
State
- contextObject
stateObject.handle()
+ setContext( context )
+ handle()
2.a: extends
Concrete State A
- stateObjectB
+ handle()
Concrete State B
- stateObjectA
+ handle()
contextObject.setState( stateObjectB )
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.
734
Peter Kaptein
Context
- stateObject
+ request()
+ setState( stateOject )
1.a: contains
object of type
stateObject.handle()
3: uses
base class
State
- contextObject
+ const stateAID
+ const stateBID
+ setContext( context )
+ handle()
- getStateObject( stateID )
- stateContextMap
+ setStateContext(
contextID,
stateID,
stateObject )
+ getStateObject(
contextID, stateID )
2.a: extends
Concrete State A
- stateObjectB
+ handle()
Concrete State B
- stateObjectA
+ handle()
contextObject.setState( stateObjectB )
735
SIMPLE DIAGRAM
::Tag: PAT-STT-DIA-001
Your Class
1: uses
State Context A
State Object A
2: has a / addresses
State container
vatiable
5: is put inside
State Object B
3: contains
4.a: changes
State Object C
State Object X
4.b: is either /
has knowledge of
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
736
Peter Kaptein
State objects have knowledge of other State objects and which State object to choose when the State
changes due to a method call.
737
2.a: is of type
State Container
variable
State Context A
2.b: is either / or
1.a: has a
6: implement /
extend
State Object A
State Object X
3: contains
State Object B
4.b: sets
State Object C
Methods A, B, C
4.a: uses
either / or
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
738
Peter Kaptein
5: instantiated from
2.c: contains
1.b: addresses /
pretends to be
Your State
Class A
Your State
Class B
Your State
Class C
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.
739
740
Peter Kaptein
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.
741
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.
742
Peter Kaptein
BONUS MATERIAL
::Tag: PAT-STT-BNS
CREATING A STATE-BRIDGE
::Tag: PAT-STT-DIA-003
Your Code
1: extends
State Context A
State Object A
2: has a / addresses
State container
vatiable
State Object B
3: contains
4.a: changes
State Object C
State Object X
4.b: is either /
has knowledge of
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.
743
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
744
Peter Kaptein
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
Refactoring and Design Patterns
745
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
746
Peter Kaptein
747
STRATEGY
::Tag: PAT-STRA: Discussing the Strategy Pattern
::includesubchapters
748
Peter Kaptein
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
Your Class
1.b: instantiates
Class X /
Strategy Y
4: is injected into
3: uses / addresses
Context Object A
2: contains
Code in
Context Object A
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.
749
DIAGRAMS
::Tag: PAT-STRA-DIA
+ yourMethodA():
if A:
do Approach A
if B:
do Approach B
+ yourMethodB()
+ yourMethodA:
do Approach A
1: extract and
split conditional
code into separate
classes
2: injected into /
replacement for: code
inside yourMethodA
3: leading to
Classes and Objects that can change part of their behavior
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.
750
Peter Kaptein
2.a: contains
object of type
interface
Strategy A
+/- executeA()
+ setStrategyA( strategy )
+ doSomethingElse()
strategyA.executeA()
+ executeA( )
2.a: implements
1: uses / can set
strategy
Client
- context
2.b: uses
Concrete Strategy A.a
+ executeA()
+ executeA()
- setStrategy(
contextID)
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.
751
SIMPLE DIAGRAM
::Tag: PAT-STRA-DIA-001
Your Class
1.b: instantiates
Class X /
Strategy Y
4: is injected into
3: uses / addresses
Context Object A
2: contains
Code in
Context Object A
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.
752
Peter Kaptein
1.b: injects
Strategy into
Factory A /
DataMap B
1.d:
can use
Interface A /
BaseCLass B
YourClass
Context Object A
Strategy A
Strategy B
4: implement / extend
Strategy C
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
753
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
754
Peter Kaptein
Variable A
3: is of type
Interface A /
BaseCLass B
1.c: is passed to
2.a: has / addresses /
1.b: has a
delegates to Strategy in
1.a: uses
YourClass
Factory A /
DataMap B
4: implement / extend
Strategy A
Strategy B
Strategy C
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
755
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
Lets 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.
756
Peter Kaptein
757
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.
758
Peter Kaptein
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.
759
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
760
Peter Kaptein
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
761
762
Peter Kaptein
[..] 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 operationsin 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.
763
TEMPLATE METHOD *
764
Peter Kaptein
VISITOR
::Tag:PAT-VIS : Discussing the Visitor Pattern
::includesubchapters
765
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
1.a: instantiates
YourClass
Visitor A
Composite
Object B
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.
766
Peter Kaptein
767
DIAGRAMS
::Tag:PAT-VIS-DIA
visitors
Object Structure A
Concrete Visitor A
Concrete Visitor B
elements
Concrete Element A
4: visits / is sent through /
can perform operations on
Concrete Element B
5: can be child of
6: leading to
A dynamic solution to run through- and perform actions on an Object
Structure from the inside using different type of visitors
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
768
Peter Kaptein
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.
Object Structure A
+ handleElementA( elementA )
+ handleElementB( elementB )
2: extends / implements
Concrete Visitor A
Overrides / Implements:
+ handleElementA( elementA )
+ handleElementB( elementB )
Concrete Visitor B
Overrides / Implements:
+ handleElementA( elementA )
+ handleElementB( elementB )
- childElementList
+ acceptVisitor( visitor )
3.a: extends
Concrete Element A
Concrete Element B
+ acceptVisitor( visitor )
+ acceptVisitor( visitor )
visitor.handleElementA(
this )
visitor.handleElementB(
this )
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.
769
770
Peter Kaptein
Visitor A
Composite
Object B
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 subparts.
771
Your Code
2: has / exposes
Method A, B, C
3: are executed by /
receive Object X via
Accept-Method A
5: can contain
6: lives inside
Object Y from
Class M
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
772
Peter Kaptein
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.
773
Visitor A
3: lives inside
Method A for
Class M
1: is passed to
Accept-Method B
4: lives inside
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 subelement 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
774
Peter Kaptein
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.
Method A for
Class M
Accept-Method B
Object Y from
Class M
4: lives inside
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
775
NOTES:
776
Peter Kaptein
777
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.
778
Peter Kaptein
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.
779
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.
780
Peter Kaptein
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
781
782
Peter Kaptein
[..] 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.
783