S9 Flashcards
(17 cards)
What is the purpose of the Adapter Pattern (also called Wrapper Pattern)?
It allows the interface of one class to be used as another interface for a different class. This ensures that two classes expecting different interfaces can still communicate.
What are the two variants of the Adapter Pattern?
Object Adapter
Class Adapter
Describe the main components of the Object Adapter pattern.
Client Interface (Target): Defines the specific interface the client uses.
Client: Collaborates with objects conforming to the Client Interface.
Service (Adaptee): Defines an existing interface that needs adapting.
Adapter: Adapts the interface of the Service to the Client Interface. It holds an instance of the Service (composition).
How does the Object Adapter achieve its goal?
The Adapter inherits and implements the interface expected by the Client (Client Interface/Target) and uses composition (holds a reference to an Adaptee/Service object) to make the Adaptee’s functionality available through the Client Interface.
Describe the Class Adapter pattern.
Similar to the Object Adapter, but the Adapter uses multiple inheritance to implement both the Client Interface and the Service interface simultaneously. This is only directly possible in languages that support multiple inheritance (e.g., C++, Python).
What is a key difference between Object Adapter and Class Adapter regarding flexibility with Services/Adaptees?
Object Adapter: Can work with many Services (the Service itself and its subclasses) because it holds a reference.
Class Adapter: Is typically tied to one specific Service class it inherits from.
What is a key difference between Object Adapter and Class Adapter regarding overriding Service behavior?
Object Adapter: Makes it harder to override Service behavior directly; requires subclassing the Service and making the Adapter refer to this new subclass.
Class Adapter: Can override some of Service’s behavior directly since the Adapter is a subclass of the Service.
When should you use the Adapter Pattern?
When you want to use an existing class, but its interface doesn’t match the one you need.
When you want to create a reusable class that cooperates with unrelated or unforeseen classes with incompatible interfaces.
(Object Adapter only) When you need to use several existing subclasses, but it’s impractical to adapt their interface by subclassing every one (as the object adapter can adapt its parent class’s interface).
What are the pros of using the Adapter Pattern?
Separates interface/data conversion code from primary business logic (Single Responsibility Principle).
Allows introduction of new adapters without breaking existing client code if they adhere to the client interface (Open-Closed Principle).
What are the cons of using the Adapter Pattern?
Can increase complexity and computation due to new interfaces and classes.
Sometimes, refactoring the Service to use the Client Interface directly might be simpler in the long run.
What is the motivation for using the Decorator Pattern?
To avoid a class explosion when needing many combinations of optional features for an object (e.g., a window with/without a scrollbar, with/without a border). Instead of numerous subclasses, functionality is added by wrapping objects in decorators.
How does the Decorator Pattern achieve adding functionality?
It uses object composition. Decorator classes wrap the original object (Component) and provide the same interface, adding their own behavior before or after delegating to the wrapped object.
Describe the main components of the Decorator Pattern.
Component: Defines the interface for objects that can have responsibilities added to them dynamically.
ConcreteComponent: Defines an object to which additional responsibilities can be attached (the base object).
Base Decorator (optional, but common): An abstract class that conforms to the Component interface and holds a reference to a Component object (the wrappee). It forwards requests to its Component object.
ConcreteDecorator: Adds responsibilities to the Component. It conforms to the Component interface (often by inheriting from Base Decorator) and adds its specific functionality.
How does the Decorator Pattern differ from the Adapter Pattern?
Adapter: Changes the interface of an existing object.
Decorator: Enhances an object without changing its interface and supports recursive composition (stacking decorators).
What are the pros of using the Decorator Pattern?
Extend an object’s behavior without making a new subclass.
Add or remove responsibilities from an object at runtime.
Combine several behaviors by wrapping an object in multiple decorators.
Divide a monolithic class with many behavioral variants into several smaller classes (Single Responsibility Principle).
what are the cons of using the Decorator Pattern?
Hard to remove a specific wrapper from a stack of decorators.
Can be difficult to implement a decorator so its behavior doesn’t depend on the order in the decorator stack.
The initial configuration code for layers of decorators might look complex.