Mais conteúdo relacionado Semelhante a Avoiding Overdesign and Underdesign (20) Avoiding Overdesign and Underdesign2. !
!
!!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
ken.pugh@netobjectives.com!
5. Ken"Pugh"
Photo
Size:
Height: 2.25
Position:
from top left corner
Horizontal 0.75
Vertical 1.
Picture Style: Simple Black
Frame
! Fellow"Consultant"
! OOA&D,"Design"PaSerns,"Lean,"Scrum,"TestVDriven"
Development"
! Over"2/5"century"of"soYware"development"
experience"
! Author"of"seven"books,"including:"
ken.pugh"
@netobjec6ves.com"
– 0Prefactoring:0Extreme0Abstrac+on,0Extreme0
Separa+on,0Extreme0Readability00(2006"Jolt"Award)"
– 0Interface0Oriented0Design0
– Lean0Agile0Acceptance0TestFDriven0Development:0
BeHer0SoIware0Through0Collabora+on0
No code goes in till the test goes on.
A journey of two thousand miles begins with a single step.
3"
"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""
"6"November"2013"
6. Lean for Executives
Product Portfolio
Management
Business Product Owner
Scaled Agile Framework
Business"
ASSESSMENTS"
CONSULTING"
T RAINING "
COACHING"
Lean"
Enterprise"
Manag
ement"
Team"
technical"
process"
Kanban / Scrum
ATDD / TDD / Design Patterns
Emergent Design
4"
Lean Management
Project Management
"Copyright"©"2007"Net"Objec6ves."All"Rights"Reserved.""
"6"November"2013"
13. Creeping"Changes"(3)""
function()
{
if (a) {
if (b) {
Do_another_thing:;
//…
}
else {
Do_one_more_thing;
//..
}
}
else {
Do_this;
Do_that;
Do_something_else;
}
}
11"
"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""
"6"November"2013"
14. Cohesion"
! Cohesion""
– How"“closely"the"opera6ons"in"a"rou6ne"[or"class]"are"related.”""
– Cohesion"as"“clarity”""
! Because"the"more"opera6ons"are"related"in"a"rou6ne"[or"class]"the"easier"it"is"to"
understand"the"code"and"what"it's"intended"to"do."*"
! Strong"cohesion"related"to"clarity"and"understanding."
! “No"schizophrenic"classes”"
*"Steve(McConnell,"Code0Complete,"1993,"p."81."Note:"This"concept"was"first"
described"by"Larry"Constan6ne"in"1975,"but"we"like"McConnell’s"defini6on"best."
12"
"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""
"6"November"2013"
15. Coupling"
! Coupling""
– Strength"of"a"connec6on"between"two"rou6nes"[or"classes].""
– Coupling"is"a"complement"to"cohesion."""
! Cohesion"describes"how"strongly"the"internal"contents"of"a"rou6ne"[or"class]"are"related"
to"each"other.""
! Coupling"describes"how"strongly"a"rou6ne"is"related"to"other"rou6nes.""
– Goal"is"to"create"rou6nes"[and"classes]"with"internal"integrity"
(strong"cohesion)"and"small,"direct,"visible,"and"flexible"
rela6ons"to"other"rou6nes"[and"classes]"(loose"coupling).”*"
! Tight"coupling"is"related"to"highly"interconnected"code."
*"Steve(McConnell,"Code0Complete,"1993,"p."81."Note:"This"concept"was"first"
described"by"Larry"Constan6ne"in"1975,"but"we"like"McConnell’s"defini6on"best."
13"
"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""
"6"November"2013"
18. Encapsula6on"
Usual"encapsula6on""
! Data"
– Hide"from"other"en66es."
! Implementa6on"
– How"par6cular"func6on"is"implemented"or"whether"it"delegates"to"other"objects"
Also:"
! Object"Type"
(
– Abstract"classes"and"interfaces"hide"implemen6ng"classes."
! Design"
– Assembling"collabora6ng"classes"with"factory"keeps"clients"decoupled"from"design"
! Construc6on"
– Encapsula6on"of"construc6on""V"wrap""new"""in"getInstance()"method""
"
16"
"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""
"6"November"2013"
25. Quali6es"and"Pathologies"
! Strong"cohesion"
– Goal:"classes"do"one"thing"–"easier"to"understand"
– Pathology:"the"“God"object”"is"as"bad"as"it"gets"
! Proper"coupling"
– Goal:"well"defined"rela6onship"between"objects"
– Pathology:"side"affects"when"have"improper"coupling"
! No"redundancy"
– Goal:"once"and"only"once"
– Pathology:"a"change"in"one"place"must"be"duplicated"in"another"
! Readability"
– Goal:"coding"standards"
– Pathology:"nonVreadable"code"
! Encapsula6on"
– Goal:"hide"data,"type,"implementa6on"
– Pathology:"assump6ons"about"how"something"is"implemented"makes"it"
difficult"to"change"
23"
"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""
"6"November"2013"
38. Problems"with"This"
! BriSle.""
– Not"easily"allow"for"new"deriva6ons"of"Card"and"Chip"
! Or"new"transmission"types"
! Redundant.""
– Changes"in"send()"in"ChipTCPIP"causes"changes"in"CardTCPIP"
! Weak"cohesion."""
– Concrete"classes"are"about"mul6ple"things."
! Mul6ple"varia6ons"cause"combinatorial"(class)"explosion"
– Increases"maintenance"problems"
! In"Short:""
– Using"inheritance"for"specializa6on"does0not0scale0
36"
"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""
"6"November"2013"
42. Gang"of"Four"Gives"Us"Guidelines*"
! Design"to"interfaces"
! Favor"object"delega6on"over"class"inheritance."
Gamma,(E.,(Helm,(R.,(Johnson,(R.,(Vlissides,(J."Design0PaHerns:0
Elements0of0Reusable0ObjectFOriented0SoIware,"1995,"pp."18,"20,"29."
40"
"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""
"6"November"2013"
50. "
Factory"Example""
// Client Selection
enum EncryptionType {Strong, Weak, None};
Encrypt getEncryptInstance(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”);
} }
48"
"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""
"6"November"2013"
51. Factory"For"Two"Strategies"
enum ChipType {ForCommercial, ForUS,
ForImportantCustomer};
Chip getChip(ChipType ct) {
switch (ct) {
case ForCommercial:
return new Chip(GetEncryptInstance(Weak),
GetSendInstance(TCP));
case ForUS:
return new Chip(GetEncryptInstance(Strong),
GetSendInstance(FTP));
case ForImportantCustomer:
return new Chip(GetEncryptInstance(Weak),
GetSendInstance(FTP);
}}
// Or use table
49"
"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""
"6"November"2013"
68. Then,"Add"New"Implementa6ons"
Chip
Used by Client
or Chip
+ encrypt()
TCPIP
EncryptNull
Encrypt64
Encrypt128
+ transmit()
Config
+ getEncrypt()
66"
Encrypt
+ get AndSendS tatus()
# get Stat us()
# enc rypt ()
# send()
Client
makes one of these
"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""
"6"November"2013"
71. Refactor"First"
Client
Used by Client
or Chip
Chip
Encrypt
+ getAndSendStatus()
# getStatus()
# encrypt()
# send()
+ encrypt()
EncryptNull
Encrypt64
Transmit
+ transmit ()
Encrypt128
Config
+ getEncrypt()
+ getTransmit()
makes this
TCPIP
makes one of these
69"
"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""
"6"November"2013"
72. Add"Other"TransmiSers"
Client
Used by Client
or Chip
Chip
Encrypt
+ getAndSendStatus()
# getStatus()
# encrypt()
# send()
+ encrypt()
EncryptNull
Encrypt64
Transmit
+ transmit()
Encrypt128
Config
+ get Encrypt()
+ get Transmit()
TCPIP
SMTP
makes one of these
makes one of these
70"
"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""
"6"November"2013"
74. First,"Refactor"So"OCP"Can"Apply"
Hardware"
+ getAndSendStatus()"
# getStatus()"
# encrypt()"
# send()"
Encrypt"
Client"
+ encrypt()"
Chip"
EncryptNull"
Used by Client "
or Hardware"
Encrypt64"
Transmit"
+ transmit()"
Encrypt128"
Config"
+ getEncrypt()"
+ getTransmit()"
+getHardware()"
TCPIP"
SMTP"
makes one of these"
makes one of these"
72"
"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""
"6"November"2013"
75. Then,"Add"New"Func6on"
Hardware"
+ getAndSendStatus()"
# getStatus()"
# encrypt()"
# send()"
Encrypt"
Client"
+ encrypt()"
Card"
Used by Client "
or Hardware"
Chip"
!(
aRern
e(p
EncryptNull" Encrypt64"
(bridg
his(is(a
T
Transmit"
+ transmit()"
Encrypt128"
Config"
+ getEncrypt()"
+ getTransmit()"
+getHardware()"
TCPIP"
SMTP"
makes one of these"
makes one of these"
73"
"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""
"6"November"2013"
76. "A"Few"Comments"
! Not"coincidence"or"good"luck"change"is"easy"
! Happened"because"
– No"redundancy""
– Unrelated"things"in"different"classes"
! Low"level"dis6nc6ons"easy"to"see"
– Even"if"immediate"benefit"is"not"
! Use"them"because"they"represent"very"low"cost"
– Will"result"in"significant"gains"if"things"change"(which"they"
almost"certainly"will)"
74"
"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""
"6"November"2013"
79. Handling"This"in"Chip"Weakens"Cohesion"
! Handle"varia6on"as:"
private void sendStatus(String anInfo) {
if (transType== TCPIP) sendStatusTCPIP(anInfo);
else sendStatusSMTP(anInfo);
}
! Requires"Chip"class"to"remember"more"detail"about"
transmission."
– More"than"how"TCP/IP"works"
– Now""SMTP"stuff""
– This"erodes"cohesion""
! So"split"out"TransmiSer."
77"
"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""
"6"November"2013"
119. Inheritance"Versus"Interface"
BaseClass
Method();
NewMethod():
What happens if new method added to base class?
Is it applicable to all derived classes?
Do you know everything that is derived?
What if four derived classes and two use same override?
Need a helper class
DerivedClass AnotherDerivedClass
Method() { anotherway;}
Interface
Method();
NewMethod():
Fourth
OneMore
DerivedClass DerivedClass
Method()
{ anotherway;}
AnotherImplementingClass InterfaceHelper
ImplementingClass
Method();
NewMethod():
OneMoreImplementingClass
AnotherWay();
FourthImplementingClass
117"
"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""
"6"November"2013"