preface
The adapter pattern allows you to extend functionality to a target class by introducing adaptation classes without changing the target code. The bridging pattern is also a structural pattern.
The following is not a more vivid introduction, combined with the usual code to understand the best
directory
A, definitions,
Decouple abstraction and implementation so that they can vary independently. The abstraction and implementation here can be understood as abstracting entities and abstracting behaviors
Two, mode principle analysis
Let’s say you have a real estate company, and then you add new business, and you set up a company to quickly copy other industries
Public abstract class Corp{// produce protected abstract void produce(); // protected abstract void sell(); Public void run(){this.produce(); this.sell(); }} public class HouseCorp extends Corp(){protected void produce(){system.out.println (" HouseCorp extends Corp() "); } protected void sell(){system.out.println (); }} public class ClothesCorp extends Corp{protected void produce(){system.out.println (); } protected void sell(){system.out.println (); }} public class Client{public static void main(String[] args){HouseCorp houseCrop = new HouseCorp(); houseCorp.run(); ClothesCorp clothesCorp = new ClothesCorp(); clothesCorp.run(); }}Copy the code
What if the fake clothing companies don’t want to make clothes anymore? Delete this class and create a new class with a new product? Is this code change, i.e. a new class inherits from Corp, acceptable to you? The early stage is ok, if the late change is fast, it will not require a lot of code changes in the scene class. We can shift the thinking and abstract the product category, and every time you just specify which product to produce, as long as it meets the specification.
Now use bridge mode instead
Public abstract class Product{public abstract void beProducted(); public abstract void beSelled(); } public class House extends Product{public void beProducted(){system.out.println (" produce House "); } public void beSelled(){system.out.println (" to sell the house "); }} public class Clothes extends Product{public void beProducted(){system.out.println (); } public void beSelled(){system.out.println (); }} public abstract class Corp{private Product Product; public Corp(Product product){ this.product = product; } public void run(){this.product.beproducted (); // this.product. BeSelled (); Public class HouseCorp extends Corp{public HouseCorp extends Corp{public HouseCorp extends Corp(House House){super(House); } public void run(){ super.run(); }} public class ShanZhaiCorp extend Corp{public ShanZhaiCorp(Product Product){super(Product); } public void run(){ super.run(); Public class Client{public static void main(String[] args){House House = new House(); HouseCorp houseCorp = new HouseCorp(house); houseCorp.run(); ShanZhaiCorp shanZhaiCorp = new ShanZhaiCorp(new Clothes()); shanZhaiCorp.run(); }}Copy the code
The constructor here is basically to remind subclasses that you have to do this work. After every shanzhai products, expansion, only need to increase the company, inherit the Corp class, add the corresponding product class.
Corresponding to the separation of abstraction and implementation, here Product can be considered an implementation and Corp can be considered an abstraction, and the subclasses of Product and ShanZhaiCorp have been separated. ShanZhaiCorp implementation class, contains the abstract behavior class Product and the implementation of the abstract behavior run.
Iii. Usage Scenarios
-
Scenarios where inheritance is not desired
-
Scenarios where the interface or abstract class is unstable
-
Message-driven scenarios. Although the behavior of messages is relatively uniform, mainly including sending, receiving, processing and receipt, in fact, the implementation of specific client is usually different, such as mobile phone SMS, email message, QQ message, wechat message, etc.
-
When splitting complex class objects. When a class contains a large number of objects and methods, it is neither easy to read nor easy to modify.
-
When you need to switch between different implementations at run time. For example, external RPC services are invoked through facade mode.
-
Scenarios that require high reusability. The finer the granularity of the design, the greater the possibility of reuse, and the use of inheritance is limited by the parent class.
Four advantages,
-
Abstraction and implementation are separated
- The disadvantages of inheritance are solved, and the implementation can be free from abstract constraints
-
Excellent expansion capability
- increase
Product
To minimize changes
- increase
-
Implementation details are transparent to the customer
- How about not worrying about the details, just finishing the product implementation
Five, the disadvantages
-
This increases maintenance costs, and with composition and aggregation relationships, it is not as easy to find calling relationships between objects as with inheritance relationships, which can affect other objects without attention
-
The bridge pattern emphasizes aggregation rather than inheritance, and requires more layers of abstraction
-
Performance deteriorates, grouping or aggregating relationships, simplifying understanding while calling more objects