概述
原则一:开闭原则(总纲和核心)
开闭原则规定软件中的对象(类、模块、函数等)对扩展开放,对修改封闭。也就是说针对需求的修改,我们要用扩展来实现,而不是通过修改已有代码来实现。
为了方便大家理解,我用王者荣耀来举例,王者荣耀中这么多英雄,如果把所有英雄都集中在一个类中来实现那是不现实的。你想想每次增加新英雄或者修改英雄的属性都要修改这一个类,那程序员还不疯了!时间长了,里面的逻辑之复杂,功能之紊乱真会要人命的。因此英雄联盟每次增加新英雄都会扩展增加一个新英雄类,这个新英雄类当然是继承“抽象英雄类”,然后实现里面的方法来定制自己的属性和功能。这就是对扩展开放,而修改关闭。
优点
(1).方便测试。我们只能以新增加的类进行测试,而不需要管其他的类。
(2).提高复用性。我们把功能拆分成一个一个小功能,是方便我们重复使用的。
(3).提高可维护性。想一下:如果有需求增加或者修改,你是希望重新扩展个类重新写呢?还是阅读别人的代码修改逻辑?
(4).符合面向对象的开发要求。
原则二:单一职责原则
“不要让类太累!”。单一职责原则规定一个类只有一个职责。如果有多个职责(功能)被设计在一个类中,这个类就违反了单一职责原则。其实这不难理解,生活中我们也是这样:专门人做专业事,即使放到公司和国家中也是这样。都会分好几个部门来处理不同的事情,不可能一个部门处理公司所有事情。
优点
(1).类的复杂性降低了,各个类都有明确清晰的职责。
(2).类的可读性提高了,我就见过这么一个同事,把好多的逻辑处理都放在一个方法中完成,看着那好几百行的方法,我真想打死他。
(3).可维护性提高了,类的功能简单了,可读性高了,自然可维护性就提高了。
虽然理论说起来简单,但是和业务结合起来这个就不是太容易了,所以要结合业务来权衡,对于这个原则,我建议是接口一定要做到单一职责,类的设计尽量做到只有一个原因引起变化。
原则三:里氏替换原则
这个原则比较难理解,下面我会花费很大篇幅来讲解这个原则。
里氏替换原则是针对继承中出现的问题进行规范,它要求:任何基类可以出现的地方,子类一定可以出现。通俗点讲:子类可以扩展父类的功能,可以实现父类抽象方法,但不能改变父类原有的功能或者非抽象方法。
子类可以扩展父类的功能我们可以理解,就是说子类可以添加父类没有的功能。但是子类不能改变父类原有的功能能或者非抽象方法如何理解呢?
我们先想想加入子类更改的父类原有的功能会出现什么问题。我们举例说明:
假设长方形类:
public class Rectangle{
setWidth(int width){
this.width=width;
}
setHeight(int height){
this.height=height
}
}
我们知道,正方形属于长方形,所以正方形应该继承长方形,注意继承的时候:正方形不能更改父类原有的功能,如果改了,那正方形就不再属于长方形了。因为它违背了:任何基类可以出现的地方,子类一定可以出现。
正方形类:
public class Square extends Rectangle{
setWidth(int width){
this.width=width;
this. height=width;
}
setHeight(int height){
this.setWidth(height);
}
}
这个正方形已经将继承来的setWidth方法和setHeight方法更改了,这就坏了,我们来使用一下你就看明白了。
//重新设置尺寸
public void resize(Rectangle r){
if(r.getHeight()<=r.getWidth){
r.setHeight(r.getWidth+1);
}
}
看的出当我们重新设置尺寸的时候,把Rectangle 的对象传进去 和 Square 传进去,运行的效果是不一致的,这也就违背了“任何基类可以出现的地方,子类一定可以出现”的原则。
相信说到这里大家能明白了吧。
具体在使用这个原则的时候有以下几点要求:
-
子类必须实现父类的抽象方法,但不得重写(覆盖)父类的非抽象(已实现)方法。
-
子类中可以增加自己特有的方法。
-
当子类覆盖或实现父类的方法时,方法形参要比父类方法的形参更宽松。
-
当子类的方法实现父类的抽象方法时,方法的返回值要比父类更严格。
下面我着重来讲解一下第三条:当子类覆盖或实现父类的方法时,方法形参要比父类方法的形参更宽松。
父类一个方法func(HashMap map); 子类方法func(Map map);
父类实例fu,子类实例zi,里氏替换原则要求fu.func(HashMap或子类) 必须和zi.func(HashMap或子类) 调用的是同一方法,试想如果子类方法func参数范围比父类的窄的话,zi.func就会优先调用子类的方法,这样就违背了里氏替换原则的基本定义了。
第四条也是同样的道理,如果子类方法的返回值要比父类更宽松的话,那么会优先调用子类的方法,这样也就违背了里氏替换原则的基本定义了。
好了,就先分享到这里,关注我,java学习不头秃,还为每位粉丝准备了一份全面的资料福利,从面试简历模板到大厂面经汇总,从大厂内部技术资料到互联网高薪必读书单,以及Java面试核心知识点(283页)和Java面试题合集2022年最新版(485页)等等,有需要的可以点下方名片领取
最后
以上就是笨笨水壶为你收集整理的设计模式7大原则——开闭&单一职责&里氏替换的全部内容,希望文章能够帮你解决设计模式7大原则——开闭&单一职责&里氏替换所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复