在开始学习编程的时候,也看见过设计模式有关的书,那时感觉不到设计模式的重要性,感觉不用照样可以实现相应的功能,随着学习的深入对设计模式有了更深入的认识。没有设计模式只能盖个小土房,而设计模式是要盖高楼大厦的。
一、单一职责原则(Single Responsibility Principle, SRP);
英文解释:There should never be more thanone reason for a class to change.通俗点说就是一个类只干一件事,很适合现在工业的分工细化等等;
在我们写代码的过程中肯定会有修改的地方,如果一个类集成很多种动作,那么我们修改起来就会很麻烦,这个时候就需要单一职责啦,一个类只负责一个职责,当需要添加或修改职责时,我只需要修改相应的职责类就行了,不需要关注其他的,这样我们就提高了代码的可维护性。
优点:1、类的复杂性降低,各司其职,互不干涉。
2、可读性提高,结构清晰。
3、和维护性提高,接口变更,只对相应的实现类有影响。
注意:单一职责这个“职责”在实际中并没有实际的定义,没有明确的边界定义。这就需要自己看情况而定啦,切记不可过分细化,这样不但没有得到想要的结果,反而增加了程序的复杂性。
二、里氏替换原则(Liskov Substitution Principle, LSP);
里氏替换原则是解决把继承中利最大化,弊最小化的问题。
继承有以下优点:1、代码共享,减少代码量,每个子类都拥有父类的属性和方法。
2、提高代码的重用。
3、子类类似父类,但又不同于父类,子类可以有自己的特色。
4、提高代码的扩展性。
5、提高产品的开放性。
缺点:1、继承是侵入性的,一旦继承了父类就必须接受父类的属性和方法。
2、降低代码的灵活性,子类在父类的基础之上,会受到父类的约束。
3、增强程序的耦合性,一旦父类的属性修改,子类必须进行相应的或者更大工作量的更改。
英文解释:If for each object o1 of type S there is an object o2of type T such for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substitued for o2 then S is a subtype of T.。所有引用基类的地方都必须透明的使用其子类的对象。
里氏替换原则四句话:
1、子类必须完全实现父类的方法。在类中调用其他类时务必要使用父类或者接口,如果不能使用父类或者接口,则说明类的设计已经违背了LSP原则。如果子类不能完整的实现父类的方法,或者父类的某些方法在子类中已经发生“畸变”,则建议断开父类继承关系,采用依赖、聚集、组合等关系替代继承。
2、子类可以有自己的个性。
3、覆盖或者实现父类的方法时,输入参数可以被放大。如果子类的前置条件较小,子类在没有覆盖父类的方法前提下,子类方法被执行了,这回引起业务逻辑的混乱。在实际中,父类一般是抽象类,而子类是实现类,传递一个这样的实现类,会扭曲父类的意图,引起意想不到的逻辑混乱。
4、覆盖或者实现父类的方法时输出的结果可以被缩小。
采用里氏替换原则的目的就是增强程序的健壮性,版本升级时可以保持非常好的兼容性。即使增加子类,原有的子类还可以继续运行,在实际项目中,每个子类对应不同的业务含义,使用父类作为参数,传递不同的子类完成不同的业务逻辑,相当完美。
三、依赖倒置原则(Dependence
Inversion Principle, DIP);
High level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions.
高层模块不应该依赖低层模块,两者都应该依赖抽象(接口和抽象类)。
抽象不应该依赖细节。
细节应该依赖抽象。
在Java中的表现为:模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系通过接口或者抽象类产生;抽象不依赖于实现类;实现类依赖抽象类或者接口;也就是面向接口的编程。
依赖倒置可以减少类间的耦合性,提高稳定性,降低并行开发的风险,提高代码的可维护性和扩展性。
通过上图可以得出,如果我们在增加汽车类的时候,只需要实现ICar接口就行,对其他的任何东西都不影响,这就增加了程序的健壮性。当周围环境变化时,其他的类任然能做到浑然不动。
依赖有三种写法:构造函数传递依赖对象;Setter方法传递依赖对象;接口声明依赖对象;
其本质就是通过抽象是各个类或者模块的实现彼此独立,不互相影响,实现模块间的松耦合,我们在项目中使用需要遵循如下规则:1、每个类尽量都有接口和抽象类,或者抽象类和接口两者都具备;
2、变量的表面类型尽量是接口或者抽象类;
3、任何类都不应该从具体类派生;
4、尽量不要覆写基类的方法;
5、结合里氏替换原则使用;