当前位置:网站首页>Bridge mode
Bridge mode
2022-06-28 09:40:00 【Beginner Xiaobai Lu】
The bridge (Bridge) The definition of a pattern is as follows : Separate abstraction from implementation , So that they can change independently . It is realized by replacing inheritance relation with combination relation , Thus, the coupling degree of the two variable dimensions of abstraction and implementation is reduced .
If you have a geometry (Shape) class , Two subclasses can be extended from it : circular (Circle) And square (Square). You want to extend this class hierarchy to include colors , So you're going to create something called red (Red) And blue (Blue) Shape subclass of . however , Because you have two subclasses , So a total of four classes need to be created to cover all combinations , For example, the blue circle (BlueCircle) And red squares (RedSquare).
Adding new shapes and colors to the hierarchy will lead to an exponential increase in code complexity . For example, add a triangle shape , You need to add two new subclasses , One for each color ; After that, we need to add three new subclasses to add a new color , One for each shape . So in the past , It's going to get worse .
terms of settlement :
The root cause of the problem is that we try to be in two independent dimensions —— Shape and color —— Extend shape class on . This is a common problem when dealing with class inheritance .
The bridging pattern solves this problem by changing inheritance to composition . say concretely , It is to extract one of the dimensions and make it an independent class hierarchy , This allows you to refer to the new level of objects in the initial class , So that a class doesn't have to have all the States and behaviors .
According to this method , We can extract color related code into color classes with two subclasses of red and blue , Then add a reference member variable to a color object in the shape class . Now? , Shape classes delegate all color related work to connected color objects . Such references become a bridge between shape and color . thereafter , The new color will no longer need to modify the class hierarchy of the shape , vice versa .
advantage
- Separation of abstraction and implementation , Strong expansion ability
- Comply with opening and closing principle
- In line with the principle of composite reuse
- In fact, the details are transparent to customers
shortcoming
Because aggregation is based on abstraction , Require developers to design and program for abstraction , Be able to correctly identify two independent changing dimensions in the system , This increases the difficulty of understanding and designing the system .
structure

The bridge (Bridge) The pattern includes the following main characters .
- Abstraction (Abstraction) role : Defining abstract classes , And include a reference to the implementation object . Provide high level control logic , Depending on the implementation object that does the underlying actual work .
- Extend abstraction (Refined Abstraction) role : It's a subclass of abstract characters , Implement the business methods in the parent class , And through the combination of relationship calls to realize the role of business methods .
- Realize (Implementor) role : Define the interfaces for implementing roles , For extension Abstract role call .
- Concrete realization (Concrete Implementor) role : Give the implementation of the role interface .
- client (Client): Just about how to work with the abstract . however , The client needs to connect the abstract object with an implementation object .
Applicable scenario
- When an object has multiple variables , Consider implementations that rely on abstraction , Not the concrete realization . For example, the mobile phone brand has 2 There are two factors of change , One is the brand , One is function .
- When multiple variation factors are shared among multiple objects , Consider abstracting the changed parts and aggregating them / Synthesize in , Such as contacts and games , In fact, it can be shared .
- When we consider that multiple change factors of an object can change dynamically , Consider using the bridge mode , For example, the mobile phone brand in the above example changes , The functions of mobile phones are also changing , So separate them , Independent change .
Realization
- Define the independent dimensions in the class . The concept of independence may be : abstract / platform , Domain / infrastructure , front end / Back end or interface / Realization .
- Understand the business requirements of the client , They are defined in the base class .
- Identify business that can be performed on all platforms . And declare the business required by the abstract part in the general implementation interface .
- Create implementation classes for all platforms in your domain , But make sure they follow the interface of the implementation part .
- Add a reference member variable to the implementation type in the abstract class . The abstract part will delegate most of the work to the implementation object pointed to by the member variable .
- If your high-level logic has multiple variants , You can create an exact abstraction for a variant by extending the abstract base class .
- The client code must pass the implementation object to the constructor of the abstract part in order for it to be related to each other . thereafter , The client only needs to interact with abstract objects , No need to deal with implementation objects .
Example 1
We need to provide large and small 3 Kinds of brushes , Be able to draw 5 Different colors , If crayons are used , We need to prepare 3*5=15 A crayon , That is to say, we must be prepared for 15 A specific crayon class . And if you use a brush , It only needs 3 Different types of brushes , Plus 5 A paint box , use 3+5=8 Classes can be implemented 15 The function of crayons .
actually , The key difference between crayon and brush is whether the pen and color can be separated . About to abstract (Abstraction) And realization (Implementation) decoupling , So that they can change independently ". The key is whether it can be decoupled . The color of the crayon is inseparable from the crayon itself , Therefore, it is necessary to use 15 Branch color 、 Draw pictures with crayons of different sizes . The brush and pigment can be well decoupled , Change independently , It simplifies the operation . ad locum , The concept at the abstract level is :“ The brush paints with paint ”, And in implementation , The brush has three sizes, large, medium and small , The pigments are red, green, blue, black and white, etc 5 Kind of , Then it can appear 3×5 Combinations of . Each participant ( Brush and paint ) Can be freely converted in their own degrees of freedom . Crayons can't separate the pen from the color , The two degrees of freedom of pen and color cannot be changed separately , So that only create 15 Only three kinds of objects can complete the task .
#include <iostream>
#include <string>
// Implementation class interface Color( Color class )
class Color
{
public:
virtual void bepaint(const std::string&, const std::string&) = 0;
};
// Concrete implementation class Red
class Red : public Color {
public:
void bepaint(const std::string& penType, const std::string& name)
{
std::cout << penType + " Red " + name + "." << std::endl;
}
};
// Concrete implementation class Green
class Green : public Color {
public:
void bepaint(const std::string& penType, const std::string& name)
{
std::cout << penType + " Green " + name + "." << std::endl;
}
};
// abstract class Pen
class Pen {
public:
virtual void draw(const std::string& name) = 0;
void setColor(Color* color)
{
this->color = color;
}
protected:
Color* color;
};
// Extended abstract class BigPen
class BigPen : public Pen {
public:
void draw(const std::string& name) {
std::string penType = " Large brush drawing ";
this->color->bepaint(penType, name);
}
};
// Extended abstract class SmallPen
class SmallPen : public Pen {
public:
void draw(const std::string& name) {
std::string penType = " Small brush drawing ";
this->color->bepaint(penType, name);
}
};
// Client test class
int main(void) {
Color* color;
Pen* pen;
// Here pretend to use reflection to get
color = (Color*) new Green();
pen = (Pen*) new SmallPen();
pen->setColor(color);
pen->draw(" christmas tree ");
delete color;
delete pen;
return 0;
}
Example 2
Abstraction.h:
// Abstraction.h:
#ifndef ABSTRACTION_H_
#define ABSTRACTION_H_
#include <string>
#include "Implementation.h"
// abstract class : Pen
class Pen {
public:
virtual void draw(std::string name) = 0;
void set_color(Color* color) {
color_ = color;
}
protected:
Color* color_;
};
#endif // ABSTRACTION_H_
RefinedAbstraction.h:
#ifndef REFINED_ABSTRACTION_H_
#define REFINED_ABSTRACTION_H_
#include <string>
#include "Abstraction.h"
// Exact abstract class : BigPen
class BigPen : public Pen {
public:
void draw(std::string name) {
std::string pen_type = " Draw with a large pen ";
color_->bepaint(pen_type, name);
}
};
// Exact abstract class : SmallPencil
class SmallPencil : public Pen {
public:
void draw(std::string name) {
std::string pen_type = " Draw with a small pencil ";
color_->bepaint(pen_type, name);
}
};
#endif // REFINED_ABSTRACTION_H_
Implementation.h:
#ifndef IMPLEMENTATION_H_
#define IMPLEMENTATION_H_
#include <string>
#include <iostream>
// Implementation class interface : Color
class Color {
public:
virtual void bepaint(std::string pen_type, std::string name) = 0;
};
#endif // IMPLEMENTATION_H_
ConcreteImplementation.h:
#ifndef CONCRETE_IMPLEMENTATION_H_
#define CONCRETE_IMPLEMENTATION_H_
#include <string>
#include "Implementation.h"
// Concrete implementation class : Red
class Red : public Color {
public:
void bepaint(std::string pen_type, std::string name) override {
std::cout << pen_type << " Red " << name << "." << std::endl;
}
};
// Concrete implementation class : Green
class Green : public Color {
public:
void bepaint(std::string pen_type, std::string name) override {
std::cout << pen_type << " Green " << name << "." << std::endl;
}
};
#endif // CONCRETE_IMPLEMENTATION_H_
main.cpp:
#include "ConcreteImplementation.h"
#include "RefinedAbstraction.h"
int main() {
// The client obtains the corresponding... According to the run-time parameters Color and Pen
Color* color = new Red();
Pen* pen = new SmallPencil();
pen->set_color(color);
pen->draw(" The sun ");
delete color;
delete pen;
}
Running results :
$g++ -g main.cpp -o bridge -std=c++11
$./bridge
Draw the red sun with a small pencil .
Example 3
use Python Realization
# Abstract specification class
class Size(object):
def __init__(self, size):
self.color = None
self._size = size
# match_color As a bridge , Respective changes , Does not affect other classifications
def match_color(self, color):
self.color = color
def produce(self):
print(f" production The specification is : {
self._size} The color is : {
self.color.color()} My pen ")
# Large size , Specific specifications , Inherit Abstract specification class
class BigSize(Size):
def __init__(self):
super(BigSize, self).__init__(' large ')
# medium , please
class MiddleSize(Size):
def __init__(self):
super(MiddleSize, self).__init__(' medium , please ')
# trumpet
class SmallSize(Size):
def __init__(self):
super(SmallSize, self).__init__(' trumpet ')
# Abstract color class
class Color(object):
def __init__(self, color):
self._color = color
def color(self):
return self._color
# Red
class RedColor(Color):
def __init__(self):
super(RedColor, self).__init__(' Red ')
# Blue
class BlueColor(Color):
def __init__(self):
super(BlueColor, self).__init__(' Blue ')
# yellow
class YellowColor(Color):
def __init__(self):
super(YellowColor, self).__init__(' yellow ')
if __name__ == "__main__":
red = RedColor()
blue = BlueColor()
yellow = YellowColor()
big_size = BigSize()
big_size.match_color(red)
big_size.produce()
big_size.match_color(blue)
big_size.produce()
big_size.match_color(yellow)
big_size.produce()
middle_size = MiddleSize()
middle_size.match_color(red)
middle_size.produce()
middle_size.match_color(blue)
middle_size.produce()
middle_size.match_color(yellow)
middle_size.produce()
small_size = SmallSize()
small_size.match_color(blue)
small_size.produce()
small_size.match_color(red)
small_size.produce()
small_size.match_color(yellow)
small_size.produce()
Example 4
# abstract class : people
class people:
def set_skill(self,skill):
self.skill=skill
def perform_skill(self):
pass
# Concrete abstract class : gardener
class hua_j(people):
def perform_skill(self):
print(' I'm a gardener ')
self.skill.perform_skill()
# Concrete abstract class : carpenter
class mu_j(people):
def perform_skill(self):
print(' I am a carpenter ')
self.skill.perform_skill()
# Concrete abstract class : Blacksmith
class tie_j(people):
def perform_skill(self):
print(' I am a blacksmith ')
self.skill.perform_skill()
# Functional class , It's also an implementation class
class skill:
def perform_skill(self):
pass
# Specific function classes , It is also a concrete implementation class grow flowers
class skill_hua(skill):
def perform_skill(self):
print(' I can plant flowers ')
# Specific function classes , It is also a concrete implementation class Make a wooden table
class skill_mu:
def perform_skill(self):
print(' I can make wooden tables ')
# Specific function classes , It is also a concrete implementation class Make an iron table
class skill_tie:
def perform_skill(self):
print(' I can make iron tables ')
# Specific function classes , It is also a concrete implementation class Be a teacher
class skill_teacher:
def perform_skill(self):
print(' I can be a teacher , Can teach students ')
# Specific function classes , It is also a concrete implementation class Make furniture
class skill_jj:
def perform_skill(self):
print(' I can make furniture ')
def main():
h=hua_j() # gardener
m=mu_j() # carpenter
t=tie_j() # Blacksmith
sh=skill_hua()# Skill : Can grow flowers
sm=skill_mu() # Skill : Can make wooden tables
st=skill_tie() # Skill : Can make an iron table
s_t=skill_teacher() # Skill : Can teach students
s_jj=skill_jj() # Skill : Can make furniture
h.set_skill(sh) # To the gardener set The ability to plant flowers
h.perform_skill() # gardener grow flowers
h.set_skill(s_t) # To the gardener set The ability to be a teacher
h.perform_skill() # The gardener taught the students
print('=============')
m.set_skill(sm) # To the carpenter set The ability to make wooden tables
m.perform_skill() # carpenter Make a wooden table
m.set_skill(s_t) # To the carpenter set The ability to be a teacher
m.perform_skill() # Carpenters teach students
m.set_skill(s_jj) # To the carpenter set The ability to make furniture
m.perform_skill() # Carpenters make furniture
print('=============')
t.set_skill(st) # To the carpenter set The ability to make wooden tables
t.perform_skill() # carpenter Make a wooden table
t.set_skill(s_t) # To the carpenter set The ability to be a teacher
t.perform_skill() # Carpenters teach students
t.set_skill(s_jj) # To the carpenter set The ability to make furniture
t.perform_skill() # Carpenters make furniture
if __name__ == '__main__':
main()
边栏推荐
- Data mining modeling practice
- Learn how Alibaba manages the data indicator system
- Key summary V of PMP examination - execution process group
- Sword finger offer | Fibonacci sequence
- 异常处理4种方法
- The digital human industry is about to break out. What is the market pattern?
- Ingersoll Rand面板维修IR英格索兰微电脑控制器维修XE-145M
- 2020-10-27
- Divide and rule classic Hanoi
- Calculation of stock purchase and sale expenses
猜你喜欢

函数的分文件编写

new URL(“www.jjj.com“)

Decision table method for basic content learning of software testing (2)

買賣股票費用計算

Virtual machine 14 installing win7 (Figure tutorial)

Write a simple timeline

Ingersoll Rand面板维修IR英格索兰微电脑控制器维修XE-145M

PMP Exam key summary VI - chart arrangement

Basic knowledge of hard disk (head, track, sector, cylinder)

HDI的盲孔设计,你注意到这个细节了吗?
随机推荐
HDI的盲孔设计,你注意到这个细节了吗?
Decision table method for basic content learning of software testing (2)
DBeaver安装与使用教程(超详细安装与使用教程)
Key summary IV of PMP examination - planning process group (2)
Campus honey decoration of APP course design (e-commerce platform)
适配器模式(Adapter)
两道面试小Demo
Interpretation of new products: realm launched GT neo2 Dragon Ball customized version
A classic JVM class loaded interview question class singleton{static singleton instance = new singleton(); private singleton() {}
Edit the live broadcast source code with me. How to write the live broadcast app code
股票 停牌
函数的分文件编写
Learn how Alibaba manages the data indicator system
P2394 yyy loves Chemistry I
abnormal
Multithreading concurrent parallel threaded process
The digital human industry is about to break out. What is the market pattern?
Calcul des frais d'achat et de vente d'actions
When the interviewer asks you to write binarysort in two ways
Fastjason filter field