Design Pattern - 7原则

简介:

很多程序员用面向对象语言写了多年的代码, 仍然不知道设计模式为何物, 这不奇怪, 设计模式并不是非有不可,可是它能让代码变的更美好。 
程序员大可闷头堆代码, 复制粘贴, 然后不断的感慨代码难以维护, 难以复用, 难以扩展, 而继续不思进取。 
当然也可以选折不断去追求更美好, 更合理的代码, 把自己从bug调试, 需求变动等噩梦中拯救出来, 进而真正体会到编码的乐趣。 
你如果选折后者那么设计模式对于你而言, 是真正必不可少的, 只有当你真正认真考虑过代码的复用性,扩展性,和合理性时, 你才能真正体会到设计模式的好处。

想知道一样东西的价值, 最好的方法就是想想, 如果没有它, 你会怎么样. 
对于学习模式, 也是一样, 不要拘泥于其中, 要多想想为什么需要它. 如果没有这种模式, 一样是很好的code, 那就说明这个模式在这种情况下没有价值, 那就不要去用他. 
如果使用了一种模式, 能使你的code从可扩展性, 可维护性和可复用性上有些提高, 那么这个就是他的价值所在.

下面是面向对象设计的7大原则,是学习编程和模式的基础

单一职责原则 (SRP)

一个类,只有一个引起它变化的原因。应该只有一个职责。如果一个类有一个以上的职责,这些职责就耦合在了一起。这会导致脆弱的设计。当一个职责发生变化时,可能会影响其它的职责. 这严重影响了代码的可维护性, 可复用性.

 

开闭原则(OCP)

开闭原则是面向对象设计中“可复用设计”的基石,是面向对象设计中最重要的原则之一,其它很多的设计原则都是实现开闭原则的一种手段。1988 年,Bertrand Meyer在他的著作《Object Oriented Software Construction》中提出了开闭原则,它的原文是这样:“Software entities should be open for extension,but closed for modification”。翻译过来就是:“软件实体应当对扩展开放,对修改关闭”。一句好说不好做的话......

 

依赖倒置原则(DIP)

依赖倒置原则(Dependence Inversion Principle)就是要依赖于抽象,不要依赖于具体。简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合。 
A.高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象。 
B.抽象不应该依赖于具体,具体应该依赖于抽象。 
依赖倒置原则的本质就是通过抽象(接口或者抽象类)使各个类或模型的实现彼此独立,不互相影响,实现模块间的松耦合。

 

接口隔离原则(ISP)

接口是我们设计时对外提供的契约,通过分散定义多个接口,可以预防未来变更的扩散,提高系统的灵活性和可维护性。 
要求在接口中尽量少公布public方法,而不是建立一个庞大的臃肿的接口,容纳所有的客户端访问。 
接口是对外的承诺,承诺地越少对系统开发越有利,变更的风险也就越少,同时也有利于降低成本。

 

迪米特法则(LoD,LKP)

迪米特法则(Law of Demeter,LoD)也称为最少知识原则(Least Knowledge Principle,LKP), 迪米特法则的核心观念就是类间解耦,弱耦合. 一个类应该对自己需要耦合或调用的类知道得最少,你(被耦合或调用的类)的内部是如何复杂都和我没关系,那是你的事情,我就知道你提供的public方 法,我就调用这么多,其他的一概不关心。 
设计模式的门面模式(Facade)和中介模式(Mediator),都是迪米特法则应用的例子。

 

里氏替换原则 (LSP)

Liskov 于1987年提出了一个关于继承的原则“Inheritance should ensure that any property proved about supertype objects also holds for subtype objects.”——“继承必须确保超类所拥有的性质在子类中仍然成立。”也就是说,当一个子类的实例应该能够替换任何其超类的实例时,它们之间才具有 is-A关系。 该原则称为Liskov Substitution Principle——里氏替换原则。 
继承是个耦合性很强的关系, 所以不能随便轻率的使用继承关系, 如果子类并不能完全替换父类的话, 应该使用聚集, 组合来代替继承. 
举个例子, 鸟-->企鹅, 可是企鹅不会飞, 无法实现fly函数, 这样的继承关系就违反了里氏替换原则.

 

合成/聚合复用原则(CARP)

合成/聚合复用原则(Composite/Aggregate Reuse Principle)的核心思想就是:要尽量使用合成/聚合,不要滥用继承.

说到这, 先来谈谈Aggregation(聚合关系)和Composition(组合关系) 
Aggregation(聚合关系), 一种弱的'拥有'关系, 比如人群和人, 就是一般的list和list item, 即表示集合和个体的关系, 用空心的菱形表示 
Composition(组合关系), 一种强的'拥有'关系, 比如人和腿, 它们具有相同的生命周期, 即表示整体和部分的关系, 用实心的菱形表示 
一般遇到的都是聚合关系, 组合关系只是聚合关系的一个特例. 组合模式(Composite)也是基于聚合关系来讨论的(虽然叫Composite模式).

继承作为面向对象的基础, 非常强大和重要, 但是滥用继承也会带来很多问题, 所以我们要明确区分"Is-A"和"Has-A"关系. 
"Is-A"是严格的分类学意义上定义,意思是一个类是另一个类的"一种"。而"Has-A"则不同,它表示某一个角色具有某一项责任。导致错误的使用继承而不是合成/聚合的一个常见的原因是错误的把"Has-A"当作"Is-A"。所以只有真正存在"Is-A"关系时, 我们才考虑使用继承, 否则尽量使用合成/聚合. 
滥用继承会有如下问题, 
1. 对象的继承关系时编译时就定义死的,无法运行时改变从父类继承的实现, 缺乏灵活性 
2. 子类和父类是紧耦合的,存在紧密的依赖关系, 父类的任何变化必然会导致子类的变化. 
3. 子类复用的问题, 当继承下来的实现不适合新的问题时, 必须要修改父类. 
4. 当然滥用继承, 会导致继承层次迅速膨胀, 成为不可控制的庞然大物.


本文章摘自博客园,原文发布日期: 2013-02-05

目录
相关文章
|
7月前
|
设计模式 安全 Java
【设计模式】JAVA Design Patterns——Curiously Recurring Template Pattern(奇异递归模板模式)
该文介绍了一种C++的编程技巧——奇异递归模板模式(CRTP),旨在让派生组件能继承基本组件的特定功能。通过示例展示了如何创建一个`Fighter`接口和`MmaFighter`类,其中`MmaFighter`及其子类如`MmaBantamweightFighter`和`MmaHeavyweightFighter`强制类型安全,确保相同重量级的拳手之间才能进行比赛。这种设计避免了不同重量级拳手间的错误匹配,编译时会报错。CRTP适用于处理类型冲突、参数化类方法和限制方法只对相同类型实例生效的情况。
【设计模式】JAVA Design Patterns——Curiously Recurring Template Pattern(奇异递归模板模式)
|
设计模式 安全 Java
设计模式|从Visitor Pattern说到Pattern Matching
在软件开发领域,我们每次遇到的问题可能都各不相同,有些是跟电商业务相关的,有些是跟底层数据结构相关的,而有些则可能重点在性能优化上。然而不管怎么样,我们在代码层面上解决问题的方法都有一定的共性。有没有人总结过这些共性呢?
设计模式|从Visitor Pattern说到Pattern Matching
|
移动开发 PHP 设计模式
|
索引
设计模式---合成模式(DesignPattern_Composite)
摘录自:设计模式与游戏完美开发 十年磨一剑,作者将设计模式理论巧妙地融入到实践中,以一个游戏的完整实现呈现设计模式的应用及经验的传承 《轩辕剑》之父——蔡明宏、资深游戏制作人——李佳泽、Product Evangelist at Unity T...
762 0