设计模式概述

107 阅读4分钟

思维导图

概述

设计模式是面向对象开发语言中,遇到的种种场景和问题,然后提出的思路和解决方案,最后沉淀下来,就成了设计模式

设计模式其实就是解决问题的思路,就是套路,学习设计模式,能够快捷优雅的解决面向对象程序开发设计问题。

设计模式不是万能的,任何一种设计模式都是解决一类问题的,而且通常在解决一类问题时,还会带来新的问题。我们需要扬长避短

创建型设计模式

关注对象的创建,怎么new一个对象

注,简单工厂不属于23种设计模式,但是在开发中用的很多

结构型设计模式

关注类与类之间的关系,就是折腾组合、继承,为程序提供更好的灵活性和扩展性。组合优于继承

行为型设计模式

关注对象和行为的分离,即行为(方法)放到哪个类里面,内容更细腻,套路更多(是个大家族)

设计模式6大原则

把这六个原则的首字母联合起来(两个 L 算做一个)就是 SOLID,其代表的含义就是这六个原则结合使用的好处:建立稳定、灵活、健壮的设计

单一职责原则

Single Responsibility Principle:单一职责原则

一个类应该只有一个发生变化的原因。单一职责原则适用于类、接口、方法

事实上,由于一些其他的因素影响,类的单一职责在项目中是很难保证的。通常,接口和方法的单一职责更容易实现。

比如我们需要一个数据库helper类,在项目中用到了redis、mysql两种数据库,那我们应该写两个数据库helper,而不是写一个通用的helper类,在类中判断是redis、mysql来执行不同的逻辑,这样就违背了单一职责原则。

开闭原则

Open Closed Principle:开闭原则

一个软件实体,如类、模块和函数应该对扩展开放,对修改关闭

当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现。因为可能会给旧代码引入错误,也有可能会对整个功能进行重构,并且需要原有代码经过重新测试

用抽象构建架构,用实现扩展细节

只要抽象的合理,可以基本保证架构的稳定。当软件需要发生变化时,我们只需要根据需求重新派生一个实现类来扩展就可以了

里氏替换原则

Liskov Substitution Principle:里氏替换原则

所有引用基类的地方必须能透明地使用其子类的对象。即所有基类在的地方,都可以换成子类,程序还可以正常运行

迪米特法则

Law of Demeter:迪米特法则

只与你的直接朋友交谈,不跟“陌生人”说话

如果两个软件实体无须直接通信,那么就不应当发生直接的相互调用,可以通过第三方转发该调用。其目的是降低类之间的耦合度,提高模块的相对独立性。

比如两个微服务之间,一个认证微服务,一个业务数据微服务,当业务数据微服务变化时,我们需要通知用户,通知功能写在认证微服务中,加入两个微服务下载一个解决方案文件夹下,可以相互调用,那么我们也不要去直接调用。我们需要发布一个集成事件,通过第三方的事件总线,认证微服务来监听这个事件并进行处理。

接口隔离原则

注:这是广义的接口,指接口、抽象类等

Interface Segregation Principle:接口隔离原则

  1. 客户端不应该依赖它不需要的接口
  2. 类间的依赖关系应该建立在最小的接口上

依赖倒置原则

总结:程序设计时应该依赖于抽象,而不是依赖于细节

  1. 上层模块不应该依赖底层模块,它们都应该依赖于抽象。即依赖抽象,而不是依赖细节,也就是面向抽象编程
  2. 抽象不应该依赖于细节,细节应该依赖于抽象

比如在DI值,注册服务时应该注册接口形式的服务类型和具体的实现类型对应关系,而不是直接注册实现类型。同样,在类中注入我们需要的服务时,我们声明的也是接口类型,而不是实现类型

//创建一个对象的常规写法
Undead undead = new Undead();

//左边抽象:用接口
IRace undead = new Undead();

//右边抽象:用工厂方法
IRace undead = SimpleFactory.CreateRace();
public class SimpleFactory {
    public static IRace CreateRace() {
        return new Undead();
    }
}

总结

使用建议

设计模式的局限性:都是在以类为最小单位,无法深入到类内部。需要靠别的手段AOP