设计模式笔记
设计模式
我们在进行软件开发时,不仅仅需要将最基本的业务给完成,还要考虑整个项目的可维护性和可复用性,我们开发的项目不单单需要我们自己来维护,同时也需要其他的开发者一起来进行共同维护,因此我们在编写代码时,应该尽可能的规范。如果我们在编写代码时不注重这些问题,整个团队项目就像一座屎山,随着项目的不断扩大,整体结构只会越来越遭。
甚至到最后你会发现,我们的程序居然是稳定运行在BUG之上的...
所以,为了尽可能避免这种情况的发生,我们就来聊聊面向对象设计原则
原则
单一职责原则
一个对象应该只包含单一的职责,并且该职责被完整地封装在一个类中。
我们将类的粒度进行更近一步的划分,这样就很清晰了,包括我们以后在设计Mapper、Service、Controller等等,根据不同的业务进行划分,都可以采用单一职责原则,以它作为我们实现高内聚低耦合的指导方针。实际上我们的微服务也是参考了单一职责原则,每个微服务只应担负一个职责。
开闭原则
软件实体应当对扩展开放,对修改关闭
里氏替换原则
简单的说就是,子类可以扩展父类的功能,但不能改变父类原有的功能:
- 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。
- 子类可以增加自己特有的方法。
- 当子类的方法重载父类的方法时,方法的前置条件(即方法的输入/入参)要比父类方法的输入参数更宽松。
- 当子类的方法实现父类的方法时(重写/重载或实现抽象方法),方法的后置条件(即方法的输出/返回值)要比父类更严格或与父类一样。
依赖倒转原则
依赖倒转原则(Dependence Inversion Principle)也是我们一直在使用的,最明显的就是我们的Spring框架了。
高层模块不应依赖于底层模块,它们都应该依赖抽象。抽象不应依赖于细节,细节应该依赖于抽象。
接口隔离原则
客户端不应依赖那些它不需要的接口。
必须要对其进行更细粒度的划分:
合成复用原则
优先使用对象组合,而不是通过继承来达到复用的目的。
迪米特法则
迪米特法则(Law of Demeter)又称最少知识原则,是对程序内部数据交互的限制。
总结
- 单一职责原则(Single Responsibility Principle, SRP):
- 一个类应该只有一个引起它变化的原因。这意味着类应该只负责一项任务或者功能。
- 在设计模式中,这个原则鼓励开发者将功能划分为更小的类,以提高模块化和可维护性。
- 开闭原则(Open/Closed Principle, OCP):
- 软件实体应该对扩展开放,对修改关闭。这意味着设计时应该允许在不修改现有代码的情况下增加新功能。
- 设计模式如工厂模式、策略模式等,通过使用接口或抽象类来实现这一点。
- 里氏替换原则(Liskov Substitution Principle, LSP):
- 子类型必须能够替换它们的父类型而不影响程序的正确性。这要求子类能够完全继承父类的行为。
- 这个原则在设计模式中确保了继承关系的合理性和子类的可替代性。
- 依赖倒置原则(Dependency Inversion Principle, DIP):
- 高层模块不应依赖低层模块,两者都应该依赖于抽象。抽象不应依赖于细节,细节应依赖于抽象。
- 这个原则在设计模式中通过依赖注入(DI)来实现,它允许系统更加灵活和可测试。
- 接口隔离原则(Interface Segregation Principle, ISP):
- 不应该强迫客户依赖于它们不使用的方法。接口应该尽可能小且特定。
- 设计模式如适配器模式和桥接模式可以帮助实现这个原则,通过提供更小的、特定的接口来满足不同的客户端需求。
- 合成复用原则(Composite Reuse Principle, CRP):
- 尽量使用对象的组合/聚合来实现代码复用,而不是通过继承。
- 这个原则在设计模式如装饰者模式和组合模式中得到了应用,它们通过组合对象来增加功能,而不是通过继承。
- 迪米特法则(Law of Demeter, LoD):
- 一个对象应该对其他对象有最少的了解。只与直接的朋友通信。
- 这个原则有助于减少对象之间的耦合,使系统更加模块化。在设计模式中,可以通过使用中介者模式来实现这一点。
创造型
工厂方法模式
首当其冲的是最简单的一种设计模式——工厂方法模式,我们知道,如果需要创建一个对象,那么最简单的方式就是直接new一个即可。而工厂方法模式代替了传统的直接new的形式,那么为什么要替代传统的new形式呢?
简单工厂包含如下角色:
- 抽象产品 :定义了产品的规范,描述了产品的主要特性和功能。
- 具体产品 :实现或者继承抽象产品的子类
- 具体工厂 :提供了创建产品的方法,调用者通过该方法来获取产品。
抽象工厂模式
不过这种模式只适用于简单对象,当我们需要生产许多个产品族的时候,这种模式就有点乏力了,比如:
- 抽象工厂(Abstract Factory):提供了创建产品的接口,它包含多个创建产品的方法,可以创建多个不同等级的产品。
- 具体工厂(Concrete Factory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。
- 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
- 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它 同具体工厂之间是多对一的关系。