【转自】itpub http://tech.it168.com/a2009/0727/612/000000612707.shtml
开闭原则是设计原则基础的基础,其它原则均围绕开闭原则进行展开。开闭原则也就是一个软件实体应当对扩展开放,但对修改关闭。满足了开闭原则的设计,我们的系统将达到在设计稳定的基础上,方便的对软件进行扩展,插入新的功能模块的目的。
怎么样做的开闭原则呢?抽象化是关键,也是我们经常听到的“面象接口编程”,具体一点就是声明的变量的类型、函数的参数类型、函数的返回类型等要尽量使用抽象类和接口。开闭原则实际也是“对可变性的封装原则”,那就是“考虑你的设计中什么可能发生变化,找到一个系统的可变因素,将它封装起来”。把变化封闭起来也就是我们经常用到的继承,编写一个抽象类用子类来继承他,或者编写一个接口让子类去实现他。继承固然很好,既封装了变化又实现了复用,但却不能滥用,也就是说应当把继承仅仅当做封装变化的方法,而不应当被认为是从一般的对象生成特殊的对象。就如我们为了复用一个类里面的函数,便用另一个毫不相干的类来继承此类,这样的继承真可谓不伦不类。更糟糕一些那便是为复用而复用,编写一个抽象类去继承一个毫不相干的另一个抽象类(这样做可能是想复用此类中封装的变化),这样便把多于一种的可变性混合在了一起,混合的结果便是最终让我们思维混乱。
开头我们说开闭原则是设计原则基础的基础,因为其它的设计原则可以作为实现开闭原则的手段和工具。
1、里氏代换原则:任何基类可以出现的地方,子类一定可以出现。
我们知道,实现开闭原则的关键是抽象化,而里氏代换原则中的基类和子类的继承关系正是抽象化的具体体现,所以里氏代换原则是对实现抽象化的具体步骤的规范。违反里氏代换原则一个最经典的例子便是把正方形设计成长方形的子类。
2、依赖倒转原则:要依赖于抽象,不要依赖于实现。说的白一点就是要依赖于抽象类和接口不要依赖具体类,具体类也就是我们可以用new关键字实例化的类。依赖倒转原则是实现开闭原则的一个手段。
3、合成/聚合复用原则:要尽量使用合成/聚合,而不是继承关系达到复用的目的。就如我们前面说的,如果为了复用,便使用继承的方式将两个不相干的类联系在一起,这样的方式是违反合成/聚合复用原则的,更进一步的后果那便是违反里氏代换原则。合成/聚合复用和里氏代换原则相辅相成,合成/聚合复用原则要求我们在复用时首先考虑合成/聚合关系,而里氏代换原则是要求我们在使用继承时,必须满足一定的条件。
4、接口隔离原则:应当为客户端提供尽可能小的单独接口,而不要提供大的总接口。
5、迪米特法则:一个软件实体应当尽可能少的与其他实体发生相互作用。
一个和其它实体关系很少的实体,在系统扩展时受的影响就会很小。当然接口隔离原则也是同样的道理,小的单独的接口,在系统扩展时受到的影响也会很小,所不同的是,迪米特法则(广义迪米特)限制的是相互作用的深度和广度,而接口隔离原则限制的只是相互作用的广度
在网上看到“板桥里人”的一篇文章《你还在用ifelse吗?》他在最后总结里说:“将ifelse用在小地方还可以,如简单的数值判断。但是如果按照你的传统习惯思维,在实现业务功能时也使用ifelse,那么说明你的思维可能需要重塑,你的编程经验越丰富,传统过程思维模式就容易根深蒂固,想靠自己改变很困难;建议接受专业头脑风暴训练。”此文通篇是如何用设计模式来替换ifelse语句的说词,不知道他这种极端的为了设计模式而设计模式的做法,是不是被他所谓的“头脑风暴”给刮疯癫所导致的。我也说一下我极端的想法,如果一个极端到没有任何可扩展性要求的系统,用面向对象的语言开发面向过程的程序,并无不可,面向对象里面的类只不过是我们分类存放函数的一个容器,其他别无用处,如果这时你还要写一大堆的接口和抽象类来显摆你所了解的设计模式,这简直就是强 奸了设计模式,因为设计模式是为方便的扩展系统而生的,并不是让你拿来显摆的。关于各种对“将条件转移语句改写成为多态性”的代码重构做法的看法,我更倾向阎宏的的看法。
上而讲的“将条件转移语句改写成为多态性”的代码重构的做法有两大缺点。
第一大缺点,任何语言都提供条件转移功能,如果抛弃语言本身的一些功能,那么语言存在的价值又能体现在哪里呢?难道一个面向对象的语言,面向对象的特性就是这个语言的全部吗?条件转移本身并不是错误的,也不是什么罪恶,他更不是某些人眼里面向过程语言向面向对象语言过渡时一个权宜的保留。如果需要,设计师完全可以选择使用条件转移ifelse,并且不需要去接受什么头脑风暴的摧残。
第二大缺点,使用多态性代替条件转移意味着大量的类被创建出来。比如一个类如果有三个方法,每个方法都有一个三段的条件转移语句,如果将它们都用多态性代替的话,就会造出九个不同的类。很难想象设计师怎么能明白这九种组合成员之间的关系。
那么何时需要用多态性取代条件转移语句呢?
应当从“开闭”原则出发来做判断。如果一个条件转移语句确实封装了某种业务逻辑的可变性,那么将此种可变性封装起来就符合“开闭”原则的设计思想。但是,如果一个条件转移语句没有涉及重要的业务逻辑,或者不会随着时间的变化而变化,也不意味着任何的可扩展性,那么它就没有涉及任何有意义的可变性。这时候将这个条件转移语句改写成为多态性就是一种没有意义的浪费。阎宏将这种对多态性的滥用叫做“多态性污染”。如果再滥用一些设计模式,估计就应该叫“设计模式污染”了。
分享到:
相关推荐
设计模式6大原则:开闭原则
开闭原则是面向对象设计中的一个核心原则,它在JAVA设计模式中占据着重要的地位。这一原则由格里·贝斯提出,旨在指导开发者如何设计可维护和可扩展的软件系统。开闭原则(Open-Closed Principle,OCP)的核心思想是...
开闭原则(Open-Closed Principle,简称OCP)是面向对象设计中的一个核心原则,它在软件工程领域具有举足轻重的地位。该原则由 Bertrand Meyer 在其著作《Object-Oriented Software Construction》中提出,旨在提高...
开闭原则是面向对象设计的核心原则之一,它的全称是"对扩展开放,对修改关闭",即在软件设计过程中,我们希望系统能够容易地添加新功能,同时保持原有代码的稳定性,避免频繁修改。这一原则由 Bertrand Meyer 在他的...
JAVA开闭原则是一种重要的软件设计思想,其核心理念在于提高软件系统的灵活性、稳定性和可维护性。开闭原则强调“对扩展开放,对修改关闭”,即在设计阶段应该确保软件模块能够在不修改原有代码的基础上,通过扩展的...
读书笔记:设计原则开闭原则
开闭原则是面向对象设计中的一个基本原则,它由软件工程专家 Bertrand Meyer 在其著作《Object-Oriented Software Construction》中提出。这个原则的核心思想是“对扩展开放,对修改关闭”。简单来说,就是模块应该...
在软件开发中,开闭原则是面向对象设计中最基础的设计原则之一,它指导我们如何建立稳定灵活的系统。开闭原则定义:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。然而,开闭原则仅仅告诉我们对扩展开放...
Closed Principle,简称OCP)是面向对象设计中的一个核心原则,它由Bertrand Meyer在1988年提出,并被收录在SOLID(单一职责原则、开闭原则、里氏替换原则、接口隔离原则、依赖倒置原则)这五大设计原则之中。...
开闭原则(Open-Closed Principle,OCP)是软件工程中的一个基本原则,由Bertrand Meyer在1988年提出,它是面向对象设计的核心之一。这个原则规定了软件实体(如类、模块、函数等)应该对扩展开放,对修改关闭。这...
面向对象设计原则:面向对象设计原则、开闭原则、里氏替换原则、里氏替换原则、里氏替换原则
例如,在 Sunny 软件公司开发的 CRM 系统中,为了支持多种图表显示方式,我们可以使用抽象化的方式来重构系统,使之符合开闭原则。在重构后,系统可以增加新的图表类时无须修改源代码,满足开闭原则。 在实际开发中...
开闭原则是面向对象设计中的一个基本原则,它主张软件实体(包括类、模块、函数等)应当对扩展开放,对修改关闭。这意味着在不改变原有代码的基础上,可以通过增加新的功能来适应需求的变化,从而提高软件的可维护性...
开闭原则是面向对象设计中的一个核心原则,它要求软件实体(例如类、模块、函数等)应该设计成对扩展开放,对修改关闭。这个原则由Bertrand Meyer在1988年提出,旨在确保软件系统能够更容易地应对需求的变化,从而...
#### 1.2.2 面向对象设计原则之开闭原则 开闭原则(Open-Closed Principle, OCP)主张软件实体(类、模块、函数等)应该是对扩展开放的,而对修改关闭的。这意味着当需求发生变化时,可以通过增加新的代码来满足新...
面向对象设计原则概述 单一职责 开闭原则 里氏代换原则 依赖倒转原则 接口隔离原则 合成复用原则 迪米特法则
开闭原则(Open-Closed Principle,简称OCP)是软件设计模式中的一个基本原则,由艾兹格·迪米特里斯·伯纳斯-李提出。这个原则指出,软件实体(类、模块、函数等)应当对扩展开放,对修改关闭。换句话说,当软件...
开闭原则是面向对象设计的基本原则之一,由格里·贝迪奇在其著作《设计模式:可复用面向对象软件的基础》中提出。这个原则主张软件实体(类、模块、函数等)应当对扩展开放,对修改关闭。简单来说,就是在不修改原有...
本文将深入探讨“开放封闭原则”这一核心设计原则,并结合C#语言环境进行解析。 开放封闭原则(Open-Closed Principle,OCP)由Bertrand Meyer在1988年提出,是面向对象设计的五大原则(SOLID)之一。该原则规定,...