6/180: Structural Design Patterns
Today is day 6 of 180 days challenge, in good rhythm hopeful to finish this challenge. In this blog I will discussing about the structural design patterns
Adapter / Decorative / Proxy / Flyweight / Bridge / Composite are all that comes under structural design patterns.
Adapter Design Pattern
Adapter pattern works in the same way the charger’s adapter works, adapter is used where we can’t connect to directly, in the same way we create the interface we want from the other interface which we are not able to connect directly.
Let’s say you have to upload data from multiple API’s data is same all over the API’s but format’s are different, some API’s give data in XML format while other in JSON and we can send data directly to our database so we create an adapter in between and convert all the API’s to a format our database understands.
Implementing an Adapter is easy. Determine the API you have and the API you need. Create a component which aggregates the adapter.
Bridge Design Pattern
Bridge refers to connecting components through abstractions. It is a mechanism that decouples an interface (hierarchies) from an implementation (hierarchies).
It decouples abstraction from implementation. Both can exists as hierarchies. It’s a stronger form of encapsulation.
Composite Design Pattern
Treating individual and aggregate objects uniformly. Objects use other objects fields methods through inheritance and composition. Composition let us make compound objects. Example: mathematical expression composed of simple expressions or a shape group made of several different shapes. Composite design pattern is used to treat both single and composite objects uniformly.
Objects can use other objects via inheritance/ composition. Some composed and singular objects need similar identical behavior. Composite design pattern lets us treat both types of objects uniformly. Java supports container iteration with the Iterable<T> interface.
Decorator Design Pattern
Adding behavior without altering the class itself.
Why was the need of decorator pattern. Want to augment an object with additional functionality. Do not want to rewrite or alter existing code (Open closed principle). Want to keep new functionality separate(Single Responsibility Principle). Need to be able to interact with existing structures.
Two options:
- Inherit from required object if possible, some classes are final
- Build a decorator, which simple reference the decorator object
Decorator facilitates the addition of behavior to individual objects without inheriting from them.
Facade Design Pattern
Exposing several components through a single interface.
Why was the need for a facade. Balancing complexity and presentation usability. Let’s take an example of home: there are many subsystems (electrical, sanitation, etc.). Complex internal structure. End user is not exposed to internals. Same with software: Many systems working to provide flexibility. API consumers want it to just work.
It provides a simple easy to understand user interface over a large sophisticated body of code.
Build a facade to provide a simplified API over a set of classes. May wish to expose internals through facade. May allow users to escalate to use more complex API’s if they need to.
Flyweight Design Pattern
Space Optimized.
Avoid redundancy when storing data. A space optimized technique that let us use less memory by storing externally the data associated with similar objects.
Store common data externally. Specify an index or a reference into the external data store. Define the idea of ranges on homogeneous collection and store data related to those ranges.
Proxy Design Pattern
An interface for accessing a particular resource.
What was the need for it? You are calling foo.bar(). This assumes that foo is in the same process as bar. What if later on you want to put all foo-related operations into a separate process. Can you avoid changing your code. Proxy to the rescue!. Same interface entirely different behavior. This is called communication proxy.
Proxy: A class that functions as an interface to a particular resource. That resource may be remote expensive to construct, or may require logging or some other added functionality.
A proxy has the same interface as the underlying object. To create a proxy simply replicate the existing interface of an object. Add relevant functionality to redefined member function. Different proxies(communication, logging, caching, etc.) have completely different behavior.
Proxy VS Decorator
- Proxy provides an identical interface, decorator provides an enhanced interface.
- Decorator typically aggregates what it is decorating, proxy don’t have to.
- Proxy might not even be working with a materialized object.