【9】OCP:开放--封闭原则

《敏捷软件开发 原则、模式与实践(c#版)》


第9章 OCP:开放--封闭原则

 定义:

    "软件实体(类、模块、函数等)应该是可以扩展的,但是不可以修改。"(P93)

OCP概述

    遵循开放--封闭原则设计出的模块具有两个主要的特征。它们是

    (1)对于扩展是开放的(open for extension)。这意味着模块的行为是可以扩展的。当应用的需求改变时,我们可以对模块进行扩展,使其具有满足那些改变的新行为。换句话说,我们可以改变模块的功能。

    (2)对于修改是封闭的(closed for modification)。对模块行为进行扩展时,不必改动模块的源代码或者二进制代码。模块的二进制可执行版本,无论是可链接的库、DLL或者是.EXE文件,都无需改动。

    这两个特征好像是互相矛盾的。扩展模块行为的通常方式,就是修改该模块的源代码,不允许修改的模块常常都认为具有固定的行为。

    怎样可能在不改动模块源代码的情况下去更改它的行为呢?如果不更改一个模块,又怎么能够去改变它的功能呢?

    答案就是 抽象。在C#或者其它任何的OOPL(面向对象程序设计语言)中,可以创建出固定却能够描述一组任意个可能行为的抽象体。这个抽象体就是抽象基类。而这一组任意个可能的行为则表现为可能的派生类。

    模块可能对抽象体进行操作。由于模块依赖于一个固定的抽象体,所以它对于更改可以是封闭的。同事,通过这个抽象体派生,可以扩展此模块的行为。

 Shape 应用程序

    Shape示例在许多讲述面向对象设计的书中都提到过。这个声明狼藉的例子常常用来展示多态的工作原理。不过,这次我们将使用它来阐明OCP。

    我们有一个需要在标准的GUI上绘制圆和正方形的应用程序。圆和正方形必须要按照特定的顺序绘制。我们将创建一个列表,列表由按照适当的顺序排列的圆和正方形组成,程序遍历该列表,依次绘制出每个圆和正方形。

 

    A 下面的代码是一个基于C语言的实现,它采用了不遵循OCP的过程化方法。

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

//-- shape.h --------------------
enum SharpType {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;i<n;i++)
   {
      struct Shape* s = list[i];
      switch(s->itsType)
      {
      case square:
         DrawSquare((struct Square*)s);
      break;
      
      case cirle:
         DrawCirle((struct Cirle*)s);
      break;
      }
   }
}

  B 下面的代码是一个基于C#语言的实现,它采用了遵循OCP的过程化方法。

/*
 * 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();
   }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值