design patterns explained: from analysis through implementation
DESCRIPTION
Ken Pugh takes you beyond thinking of design patterns as “solutions to a problem in a context.” Patterns are really about handling variations in your problem domain while keeping code from becoming complex and difficult to maintain as the system evolves. Ken begins by describing the classic use of patterns. He shows how design patterns implement good coding practices and then explains key design patterns including Strategy, Bridge, Adapter, Façade, and Abstract Factory. In small group exercises, learn how to use patterns to create robust architectures that can readily adapt as new requirements arise. Lessons from these patterns are used to illustrate how to do domain analysis based on abstracting out commonalities in a problem domain and identifying particular variations that must be implemented. Leave with a working understanding of what design patterns are and a better way to build models of your application domains.TRANSCRIPT
!
MI AM!Half(day!Tutorial!
11/11/2013!8:30!AM!
!
!
!
!
!
"Design Patterns Explained: From Analysis through
Implementation" !
!
!
Presented by:
Ken Pugh
Net Objectives !
!
!
!
!
!
Brought(to(you(by:(!
!
!
340!Corporate!Way,!Suite!300,!Orange!Park,!FL!32073!
888(268(8770!H!904(278([email protected]!H!www.sqe.com
!!!!Ken!Pugh!!!Net!Objectives!!
A fellow consultant with Net Objectives, Ken Pugh helps companies transform into lean-agile organizations through training and coaching. His special interests are in communication (particularly effectively communicating requirements), delivering business value, and using lean principles to deliver high quality quickly. Ken trains, mentors, and testifies on technology topics from object-oriented design to Linux/Unix. He has written several programming books, including the 2006 Jolt Award winner Prefactoring and his latest Lean-Agile Acceptance Test Driven Development: Better Software Through Collaboration. Ken has helped clients from London to Boston to Sydney to Beijing to Hyderabad. He enjoys snowboarding, windsurfing, biking, and hiking the Appalachian Trail. Reach Ken at [email protected]!
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
info@netobjec+ves.com000www.netobjec+ves.com0
1# #Copyright#©#2008#Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Pa*ern'Oriented'Design''
(Design'Pa*erns'Explained)'
A#New#Perspec8ve#on#ObjectDOriented#Design#
POD#Half#Day#October#2012##
2# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Teams#
! Great#designs#are#a#collabora8ve#effort#! You#will#be#part#of#a#team#for#a#couple#exercises#! Agile#teams#are#selfDorganizing##
! Form#yourself#into#three#to#five#person#teams#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
3# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Introduc8ons#
! Name#! What#do#you#do?#! Who#do#you#do#it#for?#
! Languages#used?##! Years#programming?#! What#paWerns#have#you#used?##
! Why#are#you#here?#! What#do#you#want#out#of#the#course?#
4# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Ken#Pugh#
ken.pugh#@netobjec8ves.com#
Photo#Size:####Height:#2.25#Posi8on:####from#top#le_#corner###Horizontal#0.75####Ver8cal#1.#Picture##Style:#Simple#Black#####Frame##
No0code0goes0in0+ll0the0test0goes0on.0A0journey0of0two0thousand0miles0begins0with0a0single0step.0
! Fellow#Consultant#! OOA&D,#Design#PaWerns,#Lean,#Scrum,#TestDDriven#
Development#
! Over#2/5#century#of#so_ware#development#experience#
! Author#of#seven#books,#including:#– 0Prefactoring:0Extreme0Abstrac+on,0Extreme0
Separa+on,0Extreme0Readability00(2006#Jolt#Award)#
– 0Interface0Oriented0Design0
– Lean0Agile0Acceptance0TestIDriven0Development:0BeKer0SoLware0Through0Collabora+on0
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
5# #Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Lean Enterprise
Business
Management Team
ASSESSMENTS"CONSULTING"TRAINING"COACHING"
Lean for Executives Product Portfolio Management Business Product Owner
Lean Management Project Management
ILAFYT Kanban / Scrum ATDD / TDD / Design Patterns
technical process
6# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
"PaWernDOriented#Development"#
Pa*ern5oriented'development'is'matching''
'the'forces'in'the'problem'''to'the'forces'in'pa*erns'
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
7# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Purpose#of#this#Course#
! Present#a#powerful#way#of#analyzing#and#designing#so_ware#! Incorporates:#
– Quali8es,#Principles,#and#Prac8ces##– Design#PaWerns#(seen#in#a#different#way)##
! Mostly#about#design,#not#implementa8on#! AWempts#to#change#our#paradigm#of#design#
8# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
The#Gang#of#Four#
! Design#PaWerns##– Gamma,#Helms,#Johnson,#Vlissides#
– Known#as#the#Gang#of#Four#(GOF)##! Based#on#“Timeless#Way#of#Building”#
– Christopher#Alexander##
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
9# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Logis8cs#
! Please#phones#and#pagers#off#(or#to#vibrate)#! Break#halfway##
10# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Learning#Styles#
! People#have#different#learning#styles#– One#is#not#beWer#than#another#– MisDmatches#cause#communica8on#problems#
– Please#ask#ques8ons#if#examples#are#not#detailed#enough#
~2
See:#hWp://www.netobjec8ves.com/resources/teamDissues/#for#more#informa8on#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
11# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Outline#
! Beginnings##! Code#Quali8es##! The#PaWerns#
#
12# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Agenda:#PaWerns#Covered#
! Strategy#! Template#Method#
! Bridge#! Adapter#! Façade#! Abstract#Factory##
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
13# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
The#Pyramid##
Paradigm00
PaKerns0
Wisdom0
Principles0 Prac+ces0
Quali+es##
14# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
UML#Summary#
A
B
A
B
A
B
A
B
Aggregation
A aggregates B B is a member of A
A is composed of B A contains B type objects
B implements A A depends upon B A uses B
Composition
Interface Implementation Dependency
Different#ways#to#represent#classes.
Different#rela8onships#between#classes.##Don’t#worry#about#represen8ng#the#difference#between#aggrega8on#and#composi8on.#
From#Design#PaWerns#Explained:#A#New#Perspec8ve#on##ObjectDOriented#Design.#Shalloway#and#TroW#
A
B
B is derived from A A generalizes B
Inheritance
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
15# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Sequence#Diagram#Summary##
16# ### #16#October#2013#
Beginnings'
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
17# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Retrospec8on#
! To#improve,##we#need#to#reflect#– What#worked#
– What#did#not#work#
! How#can#a#design#accommodate#change?#– Not#an+cipate#change#
18# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Creeping#Changes##
function() { Do_this; Do_that; Do_something_else; }
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
19# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Creeping#Changes#(2)##
function(a) { if (a) {
Do_another_thing: //… }
else { Do_this; Do_that; Do_something_else; }
}
20# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Creeping#Changes#(3)##
function(a, b) { if (a) {
if (b) { Do_another_thing:; //… }
else { Do_one_more_thing; //.. }
} else {
Do_this; Do_that; Do_something_else; }
}
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
21# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Spreadsheet#Conundrum#
2000#rows#10000#columns#32#MB#Flash#Drive##Access#by#individual#byte:##rowNumber#*##sizeofRow#+######columnNumber##Or##columnNumber#*#sizeofColumn##+#####rowNumber##How#will#you#store#it?###By#row?###By#column?#
22# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
How#to#organize#?#
Language / Word
ENGLISH GERMAN
NAME Name Namen
CITY City Stadt
POSTAL_CODE Zip PC
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
23# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Implementa8on#(1)#
String getLabelForNAME(Language l ) { if (l == ENGLISH) return “Name”; else if (l == GERMAN) return “Namen”; else throw Exception(“No translation for language” + l); } // Same for the other words
24# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Implementa8on#(2)#
String getLabelForGERMAN(Word w) { if (w == NAME) return “Name”; else if (w == CITY) return “Stadt”; else if (w == POSTAL_CODE) return “PC”; else throw Exception(“No German translation for word ” + w); } // Same for the other languages
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
25# ### #16#October#2013#
Code'QualiAes'
c#
Paradigm00PaKerns0
Wisdom0Principles0 Prac+ces0
Quali+es##
26# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Predictability#
! Cannot#predict#how#requirements#will#change#! How##to#increase#predic8ve#abili8es?#
– High#quality#code#easier#to#change#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
27# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Discussion#Exercise#
! Imagine#someone#brings#you#code#to#evaluate#
! What#do#you#look##for#to#decide#if#it#is#easy#to#change?##
! What#recommenda8ons#would#you#make?#
28# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Quali8es#
! In#PaWernDOriented#Development#– Focus#is#on:#
Cohesion#Coupling#NonDRedundancy#Encapsula8on#And,#overall,#Testability0
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
29# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Cohesion#
! Cohesion##– “How#closely#opera8ons#in#a#rou8ne#[or#class]#are#related.”##
! No#"schizophrenic#classes”#doing#more#than#one#thing#! No#"12Dpage#methods"#
*#Code%Complete,#Steve#McConnell,#1993,#p.#81.#This0concept0was0first0described0by0Larry0Constan+ne0in01975,0but0we0like0McConnell’s0defini+on0best.0
c#
Paradigm00PaKerns0
Wisdom0Principles0 Prac+ces0
Quali+es##
30# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Strong#Cohesion##
! Class#Cohesion##– Class#has#a#single#responsibility#– Everything#"about"#fulfilling#that#responsibility#
! Method#Cohesion#– Each#method#fulfills#only#one#aspect#of#class#responsibility#– Prac8ce:#Programming#by#inten8on#(next#slide)#
c#
Paradigm00PaKerns0
Wisdom0Principles0 Prac+ces0
Quali+es##
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
31# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Programming#by#Inten8on#
public void printReportOfEmployeesOfCustomer (String CustomerID) { Employee[] emps = getEmployees(CustomerID); if(needsSorting(emps)) sortEmployees(emps); printHeader(CustomerID); printFormattedEmployees(emps); printFooter(CustomerID); paginate(); }
"Private"* Methods
"Sergeant" Method
C#/Java/…
*Note:#These#methods#may#not#be#literally#private,#as#we#may#need#to#make#some#of#them#public#or#protected#for#tes8ng.##But#we#treat0them0as0private#from#client#objects,#to#limit#coupling.#
32# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Alterna8ve#Methods#(Separa8on#of#Concerns)###
public void printReportOfEmployeesOfCustomer (String CustomerID) { Employee[] emps = getEmployees(CustomerID); printReport(CustomerID, emps); } private void printReport(String CustomerID, Employee [] emps) { sortEmployees(emps); printHeader(CustomerID); printFormattedEmployees(emps); printFooter(CustomerID); paginate(); } private void sortEmployees(Employee [] emps){ if(needsSorting(emps)) doSortEmployees(emps); }
C#/Java/…
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
33# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Programming#by#NonDInten8on#
public void printReportOfEmployeesOfCustomer (String CustomerID) { // Get Employees Employee[] emps …Make series of calls to get employees // Sort Employees … Series of calls to sort // Print Header … Series of calls //… and so forth for lots of lines }
C#/Java/…
34# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Programming#by#Inten8on#
void Report::printReportOfEmployeesOfCustomer (string CustomerID) { vector<Employee> emps = getEmployees(CustomerID); if(needsSorting(emps)) sortEmployees(emps); printHeader(CustomerID); printFormattedEmployees(emps); printFooter(CustomerID); paginate(); }
Private Methods
"Sergeant" Method
C++
*Note:#These#methods#may#not#be#literally#private,#as#we#may#need#to#make#some#of#them#public#or#protected#for#tes8ng.##But#we#treat0them0as0private#from#client#objects,#to#limit#coupling.#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
35# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
What#Programming#by#Inten8on#Gets#You#
! Method#Cohesion#! Separa8on#of#concerns#
– "Sergeant"#method#calls#other#methods#– Private#methods##implement#details#
! Clarity##– Clear#code#beWer#than#comments##
! Ease'in'finding/forming'certain'pa*erns'! No#extra#work#is#required#
36# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Coupling##
! Coupling###– “strength#of#connec8on#between#two#rou8nes#[or#classes]”#
! Object#can#be##– Loosely#coupled##
! No#dependence#on#other#implementa8ons#
! (Also#called0inten+onal0coupling)0– Tightly#coupled##
! Objects#are#interdependent;#– Change#one#thing;#other#things#change#unpredictably#
! (Also#called#accidental0coupling)#
c#
Paradigm00PaKerns0
Wisdom0Principles0 Prac+ces0
Quali+es##
*#Code%Complete,#Steve#McConnell,#1993,#p.#81.#This0concept0was0first0described0by0Larry0Constan+ne0in01975,0but0we0like0McConnell’s0defini+on0best.0
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
37# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Coupling#To#Data#
Global#Data#
Func8on#One#
Func8on#Two#
Func8on#Three#
AWributes#
Method#One#
Method#Two#
Method#Three#
Class#
38# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Coupling#To#Other#Classes#
MyClass# YourClass#HerClass#
HisClass#Hard#to#test#Need#to#instan8ate#many#classes#Too#coupled##
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
39# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
No#Redundancy#
! "One#Rule#in#One#Place"#! Example#of#viola8on:##Y2K#! Redundancy#can#be#more#than#state##
– E.g.#.#redundant#rela8onships#! Redundancy#causes#maintenance#problems#
! Before#copying#and#pas8ng,#ask#why?##
c#
Paradigm00PaKerns0
Wisdom0Principles0 Prac+ces0
Quali+es##
40# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Redundancy#D#Shalloway’s#Law#
! From#Al#Shalloway#(CEO#of#Net#Objec8ves)##
! “When#N#things#need#to#change#and#N>1,#Shalloway#will#find#at#most#ND1#of#these#things.”#
#
! Shalloway’s'Principle:#“Avoid#situa8ons#where#Shalloway’s#Law#applies”#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
41# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Encapsula8on#
! Hide##– Data#– Implementa8on#
! Other#encapsula8on:#– Type#
! Interfaces#hide#their#implemen8ng#classes#– Design#
! Using#factory#decouples#clients#from#implemen8ng#classes#
! Details#expanded#in#next#slides##
c#
Paradigm00PaKerns0
Wisdom0Principles0 Prac+ces0
Quali+es##
42# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Encapsulate#by#Policy,#Reveal#by#Need#
! What#is#encapsulated#is#– Decoupled#– Freely#changeable#
! Never#know#what#might#want#change#
! Easier#to#deDencapsulate#than#encapsulate#later#– So#encapsulate##
#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
43# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Abstrac8on#
! Abstrac8on#encompasses#encapsula8on#– Think#about#what#you#want#done,#not#how#you#want#it#done##
! “When#You’re#Abstract,#Be#Abstract#All#the#Way”#– Never#use#a#primi8ve#(except#in#constructors)#
! Example#next#page##
Paradigm00PaKerns0
Wisdom0Principles0 Prac+ces0
Quali+es##
44# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Dollar#Abstrac8on#
! Dollar#as#double##– double#interestRate;##– double#balance;#– double##interest#=#balance#*#interestRate#;#
! Dollar#class###– Dollar#mul8plyBy(Percentage#p)#
– Dollar#add(Dollar#other)#– Dollar#mul8plyBy(Dollar#d);#
– Dollar#add(Percentage#p);##Percentage#interestRate;#
Dollar#balance;##
Dollar#interest#=#balance.mul8plyBy(interestRate);##
#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
45# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Observa8on#
! Reversible#changes#are#o_en#not#equal#in#difficulty#! Usually#easier#to#deDobjec8fy#for#performance#than#it#is#to#objec8fy#for#code#quality##
! Example:#– Dollar#balance#"#double#balance;##
– double#balance##"#Dollar#balance;#
46# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Redundancy#
Class A
-Redundant Issue
Class B
-Redundant Issue
Class A and Class B:
Have redundant state or functionality
Redundant issue inside each class
How to resolve redundancy?
c#
Paradigm00PaKerns0
Wisdom0Principles0 Prac+ces0
Quali+es##
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
47# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
It#Depends!*#
Depends#on#rela8onship#between#classes#– Conceptual?###
! Are#A#and#B#varia8ons#of#common#concept?#
or#– Rela8onship#of#consistent#use?###
! A#and#B#have#a#need#that#is#resolvable#in#a#common#way?#
Class A
-Redundant Issue
Class B
-Redundant Issue
*#©2007#All#Consultants#Everywhere#
48# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Using#Inheritance#
Class A Class B
Inheritance
Classes coupled to superclass
SuperClass
#Redundant Issue Conceptual
Concrete
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
49# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Using#Delega8on#
Class A
Class B
Delega+on.##
Class C
Redundant Issue
50# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Comparing#These#Op8ons#
! Inheritance:#– May#not#be#possible###
! Classes#may#already#have#superclass##
– May#make#superclass#less#cohesive#
! Delega8on:#– Available#if#other#en88es#need#behavior#
! Favor'delegaAon'over'inheritance''(GOF)''Paradigm00PaKerns0
Wisdom0Principles0 Prac+ces0
Quali+es##
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
51# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Testability#
! Difficult#to#unitDtest#code#is#o_en:#– Tightly#Coupled#
! “I#cannot#test#this#without#instan8a8ng#half#the#system"#
– Weakly#Cohesive#! #"This#class#does#so#much,#the#test#will#be#enormous#and#complex!"#
– Redundant#! #"I'll#have#to#test#this#in#mul8ple#places#to#ensure#it#works#everywhere"#
c#
Paradigm00PaKerns0
Wisdom0Principles0 Prac+ces0
Quali+es##
52# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
The#Role#of#Testability#
! Unit#tes8ng#is#good#! If##you#don’t#do#unit#test##
– Always#ask#"if#I#were#to#test#this,#how#would#I#do#it?"#– If#design#is#hard#to#test##
! Ask#"why#isn't#this#more#testable?"#
! It's#a#significant#trim#tab#(see#next#slide)#
c#
Paradigm00PaKerns0
Wisdom0Principles0 Prac+ces0
Quali+es##
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
53# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Trim#Tabs#
"If you try to change the course of a supertanker by pushing at the bow you will not see any change.
If you push on the rudder your chances of changing the course of the supertanker are guaranteed, but the amount of energy needed is still prohibitive.
To be the most effective we need to push on the trim tabs, those small fins on the end of the rudder.
By moving them, the rudder in turn moves and the tanker makes its turn.”
R. Buckminster Fuller "Critical Path"
~2 54# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Standards#for#High#Quality#Code#(Review)#
High#quality#code#(in#order#of#importance):#! Testable''! Contains#no#redundancy''! Inten8onal#coupling,#strong#cohesion,#encapsulaAon'! Clarity'
– Inten8onDrevealing#names#
– Adhere#to#a#coding#standard#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
55# ### #16#October#2013#
A'Design'Exercise''
56# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Exercise##
! Exis8ng#Chip#object#– Gets#status#of#hardware#– Encrypts#status##– Sends#status#to#monitoring#applica8on#
! Now#need:#– Different#encryp8on#algorithms##
! For#different#customers#
! Or#perhaps#different#8me##
! How#can#we#can#handle#this#varia8on?#
Chip
+getAndSendStatus() -getStatus() -encrypt() -send()
-ChipID:String
Note:0I0am0not0asking0for0the0best0way0to0handle0this,0just0for0the0possible0ways0
Please#don't#turn#the#page#un8l#instructed#to#do#so…#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
57# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Blank#Slide#
! One#more#uninten8onally#blank#slide#
58# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Blank#Slide#
! Another#inten8onally#blank#slide#
! Don’t#look#ahead#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
59# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Blank#Slide#
! S8ll#another#inten8onally#blank#slide#
60# ### #16#October#2013#
AlternaAves'Approaches'To'Design'Exercise'
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
61# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Different#Strategies#to#Follow#
! Best/Worst#Case##– Everyone#can#upgrade#to#the#new#encryp8on#
! Copy#and#paste##– Start#with#fresh#code,#just#make#needed#changes#
! Use#a#switch##– Add#switch#to#exis8ng#code#that#specifies#encryp8on#
! Inheritance##– Specialize##class#containing#encryp8on#code#– Override##encryp8on#method#to#use#new#encryp8on#
! Delega8on#– Encryp8on#code#in#own#class##– Different#versions#of#encryp8on#class.###– Clients#refer#to#appropriate#encryp8on#object#
! Func8on#pointers#in#C++;##delegates#in#C##62# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Ways#to#Handle#New#Func8on:#Switches#
! Chip#has#switch#based#on#value#given#by#Client#– Pro:##
! Simple,#obvious#implementa8on#
– Con:##! If#new#encryp8on#algorithm#
– Must#maintain#Chip#
! Cohesion#in#Chip#is#weakened#! May#get#“switch#creep”#
– Switches#are#not#a#good#longDterm#solu8on#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
63# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Switch#Creep#
switch (nation) {!!case US:!! !// us version!!case MEXICO:!! !// Mexican version!
!case CANADA:!! !// Canadian version!
!!
switch (nation) {!!case US:!! !// us version!!case MEXICO:!! !// Mexican version!!case CANADA:!! !// Canadian version!
}!!
Pseudocode
64# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Ways#to#Handle#New#Func8on:#Inheritance#
! Subclass#Chip:#– Chip#has#original#encryp8on#(64#bit)#– Subclass#is#Chip128E#
! Or#Make#Chip#an#abstract#class#– Implemen8ng#subclasses:#
! Encrypt#0##(no#encryp8on)#! Encrypt#64#! Encrypt#128#
– Most#func8onality#inherited#! Override#encrypt()#
Chip + getAndSendStatus() # encrypt()
Chip64E # encrypt() Chip128E
# encrypt() Chip0E
# encrypt()
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
65# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Problems#With#Inheritance#
! Inheritance#works##for#one#varia8on#– Not#for#two#
! E.g.#what#if#sending#also#varies?###! Subclassing#is#sta8c##! How#change#Chip#from#Encrypt64#to#Encrypt128?#
– Need#to#transfer#internal#state##
66# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Combinatorial#Explosion#
Chip + getAndSendStatus() # encrypt()
Chip64E # encrypt() Chip128E
# encrypt()
# send()
# send() # send()
Chip128ETCP Chip128EFTP # send() # send()
Chip64ETCP Chip64EFTP # send() # send()
Redundancies
Cohesion getting worse
and worse
-ChipID
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
67# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Delega8on#
Chip + getAndSendStatus() # encrypt()
PGP64 +encrypt()
PGP128 +encrypt()
Encryptor +encrypt()
-myEncrypt
Paradigm00PaKerns0
Wisdom0Principles0 Prac+ces0
Quali+es##
68# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Delega8on#Scales#
Chip
+ getAndSendStatus() # encrypt() PGP64
+encrypt() PGP128
+encrypt()
Encryptor +encrypt()
-mySend -myEncrypt
TCPIP +send()
FTP +send()
Sender +send()
# send()
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
69# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Refactoring:##The#Tradi8onal#View#
! Refactoring#usually#is#for#legacy#code#– Seen#as#cleaning#up#bad#code#– True,#but#not#complete#
! Refactor#code#to#issue#that#has#become0a0varia+on0– Improvement#in#light#of#new#requirements#
“Adventure”# hWp://benfry.com/distellamap/# 70# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Refactoring#(1)#
public class Chip { private String chipID; public Chip(String aChipID) { this.chipID = aChipID; } public void getAndSendStatus() { String status = getStatus(chipID); String encryptedStatus = encrypt(status); send(encryptedStatus); } private String getStatus(String chipID) { // get status from the real chip } private String encrypt(String status) { // encryption algorithm here } private void send(String status) { // sending behavior here }
}
Original'code'
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
71# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Refactoring#(2)#
// All elided code is unchanged from previous slide public class Chip {
private String chipID; private Encrypt myEncrypt; public Chip(String aChipID) { this.chipID = aChipID; this.myEncrypt = new PGP64(); } private String encrypt(String status) { return myEncrypt.encrypt(status); }
}
Delega8on#“Extract#Class”#
and#“Extract#Interface”#
72# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Enhancement###
Adding'new'encrypAon'is'enhancement,'not'refactoring'
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
73# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Factory###
Encryptor getEncryptor(CustomerType customer) { switch (customer)
{ case C1:
return new PGP64(); case C2:
return new PGP128(); default:
return new PGP0(); } }
//In Chip
public Chip(String aChipID, Customer customer) { this.chipID = aChipID;
this.myEncrypt = getEncryptor(customer); }
74# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Strategy#Injec8on##(1)#
• Constructor injection class Chip {
private Encryptor enc; public Chip(Encryptor encrypt) {
this.enc = encrypt; }
private void encrypt() { this.enc.encrypt(); } public void getAndSendStatus() { encrypt() // and other calls
}
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
75# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Strategy#Injec8on##(2)#
• Parameter injection class Chip {
public Chip() { }
public void getAndSendStatus(Encryptor enc) {
enc.encrypt(); // and other calls }
}
76# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Strategy#Injec8on##(3)#
• Setter injection class Chip { private Encryptor enc;
public Chip() { } public void setEncryptor(Encryptor encrypt) { enc = encrypt; } public void getAndSendStatus() {
enc.encrypt(); // and other calls }
}
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
77# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Injec8on#With#Mul8ple#Strategies###
// Multiple strategies, constructor injection // Chip has constructor Chip(Encryptor e, Sender s) Chip getChip(CustomerType customer)
{ switch(customer) { case C1: return new Chip(new PGP64(), new TCPIP()); case C2: return new Chip(new PGP128(), new TCPIP()); default: return new Chip(new PGP0(), new FTP()); } }
78# ### #16#October#2013#
Advice'from'the'Gang'of'Four'
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
79# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Gang#of#Four#Gives#Us#Guidelines*#
! Open/Closed'Principle'! Design'to'interfaces'! Favor'delegaAon'over'class'inheritance'! Encapsulate'concept'that'varies''
#
*'Gamma,#Helms,#Johnson,#Vlissides:#The#authors#of#Design%Pa2erns:%Elements%of%Reusable%Object<Oriented%Design%
Paradigm00PaKerns0
Wisdom0Principles0 Prac+ces0
Quali+es##
80# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
The#OpenDClosed#Principle#
! So_ware#en88es#should#be:#– Open#for#extension#– Closed#for#modifica8on##
! In#short:#– Design#modules#so#that#they#never#change##– Add#new#modules#to#handle#changed#requirements#– Not#always#achievable##
! Bertrand#Meyer:##– So_ware#en88es#(classes,#modules,#func8ons,#etc.)#should#be#open#for#
extension,#but#closed#for#modifica8on”#
! Ivar#Jacobson#:###– “All#systems#change#during#their#life#cycles.##This#must#be#borne#in#mind#
when#developing#systems#expected#to#last#longer#than#the#first#version”#A#good#ar8cle#on#the#OpenDClosed#Principle:#www.objectmentor.com/publica8ons/ocp.pdf#
c#
Paradigm00PaKerns0
Wisdom0Principles0 Prac+ces0
Quali+es##
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
81# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Design#to#Interfaces#
InterfaceA
Impl1 Impl2 Impl3
Interface B
Impl4 Impl5
Relationship
Relationship
Want#1→1#or#1→many#rela8onships#between#abstrac8on#
Not#n→m#rela8onships#between#implementa8ons#
Paradigm00PaKerns0
Wisdom0Principles0 Prac+ces0
Quali+es##
82# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Favor#Delega8on#Over#Inheritance#
! Define#interface#encapsula8ng#varia8on#! Delegate#to#concrete#class#implemen8ng#interface#
1. Decoupling concepts 2. Defer decisions until runtime 3. Small performance hit
Delegation
The "Strategy Pattern"
Chip + getAndSendStatus() # encrypt()
PGP64 +encrypt()
PGP128 +encrypt()
Encryptor +encrypt()
-myEncrypt
Paradigm00PaKerns0
Wisdom0Principles0 Prac+ces0
Quali+es##
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
83# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Treat#Conceptually#Similar#Things#the#Same#Way#
! Deal#with#things#at#an#abstract#level#! Encapsulate#that#which#varies#
Impl4
AbstractionA
Impl1 Impl2 Impl3
Client
Closed is abstraction
Open are implementations
Paradigm00PaKerns0
Wisdom0Principles0 Prac+ces0
Quali+es##
84# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Find#What#Varies#and#Encapsulate#It#
! GoF#meant#a#varying#anything:0– Varying#design#– Varying#object#crea8on#– Varying#rela8onships#(1D1,#1Dmany)#– Varying#sequences#and#workflows#– Etc…#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
85# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
This#Advice#Promotes#Quality#
Cohesive#
Decoupled#Reusable#
(eliminates#Redundant#Implementa8on)#
Encapsulated#
86# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Design#PaWerns#Are#Examples0
! Each#paWern:#– Example#of#a#design#following#general#advice#
– Discovered,#not#invented#– Example#in0a0given0context#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
87# ### #16#October#2013#
The'Strategy'Pa*ern'
88# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
The#Strategy#PaWern#
! Issue:#– Need#different#behavior#at#different#8mes#
! GoF#Intent:##– Define#a#family#of#algorithms,#encapsulate#each#one,#and#make#them#interchangeable##
– Algorithm#vary#independently#from#clients#using#it#*#
#
*Design%Pa2erns,%Elements%of%Reusable%Object<Oriented%So?ware,#Gamma,#Helm,#Johnson,#Vlissides#
Paradigm00PaKerns0Wisdom0
Principles0 Prac+ces0
Quali+es##
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
89# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
The#Canonical#Strategy#PaWern#
Java/C# // in Client: Strategy myStrategy=
Factory.getStrategy() . . . myContext.request( myStrategy) // in Context: request ( Strategy myStrategy) { myStrategy.algorithm() }
StrategyA + algorithm()
StrategyB + algorithm()
Context + request(Strategy)
Strategy + algorithm()
Client
C++ // in Client: Strategy *myStrategy=
Factory.getStrategy() . . . myContext.request( myStrategy) // in Context Context::request ( Strategy myStrategy) { myStrategy->algorithm() }
90# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Handling#Varia8ons#
! Factory#creates#different#objects#having#common#interface##(polymorphism)##– Factory#is#cohesive##D##only#deals#with#instan8a8on#
! Client#decoupled#from#actual#objects#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
91# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Strategy#PaWern#with#a#Factory#
*#
92# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Code#Examples#for#this#Approach#
class Client () { Encryptor myEncrypt; myEncrypt= Factory.getEncryptor(); // get proper derivation to use
Chip myChip= new Chip(); myChip.getAndSendStatus(myEncrypt); } class Chip () { //... public void getAndSendStatus( Encryptor anEncrypt) {
//... anEncrypt.doEncrypt(s); // ... } } // Encrypt is an interface or abstract class with a doEncrypt method.
// Have different classes implement this, each with a doEncrypt method.
C#/Java
~2
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
93# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Code#Examples#for#this#Approach#
public void main () { Encryptor * myEncrypt; myEncrypt= Factory::getEncryptor(); // get proper derivation to use Chip myChip; myChip->getAndSendStatus( myEncrypt); } // in Chip.h class Chip () { public void getAndSendStatus( Encryptor *); } // in Chip.cpp ... void Chip::getAndSendStatus( Encryptor *anEncrypt) { ... anEncrypt->doEncrypt(s); ... } } // Encrypt is an interface or abstract class with a doEncrypt method. // Have different classes implement this, each with a doEncrypt method.
C++
~2 94# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
What#Happens#Now#with#Changing#Requirements#
! If#new#encryp8on#requirement:##– 1.)#Create#new#class#implemen8ng#encryp8on#
– 2.)#Modify#Factory#to#return#new#class#– 3.)#Nothing#else!#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
95# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Creeping#Changes#(Review)#
function(a, b) { if (a) {
if (b) { Do_another_thing:; //… }
else { Do_one_more_thing; //.. }
} else {
Do_this; Do_that; Do_something_else; }
}
96# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Switch#Version#(1)#enum WhatToDo {Do_original, Do_another_thing, Do_one_more_thing}; class DoSomething { static void process(WhatToDo wtd) { switch(wtd) { case Do_original: Do_this; Do_that; Do_something_else; break; case Do_another_thing:
Do_another_thing; //.. break;
case Do_one_more_thing: Do_one_more_thing; //… break;
} }
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
97# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Switch#Version#(2)#
// Separate what to do from doing it WhatToDo factory(a, b) { if (a){
if (b) return Do_another_thing;;
else return Do_one_more_thing; }
else return Do_original; }
class Client {
WhatToDo wtd = factory(a, b); DoSomething.process(wtd); }
98# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Switch#Version#with#Func8ons###class DoSomething { static void process(WhatToDo wtd) { switch(wtd) { case Do_original: DoOriginal(); break; case Do_another_thing:
DoAnotherThing(); break; case Do_one_more_thing: DoOneMoreThing(); break; } } static void doOriginal() { Do_this; Do_that; Do_something_else; } static void doAnotherThing() {
Do_another_thing; //.. } static void DoOneMoreThing() {
Do_one_more_thing; //… }
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
99# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Convert#To#Strategy#
! Separate#what#to#construct#from#using#it##– Separate#policy#from#implementa8on#– Create#factory#to#return#implementa8on#of#interface#
#interface DoSomething{ void process(); };
100# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Convert#To#Strategy#(2)#class Do_original implements DoSomething { void process()
Do_this; Do_that; Do_something_else; } };
class Do_another_thing implements DoSomething { void process() { Do_another_thing; //… } };
class Do_one_more_thing implements DoSomething { void process() { Do_one_more_thing; //… } };
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
101# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Convert#To#Strategy#(2)#
DoSomething factory(a, b) { if (a){ if (b)
return new Do_another_thing(); else return new Do_one_more_thing(); } else return new Do_original();
} class Client { public void some_method() { DoSomething ds = factory(a, b); ds.process(); } }
102# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Select#Strategy#with#a#Table#
A# B# Return##
True# true# Do_another_thing#
True# false# Do_one_more_thing#
False# true# Do_original#
False# False# Do_original#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
103# ### #16#October#2013#
The'Template'Method'Pa*ern'
~2
Paradigm00PaKerns0Wisdom0
Principles0 Prac+ces0
Quali+es##
104# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
The#Template#Method#PaWern#
! Issue:#– Abstract#common#theme#from#cases#with#different#implementa8ons#
! GoF#Intent:##– Define#skeleton#of#an#algorithm#in#an#opera8on,#deferring#some#steps#to#subclasses.###
– Template#Method#lets#subclasses#redefine#certain#steps#of#an#algorithm#without#changing#the#algorithm’s#structure*#
! Analogy##– Hollywood#–#“Don’t#call#us,#we’ll#call#you”##
*Design%Pa2erns,%Elements%of%Reusable%Object<Oriented%So?ware,#Gamma,#Helm,#Johnson,#Vlissides#
~2
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
105# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Print#Report##
class Report { public void printReportOfEmployeesOfCustomer (String CustomerID) { Employee[] emps = getEmployees(CustomerID); if(needsSorting(emps)) sortEmployees(emps); printHeader(CustomerID); printFormattedEmployees(emps); printFooter(CustomerID); paginate(); } //.. Implementation methods here }
106# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Commonali8es#/#Variabili8es#
~2
Commonality#
Variabili8es#
printHeader(CustomerID);
printFooter(CustomerID);
printHeader(CustomerID); // Brief Header // Full Header
printFooter(CustomerID); // Brief Footer // Full Footer
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
107# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Template##PaWern#
BriefHeaderReport
#printHeader();
#printFooter();
FullHeaderReport
#printHeader();
#printFooter();
Report +printReportOfEmployeesOfCustomer()
#getEmployees(CustomerID);
#sortEmployees();
#printHeader();
#printFormattedEmployees();
#printFooter();
#paginate();
108# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Template#Method#Code#Example#
abstract class Report { public void printReportOfEmployeesOfCustomer (String customerID) { // … printHeader(customerID); printFooter(customerID); } abstract protected void printHeader(ID id); abstract protected void printFooter(ID id); } class BriefHeaderReport extends Report { protected void printHeader(ID id) { //. Code here } protected void printFooter(ID id) { //.. Code here } }
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
109# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
"Canonical"#Template#Method#
Client
ConcreteClassB
#Operation1() #Operation2()
TemplateMethod: … Operation1() … Operation2() …
AbstractTemplate +TemplateMethod()
#Operation1() #Operation2()
~2
ConcreteClassA
#Operation1() #Operation2()
110# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Strategy##PaWern#
BriefHeader
printHeader();
printFooter();
FullHeader
#printHeader();
printFooter();
Report +printReportOfEmployeesOfCustomer()
#getEmployees(CustomerID);
#sortEmployees();
#printHeader();
#printFormattedEmployees();
#printFooter();
#paginate();
Header
printHeader();
printFooter();
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
111# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Exercise#
! There#could#be#a#separate#strategy#for#both#header#and#footer.###
! What#are#the#tradeoffs#between#the#Template#Method#and#the#two#versions#of#the#Strategy#paWern#(header/footer#in#one,#header/footer#separate)##
112# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Template#Example#in#MFC#
Windows#System## Applica8on##ac8vate#
Window##ac8vate()##{draw();}#draw();###close()#minimize()#//#fi_y#more#(with#default#implementa8on)##
MyWindow##draw()#{#//#mydrawing;}##
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
113# ### #16#October#2013#
Design'Pa*erns'
Paradigm00PaKerns0Wisdom0
Principles0 Prac+ces0
Quali+es##
114# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
A#PaWern#in#Carpentry#
! Two#carpenters#are#building#a#chest#of#drawers#! One#says#to#the#other:#“should#we#build#the#joint#by#first#cuÑng#down,#then#cuÑng#up#at#a#45#degree#angle...”#
! “then#back#down#and#back#up### #the#other#way,#then#back#down”#
! “And#keep#this#up#un8l#done”#! This#is#“doveDtail#joint”##
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
115# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
DoveDTail#
116# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
A#Miter#Joint#
Commonly#used#in#picture#frames#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
117# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
PaWerns#Work#At#All#Levels#
Dovetail' Miter'
Forces' Strong,#HighDCost,#Decora8ve,#Humidity#Tolerant#
Weak,#Cheap,#Fast,#Good#for#Picture#Frames#
Design' Interlaced#joint# Single#AbuÑng#Cut#
ImplementaAon' Cut#teeth,#.5"#long,#.4"#deep,#match#teeth#to#gaps#
45#degree#angle#cut#aWached#with#staple#or#other#spanning#connector#
118# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Common#Reasons#to#Study#PaWerns#
! ReDuses#others’#experience#– some8mes#results#in#quick#solu8on#
! Designs#improved#for#modifiability#– Embrace#change#
! Use#common#terminology#– Improve#and#elevate#communica8on#
! PaWerns#are#great#examples#of#powerful#OO#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
119# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
What#Are#PaWerns?#
! PaWern:#– Collec8on#of#proven#prac8ces#for#a#recurring#problem#in#a#given#context#
! Design#paWerns##– Describe#rela8onships#between#en88es#(objects)#in#a#problem#domain#
! PaWerns#– Handle#varia8ons#in#behavior#– Use#interfaces#
! PaWerns#have#forces##– Contextual#forces#–#to#determine#what#paWern#to#use#– Implementa8on#forces#–#how#to#create#the#paWern##– Consequen8al#forces#–#what#happens#when#paWern#is#used##
! PaWerns#emphasize#importance#of#abstrac8ons#– …but#do#not#address#how#to#iden8fy#the#right#ones…#
120# ### #16#October#2013#
AbstracAon'
Paradigm00PaKerns0
Wisdom0Principles0 Prac+ces0
Quali+es##
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
121# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Consider#These#
Mop'''''''''''''''''''''''''Broom''''''''''''''Sponge'
The#same?##Different?#
122# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
“It0Depends!”#
! As#specific#objects:##– Different#
! As#a#concept#(abstrac8on):#– All#Cleaning#Tools#
! Are#there#other#abstrac8ons#with#different#commonality?##
! Which#abstrac8ons#are#useful?#####
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
123# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Various#Concepts#
Cleaning#Tool#cleanSomething()#
Mop#
Floor#Cleaning#Tool#cleanFloor()#
Water#Cleaning#Tool#removeWater()#
Mop#Mop#Broom# Broom#Sponge# Sponge#
ItemsToStore#size()#
Mop# Broom# Sponge#
ItemsForSale#price()#
Mop# Broom# Sponge#
All#Yellow#Items#
124# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
High#Abstrac8on##
! Higher#abstrac8ons#are#longer#life##– (But#can#be#less#useful)#
! Example:#– Abstrac8on###
! Automobile##– Prepare#for#following##– Follow#a#course###
! Implementa8ons:#– Turn#on#with#key##/###Push#a#buWon##– Steer#with#wheel,#speed#with#pedals#/###Use#a#joys8ck###
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
125# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
What#Is#the#Right#Abstrac8on?##
! The#United#Kingdom#"could#be#seen#as#economy#by#economists,#a#society#by#sociologists,#a#threaded#chunk#of#nature#by#conserva8onists,#a#tourist#aWrac8on#by#some#Americans,#a#military#threat#by#rulers#of#the#Soviet#Union,#and#the#green,#green#grass#of#home#to#the#more#roman8c#of#us#Britons".#
! Flood#and#Carson#! "Why#is#a#light#bulb#like#Doonesbury?"#
– Neither#one#can#whistle#
126# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
CommonalityDVariability#Analysis#
! Abstrac8on##focuses#on#commonality#(general)#! DeDemphasize#variable#details##(specifics)#.#! Acknowledgement:##
– Commonality#–#Variability#Analysis#in#James#Coplien’s#Mul8Dparadigm#Design#for#C++#
His#thesis#is#on#line#at#hWp://www.netobjec8ves.com/download/CoplienThesis.pdf#
c#
Paradigm00PaKerns0
Wisdom0Principles0 Prac+ces0
Quali+es##
His#thesis#is#on#line#at:#hWp://www.netobjec8ves.com/files/CoplienThesis.pdf#(link#is#caseDsensi8ve)#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
127# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Commonali8es#and#Variability#
! Commonali8es#can#define#basic#domain#concepts#(abstrac8ons)#– Recognized#from#experience#– Learned#through#analysis#(abstracted)#
! Variability#is#varia8on#of#commonality#(abstrac8on)##
*'MulB<Paradigm%Design%in%C++,#Jim#Coplien#
128# ### #16#October#2013#
The'Bridge'Pa*ern'
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
129# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
The#Bridge#PaWern#
! GoF#Intent:##– DeDcouple#an#abstrac8on#from#its#implementa8on#so#that#the#two#can#vary#independently#*##
! First#an#example##
*Design%Pa2erns,%Elements%of%Reusable%Object<Oriented%So?ware,#Gamma,#Helm,#Johnson,#Vlissides#
Paradigm00PaKerns0Wisdom0
Principles0 Prac+ces0
Quali+es##
130# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Rectangle#Drawing#Program#
Rectangle + draw() # drawLine(x1,y1,x2,y2)
DP1 + draw_a_line(x1,y1, x2,y2) + draw_an_arc(x, y, r, a1, a2)
Client
V1Rectangle # drawLine(x1,y1 x2,y2)
V2Rectangle # drawLine(x1,y1 x2,y2)
DP2 + drawline(x1,x2,y1,y2) + drawarc(r, x, y, a1, a2)
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
131# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Code#Example#abstract class Rectangle { private double_x1, _y1, _x2, _y2; public Rectangle(double x1, double y1, double x2, double y2){ .. } void public Draw () { DrawLine(_x1,_y1,_x2,_y1); DrawLine(_x2,_y1,_x2,_y2); DrawLine(_x2,_y2,_x1,_y2); DrawLine(_x2,_y1,_x1,_y1); } abstract void DrawLine( double x1, double y1, double x2, double y2); } class V1Rectangle : Rectangle { void override DrawLine( double x1, double y1, double x2, double y2) { DP1.draw_a_line( x1,y1,x2,y2); } } class V2Rectangle : Rectangle { void override DrawLine(double x1, double y1, double x2, double y2) { DP2.drawline( x1,x2,y1,y2); } }
C#
132# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Code#Example#
abstract class Rectangle { private double_x1, _y1, _x2, _y2; public Rectangle(double x1, double y1, double x2, double y2){ .. } void public draw () { drawLine(_x1,_y1,_x2,_y1); drawLine(_x2,_y1,_x2,_y2); drawLine(_x2,_y2,_x1,_y2); drawLine(_x2,_y1,_x1,_y1); } abstract void drawLine( double x1, double y1, double x2, double y2); } class V1Rectangle extends Rectangle { drawLine( double x1, double y1, double x2, double y2) { DP1.draw_a_line( x1,y1,x2,y2); } } class V2Rectangle extends Rectangle { drawLine(double x1, double y1, double x2, double y2) { DP2.drawline( x1,x2,y1,y2); } }
Java
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
133# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Code#Example#
class V1Rectangle : public Rectangle { … } class V2Rectangle : public Rectangle { … } void Rectangle::draw () { drawLine(_x1,_y1,_x2,_y1); drawLine(_x2,_y1,_x2,_y2); drawLine(_x2,_y2,_x1,_y2); drawLine(_x1,_y2,_x1,_y1); } void V1Rectangle::drawLine (double x1, double y1, double x2, double y2) { DP1::draw_a_line( x1,y1,x2,y2); } void V2Rectangle::drawLine (double x1, double y1, double x2, double y2) { DP2::drawline( x1,x2,y1,y2); }
C++
134# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Get#New#Requirements#
! Now#have#Circles#! Handle#similarly##
– Make##V1Circle#and##V2Circle#
! Decouple#client#from#specific#shapes##– Derive#specific#shapes#from#base#class#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
135# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Handling#New#Shape#Class#
Rectangle +draw()
Shape +draw()
Client
Circle + draw()
V1Rectangle # drawLine(x1, y1, x2, y2)
V2Rectangle # drawLine(x1, y1, x2, y2)
V1Circle #drawArc(x,y,r,a1,a2)
V2Circle # drawArc(x,y,r,a1,a2)
DP2 + drawline(x1, x2, y1, y2) + drawarc( r,x, y, a1,a2)
DP1 + draw_a_line(x1, y1, x2, y2) + draw_an_arc(x, y, r, a1, a2)
136# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Code#Example#
interface Shape { public void draw(); } abstract class Rectangle : Shape { private double _x1,_y1,_x2 _y2; public override void draw() { drawLine(_x1, _y1, _x2, _y1); drawLine(_x2, _y1, _x2, _y1); drawLine(_x2, _y2, _x1, _y2); drawLine(_x1, _y2, _x1, _y1); } abstract void drawLine( double x1, double y1, double x2, double y2); } } class V1Rectangle : Rectangle { public override void drawLine( double x1, double y1, double x2, double y2){ DP1.draw_a_line(x1,y1, x2, y2); } }
class V2Rectangle : Rectangle { public override void drawLine( double x1, double y1, double x2, double y2){ DP2.drawline(x1, x2, y1, y2); } } abstract class Circle : Shape { private double _x, _y, _r; public override void draw () { drawArc( _x, _y, _r, 0, 360); } abstract void drawArc( double x, double y, double r, double a1, double a2); } class V1Circle : Circle { protected override void drawArc(double x, double y, double r, double a1, double a2){ DP1.draw_an_arc(x,y,r,a1,a2); } } class V2Circle : Circle { protected override void drawArc(double x, double y, double r, double a1, double a2){ DP2.drawarc(_r,_x,_y,a1,a2); } }
C#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
137# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Code#Example#
interface Shape { public void draw(); } abstract class Rectangle implements Shape { private double_x1,_y1,_x2,_y2; public void draw() { drawline(_x1, _y1, _x2, _y1); drawline(_x2, _y1, _x2, _y1); drawline(_x2, _y2, _x1, _y2); drawline(_x1, _y2, _x1, _y1); } abstract void drawline( double x1, double y1, double x2, double y2); } class V1Rectangle extends Rectangle { public void drawline( double x1, double y1, double x2, double y2){ DP1.draw_a_line(x1, y1, x2, y2); } }
class V2Rectangle extends Rectangle { public override void drawLine( double x1, double y1, double x2, double y2){ DP2.drawline(x1, x2, y1, y2); } } abstract class Circle implements Shape { private double _x, _y, _r; public draw () { drawArc( _x, _y, _r, 0, 360); } abstract void drawArc( double x, double y, double r, double a1, double a2); } class V1Circle extends Circle { protected void drawArc( double x, double y, double r, double a1, double a2){ DP1.draw_an_arc(x,y,r,a1,a2); } } class V2Circle extends Circle { protected void drawArc( double x, double y, double r, double a1, double a2){ DP2.drawarc(_r,_x,_y,a1,a2); } }
Java
138# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Code#Example#
void Shape::draw () {} void Rectangle::draw () { drawLine(_x1,_y1,_x2,_y1); drawLine(_x2,_y1,_x2,_y2); drawLine(_x2,_y2,_x1,_y2); drawLine(_x1,_y2,_x1,_y1); } void V1Rectangle::drawLine ( double x1, double x2, double y1, double y2) { DP1::draw_a_line(x1,y1,x2,y2); } void V2Rectangle::drawLine ( double x1, double x2, double y1, double y2) { DP2::drawline(x1,x2,y1,y2); }
void Circle::draw () { drawArc( _x, _y, _r, 0, 360); } void V1Circle::drawArc( double x, double y, double r, double a1, double a2) { DP1::draw_an_arc(x, y, r, a1,a2); } void V2Circle::drawArc ( double x, double y, double r, double a1, double a2) { DP2::drawarc( r, x, y, a1, a2); }
C++
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
139# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Redundant#Rela8onships#
Rectangle +draw()
Shape +draw()
Client
Circle + draw()
V1Rectangle # drawLine(x1, y1, x2, y2)
V2Rectangle # drawLine(x1, y1, x2, y2)
V1Circle #drawArc(x,y,r,a1,a2)
V2Circle # drawArc(x,y,r,a1,a2)
DP2 + drawline(x1, x2, y1, y2) + drawarc( r,x, y, a1,a2)
DP1 + draw_a_line(x1, y1, x2, y2) + draw_an_arc(x, y, r, a1, a2)
6264#
140# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Did#We#Resolve#the#Redundancy?#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
141# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Problems#with#this#Approach#
! Doesn’t#scale#well#– Another#Shape#"#3#*#2#implementa8ons#– Number#implementa8ons#=#########number#of#Shape#types#8mes#number#of#drawing#programs#
! Redundant#– Drawing#with#each#shape#involves#duplica8on#– Redundancies#between#V1Rectangle#and#V2Rectangle,#etc…#
! Confusing#and#complex#– Poor#cohesion#makes#classes#hard#to#follow#
142# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Intent#Makes#Sense#Now#
! GoF#Intent:##– DeDcouple#an#abstrac8on#from#its#implementa8on#so#that#the#two#can#
vary#independently#*##! Abstrac8on:##
– Main#enAty#that#client#is#aware#of.#– E.g.#Shape#
! Implementa8on:##– Way#that#main#en8ty#fulfills#one#aspect#of#its#responsibili8es.##– E.g.##drawing#behavior#–#Drawing#
! In#other#words:#– Way#to#add#new#Shapes#OR#new#Drawing#Programs#without#affec8ng#the#
other#
*Design%Pa2erns,%Elements%of%Reusable%Object<Oriented%So?ware,#Gamma,#Helm,#Johnson,#Vlissides#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
143# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Discovering#the#Bridge#PaWern#
! Discover#the#Bridge#paWern#by:#– Find#commonali8es#and#how#they#vary##– Represent#common#concepts#with#abstrac8ons#(interfaces)#– Make#concrete#class#for#each#varia8on##
! Then:#– Observe#how#abstrac8ons#relate#– Pick#rela8onship#with#beWer#code#quali8es#
144# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
We#Have#the#Following#Commonali8es#
! Shape#class#=#abstrac8on#with#varying#behavioral#implementa8ons#
! Commonality#Variably#Analysis#separates#issues#into#isDa#rela8onships#
Shape
+draw()
Drawing
+drawLine()+drawCircle()+drawArc()0
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
145# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Derive#Varia8ons0
Shape
+draw()
Rectangle
+draw()
Drawing
+drawLine()+drawCircle()
V2Drawing
+drawLine()+drawCircle()
V1Drawing
+drawLine()+drawCircle()
Circle
+draw()
+drawArc()0
+drawArc()# +drawArc()#
146# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Determine#Remaining#Rela8onships0
Shape
+draw()
Rectangle
+draw()
Drawing
+drawLine()+drawCircle()
V2Drawing
+drawLine()+drawCircle()
V1Drawing
+drawLine()+drawCircle()
Circle
+draw()
Each side should "Design to Interfaces”
Which Way?
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
147# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Use#Quali8es#to#Define#Rela8onship#
! Ways#the#two#sides#can#relate:#– Shapes#use#drawing#programs#
– Drawing#programs#draw#shapes#– Third#object##gets#shape#and#drawing#program##
! Which#way#is#beWer?#– Score#with#quali8es#– BeWer#quali8es#"#beWer#design##
148# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Another#Quality#D#Asser8veness##
! Asser8veness###– Don’t#ask#ques8ons#of#an#object##– Assert#that#an#object#should#do#something#
! Example#on#next#slide#
c#
Paradigm00PaKerns0
Wisdom0Principles0 Prac+ces0
Quali+es##
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
149# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Inquisi8ve#
class Date { int getMonth(); int getDay(); int getYear(); }
Date d = new Date(); String output = d.getMonth() + “/” + d.getDay() + “/” +
d.getYear();
150# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Asser8ve#
class Date { String getAsString() { ] }
Date d = new Date(); String output = d.getAsString();
#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
151# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Scoring#–#Fill#It#In#
Shapes#use#DP# DP#given#Shape# 3rd#Module#
Loose#Coupling#
Strong#Cohesion#
No#Redundancy#
Encapsula8on#
Testable#
Asser8ve#
Focus#
152# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Shapes#Using#Drawing#Programs#
: Client : Rectangle : DP1
1: draw
2: drawLine
3: drawLine
4: drawLine5: drawLine
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
153# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Drawing#Programs#Using#Shapes#
: Rectangle : Client : DP1
1: draw( Shape s)
2: What kind of shape?
3: I'm a rectangle
4: Give me your line 1 info
5: Draw it
6: Give me your line 2 info
7: Draw it
8: Give me your line 3 info
9: Draw it
10: Give me your line 4 info
11: Draw it
154# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Control#Program#Using#Shapes#
: Client : ControlPrgm
: Rectangle : DP1
1: draw( Shape, DP)
2: what kind of shape?
3: I'm a rectangle
4: give me your line 1 info
5: drawLine
6: give me your line 2 info
7: drawLine
8: give me your line 3 info
9: drawLine
10: give me your line 4 info
11: drawLine
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
155# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Scoring#
Shapes#use#DP# DP#given#Shape# 3rd#Module#
Loose#Coupling# Yes# DPs#coupled#to#Shapes#
Module#coupled#to#Shapes#
Strong#Cohesion# Yes# DPs#concerned#with#Shapes#
Weak:#Shape#and#Draw#stuff#
No#Redundancy# Yes# Knowledge#of#shapes#duplicated#in#DPs#
Knowledge#of#shapes#duplicated#in#CP#
Encapsula8on# implementa8on#and#type#
implementa8on#only# implementa8on#only#
Testable# N#+#M# N#*#M# N#+#M#
Asser8ve# Yes# No# No#
Focus# Yes# Shapes#spread#out#a#liWle#
Yes#
Shapes using DPs wins! 156# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Add#the#Rela8onship#
Shape
+draw()
Rectangle
+draw()
Drawing
+drawLine()+drawArc()
1..1
1
DP2
+drawline()+drawarc()
V2Drawing
+drawLine()drawArc()
DP1
+draw_a_line()+draw_an_arc()
V1Drawing
+drawLine()+drawArc()
Circle
+draw()
drawing.drawLine()##
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
157# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Illustra8ng#the#Separa8on#
Shape
+draw()
Rectangle
+draw()
Drawing
+drawLine()+drawArc()
1..1
1
DP2
+drawline()+drawarc()
V2Drawing
+drawLine()+drawArc()
DP1
+draw_a_line()+draw_an_arc()
V1Drawing
+drawLine()+drawArc()
Circle
+draw()
Abstraction
Implementation
158# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Example#Implementa8on##class Client { public static void Main (String argv[]) { Shape s1; Shape s2; Drawing dp; // See comments below to see // what gets returned dp= Factory.getDP(); s1= Factory.getShape(dp); dp= Factory.getDP(); s2= Factory.getShape(dp); s1.draw(); s2.draw(); } } // Factory: // 1st call: getDP returns V1Drawing // 1st call: getShape returns // new Rectangle(dp,1,1,2,2); // 2nd call: getDP returns V2Drawing // 2nd call: getShape returns // new Circle( dp,2,2,4);
interface Shape { public void draw(); } class Rectangle : Shape { private Drawing _dp; Rectangle (Drawing dp, double x1, double y1, double x2, double y2) { _dp = dp; _x1= x1; _y1= y1; _x2= x2; _y2= y2;} public override void draw () { _dp.drawLine(_x1, _y1, _x2, _y1); _dp.drawLine(_x2, _y1, _x2, _y2);
_dp.drawLine(_x2, _y2, _x2, _y1); _dp.drawLine(_x2, _y1, _x1, _y1); } }
C#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
159# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Example#Con8nued#
class Circle : Shape { private Drawing _dp; Circle (Drawing dp, double x, double y, double radius) { _dp = dp; _x= x; _y= y; _radius= radius; } public override void draw () { _dp.drawArc(_x,_y,_radius, 0, 360); } }
interface Drawing { void drawLine ( double x1, double y1, double x2, double y2); void drawArc(double x, double y,double radius, double fromAngle, doubletoAngle);} class V1Drawing : Drawing { public override void drawLine ( double x1, double y1, double x2, double y2) { DP1.draw_a_line( x1, y1, x2, y2); } public override void drawArc ( double x, double y, double radius, double fromAngle, double toAngle){ DP1.draw_an_arc( x, y,radius, fromAngle,toAngle); } }
C#
160# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Example#Con8nued#
class Rectangle : Shape { Rectangle : base(dp) ( Drawing dp, double x1, double y1, double x2, double y2) { _x1= x1; _y1= y1; _x2= x2; _y2= y2; } public override void draw () { drawLine(_x1, _y1, _x2, _y1); drawLine(_x2, _y1, _x2, _y2); drawLine(_x2, _y2, _x2, _y1); drawLine(_x2, _y1, _x1, _y1); } }
C#
// With abstract base class abstract class Shape { private Drawing _dp; Shape (Drawing dp) { _dp= dp; } abstract void draw (); protected void drawLine ( double x1, double y1, double x2, double y2) { _dp.drawLine( x1, y1, x2, y2);} protected void drawArc ( double x, double y, double radius, double fromAngle, double toAngle){ _dp.drawArc( x,y,radius, fromAngle, toAngle); } }
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
161# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Example#Con8nued#
class V2Drawing : Drawing { public override void drawLine (double x1,double y1, double x2, double y2){ DP2.drawline( x1, x2, y1, y2);} public override void drawArc ( double x, double y, double radius, double fromAngle, double toAngle) { DP2.drawarc(radius, x, y, fromAngle, toAngle); } } class DP1 { static void draw_a_line ( double x1, double y1, double x2, double y2) { // draw_a_line implementation given to us} static void draw_an_arc( double x, double y, double radius, double from_angle, double to_angle) {
// draw_an_arc implementation given to us } } class DP2 { static void drawline ( double x1, double y1, double x2, double y2) { // drawline implementation given to us } static void drawarc( double radius, double x, double y, double fromangle, double toangle) { // drawarc implementation given to us } }
C#
162# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Example#Implementa8on##class Client { public static void main (String argv[]) { Shape s1; Shape s2; Drawing dp; // See comments below to see // what gets returned dp= Factory.getDP(); s1= Factory.getShape(dp); dp= Factory.getDP(); s2= Factory.getShape(dp); s1.draw(); s2.draw(); }} // Factory: // 1st call: getDP returns V1Drawing // 1st call: getShape returns // new Rectangle(dp,1,1,2,2); // 2nd call: getDP returns V2Drawing // 2nd call: getShape returns // new Circle( dp,2,2,4);
interface class Shape { void draw (); }
class Rectangle implements Shape{ private Drawing _dp; Rectangle (Drawing dp, double x1, double y1, double x2, double y2) { _dp = dp; _x1= x1; _y1= y1;
_x2= x2; _y2= y2;} public void draw () { _dp.drawLine(_x1,_y1,_x2,_y1); _dp.drawLine(_x2,_y1,_x2,_y2); _dp.drawLine(_x2,_y2,_x2,_y1); _dp.drawLine(_x2,_y1,_x1,_y1); } }
Java
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
163# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Example#Con8nued#interface Drawing { void drawLine ( double x1, double y1, double x2, double y2); void drawArc(double x, double y, double radius, double fromAngle,double toAngle);} class V1Drawing implements Drawing { public void drawLine ( double x1, double y1, double x2, double y2) { DP1.draw_a_line(x1,y1,x2,y2); } public void drawArc ( double x,double y,double radius, double fromAngle, double toAngle){ DP1.draw_an_arc( x, y,radius, fromAngle, toAngle); } }
Java
class Circle implements Shape { private Drawing _dp; Circle (Drawing dp, double x, double y, double radius) {
_dp = dp; _x= x; _y= y;
_radius= radius; } public void draw () { _dp.drawArc(_x,_y,_radius, 0, 360); } }
164# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Example#Implementa8on##With#Abstract#
// with abstract class abstract class Shape { private Drawing _dp; Shape (Drawing dp) { _dp= dp; } abstract void draw (); protected void drawLine ( double x1, double y1, double x2, double y2) { _dp.drawLine( x1, y1, x2,
y2); } protected void drawArc ( double x, double y, double radius, double
fromAngle, double toAngle){ _dp.drawArc( x, y,
radius, fromAngle, toAngle); } }
Java
class Rectangle extends Shape { Rectangle (Drawing dp, double x1, double y1, double x2, double y2) { super( dp); _x1= x1; _y1= y1; _x2= x2; _y2= y2; } public void draw () { drawLine(_x1, _y1, _x2, _y1); drawLine(_x2, _y1, _x2, _y2); drawLine(_x2, _y2, _x2, _y1); drawLine(_x2, _y1, _x1, _y1); } } class Circle extends Shape { Circle (Drawing dp, double x, double y, double radius) { super( dp); _x= x; _y= y; _radius= radius; } public void draw () { drawArc(_x,_y,_radius, 0, 360); } }
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
165# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Example#Con8nued#
class V2Drawing implements Drawing { public void drawLine ( double x1, double y1, double x2, double y2) { DP2.drawline( x1, x2, y1, y2);} public void drawArc ( double x, double y, double radius, double fromAngle, double toAngle) { DP2.drawarc(radius, x, y, fromAngle, toAngle); } }
class DP1 { static void draw_a_line ( double x1, double y1, double x2, double
y2) { // draw_a_line implementation given to us } static void draw_an_arc( double x, double y, double radius, double from_angle, double to_angle) {
// draw_an_arc implementation given to us } } class DP2 { static void drawline ( double x1, double y1, double x2, double y2) { // drawline implementation given to us } static void drawarc( double radius, double x, double y, double fromangle, double toangle) { // drawarc implementation given to us } }
Java
166# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Example#Implementa8on#
void main (String argv[], int arc) { Shape *s1; Shape *s2; Drawing *dp; dp= Factory::getDP(); s1= Factory::getShape(dp); dp= Factory::getDP(); s2= Factory::getShape(dp); s1->draw(); s2->draw(); } NOTE: Memory management has not been tested and the INCLUDE statements are not being shown.
class Shape { public: Shape (Drawing *dp); virtual void draw(); protected: drawLine( double x1, double y1, double x2, double y2); drawArc( double x, double y, double rad, double fromAngle, double toAngle); private: Drawing *_dp; }; Shape::Shape (Drawing *dp) { _dp= dp; } void Shape::drawLine( double x1, double y1, double x2, double y2) { _dp->drawLine( x1, y1, x2, y2); } void Shape::drawArc( double x, double y, double radius, double fromAngle, double toAngle){ _dp->drawArc( x, y, radius, fromAngle, toAngle); } !!
C++
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
167# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Example#Con8nued#
class Rectangle : public Shape { public: Rectangle (Drawing *dp, double x1, double y1, double x2, double y2); private: double _x1, _y1, _x2, _y2; }; Rectangle::Rectangle (Drawing *dp, double x1, double y1, double x2, double y2) : Shape(dp) { _x1=x1; _y1=y1; _x2=x2; _y2=y2; } void Rectangle::draw () { drawLine(_x1, _y1, _x2, _y1; drawLine(_x2, _y1, _x2, _y2); drawLine(_x2, _y2, _x2, _y1); drawLine(_x2, _y1, _x1, _y1); }
class Circle : public Shape { public: Circle ( Drawing *dp, double x, double y,
double radius); private:
double _x, _y, _radius;
}; Circle::Circle (Drawing *dp, double x, double y,
double radius) : Shape(dp) { _x= x; _y= y; _radius= radius; }
void Circle::draw () { Shape::drawArc( _x,_y,_radius,0,360);
}
C++
168# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Example#Con8nued#
###
class V2Drawing : public Drawing { public: void drawLine ( double x1, double y1,
double x2, double y2); void drawArc ( double x, double y, double radius, double fromAngle,
double toAngle); }; void V2Drawing::drawLine ( double x1,double y1,
double x2,double y2){ DP2::drawline( x1, x2, y1, y2); }
void V2Drawing::drawArc ( double x,double y, double radius, double fromAngle, double toAngle){ DP2::drawarc( radius, x, y, fromAngle, toAngle); }
class V1Drawing : public Drawing { public: void drawLine ( double x1, double y1, double x2, double y2);
void drawArc ( double x1, double y1, double radius, double fromAngle,
double toAngle); }; void V1Drawing::drawLine (double x1, double y1, double x2, double y2) {
DP1::draw_a_line( x1, y1, x2, y2); } void V1Drawing::drawArc ( double x, double y, double radius, double fromAngle, double toAngle){ DP1::draw_an_arc(x,y,radius, fromAngle, toAngle);
}
C++
class Drawing { public: virtual void drawLine (double x1,double y1, double x2,double y2) =0; virtual void drawArc (double x1, double y1, double radius, double fromAngle,
double toAngle)=0; };
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
169# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Example#Con8nued#
class DP1 { public: static void draw_a_line ( double x1, double y1, double x2, double y2); static void draw_an_arc( double x, double y, double radius, double fromAngle, double toAngle); }; class DP2 { public: static void drawline ( double x1, double x2, double y1, double y2); static void drawarc ( double radius, double x, double y, double fromAngle, double toAngle); }; // Implementations given to us
C++
170# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Where#is#varia8on#coming?#
Drawing Program/ Shape
DP1 DP2
Line
Rectangle
Circle
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
171# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Look#For#Abstrac8ons#
! Commonali8es#could#be##– Func8ons#– Data##
! Alterna8ve#interfaces#may#produce#different#design##
! Example#on#next#slide##
172# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Drawing#Another#Way#
Line#
DrawingPrimi8ve##
Arc#
Shape#
DrawingPrimi8ve[]#getPrimi8ves();##
In#DrawingProgram:####
draw(Shape#s)#{#
##DrawingPrimi8ve#[]#dp#=#s.getDrawingPrimi8ves();##
##//#Now#draw#each#one##
##}#
#
What#are#advantages#/#disadvantages?#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
173# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Drawing#Another#Way#(2)#
interface Shape { DrawingPrimitive [] getPrimitives(); } class Rectangle implements Shape { double x1; double y1; double x2; double y2; DrawingPrimitive [] getPrimitives() {
DrawingPrimitive [] dp = { new Line(x1,y1,x1,y2), new Line(x1,y1,x2,y1), new Line(x2,y1,x2,y2), new Line(x1,y2,x2,y2)}
return dp; }
174# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Drawing#Another#Way#–#One#Class##(3)#
class Shape { Shape (DrawingPrimitive [] primitives)
{ this.primitives = primitives;
} DrawingPrimitive [] primitives; DrawingPrimitive [] getPrimitives() { return primitives }; } // Each object has its own primitives Shape rectangle({ new Line(x1,y1,x1,y2), new Line(x1,y1,x2,y1), new Line(x2,y1,x2,y2), new Line(x1,y2,x2,y2)});
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
175# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
How#Drawing#Usually#Works#(op8onal)#
Drawing#(Graphics#Device#Interface)#draws#specific#shapes#(not#derived#from#a#Shape)##
interface GDI { drawRectangle(Rectangle r) drawCircle(Circle c) drawLine(Line l) drawPolyline(Line [ ] lines ) }
class Screen implements GDI //What are advantages / disadvantages?
176# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Who’s#In#Charge?##
! Class#PhoneNumber#– Dial#(Phone)#
! Class#Phone#– Dial(PhoneNumber)#
#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
177# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Who’s#In#Charge#(2)?##
! One#more#thing#to#dial:###
! Class#AccountNumber#– Dial#(Phone)#
! Class#Phone#– Dial(PhoneNumber)#
– Dial(AccountNumber)##
#178# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Who’s#In#Charge#(3)#?#
! Interface#Dialable##– DialableString#getStringToDial();#
! Class#AccountNumber#implements#Dialable#{##DialableString#getStringToDial()#{##//..##}###}#
! Class#PhoneNumber#implements#Dialable##
! Class#Phone#– Dial(Dialable)#
#
#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
179# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Canonical#Bridge#PaWern#
Concrete1ImpA
+ opImp1()+ opImp2()
ImpB+ opImp1()+ opImp2()
Abstraction+ operation()
Implementation+ opImp1()+ opImp2()
operat ion() { imp.opImp1()}
Concrete2
operation() { imp.opImp2()}
180# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Bridge#PaWern#as#an#Example##of#the#GoF#Approach#
Concrete1ImpA
+ opImp1()+ opImp2()
ImpB+ opImp1()+ opImp2()
Abstraction+ operation()
Implementation+ opImp1()+ opImp2()
operat ion() { imp.opImp1()}
Concrete2
operation() { imp.opImp2()}
(1)'(2)'encapsulates'variaAon'
(3)'
(1)'
(1) Find0what0varies0(the0abstrac+ons0and00implementa+ons)0and##(2) Encapsulate0it.0(3) Favor00object0delega+on0over0classIinheritance0#
(2)'encapsulates'variaAon'
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
181# ### #16#October#2013#
The'Adapter'Pa*ern'
182# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
The#Adapter#PaWern#
! Issue:#– Class#has#right#stuff##
! But#wrong#interface#! GoF#Intent:#
– #Convert#class#interface#into#the#one#client#expects##– #Allows#classes#with#incompa8ble#interfaces#to#work#together#
*Design%Pa2erns,%Elements%of%Reusable%Object<Oriented%So?ware,#Gamma,#Helm,#Johnson,#Vlissides#
Paradigm00PaKerns0Wisdom0
Principles0 Prac+ces0
Quali+es##
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
183# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Our#Problem#
Shape + setLocation() + getLocation() + display() + fill() + setColor() + undisplay()
Point + display() + fill() + undisplay()
Line + display() + fill() + undisplay()
Square + display() + fill() + undisplay()
184# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
What#We#Have#
XX_Circle
+ set_location() + get_location() + display_it() + fill_it() + set_its_color() + undisplay_it()
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
185# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
What#We#Want#
! Want#XX_Circle#to#behave#like#a#Shape#– No#polymorphism#with#XX_Circle:#
! Author#of#XX_Circle#not#willing#or#able#to#change#XX_Circle’s#interface#
Shape
XX_CIRCLE
=
186# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
How#to#Implement#the#PaWern#
Shape + setLocation() + getLocation() + display() + fill() + setColor() + undisplay()
Point + display() + fill() + undisplay()
Line + display() + fill() + undisplay()
Square + display() + fill() + undisplay()
XX_Circle + set_location() + get_location() + display_it() + fill_it() + set_its_color() + undisplay_it()
Circle + display() + fill() + getLocation() + setLocation() + setColor() + undisplay()
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
187# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Example#
class Circle : Shape { … private XX_circle pxc; … public Circle () { pxc= new XX_circle(); } public void override display() { pxc.display_it(); } }
C#
188# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Example#
class Circle extends Shape { … private XX_circle pxc; … public Circle () { pxc= new XX_circle(); } public void display() { pxc.display_it(); } }
Java
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
189# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Example#
IN HEADER class Circle : public Shape { private: XX_circle *pxc; } IN CONSTRUCTOR instantiate and initialize XX_circle. Have it refer to pxc IN CODE void Circle::display () { pxc->display_it(); }
C++
190# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Adap8ng#
// May have some state to keep class Circle implements Shape { private XX_circle pxc; private Color color; setColor(Color c)
{ this.color = c; }
fill() { pxc.fill_it(color):; }
}
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
191# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
General#Approach#
! Client#works#with#other#classes#without#"knowing"#which#one#– Create#an#interface#– Adapt#each#class#to#implement#that#interface#
! Adap8ng##is#also#called#"wrapping"#
192# ### #16#October#2013#
The'Façade'
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
193# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
The#Façade#PaWern#
! Want#:#– To#use#a#subDset#of#a#complex#system#
– Or#to#provide#OO#access#to#a#nonDOO#system#
! GoF#Intent*:##– Provide#a#unified#interface#to#a#set#of#interfaces#in#a#subsystem##
– Facade#defines#a#higherDlevel#interface#that#makes#the#subsystem#easier#to#use#
*Design%Pa2erns,%Elements%of%Reusable%Object<Oriented%So?ware,#Gamma,#Helm,#Johnson,#Vlissides#
Paradigm00PaKerns0Wisdom0
Principles0 Prac+ces0
Quali+es##
194# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Using#a#Complex#System#
! If#your#group#had#to#use#parts#of#a#complex#system,#would#you:#A. Have#everyone#learn#how#to#use#it?#B. Have#one#person#create#an#interface#to#use?#
! If#you#picked#B,#what#that#person#created#would#be#a#Façade#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
195# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Insula8ng#Ourselves#From#the#Complex#System#
Façade
#
196# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Façade#Example#(1)#
! #Example#StoreStringInFile(String filename, String data); // calls open, write, close String RetrieveStringFromFile(String filename); // calls open, read, close
! Error#handling#(try,#catch,#etc.)#in#the#implementa8on#code#! Allows#easy#mock##
– Read/write#to#memory,#rather#than#a#file##
#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
197# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Façade#Example#(2)#
SimpleFileStorageFacade#####SelectStorageDirectory(String#directory)######StoreStringInFile(String#filename,#String#data)#:#boolean#####RetrieveStringfromFile(String#filename)#:#String#
File#//#Read,#write,#open,#close#//#Excep8on#handling##
Directory#//#change#working#directory#
SimpleFileStorageFacadeMock####SelectStorageDirectory(String#directory)#####StoreStringInFile(String#filename,#String#data)#:#boolean#
#//#stores#in#memory#–#maybe#a#map#?#####RetrieveStringfromFile(String#filename)#:#String#
#//#retrieves#from#memory##
LiWle#more#complete#
198# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Standard#Façade#vs.#Encapsula8ng#Facade#
! Standard#Façade#provides#interface#– Clients#may#use#underlying#
system#directly#
! Encapsula8ng#Façade#restricts#access#to#the#underlying#system##– Clients#must#use#Façade#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
199# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Comparing#Façade#With#Adapter#
Client Pre-Existing?which pattern?
Façade# Adapter#Pre5ExisAng,'or'Foreign'classes?'
Yes# Yes#
Is'there'an'exisAng'interface'we'must'adhere'to?'
No# Yes#
Are'we'trying'to'enable'polymorphism?'
No# Usually#
Are'we'creaAng'a'new'interface'for'simplificaAon?'
Yes# No#
Is'statefullness'a'concern?' Yes,#Façades#tend#to#be#large#
Not#usually#
200# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Adapter#and#Façade#
! Use##Adapter#and#Façade#– Defer#Worrying#About#Your#Interface#
– Make#interfaces#of#classes#to#be#the#way#you#want#
! Design#by#context#– #First#figure#out#what#you#want##– Then#adapt#(or#simplify#with#a#Facade)#the#interface#to#that#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
201# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Microso_#Founda8on#Classes#(MFC)#Façade##
MFC#Classes#####Window#####Dialog##
Windows#SDK#####Win#98##
Windows#SDK#####Windows#7##
Windows#SDK#####Windows#2000#
Applica8on#
Note:#NonDencapsula8ng#facade#
202# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Façade###Usage##
Your#system#
Façade##
Third#party#library##
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
203# ### #16#October#2013#
The'Abstract'Factory'
204# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Strategy#Revisited#
! Abstract#Factory#is#strategy#of#strategies##! Here’s#an#example#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
205# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Switch#to#Strategy(1)#
// Just a switch, not a strategy enum Country {USA, MEXICO, CHINA}; functionOne (Country c){ switch(c) { case USA: doOneUSA(); break; case MEXICO: doOneMexico(); break; case CHINA: doOneChina(); break; } };
Switch#in#one#func8on#
206# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Switch#to#Strategy#(2)#
//FACTORY Strategy getStrategy(Country c){ switch(c) case USA: return new USAStrategy(); case MEXICO: return new MexicoStrategy(); case CHINA: return new ChinaStrategy(); break; } }; // USAGE: void functionOne (Country c){ Strategy s = getStrategy(c); s.doFunctionOne();}
interface Strategy { void doFunctionOne(); }; class USAStrategy implements Strategy { void doFunctionOne() { doOneUSA(); }}; class MexicoStrategy implements Strategy { void doFunctionOne(){ doOneMexcio(); } }; // .. And so on
To#a#strategy#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
207# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Switch#to#Strategy#(3)#
functionTwo (Country c){ switch(c) { case USA: doTwoUSA(); break; case MEXICO: doTwoMexico(); break; case CHINA: doTwoChina(); break; } };
Now#a#2nd#switch##
208# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
How#to#organize#?#
County/ Function
USA
MEXICO
FunctionOne
FunctionTwo
FunctionThree
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
209# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Switch#to#Strategy#(4)#
class MexicoStrategy implements Strategy { void doFunctionOne() { doOneMexcio(); } void doFunctionTwo() { doTwoMexcio(); } }; // .. And so on void functionTwo (Country c){ Strategy s = getStrategy(c); s.doFunctionTwo();}
interface Strategy { void doFunctionOne(); void doFunctionTwo(); }; class USAStrategy implements Strategy { doFunctionOne() { doOneUSA(); } doFunctionTwo() { doTwoUSA(); };
Add#to#strategy#
210# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Switch#to#Strategy#(5)#
interface Strategy { void doFunctionOne(); void doFunctionTwo(); //…. void doFunctionNintyNine(); }; class USAStrategy implements Strategy { void doFunctionOne() { doOneUSA(); } void doFunctionTwo() { doTwoUSA(); }; //…. void doFunctionNinetyNine() {
Now#99##func8ons##added#to#strategy#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
211# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Switch#to#Strategy#(5)#
interface StrategyFactory { StrategyA getStrategyA(); StrategyB getStrategyB(); ///… StrategyZ getStrategyZ(); }; class USAStrategyFactory() implements StrategyFactory { StrategyA getStrategyA() { return new USAStrategyA(); } StragegyB getStrategyB(){ return new USAStrategyB(); } //.. And so forth };
interface StrategyA { { // Related functions void doFunctionOne(); void doFunctionTwelve(); }; class USAStrategyA implements StrategyA { void doFunctionOne() { doOneUSA(); } void doFunctionTwelve() { doTwelveUSA(); } };
Break#into#related#strategies#
212# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Switch#to#Strategy#(6)#
StragetyFactory getInstanceStrategyFactory(Country c){ switch(c) { case USA: new USAStrategyFactory( (); break; case MEXICO: new MexicoStrategyFactory( (); break; case CHINA: new ChinaStrategyFactory( (); break; } };
Now#get#the#strategy#factory#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
213# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Switch#to#Strategy#(7)#
void functionTwelve(Country c) { StrategyFactory sf = getInstanceStrategyFactory(c); StrategyA sa = sf.getStrategyA(); sa.doFunctionTwelve(); } // Instead of previous operation void functionTwelve(Country c){ Strategy s = getStrategy(c); s.doFunctionTwelve();}
Usage:#
214# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
The#Abstract#Factory#PaWern#
! GoF#Intent:##– Need#to#create#families#of#objects#for#par8cular#situa8ons.##
– Provide#interface#for#crea8ng#families#of#related#or#dependent#objects##! Without#specifying#their#concrete#classes#
Design0PaKerns:0Elements0of0Reusable0ObjectIOriented0SoLware#by#Gamma,#Helm,#Johnson,#Vlissides.#AddisonDWesley#Professional.#1995.#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
215# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Abstract#Factory:#Contextual#Forces#
! Mo8va8on:##– Instan8ate#families#of#objects#
! Encapsula8on:##– Number#of#cases#
– Concrete#types#of#all#services#– Issue#that#case#varies##
216# ### #16#October#2013#
Not'an'Ending,'But'a'Beginning'
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
217# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Purpose#of#this#Course#(Revisited)#
! Present#a#powerful#way#of#designing#applica8on#architectures#! Incorporates:#
– Code#Quali8es##– Design#PaWerns#– CommonalityDVariability#Analysis#– Contextual#Design#(a#la#Alexander)#
218# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Summary#
! Design#in#context##! Code#quali8es##as#basis#for#paWerns##! Favor#delega8on#over#inheritance#! Encapsulate#variability#! What#else?##
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
219# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Thank#You##
Please#Fill#Out#Evalua8ons#
info@netobjec+ves.com000www.netobjec+ves.com0
220# #Copyright#©#2008#Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Supplemental'
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
221# ### #16#October#2013#
Factories'
Paradigm00PaKerns0
Wisdom0Principles0 Prac+ces0
Quali+es##
222# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Another#Issue#of#Perspec8ve#
! PaWerns,#e.g.#strategy,#bridge##– Create#context#for#factory##
! Factories##– Only#construct#objects,#do#not#use#
objects#Shape +centerX:int +centerY:int
Circle +diameter:int
Square +width:int +height:int
Factory +make():Shape
Client
~2
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
223# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
The#Use#of#Factories#
! Factories#decouple#object#being#used#from#client##! Factories#promote#encapsula8on#of#design#
– 1st##Determine#interfaces#and#interac8ons#of#objects##! Conceptual#and#specifica8on#perspec8ves#
– 2nd##Get#right#objects#with#factory#! Implementa8on#perspec8ve##
224# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
How#do#Factories#Make#Decisions?#
! "Extrinsic"#(to#the#client)#– Example:#
! Configura8on#file#or#device#iden8fica8on#(e.g.#version#of#Windows)#
– Only#factory#couples#to#configura8on#file##! "Intrinsic"#(to#the#client)##
– Client#decides#and#passes#a#parameter##
! "Rule#Based“#– Based#on#a#rule#– Example##
! If#user#is#administrator,#create#object#with#write#privileges##
– Only#factory#couples#to#rule##
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
225# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
#Factory#Example##
// Client Selection enum EncryptionType {Strong, Weak, None}; Encryptor getEncryptorInstance(EncryptionType et)
{ switch(et) { case Strong: return new E128(); case Weak: return new E64(); case None: return new E0(); default: throw new Exception( “Look at the EncryptionType”); } }
226# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
#Factory#Alterna8ves#
enum EncryptionType {Strong, Weak, None}; // Table (struct, array, etc.)
Type Class Strong E128 Weak E64 None E0
Encryptor getEncryptorInstance(EncryptionType et) { for (i = 0; i < table.size; i++) { if (et == table[i].type) // return new object of table[i].class
} throw new Exception(“Look at the EncryptionType”); }
// Or array indexed by enum Encrypt [] encrypt= {new E128(), new E64(), new E0()}; return encrypt[et];
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
227# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Factory#Alterna8ve#D#Service#Locator#PaWern#
class Chip { private Encryptor myEncryptor; Chip () {
myEncryptor = ServiceLocator.getEncryptor(); } } // Service locator checks a configuration file for type of encryptor to return
228# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Concept#/#Varia8ons#
Encryption
E128
E64
E0
Send
TCP
FTP
UDP
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
229# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Factory#For#Two#Strategies#
enum ChipType {ForCommercial, ForUS, ForImportantCustomer}; Chip getChip(ChipType ct) {
switch (ct) { case ForCommercial:
return new Chip(GetEncryptorInstance(Weak), GetSendInstance(TCP));
case ForUS: return new Chip(GetEncryptorInstance(Strong), GetSendInstance(FTP));
case ForImportantCustomer: return new Chip(GetEncryptorInstance(Weak), GetSendInstance(FTP);
}} // Or use table
230# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
#Discussion#Exercise#
! You#have#exis8ng#Account#object#– You#need#to#log#all#access#to#its#
public#methods#! But#only#for#certain#accounts#and/or#at#certain#8mes#of#the#day#
– You#don’t#want#client#code#to#change#a#lot##! (or#at#all,#if#possible)#
! What#would#you#do?#
Please#Don’t#Turn#the#Page#Un8l#Instructed#to#Do#So#
~2
Account + Account(AccountID id) + AddMoney(Dollar d) + TakeOutMoney(Dollar d)
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
231# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Workspace#
232# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Workspace#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
233# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Workspace#
234# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Workspace#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
235# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
One#Approach:#An#Intervening#Class#
Client Logger Account
Writes to a log file, then delegates
~2 236# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Account#Logger#(Proxy)##
Account
+ addMoney() + takeOutMoney()
Account_Impl LoggingAccount
Client
Call#logger#before#calling#original#method##
.
+ addMoney() + takeOutMoney()
+ addMoney() + takeOutMoney()
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
237# ### #16#October#2013#
The'Family'of'Proxy'Pa*erns'
Paradigm00PaKerns0Wisdom0
Principles0 Prac+ces0
Quali+es##
238# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
The#Proxy#PaWern#
! Issue:#– Need#to#add#func8onality#before#or#a_er#accessing#an#object#
! Client#should#not#know#it#is#talking#to#a#different#object#! GoF#Intent:##
– Provide#a#surrogate#or#placeholder#for#another#object*#! Summary:#
– Proxy#acts#on#behalf#of#another#class#– Proxy’s#interface#must#be#same#as#class#it#is#duplica8ng#
*Design%Pa2erns,%Elements%of%Reusable%Object<Oriented%So?ware,#Gamma,#Helm,#Johnson,#Vlissides#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
239# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
The#Proxy#PaWern#
! Many#uses#for#proxy#paWern#! Some#are:#
– Access#protec8on#! Protec+on0proxy#provides#security#for#another#object#
– Caching#! Cache0proxy#provides#caching#for#accessing#another#object#
– Virtualiza8on#! Virtual0proxy##provides#holding#point#for#another#object##
240# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
The#Protec8on#Proxy#PaWern#
! Need#to#control#access#to#exis8ng#object##! Don’t#want#to#change#exis8ng#data#object##
– Or#how#it#is#referred#to##! Follows#openDclosed#principle#
– Closed#=#exis8ng#object##– Open#=#adding#access#control#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
241# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
The#Protec8on#Proxy#PaWern#
! Example:#– Teachers#place#test#problems#and#answers#in#database#
! Access#through#Problem#with:#– String#getQues8on#(int#problem_number)#D#returns#ques8on#as#string#– String#getAnswer#(int#problem_number)#D#returns#answer#as#string#
! Now#give#students#access#to#the#ques8on#– But#not#the#answers#
! User#class#has#method#– Boolean#isTeacher()#–#returns#if#User#is#teacher##
242# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Possible#Solu8ons#
! Could#add#isTeacher()#call#before#every#getAnswer()#call#– Problem:##
! #Have#to#change#Client#code#wherever#getAnswer()#is#used##! Make#Problem#class#smarter#
– Add#isTeacher()#to#getAnswer#(int#problem_number)##– Problems:#
! Breaks#open/closed#! May#have#side#effects#for#other#Client#using#Problem##
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
243# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Protec8on#Proxy#Solu8on#
! Create#a#Problem#interface#– Both#original#Problem#and#a#new#class#(SecurityProblem)#implement#it#
! SecurityProblem#checks#user#before#passing#back#answers#– Uses#Problem#to#do#real#work#
! Client#gets#SecurityProblem,#not#Problem#to#use##– Can’t#tell#the#difference#
244# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Protec8on#Proxy#Looks#Like#
Problem
+ getAnswer() + getQuestion()
Problem_Impl
+ getAnswer() + getQuestion()
SecurityProblem
+ getAnswer() + getQuestion()
Client
getAnswer checkis type of client calls Problem_Impl's getAnswer. getQuestion just calls Problem_Impl's getQuestion.
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
245# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Protec8on#Proxy##
class SecurityProblem implements Problem { Problem original; SecurityProblem() { original = new Problem_Impl(); } String getQuestion(int which) { return original.getQuestion(which); } String getAnswer(int which) { if (User.isTeacher()) return original.getAnswer(which); else return “I can't give you answer”; } // Could also have SecurityProblem(Problem p); }
246# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
How#It#Works# : Client : Security
Problem : Problem _Impl Problem
_Factory
2: Instantiate
5: Request question 6: Request question 7: Return question
8: Return question 9: Request answer
10: Do I have a teacher? 11: If no, say can't give you answers
12: If yes, ask for answer 13: Return answer
14: Return answer
1: Get Problem
3: Instantiate (pass in Problem_Impl) 4: Return Object
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
247# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Common#Characteris8cs#of#All#Proxies#
! Proxy#paWern#characteris8cs:#– Client#uses#proxy#class#instead#of#original#class#– Proxy#and#original#class#have#same#interface##
– Proxy#calls#original#class#for#services#! No#duplica8on#of#func8onality#
248# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
The#Proxy#PaWern#Generalized:#Class#Diagram#
Original + Request()
Proxy + Request()
Interface + Request()
Client
Request() calls Original’s Request()
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
249# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
The#Proxy#PaWern#Generalized:#Interac8ve#Diagram#
Client Proxy Original
1: Request
2 : do necessary pre-processing
3: request
5: do necessary post-processing
6: Respond to client
4: respond to request
250# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
The#Cache#Proxy#PaWern#Example#
! Needs:#– Improve#performance#in#accessing#data#
– No#change#in#exis8ng#object#! Example#Situa8on:##
– Applica8on#makes#read0only0use#of#sta8c#data#through#Table#class#! Table#data#resides#on#disk#
! Problem:#– Performance#is#slow#– Many#accesses#to#table#are#for#the#same#data##
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
251# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Cache#Proxy#Looks#Like#
Cache_Table
+ read_data()
Table
+ read_data()
Table_Impl
+ read_data()
Client
read_data() calls Table_Impl read data() if info isn't cached
252# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
The#Virtual#Proxy#PaWern#Example#
! Needs:#– Exis8ng#object#uses#many#system#resources##
– Client#doesn’t#reference#object#immediately#! Don’t#want#to#use#system#resources#un8l#necessary#
! Need#a#placeholder#for#it#! Example:##
– Applica8on#contains#many#graphic#images#! Only#shows#a#few#of#them#at#a#8me#
! Problem:##– If#all#of#the#images#instan8ated,#run#out#of#memory##
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
253# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Virtual#Proxy#Looks#Like#
Image
+ display()
Image_Impl
+ display()
VirtualImage
+ display()
Client
display is implemented by instantiating the corresponding Image and displaying
- filename
254# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
The#Remote#Proxy#PaWern#
! Remote#proxy##– Access#object#on#remote#machine#
– Local#proxy#looks#like#that#object##! Almost#transparent#
– Client#may#have#to#deal#with#network#unavailability#issues#
Local#Proxy# Remote#Object#
Client# Server#Somewhere#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
255# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Other#Proxies#
! Smart'reference'proxy*.#– Replaces#“bare”#reference##– Adds#func8onality,#for#example:#
! Counts#number#of#references##
! SynchronizaAon'proxy*#– Coordinates#mul8ple#simultaneous#accesses#to#a#component#
– Locks/unlocks#the#object# ##
! Firewall'proxy*.##– Protects#local#clients#from#the#outside#world##
*Pa2ern<Oriented%So?ware%Architecture,#Buschmann,#et.#al.##256# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Browser#Proxy##
Browser## Remote#Web#Server##
Proxy##
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
257# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
What#the#Proxy#Teaches#Us#
! Use#interfaces#for#objects#whose#behavior#or#use#may#change#
! Proxies###– Accommodate#changes#that#require#preD#and#postDprocessing#
– Separate#op8onal#behavior#from#"always“#behavior###! Thus,#improved#cohesion#
258# ### #16#October#2013#
The'Decorator'Pa*ern'
Paradigm00PaKerns0Wisdom0
Principles0 Prac+ces0
Quali+es##
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
259# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
The#Decorator#PaWern#
Mo8va8on#– Change#func8onality#of#an#object#of#a#class#
! Rather#than#the#en8re#class#– Dynamically#add#addi8onal#func8onality#– Pick#from#addi8onal#behaviors#
! Add#desired#ones#for#a#par8cular#case#! Analogy#
– Electrical#connectors##! One#with#on/off#"#One#with#fuse#"#One#with#UPS##
! GoF#Intent:##– AWach#addi8onal#responsibili8es#to#an#object#dynamically.##
*Design%Pa2erns,%Elements%of%Reusable%Object<Oriented%So?ware,#Gamma,#Helm,#Johnson,#Vlissides#
260# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Decorator#PaWern#for#Streaming#IO#
Client
TCPIPStream + flush()
FileStream + flush()
U128 + flush()
CompressStream + flush()
Stream + output() + flush()
StreamDecorator
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
261# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Encapsula8on#
FileStream#
Compress#
U128#
Client#
Convert#to#U128#and#then#flush#
Compress#and#then#flush#
Send#
Each#circle#encapsulates#(hides)#what#is#within#from#what#is#without.###
Each#en8ty#(U128,#Compress,#FileStream)#also#does#not#know#if#it’s#the#outer#circle#or#not#
Construc8on:###Stream#s#=#new#U128(#####new#Compress#(#######new#FileStream(“name”)));#Use:####s.output();####s.flush();##
262# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Comparing#Adapter,#Façade,#Proxy#and#Decorator#
Adapter Facade Proxy Deco-rator
Have pre-existing stuff? Yes Yes Yes Yes Is the client expecting a particular interface?
Yes No Yes Yes
Want to make a new interface to simplify things?
No Yes No No
Modifying interface to what clients expect?
Yes No No No
Want some new function before or after the normal action?
Maybe, but not intent
Maybe, but not intent
Yes (sta-
tically)
Yes (dyna-
mically)
Client Pre-Existing?which pattern?
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
263# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Object#Diagram#of#Decorator#/#Proxy#
Decorator''B'
Decorator'A'
Client'
Original'
Proxy'
Client'
Original'
Decorator' Proxy' ! Proxy##– Func8onality#usually#added#sta8cally##
– Usually#knows#original#object#
! Decorator#– Func8onality#usually#added#dynamically##
– Does#not#know#original#object##
264# ### #16#October#2013#
Chain'of'Responsibility'
Paradigm00PaKerns0Wisdom0
Principles0 Prac+ces0
Quali+es##
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
265# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
The#Chain#of#Responsibility#PaWern#
! Issue:#– Any#of#a#set#of#objects#can#perform#a#task#– Requestor#of#task#does#not#want#to#know#which#one#does#it#
! GoF#Intent:##– Decouple#sender#of#a#request#to#its#receiver##
! By#giving#more#than#one#object#a#chance#to#handle#the#request#
– Chain#receiving#objects#! Request#passed#along#the#chain#un8l#an#object#handles#it*##
! Example:#Have#a#message#to#decode#– Chain#decoders#together#– Pass#message#to#each#one#un8l#one#decodes#it#
*Design%Pa2erns,%Elements%of%Reusable%Object<Oriented%So?ware,#Gamma,#Helm,#Johnson,#Vlissides#
266# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Chain#of#Responsibility#Object#Diagram##
Decoder1
Decoder3
Decoder2
Decoder4
return computedvalue or given
return computedvalue or given
return computedvalue or given
return computedvalue or given
2: decode ifpossible
1: decode ifpossible
3: decode ifpossible
4: decode ifpossibleClient
Requestto decode
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
267# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Example#CoR#Diagrammed#
Client
Decoder1 + decode()
Decoder2 + decode()
Decoder3 + decode()
Decoder + decode()
1#
0..1#
268# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Who#Knows#How#to#Build#the#Chain?#
! Have#to#decide#somewhere:#– Which#decoders#belong#in#the#chain#– What#order#they#should#be#in#– How#the#Chain#will#end##
! Request%execuBon%not%guaranteed%– Possible#it#not#handled#at#all#
! Good#to#have#default#"always"#en8ty#at#end#of#chain#– Either#default#behavior#or#error#signaling##
! Op8ons#included:#– Hard#code#chain#in#Client#– Client#gets#chain#from#factory##
! Factories##usually#less#likely#to#grow#in#number#than#clients#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
269# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Code#Example#of#Chain#of#Responsibility#
class Client { public string Decode( string message, Decoder aDecoder) { return aDecoder.Decode( message); } } abstract class Decoder {
private Decoder trailer; public Decoder ( Decoder nextDecoder) { trailer= nextDecoder; } public string Decode ( string message) { if (MyAction(message))
return DecodeString( message); if (trailer!= null) return trailer.Decode(message); return "Cannot decode"; } abstract protected bool MyAction( string message); abstract protected string DecodeString( string message); }
C#
270# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Code#Example#of#Chain#of#Responsibility#
class Decoder1 : Decoder { protected override bool MyAction( string message) { // see if I can do this. // if I can: // return true // if I can’t // return false } protected override string DecodeString( string message) {
String decodedMessage; //Decode the message
return decodedmessage; } } // other decoders follow this format as well.
C#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
271# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Code#Example#of#Chain#of#Responsibility#
class Client { public String decode( String message, Decoder aDecoder) { return aDecoder.decode( message); } } abstract class Decoder { private Decoder trailer; public Decoder ( Decoder nextDecoder) { trailer = nextDecoder; } public String decode ( String message) { if (myAction(message))
return decodeString( message); if (trailer!= null) return trailer.decode( message); return "Cannot decode"; } abstract protected boolean myAction( String message); abstract protected String decodeString( String message); }
Java
272# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Code#Example#of#Chain#of#Responsibility#
class Decoder1 extends Decoder { protected override boolean myAction( String message) { // see if I can do this. // if I can: // return true // if I can’t // return false } protected String decodeString( String message) {
String decodedMessage; //Decode the message
return decodedmessage; } } // other decoders follow this format as well.
Java
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
273# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Code#Example#of#Chain#of#Responsibility#
bool Client::decode ( SubString message, Decoder aDecoder) { return aDecoder.decode( message); } class Decoder { public: Decoder(Decoder*); ~Decoder(); bool decode(string); protected: virtual bool myAction( string)= 0; private: Decoder *trailer; } Decoder::Decoder (Decoder* aDecoder) { trailer= aDecoder; } bool Decoder::decode ( string message) { if (myAction(message)) return(true); if (trailer!= null) return trailer->decode(message); else return false; } }
C++
274# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Code#Example#of#Chain#of#Responsibility#
class Decoder1 : public Decoder { public: protected: bool myAction( string message); } bool Decoder1::myAction( string message) { // see if can do this. // if can: // do it here // // return true // if can’t // return false } } // other decoders follow this format as well.
C++
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
275# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
A#Focused#Example:#Poker#
Hand HandEvaluator
+eval(card[]):int
RoyalFlush
+eval(card[]):int
StraightFlush
+eval(card[]):int
4ofaKind
+eval(card[]):int
Flush
+eval(card[]):int
FullHouse
+eval(card[]):int
Straight
+eval(card[]):int
3ofaKind
+eval(card[]):int
Pair
+eval(card[]):int
HiCard
+eval(card[]):int
Encapsulated#Rules#
276# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
At#Run8me#
Hand RF
SF
4K
FH
FL
ST
3K
PR
HC
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
277# ### #16#October#2013#
Vector'Forces'Discussion'
278# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Design##
! We#need#to#store#some#related#numbers.#! Let’s#store#them#in#consecu8ve#memory#loca8ons#
– What#do#we#call#it?###A#vector#
! Alternate#way#of#storing##– Store#a#number#along#with#a#reference#to#the#next#number.#
– What#do#we#call#it?##A#linked#list##
#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
279# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Forces#
Array Vector Linked List
Random Access Quick Quick Slow
Insert Client needs to make copy
Need to copy memory
Quick
Size per element Size of data Size of data
Size of data plus the reference
Cost of insert Allocate and copy Allocate and copy
Same every time
280# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Design#
! Vector##– Consecu8ve#memory#addresses#
– Use#index#to#select#element##
! Linked#list##– NonDconsecu8ve#memory#addresses##– Reference#to#next#element#in#list##
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
281# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Implementa8on##
! Vector##– Allocate#memory#big#enough#to#hold#ini8al#elements#
– Ini8alize#each#element#to#null#or#0##
! Linked#List#– Set#ini8al#reference#to#null#– As#add#element,#update#the#reference##
– Make#sure#don’t#go#off#end#when#traversing##– Maybe#allocate#from#block#of#storage#to#avoid#severe#memory#block#use##
282# ### #16#October#2013#
Architectural'Pa*erns'
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
283# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Architectural#PaWerns#
! Model#View#Controller#– Model#–#handles#data#and#rela8onships#
– View#–#displays#the#model#– Controller#–#interface#to#changing#the#model#
Controller#
Model#
View#
284# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Architectural#PaWerns#
! Pipes#and#Filters#(Unix)#– Document#to#spell#check##– Input#"#WordBreaker#"#Sorter#"#Unique#"#Dic8onaryCompare##
– Note:##Can#be#Decorator#paWern#on#lower#level#
! Cat#filename#|#sort#|#uniq#! Filter#/#pipe#/#filter#/#pipe###
A#B#C#A#A##
Becomes##A#
A#A#
B#
C##Becomes##
A#B#
C##
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
285# ### #16#October#2013#
Inheritance'Versus'Interface'
286# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Inheritance#Issues##
! Inheritance#combines#two#perspec8ves#– Common#interface#(specifica8on)#
! Derived#classes#play#same#role#as#base#class##
– Common#implementa8on##! Inherited#methods,#aWributes#
! O_en#mix#up#these#perspec8ves###
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
287# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Changing#Base#versus#Changing#Interface#
Base#Class#
MethodOne()#
AddedMethod()#//New#
Interface#
MethodOne()#
AddedMethod()#//#New#
Derived#Class#
Does#AddedMethod()#need#overriding#?##
Implemen8ng#Class#
AddedMethod()#needs#implementa8on#
288# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Inheritance#Versus#Interface#
BaseClass#Method();#
DerivedClass# AnotherDerivedClass#Method()#{#anotherWay;}##
How#to#avoid#redundancy?#
OneMore##DerivedClass#
Fourth#DerivedClass#Method()####{#anotherWay;}##
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
289# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Inheritance#
BaseClass#Method();#
DerivedClass#
AnotherDerivedClass#
Create#hierarchy##
OneMore##DerivedClass#
Fourth#DerivedClass##
AnotherDerivedClass#Method()#{#anotherWay;}##
290# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Inheritance#
BaseClass#Method();#NewMethod();#
DerivedClass#NewMethod()#{someWay;}##
AnotherDerivedClass#
NewMethod()##Two#classes#need#same#override#
OneMore##DerivedClass#
Fourth#DerivedClass#NewMethod()#{someWay;}##
AnotherDerivedClass#Method()#{#anotherWay;}##
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
291# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Interface#
Interface#Method();#
Implemen8ngClass#
AnotherImplemen8ngClass#InterfaceHelper#Method();#AnotherWay();##
OneMoreImplemen8ngClass#
FourthImplemen8ngClass#
292# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Inheritance#Versus#Interface#
Interface#Method();#NewMethod():#
Implemen8ngClass#
AnotherImplemen8ngClass#InterfaceHelper#Method();#AnotherWay();##NewMethod();#SomeWay();#
OneMoreImplemen8ngClass#
FourthImplemen8ngClass#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
293# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Prefactoring#Guideline#
! Avoid#premature#hierarchaliza8on##– Don’t#create#hierarchies#un8l#you#really#need#them##
! Easier#to#create#right#hierarchy#than#to#deDhierarchalize#the#wrong#one#
294# ### #16#October#2013#
Code'Notes'
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
295# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Interfaces#and#Abstract#Classes#
! An#interface#– Defines#methods#and#their#signatures#
! An#abstract#class#– Defines#methods#and#their#signatures#– Can#include##
! Data#members#(aWributes)#! Method#implementa8ons#
! Class#can:#– Derive#from#abstract#class##
! O_en#only#from#one#class#(Java,#C#)#
– Implement#interface##! Can#implement#numerous#interfaces#
296# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Interface#and#Abstract#Classes#(2)#
! Interface#cannot#contain#sta8c#method#– So#some#examples#use#abstract#class##
– If#sta8c#method#is#in#another#class#(for#example#a#factory#class),#then#could#use#interface##
interface#MyInterface#####void#method();#
class#MyInterfaceHelper#####sta8c#MyInterface#getInstance();##
abstract#class#MyInterface#####void#method();#####sta8c#MyInterface#getInstance();###
class#MyClass####
class#MyClass####
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
297# ### #16#October#2013#
Naming'
298# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Naming(1)#
! Six#character#names#(FORTRAN)###– CMPORB#,#ORBCMP##
– STRCMP##– Needs#comments##
! But#now?##– What’s#the#limit?### ##
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
299# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Naming#(2)#
Class BfsSwsTpidConfigTable { BfsSwsTpidConfig TrySEHPBfsSwsTpidConfig() { try { int iRec = 0; int dwRecs = CountRecs(sizeof(BfsSwsTpidConfig)); while(iRec < dwRecs) { BfsSwsTpidConfig pbstc = (BfsSwsTpidConfig ) Pv() + iRec; if(pbstc.m_dwTPID == _dwTPID) { return pbstc; } ++iRec; } } }
300# ### #16#October#2013#
Commonality5Variability'Analysis'
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
301# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
CommonalityDVariability#Analysis#
! Abstrac8on##focuses#on#commonality#(general)#! DeDemphasize#variable#details##(specifics)#.#! Acknowledgement:##
– Commonality#–#Variability#Analysis#in#James#Coplien’s#Mul8Dparadigm#Design#for#C++#
His#thesis#is#on#line#at#hWp://www.netobjec8ves.com/download/CoplienThesis.pdf#
c#
Paradigm00PaKerns0
Wisdom0Principles0 Prac+ces0
Quali+es##
His#thesis#is#on#line#at:#hWp://www.netobjec8ves.com/files/CoplienThesis.pdf#(link#is#caseDsensi8ve)#
302# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Commonali8es#and#Variability#
! Commonali8es#can#define#basic#domain#concepts#– Recognized#from#experience#
– Learned#through#analysis#(abstracted)#! Variability#is#varia8on#of#commonality##
! From#an#architectural#perspec8ve:#– Commonality#analysis#gives#architecture#its#longevity;##– Variability#analysis#drives#its#fitness#for#use”*#
*'MulB<Paradigm%Design%in%C++,#Jim#Coplien#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
303# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Abstrac8on#Longevity##
Longevity###Interface#Car#####turn()####speedUp()####slowDown()#
Implementa8on#VW#####turn()####speedUp()####slowDown()#
Implementa8on#BMW####turn()####speedUp()####slowDown()#
Implementa8on#Yugo####turn()####speedUp()####slowDown()#
304# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Steps##
! Steps#to#follow:#– Pick#something#in#problem#domain#– Ask#is#it?#
! A#par8cular#way#of#doing#something#(a#varia8on)?#– If#so,##what#concept#is#it#a#varia8on#of?# # ##
! Or#! A#way#of#conceptually#thinking#about#different#ways#to#do#things?#
– If#so,#iden8fy#as#a#concept#! If#neither##
– (just#a#standalone#func8on)#,#iden8fy#it#as#an#en8ty#
not in sem
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
305# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Commonality–Variability#Analysis#Exercise#
! Have#to#handle#European#date#formats#as#well#as#US#date#format#
! US#Tax#! Canadian#PST,#GST#! European#VAT#! German#Shipping#Rates#! French#Freight#Rules#! Verifica8on#of#valid#addresses#
in#different#countries#
! Max#Weight#in#US#is#70#lbs#! Canadian#Freight#Rules#! US#Freight#Rules#! US#Phone##s#! European#Phone##s#! Max#Weight#in#Germany#is#40#
kg#! Euros#in#Europe,#Dollars#in#
US,#etc…#
Say#we’re#given#the#following#requirements#for#an#eDcommerce#system:#
#
306# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
CVA#and#OO#Rela8onships#
! CVA#does#not#deal#with#rela8ng#concepts#– E.G.#US$#in#US,#Euro#in#Germany.###
! Money#and#country0are#“related”#
– US$##and#Euro#varia8on#of#money##! Not#of#country##
! CVA#says:#– First#find#Commonali8es#and#Variability's#
! Limit#to#isDa#rela8onship#
– Then#iden8fy#interDrela8onships#later#! Will#use#paWerns#to#implement#rela8onships##
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
307# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Discussion#Exercise#
! For#the#eDcommerce#system##– Iden8fy#commonali8es#and#variability's#present#in#the#problem#domain#
– First#iden8fy#commonali8es#! Then#iden8fy#varia8ons#within#these#commonali8es#
not in sem 308# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Work#Space#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
309# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Work#Space#
310# #Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Work#Space#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
311# #Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Work#Space#
312# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Some#Commonali8es#and#Variabili8es#
! Con8nents#– European#– North#American#
! Countries#– France#– Germany#– Canada#– US#
! Taxes#– European#– Canadian#– US#
! Money#– US#$#– Canadian#$#– Euro#
! Phone###Formats#– European#– US/Canadian#
! Shipping#Rules#– French#– German#– Canadian#
! Date#Formats##– yyyy/mm/dd#– dd/mm/yyyy#– mm/dd/yyyy#
! Freight#Rates#– German#Rates#– French#Rates#– Canadian#Rates#
! Shipping#– Truck#– Plane#– Rail#– Ship#
! Max#Weights#– German##D#40#kg#– French#–#none#– Canada#–#none#– US#D#70#lbs#
! Address#Verifica8on#– French#– German#– Canadian#– US# Note:#If#Units#are#abstracted,#
perhaps#Max0Weights0can#simply#be#an#aWribute/value#
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
313# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Notes#about#Commonali8es#and#Their#Varia8ons#
! CVA#is#just#a#star8ng#point.##Suggests:##– Concepts#D>#abstract#interfaces#– Varia8on#D>#concrete#types#
! Not#all#commonali8es#and#varia8ons#are#useful#– Some#describe#varia8ons#implementable#by#changing#an#aWribute#value#(e.g.,#finance#charge#rate)#
314# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Ways#To#Handle#Varia8on#
! PaWerns#–#Strategy,#others#! Tables#–#Lookup#value##! Pass#in#values#
Concept / Variation US Canada Germany
Max weight 70 lbs none 40 kg
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
315# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Exercise#D#Which#Way?#
Varia8ons#(e.g.#Countries)#
Concepts#(e.g.)#Address#Verifica8on##
316# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Handling#Varia8ons##D#(1)##
int getMaximumWeight(Locale locale) { switch(locale)
{ case US:
return 70; case Canada
return UNLIMITED; //…
// Or a table lookup }
String getDateAsString(Locale locale, Date date)
{ switch(locale)
{ case US:
return date.FormattedAs(locale); //…..
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
317# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Handling#Varia8ons#(2)##
interface Details { int getMaximumWeight(); getDateAsString(Date date); }; class US implements Details { int getMaximumWeight() { return 70; } String getDateAsString) Date date){ return date.FormattedAs(US);} } class Canada implements Details { int getMaximumWeight() { return UNLIMITED; } String getDateAsString) Date date){ return date.FormattedAs(CANADA);} }
318# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
Using#CommonalityDVariability##Analysis#to#Design#Class#Structures#
Commonalityanalysis
Variabilityanalysis
Conceptualperspective
Specificationperspective
Implementationperspective
Interface
Operations
Concreteclass
Operations
Concreteclass
Operations
Design'Pa*erns'Explained'
16#October#2013#Copyright#©#2007#Net#Objec8ves.#All#Rights#Reserved.#
319# #Copyright#©#2013##Net#Objec8ves.#All#Rights#Reserved.## #16#October#2013#
How#Do#Abstrac8ons#/#CVA#Relate#to#PaWerns?#
! PaWerns#reflect#separa8on#that#good#abstrac8ons#create#in#design#
! PaWerns#proceed#from#CVA#! CVA#can#be#used#to#discover#paWerns#(to#be#shown#shortly)##