I. INTRODUCTION
Learn about bridging modes in 23 design modes today. When we design the system, if a class has two independently changing dimensions, one scenario is to use multiple layers of inheritance, and if the first dimension has a branch, and the second dimension has a branch of B, then in total we need to a*b the sub-class to implement, which will be a very large inheritance tree. If the first dimension adds a branch, then we need to increase the B subclass, and the extension becomes cumbersome. And the second way is the bridging mode that we're going to learn today, through bridging mode, we can separate two dimensions, separate them into two separate inheritance trees, and create an association in the topmost layer of abstraction, which is similar to a bridge that connects two independent structures, so we call it bridging mode.Let's look at the definition of bridging mode and the UML class diagram of bridge mode:Bridging mode (bridge pattern): separates the abstract part from its implementation, so that both can change independently. It is an object-structured pattern, also known as a handle body (Handle and body) mode or interface (Interface) mode.
Simply explain the UML class diagram of the bridging mode, the whole inheritance tree is split into two sets of inheritance trees, with abstraction as the root of the inheritance tree and implementor as the root of the inheritance tree. Abstraction calls Implementor through an abstract interface, we can inject Implementor's subclass object into the abstraction subclass object and achieve the desired effect by aggregating it.
Two. Examples of bridging modes
Let's look at the application of bridging mode in one example. We now want to design a small game, including several classes, male knife, female knife, male gunman, female gunman. How to design this person's structure system? Let's look at the situation of multi-layer inheritance and bridging mode, respectively.
1. Multi-tier inheritance scenarios
Design Pattern.cpp:Defines The entry point for the console application.//#include "stdafx.h" #include <iostream> #include <string> #include <vector>using namespace std;//character base class character{public:virtual void Attack () = 0;};/ /Man class malecharacter:public character{public:virtual void Attack () = 0;};/ /female character class femalecharacter:public character{public:virtual void Attack () = 0;};/ /male knife class physicalmalechar:public malecharacter{public:virtual void Attack () {cout << "male role: Physical attack" << Endl;}} ;//female knife class physicalfemalechar:public femalecharacter{public:virtual void Attack () {cout << "female role: Physical attack" << E ndl;}};/ /male Mage class magicmalechar:public malecharacter{public:virtual void Attack () {cout << "male character: Spell attack" << endl;}};/ /female Mage class magicfemalchar:public femalecharacter{public:virtual void Attack () {cout << "female character: Spell attack" << Endl;}} ; int _tmain (int argc, _tchar* argv[]) {character* Character = new Magicfemalchar (); Character->attack (); System ("pause"); return 0;}
Result: Female role: Spell attack
Please press any key to continue ...
Well, while we've achieved the desired functionality, if we've added a few jobs, we're going to have to create two classes for each new job, which is a hassle. Let's look at the use of bridging mode.
2. Bridging mode conditions
Design Pattern.cpp:Defines The entry point for the console application.//#include "stdafx.h" #include <iostream> #include <string> #include <vector>using namespace std;//attribute base class, equivalent to the implement class Attribute{public: virtual void Attack () = 0;};/ /character base class, equivalent to the abstract class class character{protected://in a UML diagram holds a pointer to a property attribute* m_attribute;public://set Property (occupation) void SetAttribute (attribute* Attribute) {m_attribute = Attribute;} Attack interface virtual void Attack () = 0;};/ /Man class malecharacter:public character{public:virtual void Attack () override{cout << "Male role:";m_attribute-> Attack ();}};/ /female character class femalecharacter:public character{public:virtual void Attack () override{cout << "female character:"; m_attribute- >attack ();}};/ /Physical Properties Class Physicalattribute:public attribute{public:void Attack () override{cout << "Physical attack" << endl;}};/ /legal system Attribute Class Magicattribute:public attribute{public:void Attack () override{cout << "French attack" << Endl;}; int _tmain (int argc, _tchar* argv[]) {Character* character = new Femalecharacter (); attribute* Magicattribute = new Magicattribute (); Character->setattribute (Magicattribute); Character->Attack () ; System ("pause"); return 0;}
Result: Female role: French attack
Please press any key to continue ...
We used the bridging mode to divide the characters ' gender and character attack properties as two different attributes, split into two different inheritance trees, and then hold a pointer to the character's attribute in the base class to make the two travel the aggregation relationship. In this way, we reduce redundant classes, greatly reducing the complexity of inheritance and enhancing reusability. When adding a new class or attribute, you only need to add a new attribute class, which conforms to the open-close principle.
Three. Bridging Mode Summary
Finally, let's summarize the advantages and disadvantages of bridging mode and the timing of use.
Advantages:1) Bridging mode is a good alternative solution for multi-layer inheritance system, which greatly reduces the number of subclasses and increases the reusability.2) bridging mode separates the abstract interface and the implementation part, uses the aggregation method, decouples the inherent binding relationship between abstraction and implementation, and allows the abstraction and implementation to be implemented in different inheritance systems.3) Bridging mode is a good way to improve the scalability of the system, in the expansion of any one dimension of two dimensions, there is no need to modify the original content, in line with the open-closed principle.
Disadvantages:1) Bridging mode increases the difficulty of understanding the system, and is not as straightforward as multi-layer inheritance.2) It is difficult to identify and separate two dimensions, so the use has some limitations.
Use time:If our system was previously implemented using multiple layers of inheritance, we could consider bridging mode when static inheritance between the two levels was not flexible enough. When there are two or more independently changing dimensions in our system, these two dimensions need to be expanded independently, so that we can use bridging mode in order not to change the complexity of the extension to M*n, but m+n.
Design pattern Learning Notes-bridging mode