SOLID 设计准则蕴含以下 5 种准则:
- 繁多职责准则(Single Responsibility Principle, SRP)
- 开闭准则(Open Closed Principle, OCP)
- 里式替换准则(Liskov Substitution Principle, LSP)
- 接口隔离准则(Interface Segregation Principle, ISP)
- 依赖反转准则(Dependency Inversion Principle, DIP)
繁多职责准则
了解
繁多职责准则的形容是,一个类或者模块只负责实现一个职责(或性能)。当然,繁多职责准则不止是能够针对于模块或类,对于很多粒度都有成果,如函数、类、接口、模块等等,模块通常由多个类组成。
职责能够指模块变动的起因,从这个角度了解,繁多职责准则示意不要存在超过一个导致模块变更的起因。
须要留神的是,不同的利用场景、不同阶段的需要背景、不同的业务层面,对同一个类的职责是否繁多,可能会有不同的断定后果。
长处
遵循繁多职责准则,将会有以下的长处:
- 进步代码的可维护性:职责越少,复杂度越低,可读性更好,可维护性就更高
- 升高代码变更的危险:职责越多,代码变更的可能性就越高,变更带来的危险也就越大
最佳实际
在理论开发中,呈现以下景象有可能违反了繁多职责准则:
- 模块的变量、属性或代码行数过多
- 模块的外部对外部依赖过多
- 模块的公有办法过多
- 难以给模块取一个正当的名称
- 模块的大部分操作只针对几个属性
如呈现上述情况,则须要判断是否对代码做职责拆散,以遵循繁多职责准则,最终应以进步内聚、升高耦合、保障代码的可维护性为主。
开闭准则
了解
开闭准则的形容是,软件实体(模块、类、办法等)应该“对扩大凋谢、对批改敞开”。
具体的解释就是,增加一个新的性能时,在已有代码根底上扩大代码(新增模块、类、办法等),而非批改已有代码(批改模块、类、办法等)。更宽松的了解是以最小的批改代码的代价来实现新性能的开发。
长处
遵循开闭准则,将会有以下的长处:
- 缩小测试范畴:批改的代码范畴越小,波及的测试范畴越小,未改变的测试代码仍能失常运行
- 升高保护老本:软件规模越大、寿命越长,则软件的保护老本越高
最佳实际
若要做到“对扩大开发、对批改敞开”,有以下几点须要留神:
- 时刻具备扩大意识、形象意识、封装意识,多花工夫设计代码构造,当时留好扩大点
- 大部分经典设计模式都是为了解决代码的扩展性问题而总结进去的,开闭准则是它们一个重要的评估根据
里式替换准则
了解
里式替换准则的形容是,子类对象可能替换程序中父类对象呈现的任何中央,并且保障原来程序的逻辑行为不变及正确性不被毁坏。
从代码实现上看,面向对象的多态和里式替换准则有点相似,然而它们的关注点不一样:里式替换准则是用来领导继承关系中子类该如何设计,子类的设计要保障在替换父类的时候,不扭转原有程序的逻辑以及不毁坏原有程序的正确性。
长处
遵循里式替换准则,将会有以下的长处:
- 实现有意义的继承:保障了父类的复用性,也升高了零碎出谬误的故障,避免误操作,同时也不会毁坏继承的机制
- 加强程序的健壮性:不同的子类能够实现不同的业务逻辑,即便减少子类也能放弃十分好的兼容性
最佳实际
通常,须要留神以下违反里式替换准则的代码:
- 子类违反父类申明要实现的性能,如将加法改成减法
- 子类违反父类对输出、输入、异样的约定,如同一状况抛出的异样不同等
- 子类违反父类正文中所列举的任何非凡申明
接口隔离准则
了解
接口隔离准则的形容是,接口的调用者或使用者不应该被强制依赖它不须要的接口。
通过对接口的了解不同,接口隔离准则有以下三种了解:
1、如果把“接口”了解成一组接口汇合,能够是某个微服务的接口,也能够是某个类库的接口等。如果存在局部接口只被局部调用者应用,就须要将这部分接口隔离进去,独自给这部分调用者应用,而不强制其余调用者也依赖其余不会用到的接口。
2、如果把“接口”了解成单个 API 接口或函数,局部调用者只须要其中的局部性能,则须要将这个函数拆分成更细粒度的多个函数,让调用者只依赖它须要的那个细粒度函数。
3、如果把“接口”了解成 OOP 中的接口,也能够了解成为面向对象编程语言中的接口语法,那接口的设计要尽量繁多,不要让接口的实现类和调用者依赖不须要的接口函数。
接口隔离准则和繁多职责准则有点相似,但接口隔离准则更侧重于接口的设计,通常是通过调用者如何应用接口来定义这个接口的设计是否足够职责繁多。
长处
遵循接口隔离准则,将会有以下的长处:
- 高内聚,低耦合:拆分成更小粒度的接口,缩小对外的交互,预防外来的变更,进步零碎的灵活性和可维护性
- 可读性高,易于保护:正当的接口拆分粒度能保证系统的稳定性,缩小我的项目工程的代码冗余
最佳实际
采纳接口隔离准则对接口进行束缚时,要留神以下几点:
- 接口尽量小,然而要有限度。定义过小,则会造成接口数量过多,使设计复杂化;定义多大,灵活性升高
- 每个我的项目和产品都有选定的环境因素,环境不同,接口拆分的规范就不同,深刻理解业务逻辑
依赖反转准则
了解
依赖反转准则也被叫作依赖倒置准则,其含意是:高层模块不要依赖底层模块,高层模块和底层模块应该通过形象来相互依赖;形象不要依赖具体实现细节,具体实现细节依赖形象。
Tomcat 是运行 Java Web 应用程序的容器,编写的 Web 利用程序代码只须要部署在 Tomcat 容器中下,便可被 Tomcat 容器调用执行。在这里,Tomcat 容器就是高层模块,Web 应用程序就是底层模块。Tomcat 容器和 Web 应用程序没有间接的依赖关系,而是通过 Servlet 标准实现相互依赖,而 Servlet 标准也不会依赖具体的实现细节,而是 Tomcat 和 Web 应用程序依赖 Servlet 标准。
管制反转
管制反转(Inversion Of Control, IoC)指的是将程序员本人对程序执行流程的管制反转成通过框架管制。管制反转并不是一种具体的设计技巧,而是一种抽象的设计思维,个别用来领导框架层面的设计。
实现管制反转次要有两种形式:依赖注入和依赖查找。两者的区别在于,前者是被动的接管对象,在类 A 的实例创立过程中即创立了依赖的 B 对象,通过类型或名称来判断将不同的对象注入到不同的属性中,而后者是被动索取相应类型的对象,取得依赖对象的工夫也能够在代码中自在管制。
依赖注入
依赖注入(Dependency Injection, DI)是一种具体的编码技巧。
其具体概括就是:不通过 new 的形式在类的外部创立依赖对象,而是将依赖的类对象在内部创立好之后,通过构造函数、函数参数等形式传递(或注入)给类应用。
一个简略的依赖注入代码例子如下:
package cn.fatedeity.designpattern.philosophy;
/**
* 依赖注入案例
*/
public class DependencyInjectionCase {
private MessageSender messageSender;
public DependencyInjectionCase(MessageSender messageSender) {this.messageSender = messageSender;}
public void sendMessage(String phone, String message) {this.messageSender.send(phone, message);
}
public static void main(String[] args) {MessageSender smsSender = new SmsSender();
DependencyInjectionCase dependencyInjectionCase0 = new DependencyInjectionCase(smsSender);
// SmsSender sms send sms message
dependencyInjectionCase0.sendMessage("sms", "sms message");
MessageSender inboxSender = new InboxSender();
DependencyInjectionCase dependencyInjectionCase1 = new DependencyInjectionCase(smsSender);
// SmsSender inbox send inbox message
dependencyInjectionCase1.sendMessage("inbox", "inbox message");
}
}
class InboxSender implements MessageSender {
@Override
public void send(String phone, String message) {System.out.println("InboxSender" + phone + "send"+ message);
}
}
class SmsSender implements MessageSender {
@Override
public void send(String phone, String message) {System.out.println("SmsSender" + phone + "send"+ message);
}
}
interface MessageSender {void send(String phone, String message);
}
长处
遵循依赖反转准则,将会有以下的长处:
- 查问依赖和利用代码拆散,大量升高工厂类和单例类的数量,代码档次更加清晰
- 没有侵入性,毋庸依赖容器的 API,也毋庸实现一些非凡接口
最佳实际
通过依赖注入提供的扩大点,简略配置一下所有须要的类及其类之间依赖关系,就能够实现由框架来主动创建对象、治理对象的生命周期、依赖注入等性能。
现成的依赖注入创立有很多,比方 Google Guide、Java Spring、Pico Container、Butterfly Container 等。