1--单一职责原则
顾名思义 一个类只承担一个功能,这样可以减少功能耦合,
仔细想想,如果一个类承担了多个功能,当某个功能发生变化,可能会导致类的其他功能受影响,单一职责原则使得各功能之间互不影响,降低开发过程中出现不必要的风险
2--里氏替换原则
子类可以拓展父类功能,但是不能修改父类原有的功能
子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。
当子类的方法重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。
当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。
(加上个人理解补充:父类尽量写抽象方法,让子类去具体实现,这样会更加灵活,提高代码的重用性)
3--依赖倒置原则
定义:
1.高层模块不应该依赖低层模块,两者都应该依赖其抽象
2.细节应该依赖抽象,而抽象不应该依赖细节
如下面例子,有一个需求,要定义功能不同的打印机,都有打印功能,但颜色等细节功能是不同的,一般的方法是这样定义的
Public class 打印机(){
Public void 打印(){}
}
Public cliass 黑色打印机 extends 打印机(){
Public vlid 打印(){打印黑色}
}
Public cliass 彩色色打印机 extends 打印机(){
Public vlid 打印(){打印彩色}
}
最后Main方法中根据不同需求掉用不同颜色打印机的打印方法,
If(需要黑色){
New 黑色打印机(). 打印黑色();
}
If(需要的是彩色){
New 彩色打印机(). 打印彩色();
}......
当打印机的颜色增多时,就意味着要实例化大量的不同类对象,这样会很不方便
采用下面的方式会发现有很大的优点
各种颜色打印机依赖于接口(抽象)而不是依赖于颜色(细节)
public interface Box {//抽象接口
public abstract void doPrint();
}
public class BlackCartridge implements Box{//黑色打印机实现接口
public void doPrint (){
System.out.println("黑色墨盒执行喷墨打印");
}
}
public class ColorCartridge implements Box{//彩色打印机实现接口
public void doPrint (){
System.out.println("彩色墨盒执行喷墨打印");
}
}
public class Printer {//中间转化类,这个很重要(通过他来调用具体打印机)
public void print(Box box){
box.doPrint ();
}
}
public class PrinterStart {
public static void main(String[] args) {
Printer printer= new Printer();
printer.print(new BlackCartridge());
}
}
于是乎就发现原来实现不同的打印机,需要实例化不同的类,现在通过printer 这一中间类可以通过传入不同的打印机参数就可以实现不同的打印机颜色需求了。
4--接口隔离原则
接口隔离原则(Interface Segregation Principle ISP):客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上
定义:
1.使用多个专门的接口比使用单一的总接口要好
2.一个类对另外一个类的依赖性应当是建立在最小的接口上的
3.一个接口代表一个角色,不应当将不同的角色都交给一个接口。没有关系的接口合并在一起,形成一个臃肿的大接口,这是对角色和接口的污染
4.不应该强迫客户依赖于它们不用的方法。接口属于客户,不属于它所在的类层次结构
问题由来:类A通过接口I依赖类B,类C通过接口I依赖类D,如果接口I对于类A和类B来说不是最小接口,则类B和类D必须去实现他们不需要的方法。
解决方案:将大接口I拆分为独立的几个小接口,类A和类C分别与他们需要的接口建立依赖关系。
5--开闭原则
开闭原则(Open Closed Principle OCP):一个软件实体如类、模块和函数应该对扩展开放,对修改关闭,此原则为设计模式的总纲。
定义:
1.对于扩展是开放的(Open for extension)。这意味着模块的行为是可以扩展的。当应用的需求改变时,我们可以对模块进行扩展,使其具有满足那些改变的新行为。
2.对于修改是关闭的(Closed for modification)。对模块行为进行扩展时,不必改动模块的源代码或者二进制代码。
问题由来:在软件的生命周期内,因为变化、升级和维护等原因需要对软件原有代码进行修改时,可能会给旧代码中引入错误,也可能会使我们不得不对整个功能进行重构,并且需要原有代码经过重新测试。
开闭原则的重要性:
开闭原则对测试的影响(开闭原则可是保持原有的测试代码仍然能够正常运行,我们只需要对扩展的代码进行测试就可以了)
开闭原则可以提高复用性(在面向对象的设计中,所有的逻辑都是从原子逻辑组合而来的,而不是在一个类中独立实现一个业务逻辑。只有这样代码才可以复用,粒度越小,被复用的可能性就越大)
开闭原则可以提高可维护性
面向对象开发的要求
实现方法:
实现开闭原则的关键就在于“抽象”。把系统的所有可能的行为抽象成一个抽象底层,这个抽象底层规定出所有的具体实现必须提供的方法的特征。作为系统设计的抽象层,要预见所有可能的扩展,从而使得在任何扩展情况下,系统的抽象底层不需修改;同时,由于可以从抽象底层导出一个或多个新的具体实现,可以改变系统的行为,因此系统设计对扩展是开放的。
关于系统可变的部分,还有一个更具体的对可变性封装原则(Principle of Encapsulation of Variation, EVP),它从软件工程实现的角度对开闭原则进行了进一步的解释。EVP要求在做系统设计的时候,对系统所有可能发生变化的部分进行评估和分类,每一个可变的因素都单独进行封装。
我们在实际开发过程的设计开始阶段,就要罗列出来系统所有可能的行为,并把这些行为加入到抽象底层,根本就是不可能的,这么去做也是不经济的。因此我们应该现实的接受修改拥抱变化,使我们的代码可以对扩展开放,对修改关闭。
666导航网 可以自由收藏管理个人常用网址的便捷上网工具