结构型-桥接(Bridge)

2020-10-23  本文已影响0人  DoneWillianm

桥接(Bridge)

[TOC]

定义

桥梁模式(Bridge Pattern)也叫做桥接模式,是一个比较简单的模式,其定义如下:Decouple an abstraction from its implementation so that the two can vary independently.(将抽象和实现解耦,使得两者可以独立地变化。

这话的核心在于如何去解耦,抽象者引用实现者,需要更换能力只用更换实现者即可,就好像是Android中ListView的Adapter一样,set进去的是由开发者实现的,如果想要更换逻辑,可以重新设置新的adapter即可,listView通过对adapter的抽象方法,开发者内聚自己的实现即可

要实现这样一个设计模式,需要如下几个步骤:

书上的解释给我的感觉很官方,有些晦涩,下面我来谈一谈我对这个桥接设计模式的理解

根据设计原则,在进行软件设计的时候,我们需要尽量不变动上层模块,减少上层对底层模块的耦合性,尽可能的内聚模块内的功能,弱耦合,高内聚的关系的结果其实就是对修改关闭,对扩展开放的原则,换成语言上的理解其实就是我们的业务流程,尽量直接使用抽象或者接口来完成业务工作,这样业务上层模块对底层业务实现的持有其实就是一个抽象类或者接口,那么当我们在扩展业务能力或者更换业务实现逻辑时候,就可以做到很少改动甚至不改动的情况就完成的软件的迭代和更新~

简单场景使用

老联盟了,搞一把基本英雄的创建作为背景

coding

先声明英雄单位的抽象类,需要名字,类型和技能

public abstract class AbsHero {

    private IHeroSkill mSkill;

    private String mName;

    private String mType;

    public AbsHero(IHeroSkill skill, String name) {
        mSkill = skill;
        mName = name;
        mType = genType();
    }

    protected abstract String genType();

    public void test() {
        System.out.println("开始测试英雄[" + mType + "-" + mName + "] 释放技能Q:" + mSkill.releaseSkill(IHeroSkill.CMD.Q) + ",释放技能W:" + mSkill.releaseSkill(IHeroSkill.CMD.W) + ",释放技能E:" + mSkill.releaseSkill(IHeroSkill.CMD.E) + ",释放技能R:" + mSkill.releaseSkill(IHeroSkill.CMD.R));
    }
}


public interface IHeroSkill {

    enum CMD {
        Q, W, E, R
    }
    String releaseSkill(CMD cmd);
}

实现老亚索的技能创建和英雄子类

public class HappyMan extends AbsHero {

    public HappyMan(IHeroSkill skill) {
        super(skill, "亚索");
    }

    @Override
    protected String genType() {
        return "AD";
    }
}

public class HappyManSkill implements IHeroSkill{

    @Override
    public String releaseSkill(CMD cmd) {
        switch (cmd){
            case E:
                return "快乐就完事,问好也追不上我~";
            case Q:
                return "哈撒ki~";
            case R:
                return "Holy ye kei duo~";
            case W:
                return "风墙~";
        }
        return "NOTHING";
    }
}

进行测试:

AbsHero happyMan = new HappyMan(new HappyManSkill());
happyMan.test();
//开始测试英雄[AD-亚索] 释放技能Q:哈撒ki~,释放技能W:风墙~,释放技能E:快乐就完事,问好也追不上我~,释放技能R:Holy ye kei duo~

可以看到我们的上层模块对英雄的持有是抽象的,对于技能的实现也是通过依赖注入的方式传递给了英雄中,然后直接调用测试~

接下来我们创建个新英雄狗头~

public class DogMan extends AbsHero {

    public DogMan(IHeroSkill skill) {
        super(skill, "狗头");
    }

    @Override
    protected String genType() {
        return "AD-AP";
    }
}

public class DogManSkill implements IHeroSkill {
    @Override
    public String releaseSkill(CMD cmd) {
        switch (cmd){
            case E:
                return "画个圈圈诅咒你~";
            case Q:
                return "专注发育叠被动~";
            case R:
                return "变大,增强自身属性";
            case W:
                return "恶心对面,降低对面双抗,减速~";
        }
        return "NOTHING";
    }
}

AbsHero happyMan = new HappyMan(new HappyManSkill());
happyMan.test();
AbsHero goutou = new DogMan(new DogManSkill());
goutou.test();

//开始测试英雄[AD-亚索] 释放技能Q:哈撒ki~,释放技能W:风墙~,释放技能E:快乐就完事,问好也追不上我~,释放技能R:Holy ye kei duo~
//开始测试英雄[AD-AP-狗头] 释放技能Q:专注发育叠被动~,释放技能W:恶心对面,降低对面双抗,减速~,释放技能E:画个圈圈诅咒你~,释放技能R:变大,增强自身属性

可以看到很方便我们就能创建第二英雄,并且技能可以随便配置,如果想要削弱某个英雄或者重做某个英雄的技能,直接更换已有的技能实现即可,我们的技能作为接口的方式给英雄来依赖,既不会侵入后期技能创建的迭代,也不会影响今后技能的生产,唯一可能带来的问题就可能是接口方法会发生改动,这样会直接导致实现者要发生变化,其实就算如此也不必慌,这是语言特性所导致,我们完全可以通过一个抽象类来实现这个接口,默认其他的技能创建者也都通过继承这个抽象类即可,这样就避免了今后就算接口改动导致其他子类需要改动的成本~

特点

这里还是把书里总结的贴来哈~

使用场景

总结

桥梁模式是非常简单的,使用该模式时主要考虑如何拆分抽象和实现,并不是一涉及继承就要考虑使用该模式,那还要继承干什么呢?桥梁模式的意图还是对变化的封装,尽量把可能变化的因素封装到最细、最小的逻辑单元中,避免风险扩散。因此读者在进行系统设计时,发现类的继承有N层时,可以考虑使用桥梁模式。`认为是系统中最容易重现变化的环节以接口的方式进行依赖,粒度越细越好,粒度的把握参阅上述

上一篇 下一篇

猜你喜欢

热点阅读