论坛交流
首页办公自动化| 网页制作| 平面设计| 动画制作| 数据库开发| 程序设计| 全部视频教程
应用视频: Windows | Word2007 | Excel2007 | PowerPoint2007 | Dreamweaver 8 | Fireworks 8 | Flash 8 | Photoshop cs | CorelDraw 12
编程视频: C语言视频教程 | HTML | Div+Css布局 | Javascript | Access数据库 | Asp | Sql Server数据库Asp.net  | Flash AS
当前位置 > 文字教程 > Flash AS教程
Tag:2.0,3.0菜鸟,游戏,,cs,技巧,源码,,文本,文字,函数,音乐,随机,拖拽,asp,access,xml,mc,视频教程

开放-封闭原则教程源码

文章类别:Flash AS | 发表日期:2010-4-25 9:36:12

Flash AS_开放-封闭原则教程源码 

前言:这这个例子中,将书中C++的实现转换成了As的实现方式。实际实现图形绘制到舞台的代码省略了。主要是希望看到更加清晰的程序设计结构。

2.3.1 Shape应用程序
下面的例子在许多讲述OOD的书中都提到过。它就是声名狼藉的“Shape”样例。它常常被用来展示多态的工作原理。不过,这次我们将它来阐明OCP。

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

2.3.2 违反OCP样例
如果使用过程化方法并不采用OCP,我们也许会得到如下的解决方案。其中drawAllShapes函数会按照输入的图形序列分别调用对应图形类型的函数。(这里按照as3语法编写)
package  {
public class shape {
  public var shapeType:Array=new Array("circle","square");
  public function shape():void{
  }
  function Circle(itsRadius,itsCenter){
   var r = itsRadius;
   var c=itsCenter;
   //绘制圆形
  }
  function Square(itsSide,itsTopLeft){
   var s = itsSide;
   var tl=itsTopLeft;
   //绘制方形
  }
  function drawAllShapes(shapelist:Array){
   for(var i:Number =0;i<shapelist.length;i++){
    var shape:Object = shapelist[i];
    switch(shape.type){
     case shapeType[0]:
      Circle(shape[1],shape[2]);
      break;
     case shapeType[1]:
      Square(shape[1],shape[2])
    }
   }
  }
}
}
drawAllShapes函数不符合OCP,因为它对于新的形状类型的添加不是封闭的。(举这个例子是希望大家可以看出明显的差别)如果希望这个函数能够绘制包含有三角函数的列表,就必须得更改这个函数。事实上,每增加一种新类型都要更新这个函数。

当然,这是一个简单而明显的例子。实际程序中,类似drawAllShapes中switch语句会在应用程序各个函数中重复出现,每个函数中switch语句负责完成的工作差别甚微。这些函数中,可能有负责拖扯形状对象的,有负责拉伸形状的。。。在这样的应用程序中增加一种新的形状类型,就意味这要找出所有包含上述switch的语句,并在每一处都增加新类型形状的判断。

这样的设计显然是糟糕的,不能接受的。它体现了程序的僵化性、脆弱性。

2.3.3 遵循OCP
以下程序展示了一个符合OCP的解决方案。在这个方案中我们编写了一个名为Shape的基类。这个抽象类仅有一个Draw抽象方法。circle和square都是它的派生类。
package com.mj.c9.ocp {
public class Shape {
  public  function Draw():void{
   return;
  }
}
}
package com.mj.c9.ocp {
import com.mj.c9.ocp.Shape;
public class Square extends Shape {
  public function Square() {
  }
  override function Draw():void{
   //绘制正方形
  }
}
}
package com.mj.c9.ocp {
import com.mj.c9.ocp.Shape;
public class Circle extends Shape {
  public function Circle() {
  }
  override function Draw():void{
   //绘制圆形
  }
}
}
package com.mj.c9.ocp {
/**
  * 主程序,负责绘制现状列表
  */
public class application {
  function DrawAllShapes(shapelist:Array){
   for(var i:Number=0;i<shapelist.length;i++){
    var t_shape:Shape = shapelist[i] as Shape;//将列表中的对象全部转换成Shape基类,这样可以调用统一的方法。
    t_shape.Draw();
   }
  }
}
}
可以看出,如果我们想要扩展程序中DrawAllShape函数的行为,使之能够绘制一种新的形状,我们只需要增加一个新的shape的派生类。application的DrawAllShape函数不需要任何改变,这样就符合了OCP原则。无需更改自身代码,就可以扩展它的行为。

在实际应用中,Shape类可能会有更多方法,但是在应用程序中增加一种新的形状类依然非常简单。这个解决方案不再是脆弱的。同时也不是僵化的。最后,这个方案也不再是牢固的。现在,任何程序中重用DrawAllShape时,都不需要附加Square和Circle。如果使用类库文件与主程序文件分离加载的方式,我们Flash程序的主程序甚至都不需要重新编译,只要重新编译类库文件就可以。

视频教程列表
文章教程搜索
 
Flash AS推荐教程
Flash AS热门教程
看全部视频教程
购买方式/价格
购买视频教程: 咨询客服
tel:15972130058