设计模式之——桥接设计模式

来源:互联网 发布:软件测试水杯 编辑:程序博客网 时间:2024/05/16 00:43

正如JDBC中的DriveManager的设计一样,数据的连接类型有MySQL,Oracle,SQL...,我们从中抽象化其中连接的过程,具体实现交给具体的实现类,从而做到了抽象类与抽象方法解耦,方便子类的扩展,解决了子类扩展依赖继承的问题

举个现实中的例子,我们在吃面条的时候可以选择不同辣味的多种面条,其扩展的子类就非常多了,此时我们就可以采用桥接模式,将具体实现抽象化,然后通过其抽象层控制具体的实现。您比如:

辣的类型抽取出接口,定义辣的类型,并实现几种辣:

package com.zndroid.dm.BridgeModel.Style;/** * Created by luzhenyu on 2017/9/5. *//**吃面的时候辣椒放多少单独抽取出来,具体子类是什么辣子类决定,这是一个维度,它可能有很多的子类*/public interface IStyle {    String getStyle();}

package com.zndroid.dm.BridgeModel.Style.impl;import com.zndroid.dm.BridgeModel.Style.IStyle;/** * Created by luzhenyu on 2017/9/5. *//**重辣*/public class HotStyle implements IStyle {    @Override    public String getStyle() {        return "Hot Style";    }}
package com.zndroid.dm.BridgeModel.Style.impl;import com.zndroid.dm.BridgeModel.Style.IStyle;/** * Created by luzhenyu on 2017/9/5. *//**微辣*/public class LowStyle implements IStyle {    @Override    public String getStyle() {        return "Low Style";    }}
package com.zndroid.dm.BridgeModel.Style.impl;import com.zndroid.dm.BridgeModel.Style.IStyle;/** * Created by luzhenyu on 2017/9/5. *//**中辣*/public class MidStyle implements IStyle {    @Override    public String getStyle() {        return "Mid Style";    }}
package com.zndroid.dm.BridgeModel.Style.impl;import com.zndroid.dm.BridgeModel.Style.IStyle;/** * Created by luzhenyu on 2017/9/5. *//**不辣*/public class NoneStyle implements IStyle {    @Override    public String getStyle() {        return "None Style";    }}
面条也有很多种,我们抽象出面条种类的特性,并组合辣味
package com.zndroid.dm.BridgeModel.Noodle;import com.zndroid.dm.BridgeModel.Style.IStyle;/** * Created by luzhenyu on 2017/9/5. *//**抽象具体实现类,并包含辣椒的引用,因为面条的种类也有很多种,这是第二个维度*/public abstract class Noodle {    private IStyle style;    public abstract String getNoodleName();    public Noodle(IStyle style) {        this.style = style;    }    public String match() {       return  "a bowl of " + style.getStyle() + " : " + getNoodleName();//一碗什么辣味的什么类型的面条    }}
package com.zndroid.dm.BridgeModel.Noodle.impl;import com.zndroid.dm.BridgeModel.Noodle.Noodle;import com.zndroid.dm.BridgeModel.Style.IStyle;/** * Created by luzhenyu on 2017/9/5. *//**面条的具体实现,包含对辣味的引用*/public class BeefNoodle extends Noodle {    public BeefNoodle(IStyle style) {        super(style);    }    @Override    public String getNoodleName() {        return "Beef Noodle";    }}
package com.zndroid.dm.BridgeModel.Noodle.impl;import com.zndroid.dm.BridgeModel.Noodle.Noodle;import com.zndroid.dm.BridgeModel.Style.IStyle;/** * Created by luzhenyu on 2017/9/5. *//**面条的具体实现,包含对辣味的引用*/public class EggNoodle extends Noodle {    public EggNoodle(IStyle style) {        super(style);    }    @Override    public String getNoodleName() {        return "Egg Noodle";    }}
下面来看一下使用效果:

/**         * 桥接模式         * 在软件系统中,某些类型由于自身的逻辑,它具有两个或多个维度的变化,         * 那么如何应对这种“多维度的变化”?如何利用面向对象的技术来使得该类型能够轻松的沿着多个方向进行变化,而又不引入额外的复杂度?         * 这就要使用Bridge模式。而具体使用的方式,则是将抽象部分与他们的实现部分分离,使得它们都可以独立的变化。比如Java中的数据库JDBC的连接就是很好的例子。         * 桥接模式的意图是将抽象类与抽象方法的实现相互分离来实现解耦,以便二者可以相互独立地变化。         * 使用场景:         * 1.如果你不希望在抽象和实现部分采用固定的绑定关系,可以采用桥接模式,来把抽象和实现部分分开,然后在程序运行期间来动态的设置抽象部分需要用到的具体实现,还可以动态切换具体的实现。         * 2.如果出现抽象部分和实现部分都应该可以扩展的情况,可以采用桥接模式,让抽象部分和实现部分可以独立的变化,从而可以灵活的进行单独扩展,而不是搅在一起,扩展一边可以影响另一边。         * 3.如果希望实现部分的修改,不会对客户产生影响,可以采用桥接模式,客户是面向抽象的接口在运行,实现部分的修改,可以独立于抽象部分,也就不会对客户产生影响了,也可以说对客户是透明的。         * 4.如果采用继承的实现方案,会导致产生很多子类,对于这种情况,可以考虑采用桥接模式,分析功能变化的原因,看看是否能分离成不同的维度,然后通过桥接模式来分离他们,从而减少子类的数目。         * */        //-- 小二 来一碗不辣的鸡蛋面        //-- 来嘞~  客观您稍等~        Person p = new Person();        p.eatNoodle(new EggNoodle(new NoneStyle()));        log("----------------- 第一天 ----------------");        //-- 老板 今天想吃点重口的,来碗重辣的牛肉面        //-- 您先坐,马上来        Person p1 = new Person();        p1.eatNoodle(new BeefNoodle(new HotStyle()));        log("----------------- 第二天 ----------------");        //-- 上次太辣了,不过味道不错,今天少放点辣椒吧        //-- 好的,今天想吃什么面        //-- 还是鸡蛋面吧,微辣就行  呲呲呲~        //-- 好的  您坐,马上好~        Person p2 = new Person();        p2.eatNoodle(new EggNoodle(new LowStyle()));        log("----------------- 第三天 ----------------");        //-- 老板  还有其他面条吗?        //-- 马上就推出新的面条了,过两天欢迎品尝        //OtherNoodle extends Noodle  .....


输出结果:

[ ======================================== ]
    I eat a bowl of None Style : Egg Noodle
[ ----------------- 第一天 ---------------- ]
    I eat a bowl of Hot Style : Beef Noodle
[ ----------------- 第二天 ---------------- ]
    I eat a bowl of Low Style : Egg Noodle
[ ----------------- 第三天 ---------------- ]
[ ======================================== ]

【欢迎上码】

【微信公众号搜索 h2o2s2】