From 3c4cbd564bc784baeb76d04639ca0c23859d0a44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sat, 16 Mar 2024 17:24:27 +0200 Subject: [PATCH] docs: Improve Bridge documentation --- bridge/README.md | 45 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/bridge/README.md b/bridge/README.md index 807b738bd..a679df25f 100644 --- a/bridge/README.md +++ b/bridge/README.md @@ -3,7 +3,9 @@ title: Bridge category: Structural language: en tag: - - Gang of Four + - Decoupling + - Extensibility + - Gang of Four --- ## Also known as @@ -18,15 +20,11 @@ Decouple an abstraction from its implementation so that the two can vary indepen Real-world example -> Consider you have a weapon with different enchantments, and you are supposed to allow mixing -> different weapons with different enchantments. What would you do? Create multiple copies of each -> of the weapons for each of the enchantments or would you just create separate enchantment and set -> it for the weapon as needed? Bridge pattern allows you to do the second. +> Consider you have a weapon with different enchantments, and you are supposed to allow mixing different weapons with different enchantments. What would you do? Create multiple copies of each of the weapons for each of the enchantments or would you just create separate enchantment and set it for the weapon as needed? Bridge pattern allows you to do the second. In Plain Words -> Bridge pattern is about preferring composition over inheritance. Implementation details are pushed -> from a hierarchy to another object with a separate hierarchy. +> Bridge pattern is about preferring composition to inheritance. Implementation details are pushed from a hierarchy to another object with a separate hierarchy. Wikipedia says @@ -60,7 +58,7 @@ public class Sword implements Weapon { @Override public void swing() { - LOGGER.info("The sword is swinged."); + LOGGER.info("The sword is swung."); enchantment.apply(); } @@ -92,7 +90,7 @@ public class Hammer implements Weapon { @Override public void swing() { - LOGGER.info("The hammer is swinged."); + LOGGER.info("The hammer is swung."); enchantment.apply(); } @@ -204,7 +202,33 @@ Use the Bridge pattern when * You have a proliferation of classes. Such a class hierarchy indicates the need for splitting an object into two parts. Rumbaugh uses the term "nested generalizations" to refer to such class hierarchies. * You want to share an implementation among multiple objects (perhaps using reference counting), and this fact should be hidden from the client. A simple example is Coplien's String class, in which multiple objects can share the same string representation. -## Tutorial +## Known uses + +* GUI Frameworks where the abstraction is the window, and the implementation could be the underlying OS windowing system. +* Database Drivers where the abstraction is a generic database interface, and the implementations are database-specific drivers. +* Device Drivers where the abstraction is the device-independent code, and the implementation is the device-dependent code. + +## Consequences + +Benefits: + +* Decoupling Interface and Implementation: The Bridge pattern enhances modularity by separating the interface (the high-level operations) from the implementation (the low-level operations). +* Improved Extensibility: You can extend the abstraction and implementation hierarchies independently. +* Hiding Implementation Details: Clients only see the abstraction's interface, not its implementation. + +Trade-offs: + +* Increased Complexity: The pattern can complicate the system architecture and code, especially for clients unfamiliar with the pattern. +* Runtime Overhead: The extra layer of abstraction can introduce a performance penalty, although it is often negligible in practice. + +## Related Patterns + +* [Adapter](https://java-design-patterns.com/patterns/adapter/): The Adapter pattern is used to provide a different interface to an object, while the Bridge pattern is used to separate an object's interface from its implementation. +* [Strategy](https://java-design-patterns.com/patterns/strategy/): The Strategy pattern is like the Bridge pattern, but with a different intent. Both patterns are based on composition: Strategy uses composition to change the behavior of a class, while Bridge uses composition to separate an abstraction from its implementation. +* [Abstract Factory](https://java-design-patterns.com/patterns/abstract-factory/): The Abstract Factory pattern can be used along with the Bridge pattern to create platforms that are independent of the concrete classes used to create their objects. +* [Composite](https://java-design-patterns.com/patterns/composite/): The Bridge pattern is often used with the Composite pattern to model the implementation details of a component. + +## Tutorials * [Bridge Pattern Tutorial](https://www.journaldev.com/1491/bridge-design-pattern-java) @@ -212,3 +236,4 @@ Use the Bridge pattern when * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) * [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) +* [Pattern-Oriented Software Architecture Volume 1: A System of Patterns](https://amzn.to/3TEnhtl)