badge icon

This article was automatically translated from the original Turkish version.

Article

Structural Design Patterns

1. Adapter (Adapter) Design Pattern

Enables communication between two incompatible interfaces. It converts the interface of an existing class into another interface that is expected. Ideal for integrating new code into legacy systems.

-> When to Use

  • When an existing class has the required functionality but does not match the expected interface.
  • When integrating third-party libraries into your system.
  • When backward compatibility is required.

-> Code Example

Suppose our application works with classes that use the Target interface. However, we have a class called Adaptee with a different interface. These two classes are incompatible. The Adapter adapts the Adaptee class to conform to the Target interface.


  • Target: The interface our system expects.
  • Adaptee: A class with a different interface but providing the required functionality.
  • Adapter: Takes the Adaptee and converts it to the Target interface.
  • Client: Only interacts with the Target interface.

-> Advantages

  • Allows existing code to be made compatible with new systems without modification.
  • Facilitates reuse of legacy systems.
  • Creates a bridge between different interfaces.

-> Disadvantages

  • Can increase code complexity.
  • Excessive use of adapters can make maintenance difficult.

2. Bridge (Bridge) Design Pattern

Separates abstraction from implementation, allowing both to be developed independently independent.


-> When to Use

  • When you want to change abstraction and its implementation separately.
  • When you want to avoid class hierarchy explosion.
  • When you have multiple dimensions of variability (e.g., two axes such as Device Type and Brand).

-> Real-Life Analogy

Consider controlling a TV with a remote. TVs can be from different brands (Sony, Samsung, etc.), and remotes can be of different types (BasicRemote, AdvancedRemote, etc.). We establish a bridge between the remote and the TV. We abstract the TV and can operate it with different remotes.


-> Code Example

Structures to implement:

  • Abstraction: Remote (Controller)
  • Implementor: Device
  • RefinedAbstraction: AdvancedRemote
  • ConcreteImplementor: Concrete devices (TV, Radio)



  • Device: Abstract interface for implemented functions.
  • Tv: One implementation of this interface (other devices are possible).
  • Remote: Abstract remote control.
  • AdvancedRemote: Advanced version of the remote.
  • Remote and Device are connected by a "bridge". When adding new devices, you do not need to change the remote; when adding new remotes, you do not need to change the device.

-> Advantages

  • Separates abstraction from implementation.
  • Both sides can be developed independently.
  • Reduces code duplication and increases extensibility.


-> Disadvantages

  • Due to additional layers, the structure can become slightly more complex.


3. Composite Design Pattern

Organizes objects into a tree structure and allows clients to treat individual objects and groups of objects uniformly tree.


-> When to Use

  • When objects have a hierarchical structure.
  • When the client wants to handle both individual objects and groups of objects in the same way.


-> Real-Life Analogy

Consider a company structure: CEO, managers, and employees. A manager may have other managers and employees under them. But all are "employees" and operations like getSalary() can be applied to all. Thus, a group with sub-elements can be treated just like a regular employee.


-> Code Example

Structures to implement:

  • Component: Common interface (Graphic)
  • Leaf: Leaf object (Dot, Circle)
  • Composite: Group object (CompoundGraphic)


  • Graphic: Common interface implemented by both Dot and CompoundGraphic.
  • Dot, Circle: Simple graphic elements.
  • CompoundGraphic: A group object that can hold multiple graphic elements or other CompoundGraphic objects.
  • The call to graphic.draw() draws both individual and composite objects.

-> Advantages

  • Complex tree structures are represented simply.
  • Client code can use individual objects and groups without distinguishing between them.
  • Easy extensibility.

-> Disadvantages

  • Understanding and implementing the design can be complex.
  • Managing the tree structure requires care.

4. Decorator Design Pattern

Used to extend the behavior of an object without modifying the existing class at runtime dynamic work.

-> When to Use

  • When you want to change a class’s functionality without creating subclasses.
  • When you want to add new features to an object but avoid a complex inheritance chain.

-> Real-Life Analogy

Consider a coffee order system. You have a basic coffee (Coffee), and you can add toppings like milk, sugar, and chocolate (MilkDecorator, SugarDecorator). Each decoration adds new features without changing the coffee itself.

-> Code Example

  • Component: Common interface (DataSource)
  • ConcreteComponent: Base object (FileDataSource)
  • Decorator: Abstract decorator (DataSourceDecorator)
  • ConcreteDecorator: Customized decorators (EncryptionDecorator, CompressionDecorator)



  • FileDataSource: Base data source.
  • EncryptionDecorator and CompressionDecorator: Add features (encryption, compression).
  • writeData() encrypts then compresses the data in sequence.
  • readData() decrypts then decompresses the data in sequence.

-> Advantages

  • New functionalities can be added without creating subclasses.
  • Behavior can be changed dynamically.
  • Multiple decorators can be stacked on top of each other.

-> Disadvantages

  • Can lead to creation of many small classes.
  • Attention must be paid to the order in which decorators are applied.

5. Facade Design Pattern

This pattern simplifies a complex system by combining the intricate functions of multiple classes or subsystems into a single interface, presenting a simple view to the outside world.

-> When to Use

  • When the subsystem is very complex and users only want to perform specific operations simply.
  • When you want to improve code readability and usability.
  • When you want to access the system with fewer dependencies.

-> Real-Life Analogy

You want to turn on your computer. You simply press the Power button. That button actually triggers many components: CPU, RAM, SSD, etc. There is a facade between you and these components.

-> Code Example


  • CPU, Memory, HardDrive: Subsystems.
  • ComputerFacade: Presents these systems to the outside world via a simple start() function.
  • Client: Initiates the complex operation chain by calling only start().

-> Advantages

  • Complex systems are simplified.
  • Dependencies are reduced.
  • Code readability and maintainability improve.

-> Disadvantages

  • Excessive abstraction can be limiting for advanced users.
  • The Facade class can grow too large over time and become a God Object.

6. Flyweight Design Pattern

The Flyweight design pattern uses shared states to store a large number of objects efficiently in memory. Instead of storing the same data repeatedly across multiple objects, it makes the data shared and optimizes memory usage.

-> When to Use

  • When a large number of similar objects will be created and memory usage is critical.
  • When most objects share the same data and only a small part differs.
  • When you want to optimize memory usage.

-> Real-Life Analogy

You are making multiple paper airplanes. Each airplane will have the same shape (same design, colors, etc.). However, each plane may have a different direction or speed for flight. Thus, only variables like flight direction and speed differ; all other aspects are shareable.

-> Code Example


  • TreeType: Represents tree types and contains the shared properties (name, color).
  • TreeFactory: Manages object creation and ensures sharing for objects with the same tree type.
  • Client: Uses the same tree type at different positions to efficiently use memory.

-> Advantages

  • Memory usage is optimized because shared objects are created only once.
  • Improves performance when working with a large number of objects.
  • Shared objects are not redundantly stored in memory.

-> Disadvantages

  • Can be complex to manage since objects are shared.
  • Object sharing can sometimes lead to a loss of flexibility.

7. Proxy Design Pattern

The Proxy design pattern controls interaction with another object by acting as its representative. Proxies are typically used to control, defer, or redirect access to an object.

-> When to Use

  • When you want to control access to an object before it is actually needed.
  • When you want to avoid the loading cost of large objects or limit database access.
  • When you need security, access control, or customized processing.

-> Real-Life Analogy

Consider a car rental company. The Car is only delivered to the user when the rental process occurs. Before that, the car does not need to be physically handed over. The proxy works like a car procurement service; however, the actual car is provided only when needed.

-> Code Example


  • RealSubject: Class containing the actual object’s functionality.
  • Proxy: Class that controls access to the real object. The real object is loaded by the proxy only when needed.
  • Client: Accesses the real object through the Proxy class. The proxy performs necessary operations to provide access to the real object.

-> Advantages

  • Provides lazy loading — the object is created only when truly needed.
  • Useful for access control and security. The proxy can control access to the real object.
  • Provides performance optimization, especially when working with large objects.

-> Disadvantages

  • Adds extra complexity because every access to the object goes through the proxy.
  • Interactions between the proxy and the real object can sometimes become complex.

-> Use Cases

  • Art gallery: Real paintings are large and expensive. The proxy loads the paintings only when needed.
  • Database connections: Connecting to a database can be expensive, so the proxy provides access to the database only when required.


Author Information

Avatar
AuthorSinan TuranDecember 6, 2025 at 10:51 AM

Tags

Discussions

No Discussion Added Yet

Start discussion for "Structural Design Patterns" article

View Discussions

Contents

  • 1. Adapter (Adapter) Design Pattern

    • -> When to Use

    • -> Code Example

    • -> Advantages

    • -> Disadvantages

  • 2. Bridge (Bridge) Design Pattern

    • -> When to Use

    • -> Real-Life Analogy

    • -> Code Example

    • -> Advantages

    • -> Disadvantages

  • 3. Composite Design Pattern

    • -> When to Use

    • -> Real-Life Analogy

    • -> Code Example

    • -> Advantages

    • -> Disadvantages

  • 4. Decorator Design Pattern

    • -> When to Use

    • -> Real-Life Analogy

    • -> Code Example

    • -> Advantages

    • -> Disadvantages

  • 5. Facade Design Pattern

    • -> When to Use

    • -> Real-Life Analogy

    • -> Code Example

    • -> Advantages

    • -> Disadvantages

  • 6. Flyweight Design Pattern

    • -> When to Use

    • -> Real-Life Analogy

    • -> Code Example

    • -> Advantages

    • -> Disadvantages

  • 7. Proxy Design Pattern

    • -> When to Use

    • -> Real-Life Analogy

    • -> Code Example

    • -> Advantages

    • -> Disadvantages

    • -> Use Cases

Ask to Küre