Copyright@2014 Taylor & Francis
Adair Dingle All Rights Reserved
Object-­‐Oriented	
  Design	
  
	
  
Inheritance	
  	
  
vs.	
  	
  
Composi2on:	
  
Part	
  I	
  
	
  
	
  Inheritance for Subtyping: Structural Reuse
Design	
  Ques2ons	
  
•  How	
  to	
  streamline	
  class	
  design	
  for	
  reuse?	
  
•  What	
  is	
  the	
  importance	
  of	
  type?	
  	
  	
  
•  How	
  to	
  dis2nguish	
  between	
  reuse	
  mo2ves?	
  
– Composi2on?	
  
– Inheritance?	
  	
  
Copyright@2015 Adair Dingle
Key	
  Observa2ons	
  
•  Inheritance	
  and	
  composi2on	
  BOTH	
  provide	
  
reuse	
  
•  Type	
  dependencies	
  are	
  established	
  by	
  design	
  	
  	
  
•  Differing	
  needs	
  for	
  flexibility	
  may	
  drive	
  design	
  
Copyright@2015 Adair Dingle
Chapter	
  6:	
  Structural	
  Design	
  
Class	
  Rela2onships	
  =	
  =	
  	
  
	
  	
  Design	
  alterna,ves	
  for	
  class	
  use	
  and	
  reuse	
  
	
  
•  Composi2on	
  
•  Containment	
  
•  Inheritance	
  
•  Code	
  Reuse	
  
•  Design	
  Principles	
  
	
  	
  
Copyright@2014 Taylor & Francis
Adair Dingle All Rights Reserved
Rela2onships	
  	
  
•  Containment	
  	
   	
  aka	
   	
  Holds-­‐A	
  
–  subObjects	
  held,	
  as	
  in	
  a	
  container	
  
–  LiSle	
  or	
  no	
  type	
  dependency	
  
•  Composi2on	
  	
   	
  aka	
   	
  Has-­‐A	
  
–  subObjects	
  part	
  of	
  class/type	
  composi2on	
  	
  
–  Essen2al	
  component	
  =>	
  some	
  (internal)	
  type	
  dependency	
  
•  Inheritance	
   	
   	
  aka	
   	
  Is-­‐a	
  
–  Class	
  hierachy:	
  	
  Base	
  (parent)	
  and	
  Derived	
  (child)	
  classes	
  
•  subtype	
  alters	
  or	
  augments	
  inherited	
  behavior	
  
–  significant	
  (external)	
  type	
  dependency	
  
–  Built-­‐in	
  (sub)type	
  checking	
  
Copyright@2014 Taylor & Francis
Adair Dingle All Rights Reserved
Structural	
  Design	
  Details	
  
•  Cardinality:	
  	
  	
  	
  	
  How	
  many	
  subObjects?	
  
–  1:1	
  for	
  inheritance;	
  1-­‐many	
  for	
  composi2on	
  by	
  design	
  
–  Variable	
  for	
  containment	
  
•  Ownership	
  
–  Child	
  owns	
  parent	
  component:	
  may	
  NOT	
  be	
  released	
  
–  Composing	
  object	
  may	
  stub	
  out/replace	
  subObject	
  
–  None,	
  usually,	
  for	
  containment	
  
•  Life2me	
  	
  
–  1:1	
  for	
  inheritance;	
  variable	
  by	
  design	
  for	
  composi2on	
  
•  	
  Associa2on	
  
–  Permanent	
  for	
  inheritance	
  
–  Possibly	
  transient	
  for	
  composi2on	
  
–  Temporary	
  for	
  containment	
  
Copyright@2014 Taylor & Francis
Adair Dingle All Rights Reserved
Table	
  6.1	
  	
  Rela2onship	
  details:	
  class	
  to	
  subordinate	
  	
  
Relationship Association Cardinality Ownership Dependency Replacement
Composition Stable Variable Transferable Yes Yes
Containment Temporary Variable No No Not relevant
Inheritance Permanent Fixed: 1-1 Implied Yes No
Copyright@2014 Taylor & Francis
Adair Dingle All Rights Reserved
Rela2onships:	
  Design	
  Details	
  
•  Different	
  designs	
  yield	
  different	
  	
  
–  control	
  and	
  maintainability	
  
•  Cardinality,	
  ownership,	
  life2me	
  and	
  associa2on	
  
–  Indicate	
  flexibility,	
  stability,	
  and/or	
  extensibility	
  
•  Overhead	
  gauged	
  by	
  these	
  measures.	
  	
  	
  
•  For	
  example:	
  
–  has-­‐a	
  rela2onship	
  may	
  provide	
  varying	
  cardinality	
  	
  
–  is-­‐a	
  rela2onship	
  cannot	
  vary	
  cardinality	
  	
  
–  has-­‐a	
  may	
  postpone	
  subObject	
  instan2a2on	
  
–  is-­‐a	
  cannot	
  postpone	
  parent	
  instan2a2on	
  
Copyright@2014 Taylor & Francis
Adair Dingle All Rights Reserved
Example	
  6.1	
  	
  	
  Postponed	
  Instan2a2on	
  of	
  SubObject	
  	
  
class justInTime
{ // need appropriate memory management details
// Suppress or define: copy constructor and operator=
bigData* generator;
…
public:
justInTime() { generator = 0; }
…
void process()
{
if ( !generator ) generator = new bigData;
generator.process();
}
…
};
	
  	
  
Copyright@2014 Taylor & Francis
Adair Dingle All Rights Reserved
Table	
  6.2	
  	
  Design	
  Effects	
  of	
  OO	
  Rela2onships	
  
Relationship Internal
Access
External
Access
Overhead (SubObject)
Interface
Control
Has-A Public None Variable
Avoidable
Suppressed
May echo
Replacement
Defer
instantiation
Holds-A Public None Minimal Not relevant None
Is-a Public
Protected
Public Unavoidable Support
Extend
Suppress
None
Copyright@2014 Taylor & Francis
Adair Dingle All Rights Reserved
Rela2onships:	
  Type	
  Dependency	
  
•  Implicit	
  in	
  inheritance	
  hierarchies	
  
–  Expecta2on:	
  subtypes	
  (descendants)	
  may	
  override	
  
inherited	
  behavior	
  to	
  customize,	
  augment,	
  or	
  vary	
  base	
  
behavior.	
  	
  	
  
–  Polymorphism	
  and	
  use	
  of	
  heterogeneous	
  collec2ons	
  is	
  
common	
  in	
  designs	
  employing	
  type	
  dependencies	
  
	
  
•  Significant	
  in	
  has-­‐a	
  rela2onship	
  	
  
–  Client	
  remains	
  isolated	
  from	
  internal	
  dependencies.	
  
Copyright@2014 Taylor & Francis
Adair Dingle All Rights Reserved
Table	
  6.3	
  	
  Object	
  to	
  SubObject	
  Details	
  
Accessibility Association Cardinality Ownership
Private Temporary or
Permanent
Fixed by class design
same for all objects
Object
External
Echoed
functionality
Delayed
instantiation
Fixed at instantiation
Stable for object
lifetime
Shared
Full or Partial
access
Stable but
Replaceable
Variable within object
lifetime
Transferable
Copyright@2014 Taylor & Francis
Adair Dingle All Rights Reserved
Has-­‐A	
  vs.	
  Holds-­‐a	
  
•  Has-­‐a	
  rela2onships	
  imply	
  type	
  dependency	
  
–  class	
  dependent	
  on	
  subObject	
  for	
  data	
  and/or	
  func2onality	
  
–  Constructor	
  may	
  instan2ate	
  subObject	
  
–  Class	
  methods	
  may	
  be	
  defined	
  to	
  replace/reset	
  subObject	
  
•  Holds-­‐a	
  rela2onships	
  imply	
  temporary	
  associa2on	
  
–  No	
  significant	
  dependency	
  on	
  type	
  held	
  
•  Type	
  could	
  be	
  replaced	
  
•  Number	
  of	
  subObjects	
  held	
  could	
  be	
  zero,	
  without	
  impact	
  
–  Type	
  independence,	
  like	
  that	
  of	
  a	
  container,	
  expected	
  
Copyright@2014 Taylor & Francis
Adair Dingle All Rights Reserved
Has-­‐A	
  vs.	
  Is-­‐a	
  
•  Has-­‐a	
  allows	
  one	
  to	
  encapsulate	
  and	
  control	
  subObjects	
  
–  design	
  variability	
  in	
  cardinality,	
  associa2on,	
  life2me	
  and	
  ownership	
  
–  Interfaces	
  may,	
  but	
  need	
  not,	
  be	
  echoed.	
  	
  	
  
•  Is-­‐a	
  implies	
  a	
  strong	
  type	
  dependency	
  
–  Child	
  object	
  may	
  stand	
  in	
  for	
  parent	
  object	
  
–  Polymorphism,	
  and	
  heterogeneous	
  collec2ons,	
  supported	
  through	
  
inheritance	
  and	
  difficult	
  to	
  implement	
  otherwise	
  (see	
  chapter	
  7)	
  	
  
•  Is-­‐a	
  impera2ve	
  to	
  reuse	
  func2onality	
  	
  
–  common	
  interface	
  
–  Extensibility	
  promoted	
  
–  Overhead	
  is	
  fixed	
  as	
  is	
  cardinality,	
  ownership,	
  life2me	
  and	
  associa2on...	
  	
  	
  
Copyright@2014 Taylor & Francis
Adair Dingle All Rights Reserved
Example	
  6.4	
  	
  	
  Inheritance	
  in	
  C#=>	
  Child	
  stands	
  in	
  for	
  Parent	
  	
  
Parent pObj;
// Substitutability:
// parent object (reference) can hold address of child object
// Not symmetric: child reference cannot hold parent address
// pObj: handle of type Parent =>
// Parent interface accessible; child interface not
pObj = new Parent(); pObj.parentFn();
pObj = new Child1(); pObj.parentFn();
pObj = new Child2(); pObj.parentFn();
	
  	
  
Copyright@2014 Taylor & Francis
Adair Dingle All Rights Reserved
Inheritance	
  :	
  Language	
  Differences	
  
•  Java	
  and	
  C#	
  support	
  only	
  public	
  inheritance	
  
–  do	
  not	
  allow	
  direct	
  suppression	
  of	
  inherited	
  interface	
  	
  
•  C++	
  offers	
  public,	
  protected	
  and	
  private	
  inheritance	
  
–  only	
  public	
  inheritance	
  typically	
  used	
  	
  	
  
–  with	
  protected	
  inheritance,	
  all	
  inherited	
  public	
  func2onality	
  is	
  demoted	
  
to	
  protected	
  accessibility	
  
–  with	
  private	
  inheritance,	
  all	
  inherited	
  public	
  and	
  protected	
  func2onality	
  
is	
  demoted	
  to	
  private	
  accessibility	
  
=>	
  applica2on	
  programmer	
  has	
  less	
  accessibility	
  via	
  a	
  derived	
  object	
  	
  	
  
•  C++	
  allows	
  class	
  designers	
  	
  
–  to	
  directly	
  suppress	
  inherited	
  func2onality	
  	
  
–  to	
  change	
  accessibility	
  of	
  individual	
  inherited	
  class	
  methods	
  
Copyright@2014 Taylor & Francis
Adair Dingle All Rights Reserved
Example	
  6.5	
  	
  	
  	
  C++	
  Direct	
  suppression	
  of	
  Inherited	
  Func2onality	
  	
  
class Child: public Parent
{ … // fields private by default
void parentFn() { // now private => suppressed }
public:
…
};
…
Parent pObj;
Child cObj;
pObj.parentFn();
cObj.parentFn(); // compilation error: not accessible
Copyright@2014 Taylor & Francis
Adair Dingle All Rights Reserved
Example	
  6.6	
  	
  	
  C#	
  Designated	
  suppression	
  of	
  Inherited	
  Func2onality	
  	
  
public class Child: Parent
{ …
public void parentFn() { //NOP }
…
}
// application code
Parent pObj = new Parent();
Child cObj = new Child();
pObj.parentFn(); // parent functionality
cObj.parentFn(); // compiles & runs & does nothing
Copyright@2014 Taylor & Francis
Adair Dingle All Rights Reserved
How	
  to	
  choose	
  design?	
  
•  Soiware	
  design	
  is	
  not	
  a	
  ‘one	
  size	
  fits	
  all’	
  approach.	
  	
  	
  
•  Different	
  intents	
  yield	
  different	
  designs.	
  	
  	
  
•  Code	
  reuse	
  most	
  feasible	
  with	
  clearly	
  structured	
  design	
  	
  
•  Inheritance	
  supports	
  
–  Type	
  extensibility	
  
–  Polymorphism	
  
–  Heterogeneous	
  collec2ons	
  (see	
  chapter	
  7)	
  	
  
•  Composi2on	
  provides	
  
–  Internal	
  control	
  	
  
–  Flexibility	
  and,	
  possibly,	
  reduced	
  overhead	
  
•  Encapsula2on	
  via	
  composi2on	
  or	
  containment	
  
–  isolates	
  unstable	
  code	
  and	
  allows	
  one	
  to	
  wrap	
  interfaces	
  
Copyright@2014 Taylor & Francis
Adair Dingle All Rights Reserved
Inheritance	
  
•  Appropriate	
  when	
  subtype	
  checking	
  needed	
  
–  Client	
  need	
  not	
  check	
  for	
  subtype	
  
–  Class	
  designer	
  need	
  not	
  check	
  for	
  subtype	
  
–  Subclass	
  provides	
  ‘automa2c’	
  subtype	
  check	
  (via	
  compiler)	
  
•  Automa2c	
  type	
  associa2on	
  
•  Class	
  hierarchy	
  sets	
  up	
  type	
  extensibility	
  
–  New	
  subtype	
  added	
  easily	
  
–  No	
  cut&paste	
  fixes	
  
–  Code	
  not	
  briSle:	
  new	
  subtype	
  does	
  not	
  ‘break’	
  code	
  
Copyright@2014 Taylor & Francis
Adair Dingle All Rights Reserved
Example	
  6.7	
  	
  C++	
  Monolithic	
  class	
  for	
  Icon	
  Movement	
  	
  
class Icon
{ float speed, glow, energy;
int x, y;
int subtype; //spinner, slider or hopper
bool clockwise; // need for spinner
bool expand; // need for spinner
bool vertical; // need for slider
int distance; // need for slider
bool visible; // need for hopper
int xcoord, ycoord; // need for hopper
void spin(); // functionality for spinner
void slide(); // functionality for slider
void hop(); // functionality for hopper
public:
…
Copyright@2014 Taylor & Francis
Adair Dingle All Rights Reserved
Example	
  6.7	
  	
  C++	
  Monolithic	
  class	
  …	
  con2nued	
  	
  
public:
// constructor must set subtype: client must pass value
Icon(unsigned value)
{ …
subtype = value; // use enum for readability
// and then use conditional to set associated fields
}
// tedious subtype checking: subtype drives movement
void move()
{ if (subtype == 1) spin();
else if (subtype == 2) slide();
else hop();
}
// again,tedious subtype checking:subtype drives flair
details
void flair()
{ if (subtype == 1) … }
Copyright@2014 Taylor & Francis
Adair Dingle All Rights Reserved
Example	
  6.8	
  	
  Tedious	
  Type	
  expansion	
  without	
  Inheritance	
  	
  
// ALL methods in Icon that check subtype must be altered
// in order to add new subtype ‘zigzag’
// ERROR PRONE software maintenance
void Icon::move()
{ if (subtype == 1) spin();
else if (subtype == 2) slide();
else if (subtype == 3) hop();
else zigzag();
}
// ALL methods in Icon that check subtype must be altered
// in order to add new subtype ‘zigzag’ =>
// flair() must also be altered since subtype drives details
Copyright@2014 Taylor & Francis
Adair Dingle All Rights Reserved
Example	
  6.9	
  	
  C++	
  Icon	
  class	
  hierarchy	
  
class Icon
{ protected:
float speed, glow, energy;
int x, y;
public:
Icon(…) { … }
void move() { … }
void flair() { … }
…
};
class Spinner: public Icon
{ protected:
bool clockwise, expand;
void spin();
public:
Spinner(…):Icon(…) { … }
void move() { spin();… }
void flair() { … }
…
};
Copyright@2014 Taylor & Francis
Adair Dingle All Rights Reserved
Example	
  6.9	
  	
  Icon	
  class	
  hierarchy	
  con2nued	
  
class Slider: public Icon
{ protected:
bool vertical;
int distance;
void slide();
public:
Slider(…):Icon(…) { … }
void move() { slide();… }
…
};
class Hopper: public Icon
{ protected:
bool visible;
int xcoord, ycoord;
void hop();
public:
Hopper(…):Icon(…) { … }
void move() { hop();… }
…
};
Copyright@2014 Taylor & Francis
Adair Dingle All Rights Reserved
Example	
  6.9	
  	
  Icon	
  class	
  hierarchy	
  con2nued	
  
// easy to add new subtype ‘zigzag’
class zigzag: public Icon
{ protected:
…
void zig();
void zag();
public:
zigzag(…):Icon(…) { … }
void move() { zig(); zag(); … }
…
};
Copyright@2014 Taylor & Francis
Adair Dingle All Rights Reserved
Code	
  Reuse	
  
•  via	
  Inheritance	
  	
  
– Child	
  classes	
  automa2cally	
  receive	
  
•  one	
  parent	
  (data)	
  component	
  
•  Access	
  to	
  all	
  public/protected	
  parent	
  func2onality	
  
•  via	
  Composi2on	
  
– Composing	
  class	
  automa2cally	
  receives	
  
•  zero,	
  one	
  or	
  more	
  subObject	
  
•  Access	
  to	
  all	
  public	
  subObject	
  func2onality	
  
=>	
  Code	
  reuse	
  alone	
  does	
  not	
  mo2vate	
  design	
  
Copyright@2014 Taylor & Francis
Adair Dingle All Rights Reserved
Rela2onship	
  Design	
  &	
  Code	
  Reuse	
  
•  Composi2on	
  
–  Type	
  extension	
  NOT	
  essen2al	
  
–  Type	
  extension	
  unlikely	
  to	
  be	
  used	
  alongside	
  original	
  
–  Interface	
  may	
  be	
  suppressed	
  
–  Cardinality	
  of	
  subObject	
  may	
  vary	
  	
  
•  Inheritance	
  
–  Type	
  extension	
  essen2al	
  
–  Type	
  extension	
  LIKELY	
  to	
  be	
  used	
  alongside	
  original	
  
–  Interface	
  may	
  NOT	
  be	
  suppressed	
  
–  Cardinality	
  fixed	
  at	
  one	
  (parent)	
  is	
  acceptable/preferred	
  	
  
Copyright@2014 Taylor & Francis
Adair Dingle All Rights Reserved
Composite	
  Principle	
  
Use	
  composi,on	
  in	
  preference	
  to	
  inheritance	
  	
  	
  
•  Formalizes	
  prac22oners’	
  preference	
  for	
  composi2on	
  
But	
  Why?	
  	
  	
  
•  Composi2on	
  	
  
–  more	
  flexible	
  	
  
–  offers	
  more	
  control	
  over	
  internal	
  design	
  than	
  inheritance	
  
•  But	
  remember,	
  composi2on	
  does	
  NOT	
  provide	
  
–  Built-­‐in	
  subtype	
  checking	
  
–  Polymorphism	
  
–  Support	
  for	
  heterogeneous	
  collec2ons	
  (see	
  chapter	
  7)	
  
–  Type	
  extensibility	
  
Copyright@2014 Taylor & Francis
Adair Dingle All Rights Reserved
Principle	
  of	
  Least	
  Knowledge	
  	
  	
  
Every	
  object	
  assumes	
  only	
  the	
  minimum	
  possible	
  about	
  
the	
  structure	
  and	
  proper,es	
  of	
  other	
  objects	
  	
  	
  	
  
•  Promotes	
  low	
  coupling	
  
•  Applicable	
  to	
  both	
  inheritance	
  and	
  composi2on	
  rela2ons	
  
•  Class	
  design	
  NOT	
  dependent	
  on	
  	
  
–  private	
  implementa2on	
  details	
  of	
  any	
  other	
  class	
  	
  
•  	
  Design	
  iden2fies	
  	
  
–  rela2onships	
  	
  
–  consequen2al	
  effects	
  of	
  rela2onships	
  
=>	
  Class	
  2ed	
  only	
  to	
  interface	
  of	
  parent/composed	
  subobject	
  
Copyright@2014 Taylor & Francis
Adair Dingle All Rights Reserved
Open	
  Closed	
  Principle	
  (OCP)	
  
A	
  class	
  should	
  be	
  open	
  for	
  extension	
  and	
  closed	
  for	
  modifica,on	
  
	
  	
  	
  
•  Inheritance	
  is	
  an	
  aSrac2ve	
  design	
  op2on	
  for	
  
–  class	
  hierarchies	
  with	
  implicit	
  subtype	
  selec2on	
  to	
  vary	
  func2onality	
  	
  	
  	
  
–  Subs2tutability	
  	
  (see	
  chapter	
  7)	
  
–  Heterogeneous	
  collec2ons	
  (see	
  chapter	
  7)	
  
–  Type	
  extensibility	
  
•  A	
  good	
  inheritance	
  design	
  adheres	
  to	
  OCP	
  
–  individual	
  classes	
  preserved	
  	
  
–  type	
  extensions	
  are	
  seamless	
  
•  OCP	
  promotes	
  soiware	
  maintainability.	
  	
  	
  
Copyright@2014 Taylor & Francis
Adair Dingle All Rights Reserved

Object-oriented design: Inheritance subtyping (vs. Composition)

  • 1.
    Copyright@2014 Taylor &Francis Adair Dingle All Rights Reserved Object-­‐Oriented  Design     Inheritance     vs.     Composi2on:   Part  I      Inheritance for Subtyping: Structural Reuse
  • 2.
    Design  Ques2ons   • How  to  streamline  class  design  for  reuse?   •  What  is  the  importance  of  type?       •  How  to  dis2nguish  between  reuse  mo2ves?   – Composi2on?   – Inheritance?     Copyright@2015 Adair Dingle
  • 3.
    Key  Observa2ons   • Inheritance  and  composi2on  BOTH  provide   reuse   •  Type  dependencies  are  established  by  design       •  Differing  needs  for  flexibility  may  drive  design   Copyright@2015 Adair Dingle
  • 4.
    Chapter  6:  Structural  Design   Class  Rela2onships  =  =        Design  alterna,ves  for  class  use  and  reuse     •  Composi2on   •  Containment   •  Inheritance   •  Code  Reuse   •  Design  Principles       Copyright@2014 Taylor & Francis Adair Dingle All Rights Reserved
  • 5.
    Rela2onships     • Containment      aka    Holds-­‐A   –  subObjects  held,  as  in  a  container   –  LiSle  or  no  type  dependency   •  Composi2on      aka    Has-­‐A   –  subObjects  part  of  class/type  composi2on     –  Essen2al  component  =>  some  (internal)  type  dependency   •  Inheritance      aka    Is-­‐a   –  Class  hierachy:    Base  (parent)  and  Derived  (child)  classes   •  subtype  alters  or  augments  inherited  behavior   –  significant  (external)  type  dependency   –  Built-­‐in  (sub)type  checking   Copyright@2014 Taylor & Francis Adair Dingle All Rights Reserved
  • 6.
    Structural  Design  Details   •  Cardinality:          How  many  subObjects?   –  1:1  for  inheritance;  1-­‐many  for  composi2on  by  design   –  Variable  for  containment   •  Ownership   –  Child  owns  parent  component:  may  NOT  be  released   –  Composing  object  may  stub  out/replace  subObject   –  None,  usually,  for  containment   •  Life2me     –  1:1  for  inheritance;  variable  by  design  for  composi2on   •   Associa2on   –  Permanent  for  inheritance   –  Possibly  transient  for  composi2on   –  Temporary  for  containment   Copyright@2014 Taylor & Francis Adair Dingle All Rights Reserved
  • 7.
    Table  6.1    Rela2onship  details:  class  to  subordinate     Relationship Association Cardinality Ownership Dependency Replacement Composition Stable Variable Transferable Yes Yes Containment Temporary Variable No No Not relevant Inheritance Permanent Fixed: 1-1 Implied Yes No Copyright@2014 Taylor & Francis Adair Dingle All Rights Reserved
  • 8.
    Rela2onships:  Design  Details   •  Different  designs  yield  different     –  control  and  maintainability   •  Cardinality,  ownership,  life2me  and  associa2on   –  Indicate  flexibility,  stability,  and/or  extensibility   •  Overhead  gauged  by  these  measures.       •  For  example:   –  has-­‐a  rela2onship  may  provide  varying  cardinality     –  is-­‐a  rela2onship  cannot  vary  cardinality     –  has-­‐a  may  postpone  subObject  instan2a2on   –  is-­‐a  cannot  postpone  parent  instan2a2on   Copyright@2014 Taylor & Francis Adair Dingle All Rights Reserved
  • 9.
    Example  6.1      Postponed  Instan2a2on  of  SubObject     class justInTime { // need appropriate memory management details // Suppress or define: copy constructor and operator= bigData* generator; … public: justInTime() { generator = 0; } … void process() { if ( !generator ) generator = new bigData; generator.process(); } … };     Copyright@2014 Taylor & Francis Adair Dingle All Rights Reserved
  • 10.
    Table  6.2    Design  Effects  of  OO  Rela2onships   Relationship Internal Access External Access Overhead (SubObject) Interface Control Has-A Public None Variable Avoidable Suppressed May echo Replacement Defer instantiation Holds-A Public None Minimal Not relevant None Is-a Public Protected Public Unavoidable Support Extend Suppress None Copyright@2014 Taylor & Francis Adair Dingle All Rights Reserved
  • 11.
    Rela2onships:  Type  Dependency   •  Implicit  in  inheritance  hierarchies   –  Expecta2on:  subtypes  (descendants)  may  override   inherited  behavior  to  customize,  augment,  or  vary  base   behavior.       –  Polymorphism  and  use  of  heterogeneous  collec2ons  is   common  in  designs  employing  type  dependencies     •  Significant  in  has-­‐a  rela2onship     –  Client  remains  isolated  from  internal  dependencies.   Copyright@2014 Taylor & Francis Adair Dingle All Rights Reserved
  • 12.
    Table  6.3    Object  to  SubObject  Details   Accessibility Association Cardinality Ownership Private Temporary or Permanent Fixed by class design same for all objects Object External Echoed functionality Delayed instantiation Fixed at instantiation Stable for object lifetime Shared Full or Partial access Stable but Replaceable Variable within object lifetime Transferable Copyright@2014 Taylor & Francis Adair Dingle All Rights Reserved
  • 13.
    Has-­‐A  vs.  Holds-­‐a   •  Has-­‐a  rela2onships  imply  type  dependency   –  class  dependent  on  subObject  for  data  and/or  func2onality   –  Constructor  may  instan2ate  subObject   –  Class  methods  may  be  defined  to  replace/reset  subObject   •  Holds-­‐a  rela2onships  imply  temporary  associa2on   –  No  significant  dependency  on  type  held   •  Type  could  be  replaced   •  Number  of  subObjects  held  could  be  zero,  without  impact   –  Type  independence,  like  that  of  a  container,  expected   Copyright@2014 Taylor & Francis Adair Dingle All Rights Reserved
  • 14.
    Has-­‐A  vs.  Is-­‐a   •  Has-­‐a  allows  one  to  encapsulate  and  control  subObjects   –  design  variability  in  cardinality,  associa2on,  life2me  and  ownership   –  Interfaces  may,  but  need  not,  be  echoed.       •  Is-­‐a  implies  a  strong  type  dependency   –  Child  object  may  stand  in  for  parent  object   –  Polymorphism,  and  heterogeneous  collec2ons,  supported  through   inheritance  and  difficult  to  implement  otherwise  (see  chapter  7)     •  Is-­‐a  impera2ve  to  reuse  func2onality     –  common  interface   –  Extensibility  promoted   –  Overhead  is  fixed  as  is  cardinality,  ownership,  life2me  and  associa2on...       Copyright@2014 Taylor & Francis Adair Dingle All Rights Reserved
  • 15.
    Example  6.4      Inheritance  in  C#=>  Child  stands  in  for  Parent     Parent pObj; // Substitutability: // parent object (reference) can hold address of child object // Not symmetric: child reference cannot hold parent address // pObj: handle of type Parent => // Parent interface accessible; child interface not pObj = new Parent(); pObj.parentFn(); pObj = new Child1(); pObj.parentFn(); pObj = new Child2(); pObj.parentFn();     Copyright@2014 Taylor & Francis Adair Dingle All Rights Reserved
  • 16.
    Inheritance  :  Language  Differences   •  Java  and  C#  support  only  public  inheritance   –  do  not  allow  direct  suppression  of  inherited  interface     •  C++  offers  public,  protected  and  private  inheritance   –  only  public  inheritance  typically  used       –  with  protected  inheritance,  all  inherited  public  func2onality  is  demoted   to  protected  accessibility   –  with  private  inheritance,  all  inherited  public  and  protected  func2onality   is  demoted  to  private  accessibility   =>  applica2on  programmer  has  less  accessibility  via  a  derived  object       •  C++  allows  class  designers     –  to  directly  suppress  inherited  func2onality     –  to  change  accessibility  of  individual  inherited  class  methods   Copyright@2014 Taylor & Francis Adair Dingle All Rights Reserved
  • 17.
    Example  6.5        C++  Direct  suppression  of  Inherited  Func2onality     class Child: public Parent { … // fields private by default void parentFn() { // now private => suppressed } public: … }; … Parent pObj; Child cObj; pObj.parentFn(); cObj.parentFn(); // compilation error: not accessible Copyright@2014 Taylor & Francis Adair Dingle All Rights Reserved
  • 18.
    Example  6.6      C#  Designated  suppression  of  Inherited  Func2onality     public class Child: Parent { … public void parentFn() { //NOP } … } // application code Parent pObj = new Parent(); Child cObj = new Child(); pObj.parentFn(); // parent functionality cObj.parentFn(); // compiles & runs & does nothing Copyright@2014 Taylor & Francis Adair Dingle All Rights Reserved
  • 19.
    How  to  choose  design?   •  Soiware  design  is  not  a  ‘one  size  fits  all’  approach.       •  Different  intents  yield  different  designs.       •  Code  reuse  most  feasible  with  clearly  structured  design     •  Inheritance  supports   –  Type  extensibility   –  Polymorphism   –  Heterogeneous  collec2ons  (see  chapter  7)     •  Composi2on  provides   –  Internal  control     –  Flexibility  and,  possibly,  reduced  overhead   •  Encapsula2on  via  composi2on  or  containment   –  isolates  unstable  code  and  allows  one  to  wrap  interfaces   Copyright@2014 Taylor & Francis Adair Dingle All Rights Reserved
  • 20.
    Inheritance   •  Appropriate  when  subtype  checking  needed   –  Client  need  not  check  for  subtype   –  Class  designer  need  not  check  for  subtype   –  Subclass  provides  ‘automa2c’  subtype  check  (via  compiler)   •  Automa2c  type  associa2on   •  Class  hierarchy  sets  up  type  extensibility   –  New  subtype  added  easily   –  No  cut&paste  fixes   –  Code  not  briSle:  new  subtype  does  not  ‘break’  code   Copyright@2014 Taylor & Francis Adair Dingle All Rights Reserved
  • 21.
    Example  6.7    C++  Monolithic  class  for  Icon  Movement     class Icon { float speed, glow, energy; int x, y; int subtype; //spinner, slider or hopper bool clockwise; // need for spinner bool expand; // need for spinner bool vertical; // need for slider int distance; // need for slider bool visible; // need for hopper int xcoord, ycoord; // need for hopper void spin(); // functionality for spinner void slide(); // functionality for slider void hop(); // functionality for hopper public: … Copyright@2014 Taylor & Francis Adair Dingle All Rights Reserved
  • 22.
    Example  6.7    C++  Monolithic  class  …  con2nued     public: // constructor must set subtype: client must pass value Icon(unsigned value) { … subtype = value; // use enum for readability // and then use conditional to set associated fields } // tedious subtype checking: subtype drives movement void move() { if (subtype == 1) spin(); else if (subtype == 2) slide(); else hop(); } // again,tedious subtype checking:subtype drives flair details void flair() { if (subtype == 1) … } Copyright@2014 Taylor & Francis Adair Dingle All Rights Reserved
  • 23.
    Example  6.8    Tedious  Type  expansion  without  Inheritance     // ALL methods in Icon that check subtype must be altered // in order to add new subtype ‘zigzag’ // ERROR PRONE software maintenance void Icon::move() { if (subtype == 1) spin(); else if (subtype == 2) slide(); else if (subtype == 3) hop(); else zigzag(); } // ALL methods in Icon that check subtype must be altered // in order to add new subtype ‘zigzag’ => // flair() must also be altered since subtype drives details Copyright@2014 Taylor & Francis Adair Dingle All Rights Reserved
  • 24.
    Example  6.9    C++  Icon  class  hierarchy   class Icon { protected: float speed, glow, energy; int x, y; public: Icon(…) { … } void move() { … } void flair() { … } … }; class Spinner: public Icon { protected: bool clockwise, expand; void spin(); public: Spinner(…):Icon(…) { … } void move() { spin();… } void flair() { … } … }; Copyright@2014 Taylor & Francis Adair Dingle All Rights Reserved
  • 25.
    Example  6.9    Icon  class  hierarchy  con2nued   class Slider: public Icon { protected: bool vertical; int distance; void slide(); public: Slider(…):Icon(…) { … } void move() { slide();… } … }; class Hopper: public Icon { protected: bool visible; int xcoord, ycoord; void hop(); public: Hopper(…):Icon(…) { … } void move() { hop();… } … }; Copyright@2014 Taylor & Francis Adair Dingle All Rights Reserved
  • 26.
    Example  6.9    Icon  class  hierarchy  con2nued   // easy to add new subtype ‘zigzag’ class zigzag: public Icon { protected: … void zig(); void zag(); public: zigzag(…):Icon(…) { … } void move() { zig(); zag(); … } … }; Copyright@2014 Taylor & Francis Adair Dingle All Rights Reserved
  • 27.
    Code  Reuse   • via  Inheritance     – Child  classes  automa2cally  receive   •  one  parent  (data)  component   •  Access  to  all  public/protected  parent  func2onality   •  via  Composi2on   – Composing  class  automa2cally  receives   •  zero,  one  or  more  subObject   •  Access  to  all  public  subObject  func2onality   =>  Code  reuse  alone  does  not  mo2vate  design   Copyright@2014 Taylor & Francis Adair Dingle All Rights Reserved
  • 28.
    Rela2onship  Design  &  Code  Reuse   •  Composi2on   –  Type  extension  NOT  essen2al   –  Type  extension  unlikely  to  be  used  alongside  original   –  Interface  may  be  suppressed   –  Cardinality  of  subObject  may  vary     •  Inheritance   –  Type  extension  essen2al   –  Type  extension  LIKELY  to  be  used  alongside  original   –  Interface  may  NOT  be  suppressed   –  Cardinality  fixed  at  one  (parent)  is  acceptable/preferred     Copyright@2014 Taylor & Francis Adair Dingle All Rights Reserved
  • 29.
    Composite  Principle   Use  composi,on  in  preference  to  inheritance       •  Formalizes  prac22oners’  preference  for  composi2on   But  Why?       •  Composi2on     –  more  flexible     –  offers  more  control  over  internal  design  than  inheritance   •  But  remember,  composi2on  does  NOT  provide   –  Built-­‐in  subtype  checking   –  Polymorphism   –  Support  for  heterogeneous  collec2ons  (see  chapter  7)   –  Type  extensibility   Copyright@2014 Taylor & Francis Adair Dingle All Rights Reserved
  • 30.
    Principle  of  Least  Knowledge       Every  object  assumes  only  the  minimum  possible  about   the  structure  and  proper,es  of  other  objects         •  Promotes  low  coupling   •  Applicable  to  both  inheritance  and  composi2on  rela2ons   •  Class  design  NOT  dependent  on     –  private  implementa2on  details  of  any  other  class     •   Design  iden2fies     –  rela2onships     –  consequen2al  effects  of  rela2onships   =>  Class  2ed  only  to  interface  of  parent/composed  subobject   Copyright@2014 Taylor & Francis Adair Dingle All Rights Reserved
  • 31.
    Open  Closed  Principle  (OCP)   A  class  should  be  open  for  extension  and  closed  for  modifica,on         •  Inheritance  is  an  aSrac2ve  design  op2on  for   –  class  hierarchies  with  implicit  subtype  selec2on  to  vary  func2onality         –  Subs2tutability    (see  chapter  7)   –  Heterogeneous  collec2ons  (see  chapter  7)   –  Type  extensibility   •  A  good  inheritance  design  adheres  to  OCP   –  individual  classes  preserved     –  type  extensions  are  seamless   •  OCP  promotes  soiware  maintainability.       Copyright@2014 Taylor & Francis Adair Dingle All Rights Reserved