设计模式-六大设计原则

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)

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

【实例】

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

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

  • 通过中介会避免过于耦合的关系,但是中介多了又会增加复杂性,降低模块之间的通信效率;
相关推荐
晨米酱17 小时前
JavaScript 中"对象即函数"设计模式
前端·设计模式
数据智能老司机1 天前
精通 Python 设计模式——分布式系统模式
python·设计模式·架构
数据智能老司机1 天前
精通 Python 设计模式——并发与异步模式
python·设计模式·编程语言
数据智能老司机1 天前
精通 Python 设计模式——测试模式
python·设计模式·架构
数据智能老司机1 天前
精通 Python 设计模式——性能模式
python·设计模式·架构
使一颗心免于哀伤1 天前
《设计模式之禅》笔记摘录 - 21.状态模式
笔记·设计模式
数据智能老司机2 天前
精通 Python 设计模式——创建型设计模式
python·设计模式·架构
数据智能老司机2 天前
精通 Python 设计模式——SOLID 原则
python·设计模式·架构
烛阴2 天前
【TS 设计模式完全指南】懒加载、缓存与权限控制:代理模式在 TypeScript 中的三大妙用
javascript·设计模式·typescript
李广坤2 天前
工厂模式
设计模式