结构型模式のBridge桥梁模式
桥梁模式,将抽象部分与它的实现部分分离,使它们都可以独立地变化。实现分离的办法就是增加一个类,
11.1.解释
main(),客户
IProduct,产品接口
CHouse,房子
CIPod,ipod
CClothes,服装
CNewCorp,桥梁类,MakeMoney()是桥梁方法
CNewHouseCorp,只能生产房子,所以构造函数是CHouse*
CShanZhaiCorp,什么赚钱就生产什么,所以构造函数是IProduct*
说明:客户直接使用CNewHouseCorp和CShanZhaiCorp类,在main()函数里构造产品,然后传到这两个类里。这两个类的MakeMoney()函数,先调用基类的MakeMoney(),然后分别执行各自的逻辑。
注意:CNewCorp起到了桥梁的作用。可以分别增加产品和公司。
看代码:
1 //NewCorp.h 2 3 #pragma once 4 #include "IProduct.h" 5 class CNewCorp 6 { 7 public: 8 CNewCorp(IProduct *pproduct); 9 virtual ~CNewCorp(void); 10 void MakeMoney(); 11 private: 12 IProduct *m_pProduct; 13 }; 14 15 //NewCorp.cpp 16 17 #include "StdAfx.h" 18 #include "NewCorp.h" 19 CNewCorp::CNewCorp( IProduct *pproduct ) 20 { 21 this->m_pProduct = pproduct; 22 } 23 CNewCorp::~CNewCorp(void) 24 { 25 } 26 void CNewCorp::MakeMoney() 27 { 28 //每个公司都是一样,先生产 29 this->m_pProduct->BeProducted(); 30 31 //然后销售 32 this->m_pProduct->BeSelled(); 33 }
1 //NewHouseCorp.h 2 3 #pragma once 4 #include "newcorp.h" 5 #include "House.h" 6 class CNewHouseCorp : 7 public CNewCorp 8 { 9 public: 10 CNewHouseCorp(CHouse *pHouse); 11 ~CNewHouseCorp(void); 12 void MakeMoney(); 13 }; 14 15 //NewHouseCorp.cpp 16 17 #include "StdAfx.h" 18 #include "NewHouseCorp.h" 19 #include <iostream> 20 using std::cout; 21 using std::endl; 22 CNewHouseCorp::CNewHouseCorp(CHouse *pHouse) : CNewCorp(pHouse) 23 { 24 } 25 CNewHouseCorp::~CNewHouseCorp(void) 26 { 27 } 28 void CNewHouseCorp::MakeMoney() 29 { 30 this->CNewCorp::MakeMoney(); 31 cout << "房地产公司赚大钱了..." << endl; 32 }
1 //ShanZhaiCorp.h 2 3 #pragma once 4 #include "newcorp.h" 5 #include "IProduct.h" 6 class CShanZhaiCorp : 7 public CNewCorp 8 { 9 public: 10 CShanZhaiCorp(IProduct *pproduct); 11 ~CShanZhaiCorp(void); 12 void MakeMoney(); 13 }; 14 15 //ShanZhaiCorp.cpp 16 17 #include "StdAfx.h" 18 #include "ShanZhaiCorp.h" 19 #include <iostream> 20 using std::cout; 21 using std::endl; 22 CShanZhaiCorp::CShanZhaiCorp(IProduct *pproduct) : CNewCorp(pproduct) 23 { 24 } 25 CShanZhaiCorp::~CShanZhaiCorp(void) 26 { 27 } 28 void CShanZhaiCorp::MakeMoney() 29 { 30 this->CNewCorp::MakeMoney(); 31 cout << "我赚钱呀..." << endl; 32 }
1 //IProduct.h 2 3 #pragma once 4 class IProduct 5 { 6 public: 7 IProduct(void) 8 { 9 } 10 virtual ~IProduct(void) 11 { 12 } 13 virtual void BeProducted() = 0; 14 virtual void BeSelled() = 0; 15 };
1 //House.h 2 3 #pragma once 4 #include "iproduct.h" 5 class CHouse : 6 public IProduct 7 { 8 public: 9 CHouse(void); 10 ~CHouse(void); 11 void BeProducted(); 12 void BeSelled(); 13 }; 14 15 //House.cpp 16 17 #include "StdAfx.h" 18 #include "House.h" 19 #include <iostream> 20 using std::cout; 21 using std::endl; 22 CHouse::CHouse(void) 23 { 24 } 25 CHouse::~CHouse(void) 26 { 27 } 28 void CHouse::BeProducted() 29 { 30 cout << "生产出的房子是这个样子的..." << endl; 31 } 32 void CHouse::BeSelled() 33 { 34 cout << "生产出的房子卖出去了..." << endl; 35 }
1 //Clothes.h 2 3 #pragma once 4 #include "iproduct.h" 5 class CClothes : 6 public IProduct 7 { 8 public: 9 CClothes(void); 10 ~CClothes(void); 11 void BeProducted(); 12 void BeSelled(); 13 }; 14 15 //Clothes.cpp 16 17 #include "StdAfx.h" 18 #include "Clothes.h" 19 #include <iostream> 20 using std::cout; 21 using std::endl; 22 CClothes::CClothes(void) 23 { 24 } 25 CClothes::~CClothes(void) 26 { 27 } 28 void CClothes::BeProducted() 29 { 30 cout << "生产出的衣服是这个样子的..." << endl; 31 } 32 void CClothes::BeSelled() 33 { 34 cout << "生产出的衣服卖出去了..." << endl; 35 }
1 //IPod.h 2 3 #pragma once 4 #include "iproduct.h" 5 class CIPod : 6 public IProduct 7 { 8 public: 9 CIPod(void); 10 ~CIPod(void); 11 void BeProducted(); 12 void BeSelled(); 13 }; 14 15 //IPod.cpp 16 17 #include "StdAfx.h" 18 #include "IPod.h" 19 #include <iostream> 20 using std::cout; 21 using std::endl; 22 CIPod::CIPod(void) 23 { 24 } 25 CIPod::~CIPod(void) 26 { 27 } 28 void CIPod::BeProducted() 29 { 30 cout << "生产出的ipod是这个样子的..." << endl; 31 } 32 void CIPod::BeSelled() 33 { 34 cout << "生产出的ipod卖出去了..." << endl; 35 }
1 // Bridge.cpp : 定义控制台应用程序的入口点。 2 3 #include "stdafx.h" 4 #include "ClothesCorp.h" 5 #include "NewHouseCorp.h" 6 #include "Clothes.h" 7 #include "IPod.h" 8 #include "ShanZhaiCorp.h" 9 #include <iostream> 10 using std::cout; 11 using std::endl; 12 13 void DoNewRun1() 14 { 15 cout << "----------房地产公司是这样运行的----------" << endl; 16 CHouse house; 17 CNewHouseCorp newHouseCorp(&house); 18 newHouseCorp.MakeMoney(); 19 cout << endl; 20 21 cout << "----------山寨公司是这样运行的----------" << endl; 22 CClothes clothes; 23 CShanZhaiCorp shanZhaiCorp(&clothes); 24 shanZhaiCorp.MakeMoney(); 25 cout << endl; 26 } 27 28 void DoNewRun2() 29 { 30 cout << "----------房地产公司是这样运行的----------" << endl; 31 CHouse house; 32 CNewHouseCorp newHouseCorp(&house); 33 newHouseCorp.MakeMoney(); 34 cout << endl; 35 36 cout << "----------山寨公司是这样运行的----------" << endl; 37 CIPod ipod; 38 CShanZhaiCorp shanZhaiCorp(&ipod); 39 shanZhaiCorp.MakeMoney(); 40 cout << endl; 41 } 42 43 int _tmain(int argc, _TCHAR* argv[]) 44 { 45 //只有两家公司,一家是房地产公司,另一家公司是衣服赚钱就生产衣服 46 DoNewRun1(); 47 48 //只有两家公司,一家是房地产公司,另一家公司是ipod赚钱就生产ipod 49 DoNewRun2(); 50 51 _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF | _CRTDBG_ALLOC_MEM_DF); 52 _CrtDumpMemoryLeaks(); 53 return 0; 54 }
桥梁模式(又可以称做桥接模式)属于结构型模式。CNewCorp实现了桥梁(桥接)的作用。
Bridge是设计模式中比较复杂和难理解的模式之一,也是OO开发与设计中经常会用到的模式之一。使用组合(委托)的方式将抽象和实现彻底地解耦,这样的好处是抽象和实现可以分别独立地变化,系统的耦合性也得到了很好的降低。
GoF在说明Bridge模式时,在意图中指出Bridge模式“将抽象部分与它的实现部分分离,使得它们可以独立地变化”。这句话很简单,但是也很复杂,连Bruce Eckel在他的大作《ThinkinginPatterns》中说“Bridge模式是GoF所讲述得最不好(Poorly-described)的模式”,个人觉得也正是如此。原因就在于GoF的那句话中的“实现”该怎么去理解:“实现”。特别是和“抽象”放在一起的时候我们“默认”的理解是“实现”就是“抽象”的具体子类的实现,但是这里GoF所谓的“实现”的含义不是指抽象基类的具体子类对抽象基类中虚函数(接口)的实现,是和继承结合在一起的。而这里的“实现”的含义指的是怎么去实现用户的需求,并且指的是通过组合(委托)的方式实现的,因此这里的实现不是指的继承基类、实现基类接口,而是指的是通过对象组合实现用户的需求。理解了这一点也就理解了Bridge模式,理解了Bridge模式,你的设计就会更加Elegant了。
实际上上面使用Bridge模式和使用带来问题方式的解决方案的根本区别在于是通过继承还是通过组合的方式去实现一个功能需求。因此面向对象分析和设计中有一个原则就是:Favor Composition Over Inheritance。其原因也正在这里。
本文参考:K_Eckel 的23种设计模式。
本文转自:~~~