首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

面向对象设计准则笔记

2012-09-23 
面向对象设计原则笔记开闭原则(Open/Closed Principle)核心观点:对扩展开放、对修改封闭。软件实体(类、模块、

面向对象设计原则笔记
开闭原则(Open/Closed Principle)

核心观点:对扩展开放、对修改封闭。
软件实体(类、模块、函数等)应该是可扩展的,但不可修改。模块的行为可以扩展,但不必改变模块的代码。(可增加新类,但不应修改已经存在的代码)。


对扩展开放、对修改关闭,不意味着不做任何修改,低层模块的变更,必然要有高层模块进行耦合,否则就是一个孤立的无意义的代码片段。

实现开闭原则的关键是抽象。通过接口或抽象类可以约束一组可能变化的行为,并能够实现对扩展开放:
1.通过接口或抽象类约束扩展,对扩展进行边界限定,不允许出现在接口或抽象类中不存在的public方法。
2.参数类型、应用对象尽量使用接口或者抽象类,而不是实现类。
3.抽象层尽量保持稳定,一旦确定即不允许修改。

单一职责 SRP (Single Responsibility Principle)

把职责定义为“变化的原因”(a reason for change),如果有多于一个的动机去改变一个类,这个类就具有多于一个的职责。一个类中承担的职责过多,就等于把这些职责耦合在了一起,一个职责的变化可能会削弱或抑制这个类完成其他职责的能力。


设计接口的时候一定要做到单一职责,类的设计尽量做到单一职责。生搬硬套单一职责会引起类的剧增,过分细分类的职责也会人为增加系统复杂性。
单一职责适用于接口、类,也适用于方法,一个方法尽可能只做一件事。

里氏替换原则

子类与父类的关系必须是is-A,只要父类出现的地方子类就能够出现。类A出现的所有地方换成类B,则程序的行为没有发生变化,则称类B是类A的子类.

?

OOD中的is-A关系是就行为方式而言的。子类型的正确定义是“可替换的”。正是子类的可替换性才使得使用基类类型的模块在无需修改的情况下就可以扩展。

如正方形类并不是矩形的子类,因为他们的setWidth()行为不同,正方形的setWidth()方法还会影响height的值。此时若将正方形视作矩形,先设置宽、再设置高,然后求面积,得到的是错误的结果。应该抽出公共方法,让正方形类和矩形类成为兄弟类。

在类中调用其他类时务必使用父类或接口,否则说明类的设计违背了LSP原则。


派生类必须能够接受基类可以接受的一切(范围要大,前置条件的约束更弱);派生类的行为方式和输出不能违反基类已经确立的任何限制(范围要小,后置条件的约束更强)。(约束的强弱是指遵从父类约束的强度,与子类新约束的数目无关)。(重载和覆盖都适用,同名方法)

如果一组类都支持一个公共的职责,那么它们应该从一个公共的超类继承该职责。如果公共的超类还不存在,那么就创建一个,并把公共职责放入其中。

完成的功能少于其基类的派生类通常是不能替换其基类的,因此就违反了LSP。建议采用依赖、聚集、组合等关系替代继承关系。
在派生类中存在退化函数(覆盖父类函数,但什么也不做)并不总是违反了LSP,但值得注意。

依赖倒置原则(Dependence Inversion Principle,DIP)

精简的定义就是——面向接口编程。
??? 本质是通过抽象使各个模块的实现彼此独立。

?

1.高层模块(原子逻辑的组装)不应依赖低层模块(不可分割的原子逻辑),两者都应该依赖其抽象
2.抽象(java中就是接口或抽象类)不应该依赖于细节(java中就是实现类)
3.细节应该依赖于抽象

?


应用:
1.每个类尽量有接口或抽象类,或两者兼备
2.变量的表面类型尽量是接口或抽象类
3.任何类都不应该从具体类派生(开发阶段,不是绝对,不超过两层的继承可以忍受)
4.尽量不要覆盖基类的方法(不是指实现)
5.结合里氏替换原则,接口负责定义方法,声明与其他类的依赖关系,抽象类负责公共构造部分的实现,实现类实现业务逻辑

倒置不仅仅是依赖关系的倒置,也是接口所有权的倒置。类的客户拥有类的抽象接口,服务者从接口派生。

接口隔离原则

接口种类:
1.实例接口:java中的类也是一种接口
2.类接口:java中的interface


客户端不应该依赖它不需要的接口,需要什么就提供什么,把不需要的除掉。
建立单一接口,不要建立臃肿庞大的接口。
设计是有限度的,不能无限考虑未来的变更情况。

根据接口隔离原则拆分接口时,必须满足单一职责原则。
接口要高内聚:
??? 提高处理能力,减少对外交互。要求在接口中尽量少公布public方法,接口是对外的承诺,承诺越少对系统的开发越有利,变更的风险也就越少。

如果一个客户程序依赖于一个含有它不使用的方法的类,但是其他客户程序却要使用该方法,那么当其他客户要求这个类改变时,就会影响到这个客户程序。
根据经验和常识决定接口的粒度大小,粒度太小,接口数量剧增;粒度太大,灵活性降低,无法提供定制服务。

迪米特法则

也称最少知识原则:一个对象应该对其他对象有最少的了解。一个类对需要耦合或调用的类知道得最少,只关心提供的方法。

迪米特法则的核心观念就是类间解耦,弱耦合,提高类的复用率。结果就是产生了大量的中转或跳转类,导致系统复杂性提高。


含义:

1.只和朋友交流
朋友类:出现在成员变量、方法的输入输出参数中的类称为成员朋友类,出现在方法体内部的类不属于朋友类。
一个方法尽量不引入一个类中不存在的对象(JDK 提供的API除外)

?

2.朋友间是有距离的
一个类公开的public属性或方法越多,修改时涉及的面也就越大,变更引起的风险扩散也越大。为了保持朋友类之间的距离,设计时要反复衡量:是否可以减少public方法和属性、是否可修改为private、protected或包默认、是否可加上final关键字等。

?

3.是自己的就是自己的
当遇到可放在多个类中的方法时,如果此方法放在本类中,既不增加类间关系,也不对本类产生负面影响,就放置在本类中。


热点排行