Object Oriented Design

From sheep
Jump to navigation Jump to search

Reference

http://ifacethoughts.net/2006/03/24/design-principles/

Encapsulation

  • hides implementation
  • enforces modularity

Polymorphism

  • many forms
  • Java - overridden methods

Open Closed Principle (OCP)

  • Open for extension - closed for modification

Ability to add new features without modifying existing classes <- e.g. define new subclass Principle: reduce coupling to abstract level

Polymorphic open closed principle

  • interface stays the same - implementation may change
  • abstract interface
  • any implementation may be substituted

equivalent to LSP

Liskov Substitution Principle (LSP)

 Let q(x) be a property about object x of type T
     q(y) should be true for objects y of type S where S is a subtype of T

i.e. objects of type T may be replaced by objects of type S for all S where S is a subtype of T

closely related to design by contract

  • preconditions can not be strengthened
  • post conditions can not be weakened

The above conditions have meaning out side of the Java language and can be hard to track/enforce

Design by contract

  • mutual obligations and benefits
  1. Obligations on entry - preconditions
  2. Guarentee of property on exit - postconditions
  3. Maintain property ( assumed on entry, guarantee on exit) class invariant

Violations of LSP => Violation of OCP Violation of OCP does not imply LSP violation

Dependency Inversion Principle

Coupling should be at the abstract (interface or abstract class) level not at the concrete class level DIP is the means to achieve OCP

Interface segregation Principle

  • Specific interfaces are better than general interfaces
  • Avoid multiple roles
  • Single role is more cohesive

Composite Reuse Principle

  • Favour polymorphic composition over inheritance
  • Avoid overriding default behaviour - behaviour should be the same for all ISAs

Principle of least knowledge

Only talk to your immediate friends

Any object should know as little as possible about software or properties of anything else - sub components included

i.e. object A may call methods on object B but should not call methods on objects contained within B

  • Advantage: easier to maintain - more adaptable
  • Disadvantage: class may become bloated with wrapper methods ([Facade Pattern])
  • Alternative solution is a get method returning interface not concrete class (of aggregate/composite class) - common in Java API

Facade Pattern get interface

Package Dependency

A-depends-b.png A depends on B.

If the contents of B change then this may impact package A

Release Reuse Equivalence Principle

Use of the class in the package => must deploy package Unit of reuse is unit of release

  • Don't copy code from one class to another - fixes to original will be reused
  • You should not need access to source code just deploy library
  • The package granularity helps reduce burdensome effort of tracking every class dependency

Common Closure Principle

Classes that change together belong together

  • Functional cohesion - grouping parts of a module together that perform well defined task - e.g. XML
  • Class cohesion - Functionally sound & don't cross responsibilities boundries

Common Reuse Principle

  • Classes that aren't reused together shouldn't be grouped together
  • Consider likelihood of classes changing together when choosing packaging
  • Avoid unwanted dependencies

Acyclic Dependency Principle

  • Dependencies between packages should not form a cycle
  • Dependencies should only form a DAG Directed Acyclic Graph
  • Factor out the cyclic forming part into a new Class => positive re-use

cyclic dependency

Important for a deployment perspective

Stable Dependencies Principles

Packages likely to experience frequent change (less stable) should have fewer incoming dependencies - Can have many outgoing dependencies

Packages less likely to change may have more incoming dependencies - Fewer outgoing dependencies

Stable Abstraction Principle

Stable packages should be more abstract packages

More stable packages should contain a higher number of abstract classes or interfaces

  • should heavily depend on them

Less stable packages contain high number of concrete classes

  • should not depend on such packages