桥接模式及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 }

C++设计模式-AbstractFactory抽象工厂模式

 
 

桥接模式及C++实现 C++设计模式-AbstractFactory抽象工厂模式的更多相关文章

  1. C++设计模式-AbstractFactory抽象工厂模式

    AbstractFactory 要创建一组相关或者相互依赖的对象 作用:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. UML结构图: 抽象基类: 1)AbstractProdu ...

  2. C#设计模式之四抽象工厂模式(AbstractFactory)【创建型】

    一.引言     写了3篇有关设计模式的文章了,大家有了些反馈,说能从中学到一些东西,我感到很欣慰,那就继续努力.今天我要写第四个模式了,该模式叫抽象工厂.上一篇文章我们讲了[工厂方法]模式,它是为了 ...

  3. C#设计模式之三抽象工厂模式(AbstractFactory)【创建型】

    一.引言 写了3篇有关设计模式的文章了,大家有了些反馈,说能从中学到一些东西,我感到很欣慰,那就继续努力.今天我要写第四个模式了,该模式叫抽象工厂.上一篇文章我们讲了[工厂方法]模式,它是为了解决[简 ...

  4. 乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern)

    原文:乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factor ...

  5. 再起航,我的学习笔记之JavaScript设计模式06(抽象工厂模式)

    我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 前两 ...

  6. 【设计模式】抽象工厂模式 Abstract Factory Pattern

    简单工厂模式是一个工厂类根据工厂方法的参数创建不出不同的产品, 工厂方法模式是每一个产品都有一个一一对应的工厂负责创建该产品.那么今天要讲的抽象工厂模式是一个工厂能够产生关联的一系列产品.抽象工厂模式 ...

  7. 再起航,我的学习笔记之JavaScript设计模式07(抽象工厂模式)

    我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 前两 ...

  8. 设计模式之抽象工厂模式(Abstract Factory Pattern)

    一.抽象工厂模式的由来 抽象工厂模式,最开始是为了解决操作系统按钮和窗体风格,而产生的一种设计模式.例如:在windows系统中,我们要用windows设定的按钮和窗体,当我们切换Linux系统时,要 ...

  9. Java 设计模式之抽象工厂模式(三)

    原文地址:Java 设计模式之抽象工厂模式(三) 博客地址:http://www.extlight.com 一.前言 上篇文章 <Java 设计模式之工厂模式(二)>,介绍了简单工厂模式和 ...

随机推荐

  1. 多线程学习之三生产者消费者模式Guarded Suspension

    Guarded Suspension[生产消费者模式] 一:guarded suspension的参与者--->guardedObject(被防卫)参与者                1.1该 ...

  2. IOS发展--他们控制的定义

    有没有这样的要求,,自定义panel,里面放几个控件,在多个页面中使用此panel. 有三个观点来解决这个问题: 1.自己继承UIView写一个类,在它是在代码的形式加入需要控制.完成布局. 2.使用 ...

  3. hibernate的orphanRemoval

    在@OneToMany与@OneToOne中使用orphanRemoval = true时候 改动保存时候setXXX org.springframework.orm.hibernate3.Hiber ...

  4. Linux C 多线程

    原文:Linux C 多线程 linux下C语言多线程编程 #include <pthread.h> #include <stdio.h> #include <sys/t ...

  5. Android的5样的调试信息

    Android的5样的调试信息 华清2014-10-23   北京海淀区  张俊浩 verbose:只是滤全部的信息. 啰嗦的意思. debug:debug调试的意思. info:一般提示的信息inf ...

  6. Oracle 11g for Windows 简体中文版的安装过程

    原文:Oracle 11g for Windows 简体中文版的安装过程 我的配置 操作系统:Windows Server 2003 sp2 内存:1024M以上 1.下载Oracle 11g 地址 ...

  7. SQL点滴9—SQL Server中的事务处理以及SSIS中的内建事务

    原文:SQL点滴9-SQL Server中的事务处理以及SSIS中的内建事务 我们可以把SSIS中的整个package包含在一个事务中,但是如果在package的执行过程中有一个表需要锁定应该怎么处理 ...

  8. [译]Java 设计模式之工厂

    (文章翻译自Java Design Pattern: Factory) 1.Java工厂模式的来历 工厂设计模式用于创建基于不同参数的对象.下面的例子就是在一个工厂里创建一个人.如果我们向工厂要一个b ...

  9. 安装Windows2012操作系统 - 初学者系列 - 学习者系列文章

    Windows 2012是微软最新的服务器操作系统,估计在国外服务器空间的运营商安装的比较多些吧.下面简要介绍下该操作系统的安装. 1.  将光盘放入光驱.进入BIOS设置成光驱启动.重启计算机. 2 ...

  10. 零基础学习iOS开发

    零基础学习iOS开发不管你是否涉足过IT领域,只要你对iOS开发感兴趣,都可以阅读此专题. [零基础学习iOS开发][02-C语言]11-函数的声明和定义 摘要: 在上一讲中,简单介绍了函数的定义和使 ...