每日学习一种设计模式
概述
软件设计的目标:
同时提高一个软件系统的可复用性,可拓展性,易维护性和灵活性
进行软件设计时候,要考虑封装,继承,多态把程序耦合度降低,要考虑使用一些设计模式;
类与类之间的关系
a. 关联
是对象之间的一种引用关系,用于表示一类对象与另一类对象之间的联系
b. 聚合
关联关系的一种,属于强关联,是整体与部分之间的关系;
但是成员对象依然可以脱离整体对象而存在
c. 组合
是一种更强烈的聚合关系;
整体对象可以控制部分对象的生命周期
d. 依赖
是一种使用关系;对象之间耦合度最弱的一种关系;
某个类的方法通过局部变量,方法参数或者对静态方法的调用来访问一个类;
e. 继承
对象之间耦合度最大的一种关系,是父类与子类之间的关系;
f. 实现
是接口与实现类之间的关系
软件设计原则
a.单一职责原则
Single Responsibility Principle,SRP
一个类只负责一个功能领域中的相应职责,而就一个类而言,应该只有一个引起他变化的原因;
软件系统中,一个类(大到模块,小到方法)承担的职责越多,可复用性就越小,而且一个类承担的职责过多,这些职责就会耦合在一起,一个职责变化时,会影响其它职责的运作;
所以:
不同职责应该封装在不同的类;
多个职责总是同时发生变化则可将它们封装在一个类中
单一职责原则是实现高内聚,低耦合的指导方针;
b.开闭原则
Open-Closed Principle OCP
一个软件应当对拓展开放,对修改关闭;
软件实体应在不修改原有代码情况下进行拓展
最初编写代码时,假设变化不会发生。当发生变化时,我们就创建抽象来隔离以后发生的同类变化;
也就是说,对程序的改动是通过增加新代码进行的,而不是更改现有的代码;
从现实角度看,为了满足开闭原则,需要对系统进行抽象化设计,定义一个相对稳定的抽象层,将不同的实现行为转至具体的实现层中完成;
c.里氏替换原则
所有引用父类的地方必须能透明地使用其子类的对象
也就是说,在软件中,把一个基类对象替换成它的子类对象,程序将不会产生任何错误和异常,反过来不成立;
里氏替换原则是实现开闭原则的重要方式之一;
在程序中应该尽量使用基类对象对对象进行定义,运行时再确定其子类类型,正式子类的可替换性,才是的使用基类型的模块在无需修改情况下就能拓展;
注意两个问题
1.用基类定义对象时,如果一方法只存在于子类中,是无法用基类定义的对象进行调用的;
2.尽量把基类设计为抽象类或者接口,让子类继承或者实现,并复习基类中声明的方法,运行时用子类实例替换基类的实例
d.依赖倒转原则
Dependency Incersion Principle
抽象不应依赖于细节,细节应依赖于抽象;
就是要针对接口编程,而不是针对实现编程
依赖倒转原则 要求我们在程序代码中传递参数时,尽量引用层次高的抽象层,就是用接口和抽象类进行变量类型声明,参数类型声明,方法返回类声明,以及数据类型的转换,而不是用具体实现类做这些事
一个具体类应该只实现接口或者抽象类中声明过的方法,而不要给出多余的方法,否则将无法调用到在子类中增加的新方法;
程序中尽量使用抽象层进行编程,系统行为发生变化,只需要对抽象层进行拓展,写相应的实体类;
将具体类对象通过依赖注入的方法注入到其他对象中,依赖注入是指当一个对象要与其他对象发生依赖关系时,通过抽象来注入所依赖的对象;
1.构造函数注入
2.Setter注入
3.接口注入
大多数情况下,开闭原则,里氏替换原则和依赖倒转原则会同时出现;
三者是目标,基础,手段的关系
相辅相成
e.接口隔离原则
Interface Segregation Principle
使用多个专门的接口,而不是使用单一的接口
接口提供的功能要尽量单一
f.合成复用原则
Composite/Aggegate Reuse Principle
又称为组合/聚合原则
就是尽量使用对象组合,聚合,而不是继承达到复用的目的
这种方式属于黑箱复用,耦合度相对较低;
g.迪米特法则
Law of Demeter
又称为最小知识原则,一个实体应当尽可能少地与其他实体发生相互作用
应用迪米特法则,就是一个对象只能与直接朋友发生交互,不予”陌生人”交互;