设为首页 收藏本站
查看: 1414|回复: 0

[经验分享] [9]OCP:开放--封闭原则

[复制链接]
累计签到:2 天
连续签到:1 天
发表于 2015-6-16 11:22:32 | 显示全部楼层 |阅读模式
  
《敏捷软件开发 原则、模式与实践(c#版)》
第9章 OCP:开放--封闭原则
   定义:
      "软件实体(类、模块、函数等)应该是可以扩展的,但是不可以修改。"(P93)
  OCP概述
      遵循开放--封闭原则设计出的模块具有两个主要的特征。它们是
      (1)对于扩展是开放的(open for extension)。这意味着模块的行为是可以扩展的。当应用的需求改变时,我们可以对模块进行扩展,使其具有满足那些改变的新行为。换句话说,我们可以改变模块的功能。
      (2)对于修改是封闭的(closed for modification)。对模块行为进行扩展时,不必改动模块的源代码或者二进制代码。模块的二进制可执行版本,无论是可链接的库、DLL或者是.EXE文件,都无需改动。
      这两个特征好像是互相矛盾的。扩展模块行为的通常方式,就是修改该模块的源代码,不允许修改的模块常常都认为具有固定的行为。
      怎样可能在不改动模块源代码的情况下去更改它的行为呢?如果不更改一个模块,又怎么能够去改变它的功能呢?
      答案就是 抽象。在C#或者其它任何的OOPL(面向对象程序设计语言)中,可以创建出固定却能够描述一组任意个可能行为的抽象体。这个抽象体就是抽象基类。而这一组任意个可能的行为则表现为可能的派生类。
      模块可能对抽象体进行操作。由于模块依赖于一个固定的抽象体,所以它对于更改可以是封闭的。同事,通过这个抽象体派生,可以扩展此模块的行为。
   Shape 应用程序
  Shape示例在许多讲述面向对象设计的书中都提到过。这个声明狼藉的例子常常用来展示多态的工作原理。不过,这次我们将使用它来阐明OCP。
  我们有一个需要在标准的GUI上绘制圆和正方形的应用程序。圆和正方形必须要按照特定的顺序绘制。我们将创建一个列表,列表由按照适当的顺序排列的圆和正方形组成,程序遍历该列表,依次绘制出每个圆和正方形。
  
  A 下面的代码是一个基于C语言的实现,它采用了不遵循OCP的过程化方法。
  

DSC0000.gif DSC0001.gif Code
/**//*
DSC0002.gif * Language: C
* Shape 示例程序
DSC0003.gif */
DSC0004.gif
//-- shape.h --------------------
enum SharpType DSC0005.gif {cirle,square};
struct Sharp
{
   ShapeType itsType;
};

//-- cirle.h --------------------
struct Cirle
{
   ShapeType itsType;
   double itsRadius;
   Point itsCenter;
};

void DrawCirle(struct Circle*);

//-- square.h --------------------
struct Square
{
   ShapeType itsType;
   double itsSide;
   Point itsTopLeft;
};

void DrawSquare(Struct Square*);

//-- drawAllShapes.cc --------------------
typedef struct Shape *ShapePointer;

void DrawAllShapes(ShapePointer list[],int n)
{
   int i;
   for(i=0;iitsType)
DSC0006.gif DSC0007.gif       {
      case square:
         DrawSquare((struct Square*)s);
      break;
      
      case cirle:
         DrawCirle((struct Cirle*)s);
      break;
DSC0008.gif       }
   }
}  
  
  B 下面的代码是一个基于C#语言的实现,它采用了遵循OCP的过程化方法。

Code
/**//*
* Language: C#
* Shape 示例程序
*/

public interface Shape
{
   void Draw();
}

public class Square : Shape
{
   public void Draw()
   {
      //draw a square
   }
}

public class Circle: Shape
{
   public void Draw()
   {
      //draw a circle
   }
}


public void DrawAllShapes(IList shapes)
{
   foreach(Shape shape in shapes)
   {
      shape.Draw();
   }
}  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-77909-1-1.html 上篇帖子: 敏捷软件开发——开放封闭原则OCP 下篇帖子: OCP读书笔记(25)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表