设计模式之桥接模式

来源:互联网 发布:asp.net 网页源码 编辑:程序博客网 时间:2024/05/16 09:25

1,为什么要使用桥接设计模式

我们先来说说在电脑硬件中的集成元件和独立元件之间的区别,先说说集成元件吧.

主机箱有一个叫主板的玩意,是用来插接各种不同的元件的,例如(声卡,显卡,硬盘等).然后协调这些元件进行工作.

其实最早电脑都是集成元件,也就是说主板上面不能进行插接更换元件,用的都是集成的显卡声卡等,耦合性是很高,如果用UML表示就是

总结一下这种设计模式有什么坏处:

a,如果我们去添加一种主板,例如微星的主板,那么就要单独为这种主板去创建微星主板集成显卡和微星主板集成声卡,再添加昂达主板的话与刚才所述一样,那么这个结构就会是一个庞然大物.

b,如果我们修改华硕主板类那么它下面的子类(华硕主板集成显卡和华硕主板集成声卡)都会受到影响.

那么有什么方法可以降低这样设计的耦合,这里我们得提一个设计原则叫做,合成/聚合设计原则,原意是我们优先考虑合成/聚合方式再考虑继承方式.那什么是合成/聚合呢

这里大雁与雁群就是聚合关系,翅膀和大雁的关系就是合成关系.聚合关系体现了一种弱的耦合关系,聚合类(雁群)不一定要拥有被聚合类(大雁)的对象.而合成关系则体现了一种较

强的耦合关系,合成类(大雁)一定要拥有被合成类(翅膀)的对象.

那么我们按照刚才的合成/聚合设计原则就可以解耦了.主板和元件之间就是一种聚合关系.

2,什么桥接设计模式

桥接设计模式就是利用合成/聚合设计原则,使抽象部分与实现部分分离,使它们都能够独立的变化.

就刚才的实例,抽象部分就是主板,而实现部分就是元件了.

3,怎么使用桥接设计模式

我们按照桥接设计模式修改后那么UML就如下

这样的设计模式分离了抽象部分与实现部分,其实也就是主板和元件的分离,使其添加主板或者声卡互不影响,而且不会是子类成倍扩张,修改主板类也不会影响到元件类,弥补了之前提到的a,b亮点的不足.而且还遵从了开放-封闭设计原则.

最后源代码如下:

主板.class

public abstract class 主板 {private 声卡 shengka = null;private 显卡 xianka = null;public void 装载声卡(声卡 yuanjian){shengka = yuanjian;}public void 装载显卡(显卡 yuanjian){xianka = yuanjian;}public void 运行声卡(){if(shengka == null){System.out.println("请先装载声卡.");return;}shengka.运行元件();}public void 运行显卡(){if(xianka == null){System.out.println("请先装载显卡.");return;}xianka.运行元件();}//由于具体的主板运行方式不一样,所以留给子类去实现public abstract void 运行主板();}

元件.class

public abstract class 元件 {public abstract void 运行元件();}

华硕主板.class

public class 华硕主板  extends 主板{@Overridepublic void 运行主板() {// TODO Auto-generated method stubSystem.out.print("在华硕主板上\n");this.运行声卡();this.运行显卡();}}

微星主板.class

public class 微星主板  extends 主板{@Overridepublic void 运行主板() {// TODO Auto-generated method stubSystem.out.print("在微星主板上\n");this.运行声卡();this.运行显卡();}}

声卡.class

public class 声卡 extends 元件{@Overridepublic void 运行元件() {// TODO Auto-generated method stubSystem.out.println("运行声卡");}}

显卡.class

public class 显卡 extends 元件{@Overridepublic void 运行元件() {// TODO Auto-generated method stubSystem.out.println("运行显卡");}}

Main.class

public class Main {public static void main(String [] args){主板 zhuban1 = new 华硕主板();zhuban1.装载声卡(new 声卡());zhuban1.装载显卡(new 显卡());zhuban1.运行主板();主板 zhuban2 = new 微星主板();zhuban2.装载声卡(new 声卡());zhuban2.装载显卡(new 显卡());zhuban2.运行主板();}}

最后输出:

在华硕主板上
运行声卡
运行显卡
在微星主板上
运行声卡
运行显卡