桥接模式及C++实现
桥接模式
先说说桥接模式的定义:将抽象化(Abstraction)与实现化(Implementation)分离,使得二者可以独立地变化。
桥接模式号称设计模式中最难理解的模式之一,关键就是这个抽象和实现的分离非常让人奇怪,大部分人刚看到这个定义的时候都会认为实现就是继承自抽象,那怎么可能将他们分离呢。
这里引用《大话设计模式》里面的那个例子。这个例子中,每次添加一个新的手机品牌,则必须要添加相应的通讯录和游戏,而每次要给每个手机添加新功能,则所有的手机品牌下都必须继承一个新的类,这样工作量就大了,而且可能通讯录和游戏的实现方法是一样的,这就有很多重复代码。看到这里可能已经看到了端倪了,虽然这个最顶层的抽象手机品牌一般是固定不变的,但是下面的各个继承类手机品牌M和手机品牌N却是时常会发生变化的。而只要手机品牌M和手机品牌N发生变化,它下面的继承类也要发生变化,这样极大的增加了代码的耦合性,加入通讯录和游戏下面还继续继承有类的话,那耦合性就更强了,改起来基本就是噩梦了。
其实也可以这样看,虽然手机品牌M和手机品牌N这两个类是有一部分抽象,但是还没有达到完全的抽象,还是会发生变化的。
所以,其实定义里说的实现是指的最下层的那些具体实现,抽象是指的他的父类或者更上层的父类,而要将抽象和实现分离,就是分离这个抽象和实现。说的通俗点,就是不要继承的太多了,最好是就继承一层。(我自己的理解)所以才有了合成/聚合复用原则。
合成/聚合复用原则:尽量使用合成/聚合,尽量不要使用类继承。我对这句话的理解就是,不要继承太多了,如果需要太多继承,可以考虑改为合成/聚合。
下面可以看看桥接模式的具体类图了。桥接模式就将实现与抽象分离开来,使得RefinedAbstraction依赖于抽象的实现,这样实现了依赖倒转原则,而不管左边的抽象如何变化,只要实现方法不变,右边的具体实现就不需要修改,而右边的具体实现方法发生变化,只要接口不变,左边的抽象也不需要修改。
说起来,其实桥接模式倒是与抽象工厂模式有点像,可以回忆一下抽象工厂模式,抽象工厂模式也是解决多种因素变化的一种方式,抽象工厂模式中,产品的种类和产品的具体实现都会发生变化,于是将产品的种类抽象出来,将具体的实现隔离开来。
常用的场景
1.当一个对象有多个变化因素的时候,考虑依赖于抽象的实现,而不是具体的实现。如上面例子中手机品牌有2种变化因素,一个是品牌,一个是功能。
2.当多个变化因素在多个对象间共享时,考虑将这部分变化的部分抽象出来再聚合/合成进来,如上面例子中的通讯录和游戏,其实是可以共享的。
3.当我们考虑一个对象的多个变化因素可以动态变化的时候,考虑使用桥接模式,如上面例子中的手机品牌是变化的,手机的功能也是变化的,所以将他们分离出来,独立的变化。
优点
1.将实现抽离出来,再实现抽象,使得对象的具体实现依赖于抽象,满足了依赖倒转原则。
2.将可以共享的变化部分,抽离出来,减少了代码的重复信息。
3.对象的具体实现可以更加灵活,可以满足多个因素变化的要求。
缺点
1.客户必须知道选择哪一种类型的实现。
C++实现代码
1 #ifndef _ABSTRACTION_H_ 2 #define _ABSTRACTION_H_ 3 4 #include "AbstractionImplement.h" 5 6 class Abstraction 7 { 8 public: 9 Abstraction(); 10 virtual ~Abstraction(); 11 12 virtual void operation() = 0; 13 14 15 }; 16 17 class DefinedAbstraction: public Abstraction 18 { 19 public: 20 DefinedAbstraction(AbstractionImplement* absImp); 21 ~DefinedAbstraction(); 22 23 void operation(); 24 25 private: 26 AbstractionImplement* absImp; 27 }; 28 29 30 #endif
1 #include "Abstraction.h" 2 3 4 Abstraction::Abstraction() 5 { 6 7 } 8 9 10 11 Abstraction::~Abstraction() 12 { 13 14 } 15 16 17 DefinedAbstraction::DefinedAbstraction(AbstractionImplement* absImp) 18 { 19 this->absImp = absImp; 20 } 21 22 23 DefinedAbstraction::~DefinedAbstraction() 24 { 25 26 } 27 28 29 void DefinedAbstraction::operation() 30 { 31 absImp->operation(); 32 }
1 #ifndef _ABSTRACTIONIMPLEMENT_H_ 2 #define _ABSTRACTIONIMPLEMENT_H_ 3 4 5 class AbstractionImplement 6 { 7 public: 8 AbstractionImplement(); 9 virtual ~AbstractionImplement(); 10 11 virtual void operation() = 0; 12 }; 13 14 15 class ConcreteAbstractionImplement1:public AbstractionImplement 16 { 17 public: 18 ConcreteAbstractionImplement1(); 19 ~ConcreteAbstractionImplement1(); 20 21 void operation(); 22 }; 23 24 class ConcreteAbstractionImplement2:public AbstractionImplement 25 { 26 public: 27 ConcreteAbstractionImplement2(); 28 ~ConcreteAbstractionImplement2(); 29 30 void operation(); 31 }; 32 33 34 #endif
1 #include "AbstractionImplement.h" 2 #include <stdio.h> 3 4 5 6 AbstractionImplement::AbstractionImplement() 7 { 8 9 } 10 11 12 AbstractionImplement::~AbstractionImplement() 13 { 14 15 } 16 17 18 ConcreteAbstractionImplement1::ConcreteAbstractionImplement1() 19 { 20 21 } 22 23 24 ConcreteAbstractionImplement1::~ConcreteAbstractionImplement1() 25 { 26 27 } 28 29 30 void ConcreteAbstractionImplement1::operation() 31 { 32 fprintf(stderr, "ConcreteAbstractionImplement1\n" ); 33 } 34 35 36 ConcreteAbstractionImplement2::ConcreteAbstractionImplement2() 37 { 38 39 } 40 41 42 ConcreteAbstractionImplement2::~ConcreteAbstractionImplement2() 43 { 44 45 } 46 47 48 void ConcreteAbstractionImplement2::operation() 49 { 50 fprintf(stderr, "ConcreteAbstractionImplement2\n" ); 51 }
1 #include "Abstraction.h" 2 3 4 5 int main() 6 { 7 AbstractionImplement* absImp1 = new ConcreteAbstractionImplement1(); 8 Abstraction* abs1 = new DefinedAbstraction(absImp1); 9 10 abs1->operation(); 11 12 AbstractionImplement* absImp2 = new ConcreteAbstractionImplement2(); 13 Abstraction* abs2 = new DefinedAbstraction(absImp2); 14 15 abs2->operation(); 16 return 0; 17 }
1 g++ -o client client.cpp Abstraction.cpp AbstractionImplement.cpp
运行结果
AbstractFactory
要创建一组相关或者相互依赖的对象
作用:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
UML结构图:
抽象基类:
1)AbstractProductA、AbstractProductB:分别代表两种不同类型的产品,由具体的产品派生类对其实现
2)AbstractFactory:抽象工厂类,提供创建两种产品的接口CreateProductA和CreateProductB,由派生的各个具体工厂类对其实现
说明:
AbstractFactory模式关键就是将这一组对象的创建封装到一个用于创建对象的类(ConcreteFactory)中
Abstract Factory模式和Factory最大的差别就是抽象工厂创建的是一系列相关的对象,其中创建的实现其实采用的就是Factory模式的方法,对于某个实现的有一个派生出来的抽象工厂,另一个实现有另一个派生出来的工厂
抽象工厂需要特别注意的地方就是区分不同类型的产品和这些产品的不同实现.显而易见的,如果有n种产品同时有m中不同的实现,那么根据乘法原理可知有n*m个Factory模式的使用
AbstractFactory模式是为创建一组(有多类)相关或依赖的对象提供创建接口,而Factory模式是为一类对象提供创建接口或延迟对象的创建到子类中实现。并且可以看到,AbstractFactory模式通常都是使用Factory模式实现(ConcreteFactory1)。
代码如下:
Product.h
1 #ifndef _PRODUCT_H_ 2 #define _PRODUCT_H_ 3 4 //抽象基类AbstractProductA,代表A类产品的抽象 5 class AbstractProductA 6 { 7 public: 8 virtual ~AbstractProductA()=0; 9 virtual void operation()=0; 10 protected: 11 AbstractProductA();//屏蔽构造函数 12 }; 13 14 //派生类ProductA1,继承自AbstractProductA,A类产品的一种实现 15 class ProductA1 : public AbstractProductA 16 { 17 public: 18 ProductA1(); 19 virtual void operation(); 20 virtual ~ProductA1(); 21 }; 22 23 //派生类ProductA2,继承自AbstractProductA,A类产品的另一种实现 24 class ProductA2:public AbstractProductA 25 { 26 public: 27 ProductA2(); 28 virtual void operation(); 29 virtual ~ProductA2(); 30 }; 31 32 //抽象基类AbstractProductB,代表B类产品的抽象 33 class AbstractProductB 34 { 35 public: 36 virtual ~AbstractProductB()=0; 37 virtual void operation()=0; 38 protected: 39 AbstractProductB();//屏蔽构造函数 40 }; 41 42 //派生类ProductB1,继承自AbstractProductB,B类产品的一种实现 43 class ProductB1:public AbstractProductB 44 { 45 public: 46 ProductB1(); 47 virtual void operation(); 48 virtual ~ProductB1(); 49 }; 50 51 //派生类ProductB2,继承自AbstractProductB,B类产品的另一种实现 52 class ProductB2:public AbstractProductB 53 { 54 public: 55 ProductB2(); 56 virtual void operation(); 57 virtual ~ProductB2(); 58 }; 59 60 61 #endif
Factory.h
1 #ifndef _FACTORY_H_ 2 #define _FACTORY_H_ 3 4 //AbstractFactory,工厂抽象基类,定义生产A类与B类产品的接口 5 class AbstractProductA; 6 class AbstractProductB; 7 class AbstractFactory 8 { 9 public: 10 virtual ~AbstractFactory()=0; 11 virtual AbstractProductA* CreateProductA()=0; 12 virtual AbstractProductB* CreateProductB()=0; 13 protected: 14 AbstractFactory(); 15 }; 16 17 //ConcreteFactory1,派生类,继承自AbstractFactory 18 //实现继承的接口,生产产品A和B的一种实现 19 class ConcreteFactory1:public AbstractFactory 20 { 21 public: 22 ConcreteFactory1(); 23 ~ConcreteFactory1(); 24 virtual AbstractProductA* CreateProductA(); 25 virtual AbstractProductB* CreateProductB(); 26 }; 27 28 //ConcreteFactory2,派生类,继承自AbstractFactory 29 //实现继承的接口,生产产品A和B的另一种实现 30 class ConcreteFactory2:public AbstractFactory 31 { 32 public: 33 ConcreteFactory2(); 34 ~ConcreteFactory2(); 35 virtual AbstractProductA* CreateProductA(); 36 virtual AbstractProductB* CreateProductB(); 37 }; 38 39 #endif
Product.cpp
1 #include "Product.h" 2 #include <iostream> 3 4 using namespace std; 5 6 //AbstractProductA 7 AbstractProductA::AbstractProductA() 8 { 9 cout << "AbstractProductA..." << endl; 10 } 11 12 AbstractProductA::~AbstractProductA() 13 { 14 cout << "~AbstractProductA..." << endl; 15 } 16 17 //ProductA1 18 ProductA1::ProductA1() 19 { 20 cout << "ProductA1..." << endl; 21 } 22 23 ProductA1::~ProductA1() 24 { 25 cout << "~ProductA1..." << endl; 26 } 27 28 void ProductA1::operation() 29 {} 30 31 //ProductA2 32 ProductA2::ProductA2() 33 { 34 cout << "ProductA2..." << endl; 35 } 36 37 ProductA2::~ProductA2() 38 { 39 cout << "~ProductA2..." << endl; 40 } 41 42 void ProductA2::operation() 43 {} 44 45 //AbstractProductB 46 AbstractProductB::AbstractProductB() 47 { 48 cout << "AbstractProductB..." << endl; 49 } 50 51 AbstractProductB::~AbstractProductB() 52 { 53 cout << "~AbstractProductB..." << endl; 54 } 55 56 //ProductB1 57 ProductB1::ProductB1() 58 { 59 cout << "ProductB1..." << endl; 60 } 61 62 ProductB1::~ProductB1() 63 { 64 cout << "~ProductB1..." << endl; 65 } 66 67 void ProductB1::operation() 68 {} 69 70 //ProductB2 71 ProductB2::ProductB2() 72 { 73 cout << "ProductB2..." << endl; 74 } 75 76 ProductB2::~ProductB2() 77 { 78 cout << "~ProductB2..." << endl; 79 } 80 81 void ProductB2::operation() 82 {}
Factory.cpp
1 #include "Factory.h" 2 #include "Product.h" 3 #include <iostream> 4 5 using namespace std; 6 7 AbstractFactory::AbstractFactory() 8 { 9 cout << "AbstractFactory..." << endl; 10 } 11 12 AbstractFactory::~AbstractFactory() 13 { 14 cout << "~AbstractFactory..." << endl; 15 } 16 17 ConcreteFactory1::ConcreteFactory1() 18 { 19 cout << "ConcreteFactory1..." << endl; 20 } 21 22 ConcreteFactory1::~ConcreteFactory1() 23 { 24 cout << "~ConcreteFactory1..." << endl; 25 } 26 27 AbstractProductA* ConcreteFactory1::CreateProductA() 28 { 29 return new ProductA1(); 30 } 31 32 AbstractProductB* ConcreteFactory1::CreateProductB() 33 { 34 return new ProductB1(); 35 } 36 37 ConcreteFactory2::ConcreteFactory2() 38 { 39 cout << "ConcreteFactory2..." << endl; 40 } 41 42 ConcreteFactory2::~ConcreteFactory2() 43 { 44 cout << "~ConcreteFactory2..." << endl; 45 } 46 47 AbstractProductA* ConcreteFactory2::CreateProductA() 48 { 49 return new ProductA2(); 50 } 51 52 AbstractProductB* ConcreteFactory2::CreateProductB() 53 { 54 return new ProductB2(); 55 }
main.cpp
1 #include <iostream> 2 #include "Factory.h" 3 #include "Product.h" 4 5 using namespace std; 6 7 int main() 8 { 9 AbstractFactory* fa1 = new ConcreteFactory1(); 10 AbstractProductA* a1 = fa1->CreateProductA(); 11 AbstractProductB* b1 = fa1->CreateProductB(); 12 13 cout << endl; 14 AbstractFactory* fa2 = new ConcreteFactory2(); 15 AbstractProductA* a2 = fa2->CreateProductA(); 16 AbstractProductB* b2 = fa2->CreateProductB(); 17 18 cout << endl; 19 delete fa1; 20 delete a1; 21 delete b1; 22 23 cout << endl; 24 delete fa2; 25 delete a2; 26 delete b2; 27 28 return 0; 29 }