设计模式:七大原则
1.单一职责
解释:单一职责原则(SRP:Single responsibility principle)又称单一功能原则,面向对象五个基本原则(SOLID)之一。它规定一个类应该只有一个发生变化的原因。一个类,只有一个引起它变化的原因。应该只有一个职责。每一个职责都是变化的一个轴线,如果一个类有一个以上的职责,这些职责就耦合在了一起。这会导致脆弱的设计。当一个职责发生变化时,可能会影响其它的职责。另外,多个职责耦合在一起,会影响复用性。
人话:一个类(方法、框架)只负责干一件事情
2.开闭原则
解释:开闭原则规定“软件中的对象(类,模块,函数等等)应该对于扩展是开放的,但是对于修改是封闭的”,这意味着一个实体是允许在不改变它的源代码的前提下变更它的行为。
人话:对扩展新功能开放,对修改原有功能关闭。(达文西 要你命3000)
如果一个类,从始至终只有你一个人去编写,你可以随时随地去修改源代码,因为作者是你
如果一个类,不是你写的,就不能去修改别人的源代码了,而要符合开闭原则
3.接口隔离原则
解释:客户端不应该依赖它不需要的接口。一个类对另一个类的依赖应该建立在最小的接口上。
人话:使用多个专门的接口
反例:
public interface Animal { public void eat(); public void fly(); //违反接口隔离原则,不是所有动物都能飞 }
正例:
public interface Eatable { public void eat(); } public interface Flyable { public void fly(); }
4.依赖倒置原则
解释:依赖倒置原则是程序要依赖于抽象接口,不要依赖于具体实现。简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合。
人话:上层不能依赖下层,都应该依赖于抽象。(调用别的方法的,就是上层,被其他方法调用的,就是下层)
解耦过程:
5.迪米特法则
解释:一个软件实体应当尽可能少的与其他实体发生相互作用。每一个软件单位对其他的单位都只有最少的知识,而且局限于那些与本单位密切相关的软件单位。
人话:1.只和朋友圈中的通信(适当违反一下也行) 2.知道的越少越好。
朋友圈:
类中的字段
方法的参数
方法的返回值
方法实例出来的对象
反例:
class Computer{ //电脑关机的步骤 public void saveData(){}//保存数据 public void killProcess(){}//杀死进程 public void closeScreen(){}//关屏幕 public void powerOff(){}//断电源 } class Person{ private Computer computer = new Computer(); //Person对于Computer关机的具体细节知道的太多了,代码复杂度太高,并且关机的步骤不能乱 //对于Person而言,只需按关机按钮就行了 public void shutdown(){ computer.saveData(); computer.killProcess(); computer.closeScreen(); computer.powerOff(); } }
正例:
class Computer{ //电脑关机的步骤 private void saveData(){}//保存数据 private void killProcess(){}//杀死进程 private void closeScreen(){}//关屏幕 private void powerOff(){}//断电源 public void shutdown(){ saveData(); killProcess(); closeScreen(); powerOff(); } } class Person{ private Computer computer = new Computer(); public void shutdown(){ computer.shutdown(); } }
6.里氏替换原则
解释: 里氏替换原则中说,任何基类可以出现的地方,子类一定可以出现。 LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。
人话:任何能使用父类对象的地方,都能替换为子类。
继承的原则:(符合里氏替换原则)
子类中的方法的可见性必须等于或者大于超类中的方法的可见性
子类中的方法所抛出的受检异常只能是超类中对应方法所抛出的受检异常的子类
7.组合优于继承
解释:在系统中应尽量多使用对象间的关联关系,尽量少使用甚至不使用继承关系来达到复用已有对象的目的
人话:组合优于继承
继承使用时机:父类和子类是同一个作者,放开手脚去继承
不是同一个作者,就别继承。
组合优于继承的反例:java 1.0开始的一个类Stack
为了强行复用一些代码,Stack继承了Vector,导致Stack具有一些栈没有的特性(例如可以直接remove指定索引的元素,这不是一个存粹的栈)