桥接模式

一、 桥接模式概述

  在软件系统中,有些类具有两个或多个变化维度,如一个跨平台的日志记录类,它有多种日志输出方式(XML文件、数据库文件),同时还能支持多种操作系统。那么其输出方式就是一个变化维度,而支持的操作系统又是一个变化维度。那么我们如何来设计这样的一个类呢?我们可以定义两个类,一个日志类,它能够支持多种操作系统,另一个是输出方式类,它定义了多种输出方式。然后在日志类中定义一个输出方式类的对象,这样日志类就可以方便的调用输出方式类中定义的输出方法了。这就是一个简易的桥接模式实例模型,桥接模式可以降低系统的复杂性。下面是这个实例的类图:


其实现代码如下:

#include <iostream>
#include <string>
#include <vector>
using namespace std;

class OutPut
{
public:
	virtual void outPutMethod() = 0;
};

class OutInXML : public OutPut
{
public:
	virtual void outPutMethod()
	{
		cout << "outPut in xml file." << endl;
	}
};

class OutInDatabase : public OutPut
{
public:
	virtual void outPutMethod()
	{
		cout << "outPut in database file." << endl;
	}
};

class ActivityLog
{
protected:
	OutPut *outPut;
	
public:
	void SetOutPut(OutPut *outObj)
	{
		outPut = outObj;
	}
	virtual void record() = 0;
};

class LinuxLog : public ActivityLog
{
public:
	virtual void record()
	{
		cout << "Linux Log record ";
		outPut->outPutMethod();
	}
};

class WindowsLog : public ActivityLog
{
public:
	virtual void record()
	{
		cout << "Windows Log record ";
		outPut->outPutMethod();
	}
};

int main()
{
	ActivityLog *aLog;
	aLog = new LinuxLog();
	aLog->SetOutPut(new OutInXML());
	aLog->record();
	
	aLog = new WindowsLog();
	aLog->SetOutPut(new OutInDatabase());
	aLog->record();
	
	cout << endl;
	return 0;
}

二、 桥接模式结构分析

从上面的图中我们可以看到,桥接模式中有一条连接两个继承结构的桥,下面让来仔细分析一下桥模式都有哪些角色及模式的特点。首先让我们来看一下桥接模式的典型结构图。


从图上可以看到,桥接模式主要有这些角色:

(1)、Abstraction(抽象类):用于定义抽象类的接口,其中定义了一个Implementor类型的对象,可以通过此对象调用Implementor类中定义的业务方法。

(2)、RefinedAbstraction(扩充抽象类):扩充由Abstraction定义的接口,并实现其中的业务方法。

(3)、Implementor(实现类接口):在此接口中仅提供基本操作的定义,具体实现是由子类去定义的,由于Abstraction类中有一个Implementor类的对象,所以Abstraciton的子类可以方便的调用Implementor中定义的方法,这样就可以使用关联关系来替代继承关系了。

(4)、ConcreteImplementor(具体实现类):实现Implementor接口的方法,并提供各自不同的操作方法,在运行时可替换父类对象,给客户端提供具体的业务操作方法。

桥接模式体现了很多面向对象的设计原则,包括开闭原则、合成复用原则、里氏代换原则、依赖倒转原则等。它减少了系统中子类的个数,如要设计一个跨平台的图片处理系统,如果有n个系统,m种图片格式,则用继承的方式实现需要(n * m)个子类,而用桥接模式只需要(n + m)个子类。所以桥接模式往往会使代码更简洁,生成的可执行程序文件更小。在桥接模式中,有三个非常重要的概念:抽象化、实现化、解耦合。

(1)抽象化:其实就是面向对象中的类的概念,抽象化过程就是把不同实体的相同性质抽取出来形成类的过程。

(2)实现化:也就是类的实例,即类的实例化,抽象化和实现化是一对互逆的过程。

(3)解耦合:就是将抽象化和实现化之间的耦合解开的过程,桥接模式中的解耦是通过关联关系来实现的,即在抽象化和实例化中使用关联关系而不是用继承关系,使两者可以相对独立的修改。如果使用继承关系实现,那么父类的修改对象子类的影响往往是很大的,即父类与子类的耦合比较大。

 

三、 桥接模式实例

假设我们需要设计这一些游戏角色,它们拥有的套装各类是相同的,而且可以根据需要换上不同的套装。为了简单起见,在此规定只有两种角色,三种可选择套装吧。那么我们如何实现这个设计呢?如果我们用继承来实现,显然我们需要为每个角色的每种着装都写一个实现类,这样就需要6个子类,如果角色和可选择套装增加,那么需要的子类个数就会成倍的增加(n * m数量级)。但是如果我们用关联关系,那么子类的个数就会减少很多(n + m数量级),而且系统的可扩展性很好。下面是这个设计的类图:


1.      Role(角色类):

public abstract class Role {
	protected Suit suit;
	public void setSuit(Suit suitobj)
	{
		this.suit = suitobj;
	}
	public abstract void showSuit(String suitType);
}

2.      Lion(具体角色类):

public class Lion extends Role{
	@Override
	public void showSuit(String suitType) {
		String roleName = "Lion";
		this.suit.wear(roleName, suitType);
	}	
}

3.      Hawking(具体角色类):

public class Hawking extends Role{
	@Override
	public void showSuit(String suitType) {
		String roleName = "Hawking";
		this.suit.wear(roleName, suitType);	
	}
}


4.      SuitInterface(套装接口):

public interface SuitInterface {
	void wear(String roleName, String suitType);
}

5.      ShapaeshiftingSuit(具体套装类):

public class ShapeshiftingSuit implements SuitInterface{
	@Override
	public void wear(String roleName, String suitType) {
		System.out.println(roleName + " wear " + suitType);		
	}
}

6.      MagicReinforceSuit(具体套装类):

public class MagicReinforceSuit implements SuitInterface{
	@Override
	public void wear(String roleName, String suitType) {
		System.out.println(roleName + " wear " + suitType);		
	}
}

7.      GorgeousSuit(具体套装类):

public class GorgeousSuit implements SuitInterface{
	@Override
	public void wear(String roleName, String suitType) {
		System.out.println(roleName + " wear " + suitType);		
	}
}


8. 测试类

public class ClientTest {
	public static void main(String argv[])
	{
		SuitInterface suit = new ShapeshiftingSuit();
		Role role = new Hawking();
		role.setSuit(suit);
		role.showSuit("MagicReinforceSuit");
		role.showSuit("ShapeshiftingSuit");
	}
}

四、小结   

   桥接模式分离抽象接口及其实现部分,由于桥接模式使用关系来对抽象和实现之间解耦,所以抽象和实现可以自由的修改,而且子类可以任意组合,这样就可以高效方便的得到多种组合对象;采用桥接模式,会使系统的可扩充性更好,因为抽象和实现耦合低,所以两者可以独立修改,可以方便的增加具有不同功能的子类,而不用修改原系统。

    但是,桥接模式要求必须明确系统中的多个独立变化的维度,所以其使用范围有一定的局限性,而且它会增加系统的可读性和设计难度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Storm-Shadow

你的鼓励将是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值