Showing posts with label Design pattern. Show all posts
Showing posts with label Design pattern. Show all posts
Tuesday, 7 January 2014

The visitor design pattern

The visitor design pattern provides a method of separating an algorithm on an object and the object's actual class implementation. This allows the programmer to easily follow the open/closed principle;

software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification

Object-Oriented Software Construction, Bertrand Meyer

That is, modifying an entity's behaviour without modifying the underlying source code. Following the open/closed principle provides many quality-related benefits as the original code never changes.

Benefits

  • Follows the open/closed principle
  • Allows a new operation to be defined without changing the implementation of the class
  • A visitor object can have state

Drawbacks

  • If a new visitable object is added then all visitors need to be modified
Monday, 9 December 2013

Design patterns

Design patterns in software engineering are generic solutions to some commonly occurring problems encountered when creating software. They are incredibly useful tools for both communicating a solution to a problem to other developers and also for saving time solving problems that have already been solved in quite elegant ways. Learning the big design patterns is a also just a great way to improve your skills as a software developer.

Programmer using design pattern UML diagram
Saturday, 15 December 2012

The facade design pattern

The facade design pattern is a very simple pattern that provides a simplified interface to other code that may not be structured the same way. If we look facade up in the dictionary, this is one of the definitions we get:

An outward appearance that is maintained to conceal a less pleasant or creditable reality.

Google dictionary

This is the primary purpose of the pattern; to conceal a piece of code that isn't very nice to use and replace it with something better. That's all it is really, a class that calls code elsewhere.

Benefits

  • Can change a badly-designed or hard to use API into an easy to use API
  • Can merge multiple APIs into a single API
  • If all calls to a function are done through a facade then it is very easy to refactor

Drawbacks

  • Could possibly add unnecessary complexity if overused or used incorrectly
Saturday, 1 December 2012

The factory method design pattern

The factory method design pattern attempts to implement the concept of real-world factories within your program. Instead of the object creating itself, the task of creation is given to a 'factory' object.

Factory method effectively encapsulates the creation of objects within another class, one benefit of this is that it allows access to resources or objects that may not be available within the class constructor. For example a UI framework may have a createWidget factory method, this method not only returns the new object but also adds it to the list of widgets to be drawn and updated. This is one of the most common usage examples for factory method.

Benefits

  • Provides a centralised location for pre- or post-constructor logic
  • Allows access to resources that may not be available within the class being constructed
  • Encapsulates the creation of objects

Drawbacks

  • A factory can only be used for a single family of objects
  • Can potentially overcomplicate a solution
  • Factory methods are not as easily identified as constructors are
Sunday, 4 November 2012

The decorator design pattern

The decorator pattern allows behaviour to be added to an existing object at runtime. This is achieved by wrapping the object (the component) in another class (the decorator).

Like the delegation pattern, the decorator pattern is similar to inheritance as it extends the functionality of a particular class. The primary difference between decorator and delegation is that the decorator pattern is more flexible, allowing multiple decorators to point to a single component at one time.

Reducing the complexity of an inheritance tree is one of the benefits to this pattern, imagine for example an application that prints a photo with an optional filter, an optional border and an optional rotation. This can be achieved in the following ways:

  • A single class with a lot of code; Photo
  • A class for each combination of options; Photo, BorderPhoto, FilterPhoto, RotatePhoto, BorderFilterPhoto, FilterRotatePhoto, BorderRotatePhoto, BorderFilterRotatePhoto
  • A class with optional decorators; Photo, PhotoFilterDecorator, PhotoBorderDecorator, PhotoRotateDecorator

The decorator pattern is of great use when implementing the open/closed principle, as described below:

software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification

Object-Oriented Software Construction, Bertrand Meyer

So once an application has been built, it should only be extended, not modified. It is particularly useful in a production environment as it reduces the amount of regression testing required. The decorator pattern is great here as it's simple to extend existing components in a completely modular way.

Benefits

  • Add behaviour to a component dynamically at runtime
  • Attach multiple decorators to a single component at one time
  • Completely modular, we don't need to touch the existing component
  • Can reduce the amount subclasses of a class

Drawbacks

  • Overuse of the decorator pattern can lead to very abstract and complex code
Saturday, 21 July 2012

The delegation design pattern

The delegation design pattern allows an object to delegate one or more tasks to a helper object. Two classes are used to achieve this; the delegate and delegator, both which realise a common interface. A method (or methods) on the interface represent the functionality to be delegated. A call to the delegator calls the matching function on the delegate.

While this seemingly just abstracts away some of the functionality into another class, the real power of this pattern comes when there are multiple delegates. The delegator typically has a method for each delegate that will convert the delegator to use that delegate.

It is useful for understanding to compare the delegation pattern to inheritance. Both are powerful reuse techniques with a few of key differences; inheritance is directly supported by today's object-oriented programming languages and enables the use of polymorphism, whereas the delegation pattern allows the delegate to be changed at run-time.

Benefits

  • Clearly separates the different sets of functionality
  • Run-time flexibility

Drawbacks

  • Not as trivial as implementing inheritance
Saturday, 12 May 2012

The singleton design pattern

The singleton design pattern enables easy access to a single instance of a class.

Benefits

  • Makes it very easy to get a single instance of an object globally

Drawbacks

  • They are effectively just globals, this is not object-oriented design
  • Can cause concurrency issues if not the singleton is not thread-safe
  • Can make code hard to follow
  • Makes unit testing more difficult

From the looks of the benefits and drawbacks you would wonder why you would use a singleton at all, a lot of people even consider it an anti-pattern. My answer to that question is that you should only use this pattern very sparingly and preferably not at all in large projects. You can however save yourself quite a bit of time using them in small projects.

Friday, 27 April 2012

The lazy loading design pattern

The lazy-loading design pattern provides a means to defer the creation of an object by loading it at the point it is needed. This has both benefits and drawbacks.

Benefits

  • Save memory by only loading what is needed when it's needed.
  • Reduce initial load time by deferring execution.

Drawbacks

  • There may be a delay the first time you need the object you're lazy-loading.

Lazy-loading is often a key feature of ORMs, which perform database queries only when the data is required in order to reduce the amount of data retrieved. This can lead to some issues with certain data not being present, you can usually get around this by explicitly specifying what you need. It is important to understand why this can occur when working with an ORM to prevent obscure bugs.