Presentation is loading. Please wait.

Presentation is loading. Please wait.

Design Patterns and Principles of Object Oriented Application Development “design patterns are proven techniques used by experienced developers to tackle.

Similar presentations


Presentation on theme: "Design Patterns and Principles of Object Oriented Application Development “design patterns are proven techniques used by experienced developers to tackle."— Presentation transcript:

1 Design Patterns and Principles of Object Oriented Application Development “design patterns are proven techniques used by experienced developers to tackle recurring design problems without resorting to first principles” Design Patterns: Elements of Reusable Object-Oriented Software Gamma, Helm, Johnson and Vlissides, 1995

2 Introduction Software Quality Principles of Object Oriented Design  Methods to improve on software quality Design Patterns  Principles applied

3 Software Quality External Factors  Visible to customers  Examples : Ease of Use Extendability Robustness Correctness Internal Factors  Visible to developers  Examples: Information Hiding Consistency Programming Style

4 External Factors The software performs according to the client's specification Correctness

5 External Factors The software reacts reasonably to actions and events not covered by the specification Robustness

6 External Factors A system is reliable if it is correct & robust Reliability

7 Software Quality How is Software Quality achieved?  Software Principles  Design Patterns Software principles + design patterns = Improved Internal Factors

8 Why Object Oriented Design? Object decomposition  More intuitive mapping of the problem domain to objects  What types of object are manipulated by the system? Objects as generalised type Specific behaviour given to subtypes

9 Object Oriented Design Benefits Reusability  Operations usually dependent on data  Objects bind data to operations class is the unit of reuse  DRY – Don't Repeat Yourself Extendibility  By building on existing functionality  Object heirarchies are more stable over time as system is modified

10 Modularity Decomposition  large problems into smaller manageable problems  large or complex code base composed of smaller, simpler subunits Subunits provide specific feature or functionality Composition  Build new software from existing smaller components (DRY)‏

11 Modularity Supporting Principles The Open-Closed Principle Information Hiding Uniform Access Principle Acyclic Dependency Principle Single Responsibility Principle Dependency Inversion Principle Liskov Substitution Principle Interface Segregation Principle Composite Reuse Principle Principle of Least Knowledge (Law of Demeter)‏

12 The Open-Closed Principle Modules are open for extension Modules are coupled across abstract interfaces. The interfaces should provide sufficient access to be extended by newer code. Modules are closed for modification new features are added without modifying the system's existing code. Only bug fixes are applied to existing implementation. New features are added by new classes.

13 The Open-Closed Principle Advocates always writing to interfaces or abstract classes Reduces the coupling between system components to the abstract layer only

14 The Open-Closed Principle Example

15 Information Hiding Principle Each module has a defined public interface through which all external access must occur  The module designer selects a subset of a module's properties or methods to act as this interface to client modules. A module's internal structure should be protected from external access  Implementation details remain hidden  Easier to ensure system is in a consistent/legal state if all access to data is secured against external access.

16 Uniform Access Principle "All services offered by a module should be available through a uniform notation, which does not betray whether they are implemented through storage or through computation." Bertrand Meyer

17 Uniform Access Principle Ruby Example class UAP attr_reader :value def initialize(value)‏ @value = value end def value_squared return @value*@value end uap = UAP.new(10)‏ puts uap.value puts uap.value_squared

18 Uniform Access Principle Python Example class UAP(object): def __init__(self, value): self.setValue(value)‏ def getValue(self): return self.__value def setValue(self, value): self.__value = value def getValueSquared(self): return self.__value*self.__value value = property(getValue, doc="getter for value")‏ valueSquared = property(getValueSquared, doc="getter for value squared")‏ uap = UAP(2)‏ print uap.value print uap.valueSquared

19 Acyclic Dependency Principle Package dependencies must not form cycles. Example: Package A imports Package B and Package B imports Package A Causes the tight coupling between packages. Package A must be deployed everywhere Package B is (and vice versa)‏ How to break dependency cycles?

20 Acyclic Dependency Principle Factor out code that causes the dependency into separate package

21 Single Responsibility Principle A class should have one responsibility. Each responsibility can lead to modifications to the class on changing requirements. For maintainable code, if a class has multiple responsibilities, break up the class into multiple cooperating classes.

22 Dependency Inversion Principle High level classes should depend upon low level abstractions. High level class contains reference to abstract type to perform the function.

23 Dependency Inversion Principle Example Gauge takes a string to avoid dependency on concrete GaugeType subclass. Prone to errors like typos (See Factory Pattern)‏

24 Liskov Substitution Principle Extends OCP A base class can be replaced by a derived class without changing the functionality of the module. Ensure derived classes do not change the behaviour of parent classes.

25 Liskov Substitution Principle (Contd)‏ Design by contract (from Eiffel)‏ Preconditions and postconditions of super class are maintained by subclass. If preconditions not met, don't invoke method. If postconditions not met, don't return.

26 Liskov Substitution Principle Example class Rectangle attr_accessor :width, :height def area @width * @height end class Square < Rectangle def width=(new_width)‏ @width=@height=new_width end def height=(new_height)‏ @width=@height=new_height end def printArea(shape)‏ shape.width=5 shape.height=10 if shape.is_a? Rectangle puts "Rectangle of 5x10 should have area of 50," else puts "Not a Rectangle, so don't know the area" end puts "Shape is a #{shape.class} of #{shape.width}” + “x#{shape.height}, area is #{shape.area}" end r = Rectangle.new s = Square.new printArea(r)‏ gets printArea(s)‏

27 Integration Segregation Principle Many specific interfaces are better than a large generic interface. Classes should not be forced to implement an interface they do not use. Is large interface really representative of most general type? Null operation or default methods? Reduces amount of information shared between modules.

28 Composite Reuse Principle Don't define default behaviour in base classes Prefer polymorphic composition of objects over inheritance Instance variables are references to abstract type of concrete classes providing functionality See Strategy, Composite and Visitor Patterns

29 Principle of Least Knowledge (aka Law of Demeter)‏ When calling method M of object O, M may only access methods on: O Parameters of M Objects created by M O's contained instance objects M cannot call through to methods exposed by objects outside of it's control:  Example: object.field.method()

30 Design Patterns Proven 'best practices' High level building blocks for system architecture Resulted from the experiences of their implementation across a number of scenarios.

31 Common Design Patterns Creational  Singleton  Factory  Builder Behavioural  Strategy  Visitor  Observer Structural  Decorator  Facade  Composite

32 Singleton When only a single instance of a class should be created for the entire application. class Singleton { private static Singleton instance; private Singleton() {... } public static synchronized Singleton getInstance() { if (instance == null)‏ instance = new Singleton(); return instance; } public void doSomething() {... }

33 Builder Create complex objects while hiding the complexity of the objects' creation behind an interface. The Builder pattern is indicated when the complex object can have different representations/implementations.  client is shielded from these differences in construction

34 Builder Example

35 Factory Allows clients to create objects of abstract types without depending on concrete subclasses. Two types:  Abstract Factory  Factory Method

36 Abstract Factory Provides an interface to create families of objects without the client specifying the concrete type  System can use of a multiple families of products e.g. wxWidgets or Qt window toolkits  Clients rely on interfaces, not concrete implementations

37 Abstract Factory Example

38 Factory Method Expose an interface for creating an object Subclasses determine the concrete type to instantiate  May delegate responsibility to helper classes to localise the knowledge of object's construction

39 Factory Method Example

40 Factory versus Builder Factory Method creates concrete object  Akin to a virtual constructor  Returns different subtypes depending on input Abstract Factory creates families of objects  Factory class may contain Factory Method pattern Builder assembles complex object from constituent subcomponents  Client instructs Builder how to create object and asks for result

41 Decorator Attach additional responsibilities to an object dynamically Provides a flexible alternative to subclassing for extending functionality

42 Decorator Example void doSomething() { // Preprocess... // Delegate to decorated object decorated.doSomething()‏ // Postprocess... }

43 Decorator Concrete Example InputStream is = new LineNumberInputStream( new BufferedInputStream( new FileInputStream(file)))‏ From Java's IO Stream:

44 Facade Execute the business logic from one use case as one transaction over a single method invocation utilising functionality from an existing use case. Considered as a single interface to features of a subsystem specified as a single call to the Facade object. Facade object exists in addition to the public interface it wraps.

45 Facade Example

46 Composite Represents part-whole hierarchies Define a data structure as a linked set of nodes Client can ignore whether node is a leaf or a container

47 Composite Diagram From GoF

48 Visitor Separates operations from the data structures on which they operate New operations can be defined with new Visitor implementations  adheres to the Open-Closed Principle Traversal order can be specified by:  the data structure  the Visitor class  an external operation (an iterator)‏

49 Visitor Diagram

50 Strategy Allows a family of algorithms to be used interchangeably by client classes Allows for “pluggability”  Algorithms can be selected at run time

51 Strategy Example

52 Observer Defines a one-to-many dependency between objects dependent on state through abstract interfaces  Enforces OCP and DIP  Allows a change to an object's state to be propagated to interested objects such that the number and types of Observer are immaterial to the subject

53 Observer Example

54 Further Information Books Design Patterns: Elements of Reusable Object- Oriented Software Gamma, Helm, Johnson and Vlissides, 1995 (aka Gang of Four book)‏ Refactoring: Improving the Design of Existing Code. Martin Fowler, 1999 Patterns of Enterprise Application Architecture Martin Fowler, 2002 Plenty more in the library

55 Further Information Electronic Resources Hillside.net Online Pattern Catalog (http://hillside.net/patterns/onlinepatterncatalog.htm)‏ Refactoring.com MartinFowler.com Search the Web


Download ppt "Design Patterns and Principles of Object Oriented Application Development “design patterns are proven techniques used by experienced developers to tackle."

Similar presentations


Ads by Google