Design Patterns 2 Flashcards
(32 cards)
Problem:
A class cannot anticipate the class of objects it
must create. It needs to delegate the
responsibility of instantiating objects to
subclasses to allow for flexibility and
decoupling in object creation.
Factory Pattern
Solution:
Define an interface (or abstract class) for
creating an object, but let the subclasses
decide which class to instantiate. This pattern
lets a class defer instantiation to subclasses
by implementing a factory method that
returns a product object.
Factory Pattern
Factory Pattern Adv
Consequences:
Advantages:
* Promotes Loose Coupling.
* Supports Open/Closed Principle- New
product types can be introduced without
modifying existing code.
* Improved Code Reusability and
Maintainability.
* Encourages Use of Polymorphism.
Factory Pattern Disadv
Disadvantages:
* More Classes and Complexity.
- Less Straightforward for Simple Scenarios-
Overhead might be unnecessary if only one
product type is involved.
* Harder to Trace Code Flow.
Problem:
You have a class with multiple dimensions of
variation (e.g., shape and color, or UI control
and platform), and extending the class
hierarchy to accommodate all combinations
leads to an explosion of subclasses. Tight
coupling between abstraction and
implementation makes the code difficult to
maintain or extend.
Bridge Pattern
Solution:
Decouple abstraction from its
implementation so that the two can vary
independently. Define an abstract interface
(Abstraction) and separate the
implementational aspect (Implementor). The
abstraction maintains a reference to an
implementation object and delegates work to
it.
Bridge Pattern
Bridge Pattern Adv
Advantages:
* Decouples Abstraction and Implementation- Changes to
either side don’t affect the other.
* Improved Extensibility- You can independently extend
either the abstraction or the implementation without
affecting each other.
* Avoids Class Explosion- You avoid creating a subclass for
every combination of abstraction and implementation.
* Promotes Composition Over Inheritance- Composition
allows more flexible object structures than inheritance.
Bridge Pattern Disadv
Disadvantages:
* Increased Complexity- The design can be more
complex due to the extra level of indirection.
* Indirection Overhead- Calls are forwarded from
the abstraction to the implementor, which may
slightly impact performance and traceability.
* Not Always Intuitive- For simple use cases, the
pattern may feel like over-engineering.
Problem:
You need to notify multiple objects about
changes in the state of another object without
tightly coupling them. For example, in a news
feed app, many users may want to be notified
when a new article is published, but the
publisher shouldn’t need to know about each
individual subscriber.
Observer Pattern
Solution:
Define a one-to-many dependency between
objects, where one subject (publisher) notifies
all its dependent observers (subscribers)
automatically whenever its state changes.
Observers register themselves to the subject,
and the subject broadcasts updates to all
registered observers.
Observer Pattern
Observer Pattern Adv
Consequences:
Advantages:
* Loose Coupling- The subject and observers are
decoupled; they interact only via interfaces.
* Dynamic Relationships- Observers can be added or
removed at runtime without changing the subject.
* Promotes Reusability- Subjects and observers can be
reused independently.
* Supports Broadcast Communication- One state
change can be communicated to many observers
simultaneously.
Observer Pattern Disadv
Disadvantages:
* Unintended Side Effects- A change in the subject
might trigger unexpected behavior in observers.
* Memory Leaks- If observers are not properly
removed, they may cause memory issues (especially
in languages without garbage collection).
* Notification Overhead- Too many observers can lead
to performance issues or notification storms.
* Difficult Debugging- Indirect interactions make the
flow of updates harder to trace and debug.
Problem:
You need to create families of related or dependent objects
without specifying their concrete classes. You want to
ensure that products from the same family work well
together, and prevent incompatible combinations.
Example: In a GUI application, you may want to create
components (like buttons and scrollbars) that look
consistent on Windows, macOS, or Linux. But if object
creation is not centralized, you might accidentally mix a
Windows button with a macOS scrollbar.
Abstract Factory Pattern
Solution:
Define an interface for creating families of related
objects, without specifying their concrete classes.
Concrete factories implement this interface to
create specific variants of the products.
* An Abstract Factory declares creation methods
for each type of product.
* A Concrete Factory implements these methods
to return platform-specific variants.
* Client code uses the abstract factory, unaware
of the actual product classes.
Abstract Factory Pattern
Abstract Factory Pattern Adv
Consequences:
Advantages:
* Consistency among products- Ensures that
products created by a factory are compatible.
* Encapsulation of object creation- Centralizes
object creation logic, adhering to the single
responsibility principle.
* Supports scalability- You can add new product
families without modifying existing code.
* Promotes loose coupling- Client code is
decoupled from specific classes.
Abstract Factory Pattern Disadv
Disadvantages:
* Complexity increases- More classes and
interfaces to manage, which can
overcomplicate simple scenarios.
- Difficult to support new product types-
Adding a new product requires changes in
all factory interfaces and concrete factories.
* Indirection overhead- More layers of
abstraction can make the system harder to
understand at first.
Problem:
You need to treat individual objects and groups of objects
(composites) uniformly. That is, you want clients to work
with complex tree-like structures made up of individual
parts (leaves) and groups of parts (composites) without
having to differentiate between them.
For example, in a graphics editor, both simple shapes (e.g.,
circles, lines) and groups of shapes (e.g., a diagram made of
shapes) should respond similarly to actions like move,
draw, or delete.
Composite Pattern
Solution:
Define a component interface that declares common
operations for both simple (leaf) and composite objects.
Composite objects implement the same interface and store
child components, allowing clients to treat them the same
as individual ones.
The pattern creates a tree structure where leaf nodes
represent end objects and composite nodes represent
groups of objects. Clients interact with the tree through the
component interface without worrying about whether they
are dealing with a leaf or a composite.
Composite Pattern
Composite Pattern adv
Consequences:
Advantages:
* Uniformity- Treat individual and composite objects
uniformly using the same interface.
* Extensibility- New component types (leaves or
composites) can be added easily without affecting
existing code.
* Simplifies client code- Clients don’t need to distinguish
between simple and complex components.
* Supports recursive structures- Ideal for tree or
hierarchy-like structures (e.g., file systems, UI
components).
Composite Pattern Disadv
Disadvantages:
* Can make design overly general- It’s hard to
restrict certain components to only be used as
leaves or only as composites.
* Complexity in navigation- Traversing or
managing children in large trees may require
extra logic.
* Violation of SRP- Composites must manage
child objects and implement business logic,
potentially combining multiple responsibilities.
Problem:
A class performs a specific behavior (or algorithm),
but there are multiple variations of this behavior that
may be needed at runtime. Hardcoding all these
variations into the class leads to complex and
inflexible code, making it difficult to maintain, extend,
or test.
Example: A navigation app that uses different routing
strategies (shortest path, scenic route, fastest time)
depending on user preference or real-time data.
Strategy Pattern
Solution:
Define a family of algorithms (strategies), encapsulate each
one in a separate class, and make them interchangeable.
The context class (which uses the strategy) delegates the
behavior to the strategy object rather than implementing it
directly.
This is typically achieved via:
* A common interface or abstract class for all strategies.
* Concrete implementations of different strategies.
* A context class that maintains a reference to a strategy
object and delegates the algorithm execution to it.
Strategy Pattern
Strategy Pattern Adv
Consequences:
Advantages:
* Open/Closed Principle- New strategies can be
added without modifying existing code.
* Code Reusability- Strategies can be reused
across different contexts.
* Improved Maintainability- Separates the
behavior from the context, making each easier to
manage.
* Runtime Flexibility- Strategy can be selected or
changed dynamically at runtime.
Strategy Pattern Disadv
Disadvantages:
* Increased Number of Classes- Each strategy
requires its own class, which can increase
code complexity.
* Client Complexity- The client must be aware
of different strategies and understand their
differences to select the appropriate one.
* Overhead- Minor performance overhead due
to delegation