桥接模式
简介
桥接(Bridge)是用于把抽象化与实现化解耦,使得二者可以独立变化。这种类型的设计模式属于结构型模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。
这种模式涉及到一个作为桥接的接口,使得实体类的功能独立于接口实现类。这两种类型的类可被结构化改变而互不影响。
通用类图
实现方式
桥接模式其实是基于聚合的实现方式。在日常开发中,我们需要扩展父类功能的时候,常常使用继承或者实现的方式。但是这方式在某些情况下就不适用。例如:手机不同的品牌自带的功能是不一样的,通讯录、拍照功能等都是有的,但是不是所有的手机都有公交卡充值功能,那么如果每种手机都需要扩展一个类,那么将导致系统的继承体系复杂且庞大。
基于面向对象导致的上述问题的复杂,我们可以使用聚合的形式去解决。手机是硬件和软件聚合组成的,那么手机是一个系类,软件是一个系类,手机可以自由聚合不同的软件。
那么我们以手机和软件的关系为例子,手机聚合了各种各样的软件和硬件,我们这里只聚合硬件为例子。
package com.rabbit.phone; import com.rabbit.sofa.BaseSofa; import java.util.ArrayList; import java.util.List; /** * 基础手机类别 * Created by HASEE on 2018/5/20. */ public abstract class BasePhone { protected String name; protected List<BaseSofa> sofas = new ArrayList<>(); public BasePhone(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } public boolean addSofas(BaseSofa baseSofa) { if (baseSofa == null) { throw new NullPointerException(); } return sofas.add(baseSofa); } public boolean delSofas(BaseSofa baseSofa) { if (baseSofa == null) { throw new NullPointerException(); } return sofas.remove(baseSofa); } public void showSofas() { sofas.stream().forEach(sofa -> System.out.println(sofa.toString())); } }
package com.rabbit.phone; import com.rabbit.sofa.BaseSofa; /** * Created by HASEE on 2018/5/20. */ public class OPPO extends BasePhone { public OPPO(String name) { super(name); } }
package com.rabbit.sofa; /** * 基础软件类 * Created by HASEE on 2018/5/20. */ public abstract class BaseSofa { protected String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "BaseSofa{" + "name='" + name + '\'' + '}'; } }
package com.rabbit.sofa; /** * Created by HASEE on 2018/5/20. */ public class WeChat extends BaseSofa { public WeChat(String name) { this.name = name; } }
package com.rabbit.sofa; /** * Created by HASEE on 2018/5/20. */ public class QQ extends BaseSofa { public QQ(String name) { this.name = name; } }
package com.rabbit; import com.rabbit.phone.BasePhone; import com.rabbit.phone.OPPO; import com.rabbit.sofa.QQ; import com.rabbit.sofa.WeChat; /** * Created by HASEE on 2018/5/20. */ public class Demo { public static void main(String[] args) { BasePhone oppo = new OPPO("OPPO"); //装微信 oppo.addSofas(new WeChat("微信")); //装QQ oppo.addSofas(new QQ("QQ")); //展示装好的软件 oppo.showSofas(); } }
总结
优点
1、抽象和实现的分离。 2、优秀的扩展能力。 3、实现细节对客户透明。
缺点
桥接模式的引入会增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程。
适用场景
1、如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。 2、对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。 3、一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。