设计模式之桥接模式
概述
桥接模式即将抽象部分与它的实现部分分离开来,使他们都可以独立变化。桥接模式将继承关系转化成关联关系,它降低了类与类之间的耦合度,减少了系统中类的数量,也减少了代码量。
这种模式涉及到一个作为桥接的接口,使得实体类的功能独立于接口实现类。这两种类型的类可被结构化改变而互不影响。
设计模式思想
桥接模式也分为四个角色:
- Abstraction:抽象部分的抽象类
该类保持一个对实现部分对象的引用,抽象部分中的方法需要调用实现部分的对象来实现,该类一般为抽象类; - RefinedAbstraction:抽象部分的优化 -扩充抽象类 抽象部分的具体实现,该类一般对抽象部分的方法进行完善和扩展;
- Implementor:实现部分的实现类接口
可以为接口或者是抽象类,其方法不一定要与抽象部分中的一致,一般情况下是由实现部分提供基本的操作,而抽象部分定义的则是基于实现部分基本操作的业务方法; - ConcreteImplementorA 和 ConcreteImplementorB :实现部分的具体实现类
完善实现部分中定义的具体逻辑。
下面从代码的角度对桥接模式进行说明:
实现类
Implementor 实现部分的基类,定义实现部分的基本内容。
/**
* 实现类
* @author Administrator
*
*/
public abstract class Implementor {
public abstract void Operation();
}
具体实现类
ConcreteImplementor 具体的实现类。
/**
* 具体实现类
* @author Administrator
*
*/
public class ConcreteImplementorA extends Implementor{
@Override
public void Operation() {
// TODO Auto-generated method stub
System.out.println("具体实现类A的执行方法");
}
}
/**
* 具体实现类
* @author Administrator
*
*/
public class ConcreteImplementorB extends Implementor {
@Override
public void Operation() {
// TODO Auto-generated method stub
System.out.println("具体实现类B的执行方法");
}
}
抽象类
Abstraction 抽象部分的基类,定义抽象部分的基础内容。
/**
* 抽象类
*
* @author Administrator
*该类保持一个对实现部分对象的引用,抽象部分中的方法需要调用实现部分的对象来实现,该类一般为抽象类;
*/
public class Abstraction {
protected Implementor implementor;
public void setImplementor(Implementor implementor) {
this.implementor = implementor;
}
public void Operation() {
implementor.Operation();
}
}
扩充抽象类
RefinedAbstraction 抽象部分的扩充,用于对基类的内容补充,添加特定场景的业务操作。
/**
* 扩充抽象类
* @author Administrator
*抽象部分的具体实现,该类一般对抽象部分的方法进行完善和扩展
*/
public class RefinedAbstraction extends Abstraction{
@Override
public void Operation() {
// TODO Auto-generated method stub
implementor.Operation();
}
}
测试客户端
public class Test {
public static void main(String[] args) {
Abstraction ab=new RefinedAbstraction();
ab.setImplementor(new ConcreteImplementorA());
ab.Operation();
ab.setImplementor(new ConcreteImplementorB());
ab.Operation();
}
}
测试效果:
具体实现类A的执行方法
具体实现类B的执行方法
设计模式源码
下面举一个手机品牌和手机软件的示例。
实现类——手机软件
/**
* 实现类——手机软件
* @author Administrator
*
*/
public abstract class PhoneSoft {
public abstract void run();
}
具体实现类 ——具体手机软件
/*
*具体实现类 ——手机软件QQ
*/
public class QQ extends PhoneSoft{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("登录QQ,网上聊天");
}
}
/*
*具体实现类 ——手机软件淘宝
*/
public class TaoBao extends PhoneSoft{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("登录淘宝,网上购物");
}
}
抽象部分的基类 ——手机品牌
/**
* 抽象部分的基类 ——手机品牌
* @author Administrator
*
*/
public abstract class PhoneBrands {
protected PhoneSoft pSoft;
public void setSoftWare(PhoneSoft pSoft){
this.pSoft=pSoft;
}
public abstract void run();
}
抽象部分的具体实现-手机品牌
/**
* 抽象部分的具体实现-手机品牌-华为
* @author Administrator
*
*/
public class HuaWei extends PhoneBrands{
@Override
public void run() {
System.out.println("我是华为手机:");
pSoft.run();
}
}
/**
* 抽象部分的具体实现-手机品牌-苹果
* @author Administrator
*
*/
public class Iphone extends PhoneBrands{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("我是苹果手机:");
pSoft.run();
}
}
测试客户端
public class TestBridge {
public static void main(String[] args) {
PhoneBrands pb;
pb=new Iphone();
pb.setSoftWare(new QQ());
pb.run();
pb.setSoftWare(new TaoBao());
pb.run();
pb=new HuaWei();
pb.setSoftWare(new QQ());
pb.run();
pb.setSoftWare(new TaoBao());
pb.run();
}
}
测试效果:
我是苹果手机:
登录QQ,网上聊天
我是苹果手机:
登录淘宝,网上购物
我是华为手机:
登录QQ,网上聊天
我是华为手机:
登录淘宝,网上购物
优缺点及使用场景
优点:
1、分离抽象接口及其实现部分。提高了比继承更好的解决方案。
2、桥接模式提高了系统的可扩充性,在两个变化维度中任意扩展一个维度,都不需要修改原有系统。
3、实现细节对客户透明,可以对用户隐藏实现细节。
缺点:
1、桥接模式的引入会增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程。
2、桥接模式要求正确识别出系统中两个独立变化的维度,因此其使用范围具有一定的局限性。
使用场景:
1、如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。
2、对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。
3、一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。
总结
桥接(Bridge)是用于把抽象化与实现化解耦,使得二者可以独立变化。这种类型的设计模式属于结构型模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。