- 单一职责 SRP
- 开闭原则 OCP
- 里氏置换 LSP
- 接口隔离 ISP
- 依赖倒置 DIP
- 最少知识原则(迪米特法则 )LKP
- 组合/聚合复用原则 CRP
单一职责 S
- Single-Responsibility Principle:一个类,应该只专注于做一件事和仅有一个引起它变化的原因。
- 如果你发现有两个变化,就需要拆分这个类。就像一个人身兼数职,而这些事情相互关联不大,甚至有冲突,那他就无法很好的解决这些职责,应该分到不同的人身上去做才对。
- 正确的例子:比如Spring中Controller、Service、DAO,在不同的层专注不同的业务。
- 根据职责去拆分函数、类、包名、模块。
开闭原则 O
- Open Closed Principle:对扩展开放,对修改关闭。
- 衡量扩展性的重要标准。
- 扩展时是否需要修改已有类的代码,如果扩展时,仅新增类型,而不需要修改原有代码,那就是符合开闭原则的。
- 完美的开闭依赖反射、注解、系统配置(文件、注册表、数据库、内存)、透明代理等
简单的说也就是我们的业务扩展的时候只需要添加类继承就可以完美解决问题,而不是该原有的代码,下面借鉴一个例子进行说明:
以书店销售书籍为例
名称,价格,作者
有的同学能看到,价格是个int类型的,加入我们小说打折扣呢,难免会出现double类型的吧,那该怎么扩展呢
看上图我们发现,我们不用改原有的逻辑,只需要扩展一个子类,覆写一下方法就可以了。
里氏替换 L
- Liskov Substitution Principle:一个基类对象替换成它的子类对象,程序将不会产生任何错误和异常。换句话:使用基类对象引用的函数必须能够在不了解子类的条件下使用子类的对象。
- Barbara Liskov 在 1988 年提出了这一原则。
- 如果把基类替换成子类,程序逻辑和行为发生异常,那就说明抽象出现了问题。
根本原因是基类定下了契约,宽和高可以不等,并没有必然的强制关联关系,而正方形这个子类打破了这一点。导致了依赖基类Rectangle的部分逻辑出现了异常。
接口隔离 I
- Interface Segregation Principle:客户类不应被强迫依赖那些它们不需要的接口。
- 一个接口服务于多个客户端,不如将他们拆分成细粒度的,每个接口服务一个客户端。
- 解决接口污染、胖接口的问题。
依赖倒置D
- Dependency Inversion Principle:抽象(基类)不应当依赖于细节。要针对接口编程,不要针对实现编程。
- 当你发现某个类中出现访问具体类时使用if-else、switch case的时候就需要抽象了。
- 讲解分层概念、依赖注入。
假设我们做一个拷贝程序,需要抽象一下,如图:
迪米特法则 LKP
- Law Of Demeter,LoD,或者Least Knowledge Principle(最少知识原则).
- 一个对象应该对其他对象保持最少的了解.
- 具体点儿就是,对象应尽可能地避免调用由另一个方法返回的对象的方法。
- 现代面向对象程序设计语言通常使用 "." 作为访问标识,LoD 可以被简化为 "仅使用一个点(use only one dot)"。也就是说,代码 a.b.Method() 违反了 LoD,而 a.Method() 则符合 LoD。打个比方,人可以命令一条狗行走,但是不应该直接指挥狗的腿行走,应该由狗去指挥它的腿行走。
- 不用所有的成员都是public,用好访问修饰符,不要把自己的内脏暴露出来。
- 缺点:应用 Law of Demeter 可能会导致不得不在类中设计出很多用于中转的包装方法(Wrapper Method),这会提升类设计的复杂度,需要权衡。