6. 单一职责——桥模式

“单一职责” 模式

  • 在软件组织的设计中,如果责任划分的不清晰,使用继承得到的结果往往是随着需求的变化,子类急剧膨胀,同时充斥着重复代码,这时候的关键是划清责任。
  • 典型模式:
    • Decorator
    • Bridge

一、代码示例

**背景:**假设现在有一款游戏,我们要在手机品牌M和手机品牌N上都可以玩该游戏,那么很容易就有如下的实现思路:

interface BrandGame {
    void run();
}

class BrandMGame implements Game {
    @Override
    public void run() {
        System.out.println("M手机运行游戏");
    }
}

class BrandNGame implements Game {
    @Override
    public void run() {
        System.out.println("N手机运行游戏");
    }
}

**需求变更一:**此时我们不仅要在手机中实现玩游戏的功能,还要实现通讯录的增删改查的功能,基于继承的思路,就会抽象出手机品牌基类,品牌M和品牌N继承自该类,M和N又有各自的子类,就有了下面的结构:

在这里插入图片描述

代码如下:

interface Brand {
    void run();
}

abstract class BrandM implements Brand {
    
}

abstract class BrandN implements Brand {

}

class BrandMGame extends BrandM {
    @Override
    public void run() {
        System.out.println("运行M品牌游戏");
    }
}

class BrandNGame extends BrandN {
    @Override
    public void run() {
        System.out.println("运行N品牌游戏");
    }
}

class BrandMAddressList extends BrandM {
    @Override
    public void run() {
        System.out.println("运行M品牌通信录");
    }
}

class BrandNAddressList extends BrandN {
    @Override
    public void run() {
        System.out.println("运行N品牌通信录");
    }
}

**需求变更二:**我们要添加MP3音乐播放器的功能,并且要添加一个手机品牌Q。此时我们按照上面的思路,需要新加6个类。如果有n个功能,m个品牌,我们需要维护的类就是m * n个。

分析:这种架构违反了单一职责原则,即品牌和功能是两个变化的方向,我们如果将其耦合到一起,会导致类的个数急剧增加,但是每个累的基本功能又一样,从而导致在发生修改的时候变得难以维护。

**解决办法:**将手机品牌和功能分离开来,使用如下的结构:

在这里插入图片描述

interface Software {
    void run();
}

class Game implements Software {
    @Override
    public void run() {
        System.out.println("运行游戏");
    }
}

class AddressList implements Software {
    @Override
    public void run() {
        System.out.println("运行通信录");
    }
}

abstract class Brand {
    protected Software software;
    public void setSoftware(Software software) {
        this.software = software;
    }

    public abstract void run();
}

class BrandM extends Brand {
    @Override
    public void run() {
        System.out.println("M品牌手机运行软件");
        software.run();
    }
}

class BrandN extends Brand {
    @Override
    public void run() {
        System.out.println("N品牌手机运行软件");
        software.run();
    }
}

在客户端调用的代码:

//客户端调用代码
class Client {
    public static void main(String[] args) {
        Software software;
        software = new Game();

        Brand bM = new BrandM();
        bM.setSoftware(software);
        bM.run();
        
        Brand bN = new BrandN();
        bN.setSoftware(software);
        bN.run();
    }
}

之后如果需要添加新的手机品牌或者新的功能,我们只需要添加两个类即可。

二、动机

​ 由于某些类型的固有实现逻辑,导致它们具有两个甚至多个变化的维度,多个变化的维度将使代码变得很难维护。

三、定义

​ 将抽象部分与实现部分分离,使它们都可以独立地变化。

​ 即:实现系统可能有多角度的分类,每一种分类都有可能变化,那么就把这种多角度分离出来让它们独立变化,减少它们之间的耦合。

四、结构

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值