Monday, September 15, 2008

Abstract Factory Pattern


As my first September post I've decided to write a bit about the Abstract Factory.
Remember from the previous posts that the main idea of a reusable object is to capture your dynamic content. In the case of the Abstract Factory, the dynamic component might not seem obvious at first.

It helps to compare this pattern to an "actual factory" e.g. a car factory. The factory produces cars and these cars may be grouped into categories (or products if you'd like). However, each category may consist of several versions of the "same" car (a different colour, different sound system, special add-ons), all tweaked and modified to fit a client's specific needs. Every car is built similar with four wheels, similar framework, and using the same materials.

The same principle applies in software development. You might need to produce the same component (e.g. a window, scrollbar or a panel), but would like to have each component BEHAVE or LOOK differently on different platforms or situations (each one customised to fit the client's specific needs).

The Abstract Factory is abstract, which implies that the actual behaviour or cosmetics is delegated to its implementation. The idea of the Abstract Factory pattern is to have the client code call a particular Concrete Factory implementation to produce the desired components. Each factory might produce windows, scrollbars and panels with a specific theme (e.g. one might produce grey windows while another creates windows that are blue). You end up having several Concrete Factories; each one adding its own touch to the products it produces.

At first you might be tempted to use the Decorator pattern, but this pattern is more usefull in encapsulating extending functionality. It wraps over an existing object and adds more functionality. This could prove to be a better solution than simple subclassing in some scenarios, but the Abstract Factory scenario is different.

A situation might arise where we would like to choose between several of these decorated objects (each one having just a small difference from the other). This would imply an explosion of objects that all look the same, act the same and are used in the same way. Instead of a complex system with thousands of objects, we could try to encapsulate the dynamic component which in this case is the small difference between the various object types or products (e.g. the colour difference between the different types of windows, scrollbars or panels). That is where the Abstract Factory pattern becomes usefull where each Concrete Factory produces its own family of products all using the same theme or colour schema.

Some tips for using this pattern. Use an Abstract Factory:

[1] When decoupling is needed between your system and some individual products. How the underlying components or products are created, composed and represented becomes independent of system behaviour. The system only interacts with abstract interfaces to the underlying components.

[2] When the small differences (e.g. colour) are existent between entire families of products.

[3] When the family of products is designed to be used together (because they're all using the same theme for example).

[4] When you'd like to provide a library of products, but just reveal their interfaces and not their implementations to the system.

Usually the Concrete Factory is instantiated as a singleton (since only one factory is required for every family). The individual products are instantiated using the factory itself and doesn't care whether the factory is a singleton or not. This is analogous to several cars produced in the same car factory (having only one factory doesn't mean you're obliged to produce only one car). On the other hand, you might have several different factories (Mercedes, BMW etc.) each producing their own "families" of cars.

The main point is this: use an Abstract Factory to produce entire families of products or components with some special attribute that distinguishes them from the other families.

0 comments: