How unit 3 is examined
This unit covers the idea of a design pattern, the GoF catalogue and the creational patterns (Singleton, Factory Method, Abstract Factory, Builder, Prototype); no question on it appeared in the supplied papers, so every part is taught for the first time it is asked.
Design patterns - 1
<span style="display:inline-block;padding:.16em .6em;border:1.5px solid currentColor;border-radius:999px;font-size:.68em;font-weight:700;letter-spacing:.06em;text-transform:uppercase;opacity:.75">Not asked since 2022</span>
Definition. <mark>A design pattern is a proven, reusable solution to a commonly occurring problem in software design, described as a template that can be adapted to many situations rather than as finished code.</mark>
Key points.
- A pattern is written down with a name, the problem it solves, the solution (classes and their collaboration) and the consequences of using it, so that developers share one vocabulary.
- The Gang of Four (Gamma, Helm, Johnson, Vlissides) catalogued 23 patterns in the book "Design Patterns: Elements of Reusable Object-Oriented Software", which is why they are called GoF patterns.
- The 23 patterns fall into three groups: creational (how objects are created), structural (how classes and objects are composed) and behavioural (how objects communicate and share responsibility).
- Patterns follow the principle "program to an interface, not an implementation" and prefer object composition over class inheritance, which keeps code loosely coupled and easy to change.
- Patterns improve reuse, maintainability and communication in a team, but a pattern used where a plain solution would do only adds needless complexity.
Diagram.
<figure class="ds-fig" style="margin:1.4rem 0;overflow-x:auto"><svg xmlns="http://www.w3.org/2000/svg" id="dsfig-u3-01" viewBox="0 0 1847 194" width="1847" height="194" role="img" aria-label="GoF classification of design patterns; Unit 3 stresses the creational group and Unit 4 continues with the rest"><style>#dsfig-u3-01 .e{stroke:#454C5A;stroke-width:1.4;fill:none}#dsfig-u3-01 .e.hi{stroke:#2340B8;stroke-width:2.6}#dsfig-u3-01 .n{fill:#FFFFFF;stroke:#16181D;stroke-width:1.4}#dsfig-u3-01 .n.hi{fill:#E3E9FC;stroke:#2340B8;stroke-width:2.2}#dsfig-u3-01 .n.rb-b{fill:#16181D;stroke:#16181D}#dsfig-u3-01 .n.rb-r{fill:#BD3227;stroke:#BD3227}#dsfig-u3-01 text{font-family:"JetBrains Mono",ui-monospace,Menlo,Consolas,monospace;font-size:13px}#dsfig-u3-01 .t{fill:#16181D;font-weight:500}#dsfig-u3-01 .t.inv{fill:#FFFFFF;font-weight:700}#dsfig-u3-01 .kd{stroke:#16181D;stroke-width:1.2}#dsfig-u3-01 .dot{fill:#16181D}#dsfig-u3-01 .ann{fill:#2340B8;font-size:11px;font-weight:700}#dsfig-u3-01 .lbl{fill:#6F7787;font-family:system-ui,-apple-system,sans-serif;font-size:12px;font-weight:700}#dsfig-u3-01 .ptr{fill:#2340B8;font-size:12px;font-weight:700}#dsfig-u3-01 .ah{fill:#454C5A}#dsfig-u3-01 .ah.hi{fill:#2340B8}#dsfig-u3-01 .wl rect{fill:#FFFFFF;stroke:#DCE0E7}#dsfig-u3-01 .wl .t{font-size:12px;font-weight:700}#dsfig-u3-01 .wl.hi rect{fill:#2340B8;stroke:#2340B8}#dsfig-u3-01 .wl.hi .t{fill:#FFFFFF}html.dark #dsfig-u3-01 .e{stroke:#B1B7C3}html.dark #dsfig-u3-01 .e.hi{stroke:#8FA3FF}html.dark #dsfig-u3-01 .n{fill:#161920;stroke:#E6E8ED}html.dark #dsfig-u3-01 .n.hi{fill:#1E2748;stroke:#8FA3FF}html.dark #dsfig-u3-01 .n.rb-b{fill:#E6E8ED;stroke:#E6E8ED}html.dark #dsfig-u3-01 .n.rb-r{fill:#FF7E71;stroke:#FF7E71}html.dark #dsfig-u3-01 .t{fill:#E6E8ED}html.dark #dsfig-u3-01 .t.inv{fill:#0F1115}html.dark #dsfig-u3-01 .kd{stroke:#E6E8ED}html.dark #dsfig-u3-01 .dot{fill:#E6E8ED}html.dark #dsfig-u3-01 .ann{fill:#8FA3FF}html.dark #dsfig-u3-01 .lbl{fill:#858D9C}html.dark #dsfig-u3-01 .ptr{fill:#8FA3FF}html.dark #dsfig-u3-01 .ah{fill:#B1B7C3}html.dark #dsfig-u3-01 .ah.hi{fill:#8FA3FF}html.dark #dsfig-u3-01 .wl rect{fill:#161920;stroke:#2A2E37}html.dark #dsfig-u3-01 .wl.hi rect{fill:#8FA3FF;stroke:#8FA3FF}html.dark #dsfig-u3-01 .wl.hi .t{fill:#0F1115}</style><defs><marker id="ah1" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path class="ah" d="M0,1 L9,5 L0,9 z"/></marker><marker id="ahh1" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path class="ah hi" d="M0,1 L9,5 L0,9 z"/></marker></defs><line class="e" x1="930" y1="37" x2="312" y2="101"/><line class="e" x1="930" y1="37" x2="948.5" y2="101"/><line class="e" x1="930" y1="37" x2="1548" y2="101"/><line class="e" x1="312" y1="101" x2="59.5" y2="165"/><line class="e" x1="312" y1="101" x2="186" y2="165"/><line class="e" x1="312" y1="101" x2="339.5" y2="165"/><line class="e" x1="312" y1="101" x2="465.5" y2="165"/><line class="e" x1="312" y1="101" x2="564.5" y2="165"/><line class="e" x1="948.5" y1="101" x2="663.5" y2="165"/><line class="e" x1="948.5" y1="101" x2="750.5" y2="165"/><line class="e" x1="948.5" y1="101" x2="845.5" y2="165"/><line class="e" x1="948.5" y1="101" x2="952.5" y2="165"/><line class="e" x1="948.5" y1="101" x2="1047.5" y2="165"/><line class="e" x1="948.5" y1="101" x2="1142.5" y2="165"/><line class="e" x1="948.5" y1="101" x2="1233.5" y2="165"/><line class="e" x1="1548" y1="101" x2="1320.5" y2="165"/><line class="e" x1="1548" y1="101" x2="1419.5" y2="165"/><line class="e" x1="1548" y1="101" x2="1514.5" y2="165"/><line class="e" x1="1548" y1="101" x2="1609.5" y2="165"/><line class="e" x1="1548" y1="101" x2="1696.5" y2="165"/><line class="e" x1="1548" y1="101" x2="1775.5" y2="165"/><rect class="n" x="873" y="22" width="114" height="30" rx="8"/><text class="t" x="930" y="37" dy=".35em" text-anchor="middle">GoF patterns</text><rect class="n" x="263" y="86" width="98" height="30" rx="8"/><text class="t" x="312" y="101" dy=".35em" text-anchor="middle">Creational</text><rect class="n" x="14" y="150" width="91" height="30" rx="8"/><text class="t" x="59.5" y="165" dy=".35em" text-anchor="middle">Singleton</text><rect class="n" x="121" y="150" width="130" height="30" rx="8"/><text class="t" x="186" y="165" dy=".35em" text-anchor="middle">Factory Method</text><rect class="n" x="267" y="150" width="145" height="30" rx="8"/><text class="t" x="339.5" y="165" dy=".35em" text-anchor="middle">Abstract Factory</text><rect class="n" x="428" y="150" width="75" height="30" rx="8"/><text class="t" x="465.5" y="165" dy=".35em" text-anchor="middle">Builder</text><rect class="n" x="519" y="150" width="91" height="30" rx="8"/><text class="t" x="564.5" y="165" dy=".35em" text-anchor="middle">Prototype</text><rect class="n" x="899.5" y="86" width="98" height="30" rx="8"/><text class="t" x="948.5" y="101" dy=".35em" text-anchor="middle">Structural</text><rect class="n" x="626" y="150" width="75" height="30" rx="8"/><text class="t" x="663.5" y="165" dy=".35em" text-anchor="middle">Adapter</text><rect class="n" x="717" y="150" width="67" height="30" rx="8"/><text class="t" x="750.5" y="165" dy=".35em" text-anchor="middle">Bridge</text><rect class="n" x="800" y="150" width="91" height="30" rx="8"/><text class="t" x="845.5" y="165" dy=".35em" text-anchor="middle">Composite</text><rect class="n" x="907" y="150" width="91" height="30" rx="8"/><text class="t" x="952.5" y="165" dy=".35em" text-anchor="middle">Decorator</text><rect class="n" x="1014" y="150" width="67" height="30" rx="8"/><text class="t" x="1047.5" y="165" dy=".35em" text-anchor="middle">Facade</text><rect class="n" x="1097" y="150" width="91" height="30" rx="8"/><text class="t" x="1142.5" y="165" dy=".35em" text-anchor="middle">Flyweight</text><rect class="n" x="1204" y="150" width="59" height="30" rx="8"/><text class="t" x="1233.5" y="165" dy=".35em" text-anchor="middle">Proxy</text><rect class="n" x="1495" y="86" width="106" height="30" rx="8"/><text class="t" x="1548" y="101" dy=".35em" text-anchor="middle">Behavioural</text><rect class="n" x="1279" y="150" width="83" height="30" rx="8"/><text class="t" x="1320.5" y="165" dy=".35em" text-anchor="middle">Observer</text><rect class="n" x="1378" y="150" width="83" height="30" rx="8"/><text class="t" x="1419.5" y="165" dy=".35em" text-anchor="middle">Strategy</text><rect class="n" x="1477" y="150" width="75" height="30" rx="8"/><text class="t" x="1514.5" y="165" dy=".35em" text-anchor="middle">Command</text><rect class="n" x="1568" y="150" width="83" height="30" rx="8"/><text class="t" x="1609.5" y="165" dy=".35em" text-anchor="middle">Iterator</text><rect class="n" x="1667" y="150" width="59" height="30" rx="8"/><text class="t" x="1696.5" y="165" dy=".35em" text-anchor="middle">State</text><rect class="n" x="1742" y="150" width="67" height="30" rx="8"/><text class="t" x="1775.5" y="165" dy=".35em" text-anchor="middle">Others</text></svg><figcaption style="font-size:.82em;opacity:.72;margin-top:.45rem">GoF classification of design patterns; Unit 3 stresses the creational group and Unit 4 continues with the rest</figcaption></figure>
Creational patterns. Creational patterns hide how objects are made, so the system does not depend on how its objects are created, composed and represented.
| Pattern | Intent | Typical use |
|---|---|---|
| Singleton | Only one instance of a class, with a global access point | Logger, configuration, database connection pool |
| Factory Method | An interface for creating an object, but subclasses decide which class to instantiate | Document creators, UI widgets per platform |
| Abstract Factory | An interface for creating families of related objects without naming concrete classes | Look-and-feel toolkits (Windows, Mac widgets) |
| Builder | Separates construction of a complex object from its representation, built step by step | Building a meal, a report, an SQL query |
| Prototype | Creates new objects by cloning an existing prototype | Copying costly-to-create objects |
Singleton.
- The constructor is made private (or controlled) so no other class can create instances with
new. - The class keeps one static reference to its only instance.
- A static method such as
getInstance()creates the instance on first call and returns the same one afterwards. - In multi-threaded programs the creation must be synchronised, or the instance created eagerly at class-load time.
class Single:
_i = None
def __new__(c):
if c._i is None:
c._i = super().__new__(c)
return c._i
print(Single() is Single()) # True
Factory Method.
- A
Creatordeclares the factory method that returns aProductinterface. - Each
ConcreteCreatoroverrides it to return aConcreteProduct. - The client works only with the
Productinterface, so a new product is added without changing client code, which follows the open-closed principle.
class Dog:
def speak(s): return "Woof"
class Cat:
def speak(s): return "Meow"
def make(kind):
return {"dog": Dog, "cat": Cat}[kind]()
print(make("cat").speak()) # Meow
Abstract Factory.
- An
AbstractFactoryinterface declares one creation method for each product in a family (for examplecreateButton()andcreateCheckbox()). - Each
ConcreteFactory(for example WindowsFactory, MacFactory) creates the products of one consistent family. - The client uses only the abstract factory and abstract products, so the whole family can be switched by changing one factory object.
- It differs from Factory Method because it creates several related products, usually with composition, instead of a single product through inheritance.
Builder.
- A
Directorcontrols the order of construction steps and calls theBuilderinterface. - A
ConcreteBuilderimplements the steps (buildPartA(),buildPartB()) and returns the finished product throughgetResult(). - The same construction process can therefore produce different representations, and it avoids a constructor with many parameters.
Prototype.
- A
Prototypeinterface declares aclone()operation and the concrete class copies itself. - The client obtains new objects by cloning a registered prototype instead of building one from scratch, which saves cost when creation is expensive.
- A shallow copy shares nested objects with the original, whereas a deep copy duplicates them; a deep copy is needed for independent objects.
import copy
class P:
def __init__(s): s.tags = ["a"]
a = P()
b = copy.deepcopy(a)
b.tags.append("b")
print(a.tags, b.tags) # ['a'] ['a', 'b']
Answer frame. Open with the definition of a design pattern and its three GoF groups; draw the classification tree; then develop the creational patterns in the order Singleton, Factory Method, Abstract Factory, Builder, Prototype, giving intent, structure and one example each; close with the benefit of reuse and loose coupling.
Answer frame (one pattern). Open with the intent of the pattern in one line; draw its class diagram (for Singleton a single class with a private constructor and getInstance()); list the participants and steps; give a short code snippet and a real use such as a logger; close with one advantage and one drawback.
Comparison.
| Basis | Factory Method | Abstract Factory |
|---|---|---|
| Creates | One product | A family of related products |
| Mechanism | Inheritance, subclass overrides the method | Composition, a factory object is passed in |
| Interface | One creation method | One creation method per product |
| Adding a new product kind | Add a subclass | Change the factory interface, which is harder |
| Adding a new family | Not directly supported | Add a new concrete factory |
Pitfall: Do not say Singleton is a structural pattern or that Prototype uses
new; Singleton, Factory, Abstract Factory, Builder and Prototype are all creational, and Prototype creates objects by cloning.
Last-minute revision
- A design pattern is a proven, reusable solution to a recurring design problem, given as a template.
- GoF gave 23 patterns: creational, structural and behavioural.
- Creational patterns: Singleton, Factory Method, Abstract Factory, Builder, Prototype.
- Singleton means one instance, a private constructor and a static
getInstance(). - Factory Method lets subclasses decide which class to instantiate.
- Abstract Factory creates families of related objects through concrete factories.
- Builder constructs a complex object step by step using a Director and a Builder.
- Prototype creates new objects by cloning; deep copy duplicates nested objects.
- Design principle: program to an interface and prefer composition over inheritance.
- Factory Method uses inheritance; Abstract Factory uses composition.
Memory hooks
- GoF = 23 patterns in 3 groups: Create, Structure, Behave.
- Creational five: "S-F-A-B-P" = Single, Factory, Abstract, Builder, Prototype.
- Singleton = "only one".
- Factory = "ask the factory, do not call new".
- Builder = "step by step, Director in charge".
- Prototype = "photocopy, not rebuild".
Coverage checklist
- Design patterns - 1: definition, GoF classification, creational patterns Singleton, Factory Method, Abstract Factory, Builder, Prototype, comparison of Factory Method and Abstract Factory (no past questions in the supplied papers).