Definition
The Bridge pattern separates abstraction from implementation so that they can change independently. It is realized by using combination relation instead of inheritance relation, which reduces the coupling degree of abstraction and realization.
Main points
[advantages]
Separation of abstraction and realization, strong extension ability;
Make the details transparent to customers.
[disadvantages]
Because the aggregation relationship is based on the abstraction layer, developers are required to design and program for abstraction, which increases the difficulty of system understanding and design.
- Abstraction role: abstracts the given definition and holds a reference to the implemented object.
- Refined abstraction role: extend the abstract role, change and modify the parent class's definition of abstraction.
- Implementor role: this role provides the interface of the implementer role, but does not provide the specific implementation. It must be noted that this interface is not necessarily the same as the interface definition of the abstract role, in fact, the two interfaces can be very different. The implementation role should only provide the underlying operations, while the abstract role should only provide the higher level operations based on the underlying operations.
- Concrete implementor role: this role gives the concrete implementation of the implementation role interface.
scene
There are many flavors of coffee in the coffee shop. Each flavor has a variety of specifications of cup models. Please design code scenarios to match these two change dimensions.
Realization
- Abstract class level
Coffee
/** * Coffee (abstract class level) */ public abstract class Coffee { /** * Use aggregate relationships */ protected Cup cup; protected Coffee(Cup cup) { this.cup = cup; } /** * Order coffee */ public abstract void orderCoffee(int count); }
CoffeeWithMilk
/** * Coffee with milk */ public class CoffeeWithMilk extends Coffee { public CoffeeWithMilk(Cup cup) { super(cup); } @Override public void orderCoffee(int count) { System.out.println(String.format("Coffee with milk%s x %d", cup.getSize(), count)); } }
CoffeeWithSugar
/** * Coffee with sugar */ public class CoffeeWithSugar extends Coffee { public CoffeeWithSugar(Cup cup) { super(cup); } @Override public void orderCoffee(int count) { System.out.println(String.format("Sugar coffee%s x %d", cup.getSize(), count)); } }
- Implementation class level
Cup
/** * Cup (implementation class level) */ public interface Cup { String getSize(); }
SmallCup
/** * Small cup */ public class SmallCup implements Cup { @Override public String getSize() { return "Small cup"; } }
MediumCup
/** * Middle cup */ public class MediumCup implements Cup { @Override public String getSize() { return "Middle cup"; } }
BigCup
/** * Large cup */ public class BigCup implements Cup { @Override public String getSize() { return "Large cup"; } }
Test
public class Test { public static void main(String[] args) { Coffee coffee = new CoffeeWithMilk(new MediumCup()); coffee.orderCoffee(3); Coffee coffee1 = new CoffeeWithSugar(new BigCup()); coffee1.orderCoffee(4); } } //Output: //Milk coffee medium cup x 3 //Sugar coffee large x 4
source code
summary
- It realizes the separation of the abstract part and the implementation part, which greatly provides the flexibility of the system, and makes the abstract part and the implementation part independent, which helps the system to carry on the layered design, so as to produce a better structured system.
- For the high-level part of the system, you only need to know the interface between the abstract part and the implementation part, and the other parts are completed by the specific business.
- The bridge mode can reduce the number of subclasses and the cost of management and maintenance.
- The introduction of bridge mode increases the difficulty of system understanding and design. Because the aggregation relationship is established in the abstract layer, developers are required to design and program for the abstract.
- The bridge pattern requires the correct recognition of two independent changing dimensions (abstract, and Implementation) in the system, so its scope of use has certain limitations, that is, it needs to have such application scenarios. For those systems that do not want to use inheritance or the number of system classes increases sharply due to multi-level inheritance, the bridging mode is particularly suitable.
Bridge mode is used in JDBC source code
Other examples:
-
Bank transfer
Transfer classification: online transfer, counter transfer, AMT transfer
User type: ordinary user, silver user, gold user -
Message management
Message classification: instant message, delay message
Way type: SMS, email, QQ