美文网首页
设计模式之桥接模式

设计模式之桥接模式

作者: 发现未知的自己 | 来源:发表于2022-04-30 20:47 被阅读0次

    1 定义

    桥接模式将抽象部分与它的实现部分分离,使它们可以独立地变化。或者也可以定义为:一个类存在两个(或多个)独立变化的维度,我们可以通过组合的方式,让这两个(或多个)维度可以独立进行扩展。

    2 类图

    桥接模式.png

    3 伪代码实现

    public abstract class Abstraction {
        protected Implementor implementor;
        
        public Abstraction(Implementor implementor) {
            this.implementor = implementor;
        }
        
        public abstract void operation();
    }
    
    public class RefinedAbstraction extends Abstraction {
        public void RefinedAbstraction(Implementor implementor) {
            super(implementor);
        }
        
        public void operation() {
            implementor.operationImpl();
        }
    }
    
    public interface Implementor {
        void operationImpl();
    }
    
    public class ConcreteImplementorA {
        public void operationImpl() {
            
        }
    }
    
    public class ConcreteImplementorB {
        public void operationImpl() {
            
        }
    }
    

    4 使用场景

    假设有两个手机品牌M和N,两个品牌都有游戏和通讯录,从面向对象的角度来设计,如果采用继承的方式,我们会做如下设计:

    c7661ca54385912394a7528aafe366fd.png

    (引自大话设计模式)

    3b91dbcc141f666276bd29fa1d555de9.png

    (引自大话设计模式)

    上面两种方式虽然采用了面向对象的设计方式,遵循了对修改关闭对扩展开放的设计原则,但是仔细想想,会出现什么问题?假设我们还有手机品牌H,I...,各类手机还有音乐软件、阅读软件等等其他软件,手机品牌和软件一组合,我们要编写的类就会出现指数级增长,这会导致系统越来越庞大,难以管理。

    在这种情况下,我们就可以使用桥接模式,将继承改成组合的方式,增加一个手机品牌,我们只需增加一个品牌子类即可,增加一个软件,我们也只需增加一个类就行,新的手机品牌和新的软件功能只要组合起来就行了。

    4.1 java代码

    public interface IHandsetSoft {
        void run();
    }
    
    public class HandsetGame implements IHandsetSoft {
        @Override
        public void run() {
            System.out.println("运行手机游戏");
        }
    }
    
    public class HandsetAddressList implements IHandsetSoft {
        @Override
        public void run() {
            System.out.println("运行手机通讯录");
        }
    }
    
    public abstract class HandsetBrand {
    
        protected IHandsetSoft handsetSoft;
    
        public HandsetBrand(IHandsetSoft handsetSoft) {
            this.handsetSoft = handsetSoft;
        }
    
        public abstract void run();
    }
    
    public class HandsetBrandM extends HandsetBrand {
        public HandsetBrandM(IHandsetSoft handsetSoft) {
            super(handsetSoft);
        }
    
        @Override
        public void run() {
            System.out.println("手机品牌M");
            handsetSoft.run();
        }
    }
    
    public class HandsetBrandN extends HandsetBrand {
        public HandsetBrandN(IHandsetSoft handsetSoft) {
            super(handsetSoft);
        }
    
        @Override
        public void run() {
            System.out.println("手机品牌N");
            handsetSoft.run();
        }
    }
    
    public class Client {
        public static void main(String[] args) {
            // 手机游戏
            IHandsetSoft handsetGame = new HandsetGame();
    
            // 手机通讯录
            IHandsetSoft handsetAddressList = new HandsetAddressList();
    
            // 在手机品牌M上运行手机游戏
            HandsetBrand handsetBrandM = new HandsetBrandM(handsetGame);
            handsetBrandM.run();
    
            // 在手机品牌M上运行手机通讯录
            handsetBrandM = new HandsetBrandM(handsetAddressList);
            handsetBrandM.run();
    
            // 在手机品牌N上运行手机游戏
            HandsetBrand handsetBrandN = new HandsetBrandN(handsetGame);
            handsetBrandN.run();
    
            // 在手机品牌N上运行手机通讯录
            handsetBrandN = new HandsetBrandN(handsetGame);
            handsetBrandN.run();
        }
    }
    

    采用继承的方式,是一种紧耦合的方式,可以做扩展,但是比较困难,采用组合的方式是一种松耦合的方式,可以进行轻松的扩展。继承是is-a的关系,如果是is-a的关系,适合使用继承,组合是has-a的关系,如果是has-a的关系,适合使用组合。比如上面是手机上有手机游戏和手机通讯录,所以用组合更合适。
    再比如红色长方形,绿色长方形,红色圆形,绿色圆形,可以理解为长方形或者原型具有红色或者绿色的属性,可以使用组合的方式。类图如下:

    微信图片_20220430202617.png

    (引自https://www.runoob.com/design-pattern/bridge-pattern.html)

    相关文章

      网友评论

          本文标题:设计模式之桥接模式

          本文链接:https://www.haomeiwen.com/subject/vvoyyrtx.html