Abstract Factory Pattern

실리콘·2023년 2월 15일
0

Intent

Provide an interface for creating families of related or dependent objects, w/o specifiying their concrete classes.

Also Known As

Kit

Motivation

To enable easy changing of the look, feel of an application. Also clients should stay independent of the prevailing look and feel. WidgetFactory is the topmost abstract class. There will be concrete subclass of WidgetFactory for each look-and-feel standard. ex. MotifWidgetFactory, which returns a Motif scroll bar. PMWidgetFactory, returning a scroll bar for Presentaion Manager.
Clients have no idea of WidgetFactory interface. Only use instance of the concrete subclasses, but adhere to interface defined by the abstract class WidgetFactory.

Applicability

  • A system should be independent of how its products are created, composed, and represented.
  • A system should be configured with one of multiple families of products.
  • A family of related product objects is designed to be used together, and you need to enforce this constraint.
  • You want to provide a class library of products, and want to reveal interfaces only, not implementation

Structure

Participants

  • AbstractFactory (WidgetFactory)
    - declares an interface for operations that create abstract product objects.
  • ConcreteFactory (MotifWidgetFactory, PMWidgetFactory)
    - implements the operations to create concrete product objects.
  • AbstractProduct (Window, ScrollBar)
    - declares an interface for a type of product object.
  • ConcreteProduct (MotifWindow, MotifScrollBar)
    - defines a product object to be created by the corresponding concrete factory.
    - implements the AbstractProduct interface.
  • Client
    - Only use interfaces defined by AbstratFactory and AbstractProduct

Collaborations

  • Normally a single instance of a ConcreteFactory class is created at run-time. Of course. its a factory. Creates one kind of product. If client wants different product, use another factory.
  • AbstractFactory defers creation of product objects to its ConcreteFactory subclass.

Consequences

Benefits & Liabilities
1. It isolates concrete classes. Product class names are isolated in the implementation of the concrete factory. not in client code.
2. It makes exchangin product families easy. The class of concrete factory appears only once in an application, where it's instantiated. So no duplicate code change when changin concrete factory to use.
3. Promotes consistency among products. AbstractFactory enforcement.
4. Supporting new kinds of products is difficult. Fixed interface. What if new product requires extended interface? hard. Lots of code to change. But one possible solution in Implementaion section.

Implementation

Some useful techniques for implementing the Abstrat Factory pattern.
1. Factories as singletons.
2. Creating the products. See Factory Method pattern for each product. This overrides I think the constructor() for product classes?
If many product families are possible, refer to Prototype pattern. A javascript like pattern I think.
Pure Prototype apporach
Concrete factory has protype of a product. Factory clones the prototype, and creates the product. Eliminates the need for a new concrete factory calss for each new product family.
Prototype variant
Possible in languages that treat classes as first-class objects. Define a new factory by initializing an instance of concrete factory with classes of products, not by subclassing. This approach takes advantage of language characteristics, whereas the pure Prototype-based approach is language-independent.
3. Defining extensible factories. AbstractFactory usually defines a different operation for each kind of product it can produce. The kinds of products are encoded in the operation signatures. Adding a new kind of product requires changin the AbstractFactory interface and all the classes that depend on it.

  • A more flexible, but less safe design is to add a parameter to operations that create objects. This parameter specified the kind of object to be created. Can be class identifier, integer, whatever. Then AbstractFactory would only need a single make() method with a parmeter indicating the kind of object to create. This is the technique used in the Prototype- and the class-based abstract factories discuessed earlier.
  • This variation is easier to use in a dynamically typed language (js, python).
  • A inherent problem: All products are returned to the client with the same abstract interface as given by the return type. The client will not be able to differentiate or mkae safe assumptions about the class of a product. If clients need to perform subclass-specific operations, they won't be accessible through the abstract interface. Could do a downcast, but not always feasible or safe, as downcast can fail. This is a classic trade-off for a highly flexible and extensible interface.

Sample Code

in C++ in books.
if you want dynamic language example, there is also SmallTalk example. But you have to know the C++ example first to understand.

Known Uses

Old cases.. Interviews? ET++?

implement using Factory Method, or Prototype
A concrete factory is often a Singleton.

profile
software engineer

0개의 댓글