设计模式-六大设计原则

1、单一职责原则(Single Responsibitity Principle)

一个类或者模块只负责完成一个职责;

【实例】

上面这个类,当此类只是用来展示用户信息,则设计符合单一职责;当此用户的地址经常需要使用,比如电商平台类的项目,则需要将地址信息分离出来才符合单一职责。

1.1 如何判断一个类是否违反单一职责

  • 类中代码行数、函数、属性过多
  • 类依赖的其他类过多(如果某个 service 类需要依赖多个不同功能的 service 类来完成一个复杂的业务逻辑,但自身的职责仍然是单一的,那么这也是符合单一职责原则的)
  • 私有方法过多
  • 类中的大量的方法总是操作类中的几个属性(这种时候这几个属性可能构成独立职责)

2、开闭原则(Open Close Principle)

软件当中的对象、类、模块和函数对扩展应当开放,对于修改应该封闭;

【实例】

系统A与系统B之间进行数据传输使用的是427版本的协议,一年以后对427版本的协议进行了修正;设计时应该考虑的数据传输协议的可变性,抽象出具有报文解译、编制、校验等所有版本协议使用的通用方法 ;

2.1 如何保证开闭原则的实现

需要培养顶层设计思维:

  • 抽象意识:要求我们在编写代码时尽量定义抽象(如接口或抽象类),而不是具体的实现;这使得我们能够在需要扩展功能时,通过实现新的具体类而不是修改已有类的方式来实现。
  • 封装意识:要求我们将变化的细节封装起来,通过稳定的接口对外提供服务。这样,当需要更改内部实现时,对外部使用者的影响最小。
  • 扩展意识:设计灵活的体系结构,使系统能够通过添加新代码来实现扩展,而不是修改现有代码。

3、里氏替换原则(Liskov Substitution Principle)

子类对象能够替换程序中父类对象出现的任何地方,并且保证原来程序的逻辑行为不变及正确性不被破坏。

【实例】

如在一个商城项目中, 定义结算接口Istrategy,该接口有三个具体实现类,分别为 PromotionalStrategy (满减活动,两百以上打八折)、RebateStrategy (打折活动)、 ReduceStrategy(返现活动)

结算接口与三个实现类:

java 复制代码
public interface Istrategy {
    public double realPrice(double consumePrice);
}

public class PromotionalStrategy implements Istrategy {
    public double realPrice(double consumePrice) {
        if (consumePrice > 200) {
            return 200 + (consumePrice - 200) * 0.8;
        } else {
            return consumePrice;
        }
    }
}
public class RebateStrategy implements Istrategy {
    private final double rate;
    public RebateStrategy() {
        this.rate = 0.8;
    }
    public double realPrice(double consumePrice) {
        return consumePrice * this.rate;
    }
}
public class ReduceStrategy implements Istrategy {
    public double realPrice(double consumePrice) {
        if (consumePrice >= 1000) {
            return consumePrice - 200;
        } else {
            return consumePrice;
        }
    }
}

调用方

java 复制代码
public class Context {
    //使用基类定义对象变量
    private Istrategy strategy;
    // 注入当前活动使用的具体对象
    public void setStrategy(Istrategy strategy) {
        this.strategy = strategy;
    }
    // 计算并返回费用
    public double cul(double consumePrice) {
        // 使用具体商品促销策略获得实际消费金额
        double realPrice = this.strategy.realPrice(consumePrice);
        // 格式化保留小数点后1位,即:精确到角
        BigDecimal bd = new BigDecimal(realPrice);
        bd = bd.setScale(1, BigDecimal.ROUND_DOWN);
        return bd.doubleValue();
    }
}

4、接口隔离原则(Interface Segregation Principle)

客户端不应该被迫依赖于他不使用的方法。 --《代码整洁之道》

要为各个类建立他们需要的专用接口,而不要试图去建立一个很庞大的接口供所有依赖它的类去调用;

【实例】

实现删除用户的功能遵照接口隔离原则,为依赖接口的类定制服务。只提供调用者需要的方法,屏蔽不需要的方法。

将删除接口单独放到另外 一个接口 RestrictedUserService 中, 然后将 RestrictedUserService 只打包提供给后台管理系统来使用。

5、依赖倒置原则(Dependence Inversion Principle)

高层模块不应该依赖于底层模块,二者都应该依赖于抽象;抽象不应该依赖于细节,细节应该依赖于抽象。

【实例】

假设需要组装一台电脑,需要cpu、硬盘、内存等,具体的配置有多种品牌的选择;

这样设计电脑就可以随意搭配不同品牌配置,使得代码更加灵活;

6、迪米特法则(Law Of Demter)

一个类(模块)对其他的类(模块)有越少的了解越好;

【实例】

如明星与经纪人、粉丝之间的关系

明星不需要对粉丝有过多了解,他们之间的互动通过经纪人来运行;

  • 通过中介会避免过于耦合的关系,但是中介多了又会增加复杂性,降低模块之间的通信效率;
相关推荐
bigbread10 小时前
策略模式 + 工厂方法模式在项目中的实战应用
设计模式
高晶11 小时前
C 语言实现 BMS 系统中 SPI 通信协议实战指南
设计模式·程序员
代钦塔拉11 小时前
【C++/Qt 进阶】设计模式系列(2):工厂模式——从游戏角色到披萨店
c++·算法·设计模式
高晶12 小时前
2A3 单端甲类功放从零制作全攻略:电路设计、焊接调试到煲机维护一站式指南
前端·设计模式
代钦塔拉15 小时前
【C++/Qt 进阶】设计模式系列(4):原型模式——用“克隆“代替“重新构造“
c++·qt·设计模式
博风17 小时前
11、设计模式应用举例:迭代器模式:使用多个集合存储对象
设计模式·迭代器模式
日和雫1 天前
面向对象与面向过程,谁才是“银弹”?
设计模式
geovindu2 天前
rust: Iterator Pattern
开发语言·后端·设计模式·rust·行为模式·迭代器模
高晶2 天前
ARM 嵌入式 Linux 系统启动流程实战指南
设计模式·程序员
高晶2 天前
BMS 通信开发实战:从 PMBus 协议到数据采集的完整指南
设计模式·程序员