SlideShare uma empresa Scribd logo
1 de 120
Baixar para ler offline
!

BT6

Concurrent!Session!
11/14/2013!2:15!PM!
!
!
!
!

"Avoiding Overdesign and
Underdesign"
!
!
!

Presented by:
Ken Pugh
Net Objectives
!
!
!
!
!
!
!
!
!

Brought(to(you(by:(
!

!
!
340!Corporate!Way,!Suite!300,!Orange!Park,!FL!32073!
888C268C8770!E!904C278C0524!E!sqeinfo@sqe.com!E!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
ken.pugh@netobjectives.com!
info@netobjec+ves.com000
www.netobjec+ves.com
0

Avoiding(Over(and(
Under(Design(
In"Agile"Projects"
"
Ken"Pugh"
Fellow"Consultant"
Net"Objec6ves"

1"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Agenda"

!  Emergent"Design"
–  Code"Quali6es"
–  Refactoring"

!  Case"Study"
!  Advice"from"the"Gang"of"Four"
!  Emergent"Design"In"Ac6on"
"
"

2"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
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"
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"
Emergent(Design(
3(Code(Quali8es(

5"

"""

"6"November"2013"
Predictability"

!  Can’t"predict"how"requirements"going"to"change"
!  Can"predict"how"code"will"adapt"to"unpredictable"

requirements"changes"
!  How"to"increase"predic6on"abili6es"of"code"quality?"

6"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Ques6on"to"Ask"

!  When"working"on"a"mature"system"consider"when"
adding"a"new"func6on…"

""""""which"task"area"takes"more"6me"
""
"–"wri6ng"the"new"func6on"or""
""
"–"integra6ng"it"into"the"system?"

7"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
8"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Creeping"Changes"
function()
{
Do_this;
Do_that;
Do_something_else;
}

9"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Creeping"Changes"(2)""
function()
{
if (a) {
Do_another_thing:
//…
}
else {
Do_this;
Do_that;
Do_something_else;
}
}

10"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
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"
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"
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"
Coupling"To"Data"
Class
Global Data

Attributes

Function
One
Function
Two
Function Three

14"

Method One
Method Two
Method Three

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
No"Redundancy"

!  "One"Rule"in"One"Place""
!  Redundancy"is"not"just:"
–  Redundant"state"
–  Redundant"func6ons"

!  It"can"also"be"redundant"rela+onships0

15"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
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"
Abstrac6on"

!  Abstrac6on"encompasses"encapsula6on"
–  Think"about"what"you"want"done,"not"how"you"want"it"done""

!  “When"You’re"Abstract,"Be"Abstract"All"the"Way”"
–  Never"use"a"primi6ve"

!  Example:"

–  double"GetCost();""
–  AddToOrder(double"price);"

!  Versus"

–  Dollar"GetCost();"
–  AddToOrder(Dollar"price);""

""

17"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Observa6on"

!  Reversible"changes"are"oYen"not"equal"in"difficulty"
!  Usually"easier"to"deobjec6vey"for"performance"than"it"
is"to"objec6vey"for"code"quality""
!  Example:"

–  double"GetCost()""""Dollar"GetCost()"
–  Dollar"GetCost()"""double"GetCost()""

18"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Testability"and"Design"

!  Crea6ng"tests"first"is"a"kind"of"design"
!  Forces"look"at:"
–  Public"method"defini6ons"
–  What"responsibili6es"of"object"are"

!  Easy"testability"6ghtly"correlated"to:"
–  Loose"coupling""
–  Strong"cohesion"

19"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Testability"

!  Difficult"to"unit"test""code"is"oYen:"
–  Tightly(Coupled:""
"I"cannot"test"this"without"instan6a6ng"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"mul6ple"places"to"ensure"it"works"everywhere""

20"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Unit"Tes6ng"

!  Tests"at"low"or"granular"level"
!  Test"confirms"that"code"reflects"one"inten6on"of"system"
!  Good"test"of"our"thought"process:"
–  If"class"does"one"thing"(strong"cohesion)"
!  Then"func6onality"is"testable"
–  If"class"does"not"create"side"effects"in"other"classes,"(loose"
coupling),""
!  Then"testable"individually"

21"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Testability"and"Contracts"

!  Contracts"
–  Seman6c"–"desired"behavior""
–  Syntac6c"–"enforced"by"language""

!  Seman6c"contract"enforced"by"syntac6c"contract"
requires"less"tes6ng"
!  Example:"
–  void"setPriority(int"priority);"
"versus"
–  void"setPriority(Priority"aPriority);"

22"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
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"
Emergent(Design(
Refactoring(

24"

"""

"6"November"2013"
Refactoring"

!  Refactoring:""Improving"the"Design"of"Exis6ng"Code"*"
!  “Refactoring"is"the"process"of"changing"a"soYware"

system"in"such"a"way"that"it"does"not"alter"the"external"
behavior"of"the"code"yet"improves"its"internal"
structure.”*"

0
Mar8n(Fowler,"Refactoring:0Improving0the0Design0of0Exis+ng0Code."AddisonVWesley."1999."
*

25"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Types"of"Refactoring"
Refactoring(Bad(Code(
!  Code""smells""
!  Improve"code"quality"
!  Clean"up"code"without"
breaking"system"

26"

Refactoring(Good(Code(
!  Code"is""6ght""
!  New"Requirement"means"
change"in"code"/"design"
!  Way"to"make"change"
without"breaking"system"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Case(Study(
Monitoring"Microwave""
Communica6ons"Hardware"
"

27"

"""

"6"November"2013"
Complete"Requirements"
!  Need"to"monitor"both"chips"and"cards"
–  Program"requests"status"of"either"and"sends"it"""

!  Over"either"a"TCP/IP"connec6on"or"via"eVmail"(SMTP)""

!  Messages"may"be"encrypted""
–  PGP64"bit"or"PGP128"bit"

!  Chip"status"queued"for"sending"up"to"10"minutes"unless"an"error"
–  Card"status"sent"immediately"

!  Configura6on"file"gives"transmission"method"to"use"

28"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Accommoda6ng"Change"with"Specializa6on"

!  One"way"problem"could"evolve:"
–  Start"with"Chip"and"TCP/IP"
–  Add"one"func6on"at"a"6me"
–  Accommodate"through"specializa6on"

!  Result"not"preSy"(except"as"in"preSy"common)"

29"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Start"with"ChipTCPIP"Requirement"

Client
ChipTCPIP
+ getAndSendStatus()
# sendWithTCPIP()

30"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Now"Get"Card"with"SMTP"

Client
ChipTCPIP
+ getAndSendStatus()
# getStatus()
# send()

CardSMTP
# getStatus()
# send()

31"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
BeSer"Way"

Client

Hardware
+ getAndSendStatus()

ChipTCPIP
# get Stat us()
# send()

32"

CardSMTP
# getStatus()
# send()

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Then"Get"Chip"with"SMTP"Requirement"

Client

Hardware
+ getAndSendStatus()

Chip
# getStatus()

ChipTCP
# send()

33"

CardSMTP
# getStatus()
# send()

ChipSMTP
# send()

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Finally"Get"Card"with"TCPIP"Requirement"

Hardware

Client

+ getAndSendStatus()

Chip
# getStatus()

ChipTCPIP
# send()

34"

Card
# getStatus()

ChipSMTP
# send()

CardTCPIP
# send()

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

CardSMTP
# send()

"6"November"2013"
It"Is,"Of"Course,"Worse0

!  Have"not"discussed"varia6ons"of"encryp6on"
–  Will"make"things"worse"

!  Using"switches"instead"of"inheritance""
–  Will"have"coupled"switches"instead"of"class"hierarchy"

35"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
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"
Combinatorial"Explosion"
Hardware

Client

+ getAndSendStatus()

Card
# getStatus()

Chip
# get Stat us()

CardTCPIP
# send()

ChipTCPIP
# send()

37"

ChipSMTP
# send()

CardSMTP
# send()

CardFTP
# send()

ChipFTP
# send()

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Tes6ng"

!  10"Varia6ons"of"sending""
!  10"Varia6ons"of"encryp6ng""
!  10"Varia6ons"of"compressing""
!  How"many"classes"if"use"inheritance?""
!  How"many"if"use"delega6on?"""

38"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Advice(from(the(
Gang(of(Four(

39"

"""

"6"November"2013"
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"
Design"to"Interfaces"

!  Determine"interface"for"class""
–  Design"to"that,"ignoring"implementa6on"details"
!  Therefore"cannot"couple"to"them"
–  What"you"hide"you"can"change"

!  Stay"at"conceptual"level,"while"designing"
–  Promotes"Cohesion"

41"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Find"What"Varies"and"Encapsulate"It"

!  Iden6fy"varying"behavior"
!  Define"interface"for"behavior""
–  Tailor"as"you"go"
–  Extract"varia6ons"resul6ng"from"new"requirements"
–  Put"those"into"their"own"interfaces"

42"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Favor"Delega6on"Over"Inheritance"

!  Define"interface"encapsula6ng"varia6on""
!  Use"delega6on"to"instance"of"an"implementa6on""

Socket0
Socket_cmp1"

Socket"

Socket_cmp2"

Class0Inheritance0to0Specialize0

Compression0
Cmp1"

Cmp2"

Object0delega+on0

1.  Decouples"concepts"
2.  Can"defer"decisions"un6l"run6me"
3.  Small"performance"hit"
43"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Interface"Oriented"Design"

!  To"save"code,"you"can"use""
–  Inheritance""
–  Delega6on"to"another"class""

!  Cannot"inherit"from"two"classes"(other"than"C++)"
!  Therefore"either""
–  Need"to"determine"the"“most"important”"rela6onship""

44"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Interface"Oriented"Design"(2)"

!  Lean"principle""
–  Make"commitment"at"the"last"possible"moment""
–  (Or"not"at"all"if"possible)""

!  Prefactoring"guideline"
–  Avoid"premature"hierarchiliza6on""
–  Don’t"make"hierarchy"unless"it"is"necessary"""

45"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Separate"Use"From"Construc6on"

!  An"object"should"construct"another"object"or"use"
another"object"
–  But"not"both"

!  Implement"construc6on"with"a"factory""

46"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Concept"/"Varia6ons"
Encryption
E128

TCP

E64

FTP

E0

47"

Send

UDP

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
"
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"
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"
Emergent(Design(
In"Ac6on"

50"

"""

"6"November"2013"
Emergent"Design"

!  TestVDriven"Development,"integrated"with:"
–  High"quality"code"
–  Knowledge"of"design"paSerns"
–  A~tude"of"building"only"what"you"need"(Agile,"YAGNI)"

!  Allows"for"designs"to"emerge"
!  Can"take"advantage"of"what"we"know"
–  Without"overbuilding"or"overVdesigning."

51"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Requirements"as"“Stories”"
!  Story(1:"Request"the"status"of"a"chip,"encrypt"it"with"PGP64"bit"

encryp6on"and"send"that"status"out"via"TCP/IP"
!  Story(2:"Allow"for"not"encryp6ng"the"status"or"using"either"
PGP64"bit"or"PGP128"bit"encryp6on.""A"configura6on"file"will"
determine"what"(if"any)"encryp6on"is"needed"
!  Story(3:"Support"transmission"via"an"eVmail"connec6on.""A"
configura6on"file"will"determine"which"type"of"transmission"to"
use"
!  Story(4:"Support"ge~ng"and"sending"the"status"for"a"card"as"well"

52"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Emergent"Design:"Star6ng"with"Story"1"

!  Request"status"of"a"chip,"encrypt"it"with"PGP64"bit"
encryp6on"and"send"that"status"out"via"TCP/IP"
!  Implement"simplest"solu6on"possible:"
–  No"extra"func6on"
–  Design"for"full"system"will"emerge"via"refactoring"

53"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Thinking"from"a"Testability"Perspec6ve"

!  What"do"we"need"to"test?"
–  Ge~ng"status"
–  Encryp6ng"a"string"
–  Sending"an"encrypted"string"

!  Straighorward"to"write"tests"for"individual"methods"
!  Where"should"the"methods"lie?"
!  What’s"the"easiest"way?"

54"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
TestVFirst"Development"Steps"

1.  Write"a"test"that"expresses"an"intent"of"a"class"in"
system"

– 

Stub"out"class"(enough"to"allow"the"test"to"compile)"

– 

Change"class"just"enough"to"pass"test"

2.  Fail"the"test"(don't"skip"this)"

3.  Pass"the"test"
4.  Examine"class"for"coupling,"cohesion,"redundancy,"and"
clarity"problems."""

– 

Refactor."

5.  Pass"the"test"
6.  Return"to"#1"un6l"all"inten6ons"are"expressed"
55"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Solu6on"Diagrammed"

Client

Chip
+ getAndSendStatus()
# getStatus()
# encrypt()
# send()

Encrypt
+ encrypt()

TCPIP
+ transmit()

56"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Why"Is"this"BeSer?"

!  Clear"what"pieces"do"and"how"they"relate"
–  Increases"extensibility"
–  Eases"maintainability"

!  Some6mes"requirements"misVlead"us"

57"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Transi6on"

!  Remember:"Two"Kinds"of"Refactoring"
1.  Refactoring0Bad0Code:""
!  To"improve"code"quality"
2.  Refactoring0Good0Code:"
!  To"implement"new/changed"requirement,"
–  Now"going"to"do"the"second"

58"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Story"2:"Mul6ple"Encryp6ons"

!  Allow"for"using"no"encryp6on,"PGP64"bit"encryp6on"or"
PGP128"bit"encryp6on"

59"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Refactoring"Says"to"Restructure"Before"Adding"

!  Refactoring:""
–  Change"code"before"adding"new"func6on."
–  Keep"func6on"same,"but"restructure"code"to"improve"it"

!  Advantages:"
–  If"upVfront"tes6ng,"tests"don’t"need"to"change"
!  Doing"same"things"
–  Always"have"something"that"works"
–  If"one"step"at"a"6me"and"something"breaks"
!  More"likely"to"know"what"caused"it""

60"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
How"Can"We"Most"Easily"Test"Things?"

!  Need"to"test"every"encryp6on"
!  Want"to"deal"with"encryp6ons"same"way."
!  Easy"if"have"a"common"interface"for"encryp6ons"
!  If"interfaces"aren’t"the"same,"then"either:"
–  Chip"has"to"deal"with"differences""
–  Use"design"paSerns"to"hide"varia6ons"
!  Requires"wrapping"differences"

61"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
OpenVClosed"Principle"
!  Ivar"Jacobson"said:""
–  “All"systems"change"during"their"life"cycles.""This"must"be"borne"in"mind"
when"developing"systems"expected"to"last"longer"than"the"first"version”"

!  Bertrand"Meyer"summarized"this"as:""

–  SoYware"en66es"(classes,"modules,"func6ons,"etc.)"should"be"open"for"
extension,"but"closed"for"modifica6on"

!  In"short:"

–  Design"modules"so"that"they"never"change."""
–  When"requirements"change,"add"new"modules"to"handle"things"

For"a"good"ar6cle"on"the"OpenVClosed"Principle,"see"www.objectmentor.com/publica6ons/ocp.pdf""

62"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Refactoring"to"OpenVClosed"

!  First"refactor"code"so"can"add"new"func6on"following"
OCP"
!  Then"add"new"code"

63"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
First,"Add"Needed"Interface"and"Factory"

Client

Used by Client
or Chip
Config

Chip

Encrypt

+ getAndSendStatus()
# getStatus()
# encrypt()
# send()

+ encrypt()

Encrypt64

TCPIP
+ transmit()

+ getEncrypt()

64"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Now,"Can"Put"in"the"New"Func6on"
! 
! 
! 
! 
! 
! 

Someone"must"determine"which"encryp6on"to"use"
Maybe"configura6on"object"can"do"that""
Client"object"asks"configura6on"object"what"to"use"
Chip"object"given"needed"behavior""
Now"add"encrypt128"and"no"encrypt"op6ons"
Note:""
–  Chip"object"could"talk"to"configura6on"object"
–  Then"Client"must"give"Chip"informa6on"configura6on"object"needs"

"

65"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
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"
Story"3"

!  Support"transmission"via"an"eVmail"connec6on.""A"
configura6on"file"will"determine"which"type"of"
transmission"to"use"
!  Testability"suggests"concept"of"Transmission"
–  Don’t"have"to"test"all"combina6ons"

!  Design"PaSerns"tell"us"same"thing"

67"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Want"to"Follow"Gang"of"Four"Advice"

!  Because"transmission"will"vary,"
–  Encapsulate"it"and"delegate"to"it"from"Chip"

!  To"implement"
–  First"pull"out"exis6ng"transmission"func6onality"into"own"class"""

!  No"extra"cost"by"doing"this"now"instead"of"when"
possibility"first"no6ced"

68"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
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"
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"
Story"4:"Support"Cards"

!  For"tes6ng"reasons"
–  Don’t"want"to"have"to"handle"different"func6onal"test"cases"
when"we"have"Cards"or"Chips"
–  Want"to"handle"them"together"

!  Want"Cards"and"Chips"to"appear"to"be"the"same"to"the"
Client"
!  Implement"with"twoVstep"RefactorVOCP"shuffle"

71"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
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"
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"
"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"
Code(Quali8es((
As(A(Guide(

75"

"""

"6"November"2013"
Using"Coding"Quali6es"

!  Could"arrive"by"following"coding"quali6es.""
!  TDD,"DPs"and"CVA"(Commonality/Variability"
Analysis)"are"related"to"code"quali6es""
–  Easy"to"use,"so"use"them""

!  However,"to"illustrate,"say"started"with:"
Client
ChipTCPIP
+ getAndSendStatus()
# sendWithTCPIP()

!  and"then"got"another"transmiSer."

76"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
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"
Using"Encapsula6on"

!  Consider"how"to"break"up"func6onality"into"classes"
–  Where"as"much"as"possible"is"encapsulated""

!  Implementa6on"encapsula6on"implies""
–  Pull"out"encryp6on"

!  Design"encapsula6on"means""
–  Chip"should"not"know"about"mul6ple"encryp6ons"
–  Hence"polymorphism"and"factory"

78"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Different"Approaches"for"Different"Situa6ons"

!  Emergent"Design"allows"forward"mo6on:"
–  When"certainty"
!  PaSern"Oriented"Design"
–  When"a"lack"of"certainty"
!  TestVDriven"Development,"supported"by"
–  Refactoring"

!  PaSerns"help"us"see""leading"edge""of"new"designs"

"

79"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Not(An(Ending,(
But(a(Beginning(
"
"

80"

"""

"6"November"2013"
Conclusions(1)"

!  Design"emerges"from:"
–  Concepts"and"varia6ons"(Commonality/Variability"Analysis)""
–  Abstrac6ons"(and"encapsula6on)"
–  Refactoring,"with"adherence"to"good"principles"
–  Thinking"about"paSerns,"which"reflect"past"adherence"to"
good"principles"

81"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Conclusions"(2)"

!  Agility"requires"flexibility"
!  Flexibility"comes"from:"
–  Adherence"to"Good"Principles,"
–  Maintaining"awareness"of"emergent"design,"
–  Understanding"the"forces"of"change"
–  Recognizing"applicable"paSerns"in"a"design"

"

!  We"can"create"maintainable"code!"

82"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
!  Thank"you"
!  Please"fill"out"evalua6ons""

83"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
info@netobjec+ves.com000
www.netobjec+ves.com
0

Supplemental
(

84"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Designing(with(
PaRerns(

85"

"""

"6"November"2013"
The"Bridge"PaSern"
!  GoF(Intent:"“DeVcouple"an"abstrac6on"from"its"implementa6on"
so"that"the"two"can"vary"independently”*"
!  In"example:"

–  Abstrac6on"is"Hardware"V"Chips"and"Cards)"
–  Implementa6on"is"oneaspect"of"its"responsibility"(TCP/IP"communica6on"
and"eVmail"communica6on)"

!  All"implementa6ons"must"look"same"to"abstrac6on"

Gamma, E., Helm, R., Johnson, R., Vlissides, J. Design
Patterns: Elements of Reusable Object-Oriented Software, 1995.
86"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
An"Abstrac6on"(Hardware)"Tightly"Coupled"
to"Its"Implementa6on"(Transmission)"

Hardware

Client

+ getAndSendStatus()

Chip

Card

+ getAndSendStatus()

+ getAndSendStatus()

ChipTCPIP

ChipSMTP

+ getAndSendStatus() + getAndSendStatus()
# sendWithTCPIP()
# sendWithSMTP()

87"

CardTCPIP

CardSMTP

+ getAndSendStatus() + getAndSendStatus()
# sendWithTCPIP()
# sendWithSMTP()

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Bridge"Would"Tell"Us"to"Build"It"This"Way"

Client

Transmit

Hardware

+ sendInfo(string)
+ start()
+ done()

+ getAndSendStatus()

Chip

Card

+ getAndSendStatus()

+ getAndSendStatus()

TCPIP
+ sendInfo(string)
+ start()
+ done()

88"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

SMTP
+ sendInfo(string)

"6"November"2013"
Refactoring(a(
Poor(Design
(

89"

"""

"6"November"2013"
Poor"Design"as"a"Result"of"Using"En66es""
and"Behaviors"/"Specializa6on"

Hardware

Client

+ getAndSendStatus()

Chip

Card

+ getAndSendStatus()

+ getAndSendStatus()

ChipTCPIP

ChipSMTP

+ getAndSendStatus() + getAndSendStatus()
# sendWithTCPIP()
# sendWithSMTP()

90"

CardTCPIP

CardSMTP

+ getAndSendStatus() + getAndSendStatus()
# sendWithTCPIP()
# sendWithSMTP()

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Pull"Out"Duplica6on"of"Transmission"
Hardware

Client

+ getAndSendStatus()

Chip

Card

+ getAndSendStatus()

+ getAndSendStatus()

ChipTCPIP

ChipSMTP

CardTCPIP

CardSMTP

+ getAndSendStatus() + getAndSendStatus() + getAndSendStatus() + getAndSendStatus()

TCPIP
+ sendTCPIP(string)
+ start()
+ done()

91"

SMTP
+ sendSMTP(string)

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Create"Trans0Class"to"Simplify"Things"
Hardware

Client

+ getAndSendStatus()

Chip

Card

+ getAndSendStatus()

+ getAndSendStatus()

ChipTCPIP

CardTCPIP

ChipSMTP

CardSMTP

+ getAndSendStatus() + getAndSendStatus() + getAndSendStatus() + getAndSendStatus()

Transmit
+ sendInfo(string)
+ start()
+ done()

TCPIP
+ sendInfo(string)
+ start()
+ done()

92"

SMTP
+ sendInfo(string)

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Derived"Classes"Now"Not"Needed"
Hardware

Client

+ getAndSendStatus()

Chip

Card

+ getAndSendStatus()

+ getAndSendStatus()

Transmit
+ sendInfo(string)
+ start()
+ done()

TCPIP
+ sendInfo(string)
+ start()
+ done()

93"

SMTP
+ sendInfo(string)

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Can"Keep"Reference"in"Hardware"

Client

HWComp
+ getAndSendStatus()

Transmit
Chip

Card

+ getAndSendStatus() + getAndSendStatus()

+ sendInfo(string, int)
+ start()
+ done()

TCPIP
+ sendInfo(string, int)
+ start()
+ done()

94"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

SMTP
+ sendInfo(string, int)

"6"November"2013"
Technical(
Solu8ons(to(Aid(
Scaling(

95"

"""

"6"November"2013"
Keep"Technical"Dependencies"Low"

!  Ways"minimize"dependencies"of"different"projects"on"
each"other"

–  Design"PaSerns"
–  APIs"to"return"Value"Objects"
–  Mocks"to"provide"layering""
!  And"to"avoid"scheduling"dependencies"

!  Difficul6es"when"one"project"uses"another"
–  Use"component"tes6ng"as"a"method"of"decoupling"components"
–  Implement"with"up"front"testVspecifica6on"and"mocks"

!  Minimize"impacts"that"do"occur"with"Test"Driven"
Development"

96"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Using"Design"PaSerns"

!  Design"paSerns"
–  How"to"deal"with"implementa6ons"at"the"conceptual"level,"
i.e.,"through"an"API"
–  If"added"or"changed"implementa6on""
!  Using"code"does"not"change"
–  Handles"varia6on"

!  DP"can"be"used"in"agile"projects"effec6vely.""

97"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Decoupling"Projects"
!  4"Groups"(A,"B,"C,"D)"
–  All"use"a"network"maintained"by"E"
–  These"groups"all"need"informa6on"from"each"other"
–  They"stated"what"info"was"needed"at"start"of"project"

Group"B"

Group"A"

Group"E"

Group"C"
98"

Group"D"
"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Good"Start,"Bad"Finish"

!  New"informa6on"becomes"needed."
–  Group"A"needs"something"from"Group"B"
–  Group"B"is"busy"and"not"par6cularly"helpful"
–  Group"B"will"not"allow"group"A"to"touch"their"code"

!  How"could"we"have"set"it"up"to"resolve"these"issues?"
–  While"not"requiring"us"to"be"preVcogni6ve?"

!  Use"the"ValueVObject"PaSern"

99"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Value"Object"PaSern"
!  Have"each"group"have"an"API"that"has:"

–  setUp("flag,"GetInfo"useThis)"–"used"to"say"which"value"object"to"use."
–  ValueObject"getInfo(flag)"

!  Calling"program"knows"

–  Type"of"value"object"to"use""
!  and"the"rou6ne"to"fill"it"out"
–  Knows"what"it"gets"back"
!  Can"use"that"par6cular"informa6on"

100"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Shown"in"the"UML"
Group"A"

Group"B"

Group"C"

+setUp(flag,"GetInfo"useThis)"
"""
""""
+getInfo(flag)"

Group"D"
ValueObject"

GetInfo"
+ValueObject"getInfo()"

ValueObjectA"

ValueObjectC"

ValueObjectD"

GetInfoForA"

GetInfoForC"

+ValueObject"getInfo()"

+ValueObject"getInfo()"

GetInfoForD"
+ValueObject"getInfo()"
101"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
How"This"Works"
Group"A"

Group"B"

Group"C"

+setUp(flag,"useThis)"
"""
""""
+getInfo(flag)"

Group"D"
ValueObject"

GetInfo"
+ValueObject"getInfo()"

ValueObjectA"

ValueObjectC"

ValueObjectD"

GetInfoForA"

GetInfoForC"

+ValueObject"getInfo()"

+ValueObject"getInfo()"

GetInfoForD"
+ValueObject"getInfo()"
102"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
info@netobjec+ves.com000
www.netobjec+ves.com
0

103"

Mocks(on(a(Large(
Scale(

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Managing"Dependencies"

!  Let’s"say"group"A"needs"to"use"the"system"built"by"

group"B""
!  Group"A"specifies"to"Group"B"what"group"B"needs"to"
provide"
!  Group"A’s"and"Group"B’s"understanding"is"changing"as"
6me"goes"by"
!  How"can"we"manage"this?"

104"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Managing"Dependencies"

Team"A:"“We"need"
this”"
“When"your"system"
does"this”"

105"

Team"B:"“How"will"
we"know"we’ve"done"
that?”"
How"should"team"B"
respond?"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Managing"Dependencies"

Team"B"should"build"a"mock"of"their"system"
The"mock"sa6sfies"the"tests"that"team"A"specifies"
A’s""
System"

106"

Uses"

Mock"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
A"Mock"as"Requirements/Test"

!  Note"mock"fulfills"the"following"uses:"
–  Defines"the"requirements"for"A"
–  Can"be"used"by"A"to"run"while"team"B"builds"it"
–  Is"an"executable"specifica6on"for"team"B"
!  So"they"can"see"if"they"are"building"the"right"thing"

!  Tests"that"define"the"mock"can"be"used"as"tests"for"

team"B’s"system"
!  What"happens"if"team"A’s"or"team"B’s"understanding"
changes?"
–  The"mock"must"be"updated"

107"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Resources"
!  Resources:"www.netobjec6ves.com/resources""

! 
! 
! 
! 
! 

– 
– 
– 
– 
– 

Webinars/Training"Videos"(PowerPoint"with"audio)"
Ar6cles"and"whitepapers"
Pre/post"course"support"Suppor6ng"materials"
Quizzes"
Recommended"reading"paths"

Blogs"and"podcasts:"blogs.netobjec6ves.com"
Annotated"Bibliography"
AYerVCourse"Support"(students"only)"
Addi6onal"Training"
Two"User"Groups"

–  hSp://tech.groups.yahoo.com/group/leanagile""
–  hSp://tech.groups.yahoo.com/group/leanprogramming""
Join"our"eVmail"list"to"receive"regular"updates"and"informa6on"
about"our"resources"and"training"of"interest"to"you"

108"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Context"

!  How"do"you"avoid"over"and"under"design"in"agile"
projects?"

109"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Exercise"

1.  Imagine"a"6me"you"built"something"in"2"steps"(or"

more)"and"had"significant"rework"in"later"steps"
because"of"not"looking"ahead."That"is,"this"is"the"
situa6on"you"are"concerned"about."
2.  Now,"imagine"you"can"go"back"and"do"the"first"step"
again"with"the"following"condi6ons:"
1.  You"know"everything"you"know"now"
2.  You"can"design"it"differently,"but"you"can’t"add"anything"that"
isn’t"needed"for"the"first"step"

3.  How"would"you"design"it?"
110"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Good"Ques6ons"to"Ask"

!  How"would"you"do"your"design"if"you"knew"later"that"
whatever"you"did"now"was"wrong?""

111"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Emergent(Design(
Design"PaSerns"and"
Refactoring"for"Agile"
Development"

112"

"""

"6"November"2013"
Test:"What"Does"It"Mean?"
!  1(a"chiefly0Bri+sh":(CUPEL"b((1)":"a"cri6cal"examina6on,"

observa6on,"or"evalua6on":(TRIAL;"specifically":"the'procedure'of'
submi1ng'a'statement'to'such'condi4ons'or'opera4ons'as'will'
lead'to'its'proof'or'disproof'or'to'its'acceptance'or'rejec4on(<a"
test"of"a"sta6s6cal"hypothesis>"(2)":"a"basis"for"evalua6on":(
CRITERION"c":"an"ordeal"or"oath"required"as"proof"of"conformity"
with"a"set"of"beliefs""

!  Test"can"be"thought"of:"
–  Specifica6on"that"says"you"are"doing"what"you"should"be"
doing"

113"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Inheritance(
Versus(Interface
(

114"

"""

"6"November"2013"
Inheritance"Issues""

!  Combines"two"perspec6ves"
–  Common"interface"(specifica6on)"
!  Derived"classes"play"the"same"role"as"base"class""
–  Common"implementa6on""
!  inherited"methods,"aSributes"

!  OYen"mix"up"these"perspec6ves"""

115"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
Changing"Base"vs"Interface"

Base Class

Interface

Methodone()

Methodone()

Addedmethod() //New

Addedmethod() // New

Derived Class
Does Addedmethod() need
overriding ?

116"

Implementing Class
Addedmethod() needs
implementation

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"
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"
Prefactoring"Guideline"

!  Avoid"premature"hierarchiliza6on""
–  Don’t"create"hierarchies"un6l"you"really"need"them""

!  It"is"easier"to"create"the"right"hierarchy"than"to"
dehierarchalize"the"wrong"one"

118"

"Copyright"©"2008"Net"Objec6ves."All"Rights"Reserved.""

"6"November"2013"

Mais conteúdo relacionado

Mais procurados

Agile 1.0: The Fundamentals
Agile 1.0: The FundamentalsAgile 1.0: The Fundamentals
Agile 1.0: The Fundamentals
greivinlopez
 
DevOps - A catalyst to enterprise agility - Heidi Araya & Esteban Garcia
DevOps - A catalyst to enterprise agility - Heidi Araya & Esteban GarciaDevOps - A catalyst to enterprise agility - Heidi Araya & Esteban Garcia
DevOps - A catalyst to enterprise agility - Heidi Araya & Esteban Garcia
Heidi Araya
 
DOES16 San Francisco - Damon Edwards - The Talent You Need is Already Inside ...
DOES16 San Francisco - Damon Edwards - The Talent You Need is Already Inside ...DOES16 San Francisco - Damon Edwards - The Talent You Need is Already Inside ...
DOES16 San Francisco - Damon Edwards - The Talent You Need is Already Inside ...
Gene Kim
 
Key lean principles for organizational change
Key lean principles for organizational changeKey lean principles for organizational change
Key lean principles for organizational change
LeanDog
 
Integrating agiledevsixsigmabp mandcm-presented
Integrating agiledevsixsigmabp mandcm-presentedIntegrating agiledevsixsigmabp mandcm-presented
Integrating agiledevsixsigmabp mandcm-presented
drewz lin
 

Mais procurados (20)

Agile 1.0: The Fundamentals
Agile 1.0: The FundamentalsAgile 1.0: The Fundamentals
Agile 1.0: The Fundamentals
 
The D Files: Debunking Myths About Distributed Teams
The D Files: Debunking Myths About Distributed TeamsThe D Files: Debunking Myths About Distributed Teams
The D Files: Debunking Myths About Distributed Teams
 
DevOps - A catalyst to enterprise agility - Heidi Araya & Esteban Garcia
DevOps - A catalyst to enterprise agility - Heidi Araya & Esteban GarciaDevOps - A catalyst to enterprise agility - Heidi Araya & Esteban Garcia
DevOps - A catalyst to enterprise agility - Heidi Araya & Esteban Garcia
 
Shaaron A Alvares GitLab Keynote - Agile Transformation
Shaaron A Alvares GitLab Keynote - Agile TransformationShaaron A Alvares GitLab Keynote - Agile Transformation
Shaaron A Alvares GitLab Keynote - Agile Transformation
 
Improve customer experience through operational transformation and investment...
Improve customer experience through operational transformation and investment...Improve customer experience through operational transformation and investment...
Improve customer experience through operational transformation and investment...
 
DOES15 - Mike Bland - Pain Is Over, If You Want It
DOES15 - Mike Bland - Pain Is Over, If You Want ItDOES15 - Mike Bland - Pain Is Over, If You Want It
DOES15 - Mike Bland - Pain Is Over, If You Want It
 
Agile 2 - The Next Iteration of Agile - Lisa Cooney for Agile Nova 7-29-2021
Agile 2  - The Next Iteration of Agile - Lisa Cooney for Agile Nova 7-29-2021Agile 2  - The Next Iteration of Agile - Lisa Cooney for Agile Nova 7-29-2021
Agile 2 - The Next Iteration of Agile - Lisa Cooney for Agile Nova 7-29-2021
 
DOES16 San Francisco - Damon Edwards - The Talent You Need is Already Inside ...
DOES16 San Francisco - Damon Edwards - The Talent You Need is Already Inside ...DOES16 San Francisco - Damon Edwards - The Talent You Need is Already Inside ...
DOES16 San Francisco - Damon Edwards - The Talent You Need is Already Inside ...
 
Extreme Programming 2018 — Agile Beyond Scrum
Extreme Programming 2018 — Agile Beyond ScrumExtreme Programming 2018 — Agile Beyond Scrum
Extreme Programming 2018 — Agile Beyond Scrum
 
Key lean principles for organizational change
Key lean principles for organizational changeKey lean principles for organizational change
Key lean principles for organizational change
 
Holistic Product Development
Holistic Product DevelopmentHolistic Product Development
Holistic Product Development
 
Integrating agiledevsixsigmabp mandcm-presented
Integrating agiledevsixsigmabp mandcm-presentedIntegrating agiledevsixsigmabp mandcm-presented
Integrating agiledevsixsigmabp mandcm-presented
 
"Hack Your Project" by Andrea Fryrear and David Lesue
"Hack Your Project" by Andrea Fryrear and David Lesue"Hack Your Project" by Andrea Fryrear and David Lesue
"Hack Your Project" by Andrea Fryrear and David Lesue
 
Upskilling Your Team: One Peer At A Time
Upskilling Your Team: One Peer At A TimeUpskilling Your Team: One Peer At A Time
Upskilling Your Team: One Peer At A Time
 
Coevolving Organisational and Technical Boundaries
Coevolving Organisational and Technical BoundariesCoevolving Organisational and Technical Boundaries
Coevolving Organisational and Technical Boundaries
 
2020 git lab-commit-inclusion in tech
2020 git lab-commit-inclusion in tech2020 git lab-commit-inclusion in tech
2020 git lab-commit-inclusion in tech
 
Beyond Scrum and SAFe
Beyond Scrum and SAFeBeyond Scrum and SAFe
Beyond Scrum and SAFe
 
The Future of Testing and Testers
The Future of Testing and TestersThe Future of Testing and Testers
The Future of Testing and Testers
 
Transforming Government Content: How We Cut 90,000 Pages of Government Conten...
Transforming Government Content: How We Cut 90,000 Pages of Government Conten...Transforming Government Content: How We Cut 90,000 Pages of Government Conten...
Transforming Government Content: How We Cut 90,000 Pages of Government Conten...
 
[Europe merge world tour] Perforce Europe Merge World Tour Keynote
[Europe   merge world tour] Perforce Europe Merge World Tour Keynote[Europe   merge world tour] Perforce Europe Merge World Tour Keynote
[Europe merge world tour] Perforce Europe Merge World Tour Keynote
 

Destaque

A Rapid Introduction to Rapid Software Testing
A Rapid Introduction to Rapid Software TestingA Rapid Introduction to Rapid Software Testing
A Rapid Introduction to Rapid Software Testing
TechWell
 

Destaque (15)

Beyond Processes and Tools: What about Ethics?
Beyond Processes and Tools: What about Ethics?Beyond Processes and Tools: What about Ethics?
Beyond Processes and Tools: What about Ethics?
 
The Four Dimensions of Performance Improvement
The Four Dimensions of Performance ImprovementThe Four Dimensions of Performance Improvement
The Four Dimensions of Performance Improvement
 
Testing in the Age of Distraction: Flow, Focus, and Defocus in Testing
Testing in the Age of Distraction: Flow, Focus, and Defocus in TestingTesting in the Age of Distraction: Flow, Focus, and Defocus in Testing
Testing in the Age of Distraction: Flow, Focus, and Defocus in Testing
 
The Leadership Tutorial: Improving Your Ability to Stand and Deliver
The Leadership Tutorial: Improving Your Ability to Stand and DeliverThe Leadership Tutorial: Improving Your Ability to Stand and Deliver
The Leadership Tutorial: Improving Your Ability to Stand and Deliver
 
A Rapid Introduction to Rapid Software Testing
A Rapid Introduction to Rapid Software TestingA Rapid Introduction to Rapid Software Testing
A Rapid Introduction to Rapid Software Testing
 
Reduce Release Cycle Time: Nine Months to a Week - Nice!
Reduce Release Cycle Time: Nine Months to a Week - Nice!Reduce Release Cycle Time: Nine Months to a Week - Nice!
Reduce Release Cycle Time: Nine Months to a Week - Nice!
 
Test Status Reporting: Focus Your Message for Executives
Test Status Reporting: Focus Your Message for ExecutivesTest Status Reporting: Focus Your Message for Executives
Test Status Reporting: Focus Your Message for Executives
 
It's a Phone First! How to Test Your Five-star Mobile Apps
It's a Phone First! How to Test Your Five-star Mobile AppsIt's a Phone First! How to Test Your Five-star Mobile Apps
It's a Phone First! How to Test Your Five-star Mobile Apps
 
Twelve Heuristics for Solving Tough Problems—Faster and Better
Twelve Heuristics for Solving Tough Problems—Faster and BetterTwelve Heuristics for Solving Tough Problems—Faster and Better
Twelve Heuristics for Solving Tough Problems—Faster and Better
 
Using Mindmaps to Develop a Test Strategy
Using Mindmaps to Develop a Test StrategyUsing Mindmaps to Develop a Test Strategy
Using Mindmaps to Develop a Test Strategy
 
Test Automation Patterns: Issues and Solutions
Test Automation Patterns: Issues and SolutionsTest Automation Patterns: Issues and Solutions
Test Automation Patterns: Issues and Solutions
 
A Rapid Introduction to Rapid Software Testing
A Rapid Introduction to Rapid Software TestingA Rapid Introduction to Rapid Software Testing
A Rapid Introduction to Rapid Software Testing
 
Scaling Agile at Dell: Real-life Problems - and Solutions
Scaling Agile at Dell: Real-life Problems - and SolutionsScaling Agile at Dell: Real-life Problems - and Solutions
Scaling Agile at Dell: Real-life Problems - and Solutions
 
Exploratory Testing on Agile Projects: Combining SBTM and TBTM
Exploratory Testing on Agile Projects: Combining SBTM and TBTMExploratory Testing on Agile Projects: Combining SBTM and TBTM
Exploratory Testing on Agile Projects: Combining SBTM and TBTM
 
Agile Code Reviews for Better Software—Sooner
Agile Code Reviews for Better Software—SoonerAgile Code Reviews for Better Software—Sooner
Agile Code Reviews for Better Software—Sooner
 

Semelhante a Avoiding Overdesign and Underdesign

Agile the Squads Way
Agile the Squads WayAgile the Squads Way
Agile the Squads Way
Daan Assen
 

Semelhante a Avoiding Overdesign and Underdesign (20)

Eight Steps to Kanban
Eight Steps to KanbanEight Steps to Kanban
Eight Steps to Kanban
 
An Introduction to SAFe: The Scaled Agile Framework
An Introduction to SAFe: The Scaled Agile FrameworkAn Introduction to SAFe: The Scaled Agile Framework
An Introduction to SAFe: The Scaled Agile Framework
 
Design Patterns Explained: From Analysis through Implementation
Design Patterns Explained: From Analysis through ImplementationDesign Patterns Explained: From Analysis through Implementation
Design Patterns Explained: From Analysis through Implementation
 
Bw5 pugh
Bw5 pughBw5 pugh
Bw5 pugh
 
Prototyping Approaches and Outcomes
Prototyping Approaches and OutcomesPrototyping Approaches and Outcomes
Prototyping Approaches and Outcomes
 
IxDA October Event: Prototyping Approaches and Outcomes
IxDA October Event: Prototyping Approaches and OutcomesIxDA October Event: Prototyping Approaches and Outcomes
IxDA October Event: Prototyping Approaches and Outcomes
 
GeekyAnts- App development company's Experience deck .pptx
GeekyAnts- App development company's Experience deck .pptxGeekyAnts- App development company's Experience deck .pptx
GeekyAnts- App development company's Experience deck .pptx
 
OWASP Developer Guide Reboot
OWASP Developer Guide RebootOWASP Developer Guide Reboot
OWASP Developer Guide Reboot
 
What's Agile ? Introduction to Agile methods
What's Agile ? Introduction to Agile methodsWhat's Agile ? Introduction to Agile methods
What's Agile ? Introduction to Agile methods
 
Heart of Agile
Heart of AgileHeart of Agile
Heart of Agile
 
Heart of Agile: What is Agile?
Heart of Agile: What is Agile?Heart of Agile: What is Agile?
Heart of Agile: What is Agile?
 
Agile the Squads Way
Agile the Squads WayAgile the Squads Way
Agile the Squads Way
 
CodeIT company presentation
CodeIT company presentationCodeIT company presentation
CodeIT company presentation
 
Exquisite Brochure 2015
Exquisite Brochure 2015Exquisite Brochure 2015
Exquisite Brochure 2015
 
Exquisite Software Development, LLC - 2015 Brochure
Exquisite Software Development, LLC - 2015 BrochureExquisite Software Development, LLC - 2015 Brochure
Exquisite Software Development, LLC - 2015 Brochure
 
ASPER BROTHERS Presentation
ASPER BROTHERS PresentationASPER BROTHERS Presentation
ASPER BROTHERS Presentation
 
ASPER BROTHERS Presentation
ASPER BROTHERS PresentationASPER BROTHERS Presentation
ASPER BROTHERS Presentation
 
Offshore Software Development: Software Development Company India Indus Infotek
Offshore Software Development: Software Development Company India Indus InfotekOffshore Software Development: Software Development Company India Indus Infotek
Offshore Software Development: Software Development Company India Indus Infotek
 
Cq5 Development
Cq5 Development Cq5 Development
Cq5 Development
 
201705 neoteric software development intro
201705 neoteric software development intro201705 neoteric software development intro
201705 neoteric software development intro
 

Mais de TechWell

Mais de TechWell (20)

Failing and Recovering
Failing and RecoveringFailing and Recovering
Failing and Recovering
 
Instill a DevOps Testing Culture in Your Team and Organization
Instill a DevOps Testing Culture in Your Team and Organization Instill a DevOps Testing Culture in Your Team and Organization
Instill a DevOps Testing Culture in Your Team and Organization
 
Test Design for Fully Automated Build Architecture
Test Design for Fully Automated Build ArchitectureTest Design for Fully Automated Build Architecture
Test Design for Fully Automated Build Architecture
 
System-Level Test Automation: Ensuring a Good Start
System-Level Test Automation: Ensuring a Good StartSystem-Level Test Automation: Ensuring a Good Start
System-Level Test Automation: Ensuring a Good Start
 
Build Your Mobile App Quality and Test Strategy
Build Your Mobile App Quality and Test StrategyBuild Your Mobile App Quality and Test Strategy
Build Your Mobile App Quality and Test Strategy
 
Testing Transformation: The Art and Science for Success
Testing Transformation: The Art and Science for SuccessTesting Transformation: The Art and Science for Success
Testing Transformation: The Art and Science for Success
 
Implement BDD with Cucumber and SpecFlow
Implement BDD with Cucumber and SpecFlowImplement BDD with Cucumber and SpecFlow
Implement BDD with Cucumber and SpecFlow
 
Develop WebDriver Automated Tests—and Keep Your Sanity
Develop WebDriver Automated Tests—and Keep Your SanityDevelop WebDriver Automated Tests—and Keep Your Sanity
Develop WebDriver Automated Tests—and Keep Your Sanity
 
Ma 15
Ma 15Ma 15
Ma 15
 
Eliminate Cloud Waste with a Holistic DevOps Strategy
Eliminate Cloud Waste with a Holistic DevOps StrategyEliminate Cloud Waste with a Holistic DevOps Strategy
Eliminate Cloud Waste with a Holistic DevOps Strategy
 
Transform Test Organizations for the New World of DevOps
Transform Test Organizations for the New World of DevOpsTransform Test Organizations for the New World of DevOps
Transform Test Organizations for the New World of DevOps
 
The Fourth Constraint in Project Delivery—Leadership
The Fourth Constraint in Project Delivery—LeadershipThe Fourth Constraint in Project Delivery—Leadership
The Fourth Constraint in Project Delivery—Leadership
 
Resolve the Contradiction of Specialists within Agile Teams
Resolve the Contradiction of Specialists within Agile TeamsResolve the Contradiction of Specialists within Agile Teams
Resolve the Contradiction of Specialists within Agile Teams
 
Pin the Tail on the Metric: A Field-Tested Agile Game
Pin the Tail on the Metric: A Field-Tested Agile GamePin the Tail on the Metric: A Field-Tested Agile Game
Pin the Tail on the Metric: A Field-Tested Agile Game
 
Agile Performance Holarchy (APH)—A Model for Scaling Agile Teams
Agile Performance Holarchy (APH)—A Model for Scaling Agile TeamsAgile Performance Holarchy (APH)—A Model for Scaling Agile Teams
Agile Performance Holarchy (APH)—A Model for Scaling Agile Teams
 
A Business-First Approach to DevOps Implementation
A Business-First Approach to DevOps ImplementationA Business-First Approach to DevOps Implementation
A Business-First Approach to DevOps Implementation
 
Databases in a Continuous Integration/Delivery Process
Databases in a Continuous Integration/Delivery ProcessDatabases in a Continuous Integration/Delivery Process
Databases in a Continuous Integration/Delivery Process
 
Mobile Testing: What—and What Not—to Automate
Mobile Testing: What—and What Not—to AutomateMobile Testing: What—and What Not—to Automate
Mobile Testing: What—and What Not—to Automate
 
Cultural Intelligence: A Key Skill for Success
Cultural Intelligence: A Key Skill for SuccessCultural Intelligence: A Key Skill for Success
Cultural Intelligence: A Key Skill for Success
 
Turn the Lights On: A Power Utility Company's Agile Transformation
Turn the Lights On: A Power Utility Company's Agile TransformationTurn the Lights On: A Power Utility Company's Agile Transformation
Turn the Lights On: A Power Utility Company's Agile Transformation
 

Último

Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
Earley Information Science
 

Último (20)

Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 

Avoiding Overdesign and Underdesign