一、 "开放-封闭"原则(OCP)

一、 "开放-封闭"原则(OCP),第1张

概述 软件腐化的原因:问题所在   设计目标----------------------------------------------------------------------------过于僵硬   可扩展性(新性能可以很容易加入系统)过于脆弱   灵活性(修改不会波及其它)复用率低  粘度过高   可插入性(新功能容易加入系统(气囊加入方向盘))* 提高系统可复用性的几点原则:传统复用:1. 代码的粘帖复用2. 算法的复用3. 数据结构的复用* 可维护性与可复用性并不完全一致* 对可维护性的支持:一、 "开放封闭"原则(OCP)Open-Closed Principle原则讲的是:一个软件实体应当对扩展开放,对修改关闭。优点:    通过扩展已有软件系统,可以提供新的行为,以满足对软件的新的需求,使变化中的软件有一定的适应性和灵活性。    已有软件模块,特别是最重要的抽象层模块不能再修改,这使变化中的软件系统有一定的稳定性和延续性。例子:玉帝招安美猴王当年大闹天宫便是美猴王对玉帝的新挑战。美猴王说:"'皇帝轮流做,明年到我家。'只教他搬出去,将天宫让于我!"对于这项挑战,太白金星给玉皇大帝提出的建议是:"降一道招安圣旨,宣上界来…,一则不劳师动众,二则收仙有道也。"换而言之,不劳师动众、不破坏天规便是"闭",收仙有道便是"开"。招安之道便是玉帝天庭的"开放-封闭"原则。 招安之法的关键便是不允许更改现有的天庭秩序,但允许将妖猴纳入现有秩序中,从而扩展了这一秩序。用面向对象的语言来讲,不允许更改的是系统的抽象层,而允许更改的是系统的实现层。二、 里氏代换原则(LSP)Liskov Substitution Principle(里氏代换原则):子类型(subtype)必须能够替换它们的基类型。白马、黑马 反过来的代换不成立《墨子·小取》说:"娣,美人也,爱娣,非爱美人也……"娣便是妹妹,哥哥喜爱妹妹,是因为两人是兄妹关系,而不是因为妹妹是个美人。因此,喜爱妹妹不等同于喜爱美人。用面向对象语言描述,美人是基类,妹妹是美人的子类。哥哥作为一个有"喜爱()"方法,接受妹妹作为参数。那么,这个"喜爱()"方法一般不能接受美人的实例。 一个违反LSP的简单例子(长方形和正方形)public class Rectangle{   private long width;   private long height;       public void setWidth(long width)   {      this.width = width;   }   public long getWidth()   {      return this.width;   }   public void setHeight(long height)   {      this.height = height;   }   public long getHeight()   {      return this.height;   }}public class Square{   private long side;       public void setSide(long side)   {      this.side = side;   }   public long getSide()   {      return side;   }}正方形不可以做长方形的子类using System;public class Rectangle{   private long width;   private long height;       public void setWidth(long width)   {      this.width = width;   }   public long getWidth()   {      return this.width;   }   public void setHeight(long height)   {      this.height = height;   }   public long getHeight()   {      return this.height;   }}public class Square : Rectangle{   private long side;   public void setWidth(long width)   {      setSide(width);   }   public long getWidth()   {      return getSide();   }   public void setHeight(long height)   {      setSide(height);   }   public long getHeight()   {      return getSide();   }   public long getSide()   {      return side;   }   public void setSide(long side)   {      this.side = side;   }}public class SmartTest{   public void resize(Rectangle r)   {      while (r.getHeight() >= r.getWidth() )      {         r.setWidth(r.getWidth() + 1);      }   }} 在执行SmartTest的resize方法时,如果传入的是长方形对象,当高度大于宽度时,会自动增加宽度直到超出高度。但是如果传入的是正方形对象,则会陷入死循环。代码重构public interface Quadrangle{   public long getWidth();   public long getHeight();}public class Rectangle : Quadrangle {   private long width;   private long height;       public void setWidth(long width)   {      this.width = width;   }   public long getWidth()   {      return this.width;   }   public void setHeight(long height)   {      this.height = height;   }   public long getHeight()   {      return this.height;   }}public class Square : Quadrangle {   private long side;   public void setSide(long side)   {      this.side = side;   }   public long getSide()   {      return side;   }   public long getWidth()   {      return getSide();   }   public long getHeight()   {      return getSide();   }} 参考文献:阎宏,《Java与模式》,电子工业出版社[美]James W. Cooper,《C#设计模式》,电子工业出版社[美]Alan Shalloway James R. Trott,《Design Patterns Explained》,中国电力出版社[美]Robert C. Martin,《敏捷软件开发-原则、模式与实践》,清华大学出版社[美]Don Box, Chris Sells,《.NET本质论 第1卷:公共语言运行库》,中国电力出版社http://www.dofactory.com/Patterns/Patterns.aspx posted on 2004-08-24 00:29 吕震宇 阅读(11264) 评论(33)  编辑 收藏 引用 网摘 所属分类: 设计模式评论# re: C#设计模式(2) 2004-09-03 17:07 runmin我有个问题:您所提到的可维护与下面的可扩展性、可插入性、灵活性的关系是怎么样的?可维护性包含扩展、插入、灵活性吗?----------------------------------------------------------------------------过于僵硬 可扩展性(新性能可以很容易加入系统)过于脆弱 灵活性(修改不会波及其它)复用率低粘度过高 可插入性(新功能容易加入系统(气囊加入方向盘))  回复  更多评论  # re: C#设计模式(2) 2004-09-03 17:28 吕震宇过于僵硬、过于脆弱、复用率低、粘度过高的系统都必然导致可维护性的减弱。反过来,可扩展、可插入、灵活的设计是提高可维护性的基础,但不一定能够保证可维护性。有些人开发的系统高度灵活,所有数据库字段都可以动态添加、删除,表也可以动态构建。可以说灵活性高、可插入、可扩展性也很强。但导致代码超级复杂,读起来根本就找不到北,更不用说修改了。这时候,可维护性就显得很低。甚至在维护代码时,不小心触动一些关键部件造成系统出现问题。有时候我提倡为开发人员写代码(注意:不是注释)。有些代码不是给客户用的,而是给开发人员用的。包括必要的错误定位工具,内部调试断点,性能计数器等等。这些代码可以帮助提高系统的可维护性。总之,可维护性是一个综合的概念,任何人都无法预料客户需求会发生什么样的变化,“未雨绸缪”和“亡羊补牢”都是提高可维护性的一个很好切入点。测试驱动开发以及契约式开发对提高可维护性也有不少帮助。  回复  更多评论  # re: C#设计模式(2) 2004-09-06 09:49 runmin......没想到会有这么多的回答,非常感谢。  回复  更多评论  # re: C#设计模式(2) 2005-03-29 14:26 Harry看来这是对矛盾:一方面为了不使程序的脆弱,复用率低而写的灵活,但是写得太灵活又会使程序的可维护性低.这方面我也有体会,有时候为了程序不那么死板,就写得灵活点,所以用了大量得字段变量,一层层封装,做完之后看上去确实很cool,但是过了一段时间要修改bug或需求时,真的很累...  回复  更多评论  # re: C#设计模式(2) 2005-06-16 09:10 xinbin1122如果一定要有联系的话,长方形应该是正方形的子类。因为长方形比正方形多了属性。  回复  更多评论  # re: C#设计模式(2) 2005-06-16 12:20 o945长方形能作为正方形的子类吗?不能!  回复  更多评论  # re: C#设计模式(2) 2005-06-19 10:27 往事如风楼上的说得很对。长方形没有正方形的一些特性,正方形也没有长方形的一些特性,如果说要通过增加和删除基类的一些特性来创建子类的话,只能说明这2者是不适合有继承关系的,这正如猫之于狗。  回复  更多评论  # re: C#设计模式(2) 2005-09-05 16:30 刘余学从数学的角度来说,正方形只是长方形的一个特例,所以应该是正方形是长放行的子类才对。有人可能说这样多了一条属性,有龙余,事实上这点龙余换来的可维护性是很强的。比如,将来,画图形的时候,你就不用单独对正方形做特殊处理了。  回复  更多评论  # re: C#设计模式(2) 2005-09-26 22:01 netmini正方形只是长方形有点像男人和女人的关系,大部分属性相同,就那么一点不同,但失之毫厘,差之千里,正放形和长方形在继承层次里面应该属于同一层次

 软件腐化的原因:
<p >问题所在   设计目标----------------------------------------------------------------------------过于僵硬   可扩展性(新性能可以很容易加入系统)过于脆弱   灵活性(修改不会波及其它)复用率低   粘度过高   可插入性(新功能容易加入系统(气囊加入方向盘))


<p > 提高系统可复用性的几点原则:传统复用:1. 代码的粘帖复用2. 算法的复用3. 数据结构的复用


<p >
可维护性与可复用性并不完全一致


<p >* 对可维护性的支持:

一、 "开放-封闭"原则(OCP)

二、 里氏代换原则(LSP)

= r.getWIDth() )


= r.getWIDth() 改为r.getHeight() > r.getWIDth() 。这样就不会出现死循环了,而且我认为也应该是合理的,不知道是不是应该这样,还请吕兄赐教。        = r.getWIDth() 改为r.getHeight() > r.getWIDth() ”,那么在系统中加入正方形类后代码中所有长方形相关的代码都会受影响,这不正是失去了抽象的意义了吗?这样正好违反了LSP原则 !        中有详细说明,大家可以去看看。 再举一个鸭嘴兽的例子,假如浦乳动物的约束是:恒温,喂奶,那么鸭嘴兽可以是浦乳动物的子类,但要是再加一个约束:必须是胎生,那么鸭嘴兽就不可做浦乳动物的子类,目前动物学术界基本上认为鸭嘴兽属于浦乳动物。        = rectangle.getSIDe2() ) { rectangle.setSIDe2(rectangle.getSIDe2() + 1); } System.out.println("rectangle:"); System.out.println(rectangle.getSIDe1()); System.out.println(rectangle.getSIDe2()); System.out.println(); } } 我传入的矩形是一个正方形,结果也没什么死循环啊。        总结

以上是内存溢出为你收集整理的一、 "开放-封闭"原则(OCP)全部内容,希望文章能够帮你解决一、 "开放-封闭"原则(OCP)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1264037.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存