A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

面向对象设计七大原则
‎2011-8-24 16:16:16
“开—闭”原则
面向对象设计的基石是“开—闭”原则。 “开一闭”原则讲的是:一个软件实体应当对扩展开放,对修改关闭。这个规则说的是,在设计一个模块的时候,应当使这个模块可以在不被修改的前提下被扩展。从另外一个角度讲,就是所谓的“对可变性封装原则”。
“对可变性封装原则”意味着两点:
1. 一种可变性不应当散落在代码的很多角落里,而应当被封装到一个对象里面。同一种可变性的不同表象意味着同一个继承等级结构中的具体子类。
2. 一种可变性不应当与另一种可变性混合在一起。即类图的继承结构一般不应超过两层。做到“开—闭”原则不是一件容易的事,但是也有很多规律可循,这些规律同样也是设计原则,它们是实现开—闭原则的工具。
满足“开-闭”原则系统的优点:
1. 通过扩展已有的模块,提供新的行为,满足新需求,使得变化中的软件系统有一定的适应性和灵活性
2. 已有的软件模块,特别是最重要的抽象层模块不能再修改,这就使得变化中的模块有一定的稳定性和延续性.
怎样才能做到开闭原则?
1. 抽象化,为系统定义一个不再更改的抽象设计,这个设计预见 了所有可能的变化。满足了开闭原则的“闭”
2. 找到系统中变化的部分,把可变性封装起来。使用继承或者其他方式来封装变化,将变化封装在一个方法中或者一个类中。

里氏代换原则
里氏代换原则:即如果一个软件实体使用的是基类的话那么也一定适用于子类。也就是基类出现的地方,子类一定可以出现,替换后软件行为不会发生变化, 而且它根本不能识别出基类和子类对象的区别。但反过来的代换不成立。
里氏转换原则是继承复用的基础.只有当衍生类可以替换掉基类,软件功能不会受到影响的时候,基类才能被真正复用,而衍生类才能在基类的基础 上增加新的行为。
里氏转换原则是对开-闭原则的补充。违反了里氏原则,有就违反了开闭原则;反之不成立。
如果有两个具体类A和B之间的关系违反了里氏代换原则,可以在以下两种重构方案中选择一种:
1 创建一个新的抽象类C,作为两个具体类的超类,将A和B共同的行为移动到C中,从而解决A和B行为不完全一致的问题。
2 从B到A的继承关系改写为委派关系。
咋一看觉得这个怎么还是面向对象设计的原则呢?这个明明就是Java的语法规则。对,Java是提供了对里氏代换原则在语法上的支持。但是仅仅是语法上,在和现实世界的相符合程度上根本没有提供。所有常常会有不符合里氏代换原则的情况出现。
依赖倒转原则
依赖倒转原则讲的是:抽象不应该依赖于细节, 细节应该依赖于抽象。(高层模块不应该依赖于底层模块,两个都依赖于抽象)。即针对接口编程,不要针对实现编程。
针对接口编程的意思是,应当使用接口和抽象类进行变量的类型声明、参量的类型声明,方法的返还类型声明,以及数据类型的转换等。
不要针对实现编程的意思就是说,不应当使用具体类进行变量的类型声明、参量的类型声明,方法的返还类型声明,以及数据类型的转换等。
依赖倒转原则虽然强大,但却不易实现,因为依赖倒转的缘故,对象的创建很可能要使用对象工厂,以避免对具体类的直接引用,此原则的使用还会导致大量的类。维护这样的系统需要较好的面向对象的设计知识。此外,依赖倒转原则假定所有的具体类都是变化的,这也不总是正确的。有一些具体类可能是相当稳定、
不会发生变化的,消费这个具体类实例的客户端完全可以依赖于这个具体类。

接口隔离原则
接口隔离原则讲的是:使用多个专门的接口比使用单一的接口要好。一个类对另外一个类的依赖性应当是建立在最小的接口上的。
从客户的角度来说:如果客户端只需要某一些方法的话,那么就应当向客户端提供这些需要的方法,而不要提供不需要的方法。
提供接口意味着向客户端作出承诺,过多的承诺会给系统的维护造成不必要的负担。
合成、聚合复用原则
合成、聚合复用原则就是将一个已经有的对象纳入新对象中,使之成为新对象的一部分, 新对象可以调用引入的旧对象的方法和功能。这个原则有一个简短的描述:要尽量使用合成、聚合,尽量不要使用继承。
合成、聚合有如下好处:1. 新对象存取成分对象的唯一方法是通过成分对象的接口。2. 这种对象的复用是黑箱复用,因为成分对象的内部实现细节对于新的对象是看不见的。3. 这种复用支持包装。4. 新对象可以在运行的时候动态的引用于成分对象类型相同的对象。
继承复用的优势:1. 新的实现较为容易,因为超类的大部分功能可以通过继承关系自动进入子类。2. 修改或者扩展继承而来的实现比较容易。
继承复用的缺点:1. 继承复用破坏包装。将超类的实现细节暴露给子类。超类的内部细节常常对子类是透明的,白箱复用。2. 超类的实现发生了改变,子类的实现也不得不改变3. 超类继承而来的是静态的,不可能在运行时间内发生改变。因此没有足够的灵活性。
合成、聚合可以应用到任何环境中去,而继承只能应用到一些有限环境中去。导致错误的使用合成、聚合与继承的一个常见原因是错误的把“Has-a”关系当作“Is-a”关系。如果两个类是“Has-a”关系那么应使用合成、聚合,如果是“Is-a”关系那么可使用继承。

迪米特法则
迪米特法则说的是一个对象应该对其它对象有尽可能少的了解。即只与你直接的朋友通信,不要跟陌生人说话。如果需要和陌生人通话,而你的朋友与陌生人是朋友,那么可以将你对陌生人的调用由你的朋友转发,使得某人只知道朋友,不知道陌生人。换言之,某人会认为他所调用的是朋友的方法。以下条件称为朋友的条件:当前对象本身。以参量的形式传入到当前对象方法中的对象。当前对象的实例变量直接引用的对象。当前对象的实例变量如果是一个聚集,那么聚集中的元素也都是朋友。当前对象所创建的对象。任何一个对象,如果满足上面的条件之一,就是当前对象的朋友,否则就是陌生人。迪米特法则的主要用意是控制信息的过载,在将其运用到系统设计中应注意以下几点:在类的划分上,应当创建有弱耦合的类。类之间的耦合越弱,就越有利于复用。在类的结构设计上,每一个类都应当尽量降低成员的访问权限。一个类不应当public自己的属性,而应当提供取值和赋值的方法让外界间接访问自己的属性。在类的设计上,只要有可能,一个类应当设计成不变类。在对其它对象的引用上,一个类对其它对象的引用应该降到最低。

单一职责原则
就一个类而言,应该仅有一个引起他变化的原因。
如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力。这种耦合会导致脆弱的设计。当变化发生的时候,设计会遭受意想不到的破坏。
对设计而言,就是发现职责并把这些职责分离。

面向对象系统设计的步骤:
1 细化重组类
2 细化和实现类之间的关系,明确其可见性.
3 增加属性,指定属性的类型和可见性.
4 分配职责,定义执行每个职责的方法.
5 对消息驱动的系统,明确消息传递的方式.
6 利用设计模式进行局部设计.
7 画出详细的类图和时序图

评分

参与人数 1黑马币 +30 收起 理由
田建 + 30 不错不错!!

查看全部评分

2 个回复

倒序浏览
{:soso_e179:}  顶一个  收藏了
回复 使用道具 举报
顶一个,谢谢楼主。收藏了。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马