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程序的主程序甚至都不需要重新编译,只要重新编译类库文件就可以。
Word教程网 | Excel教程网 | Dreamweaver教程网 | Fireworks教程网 | PPT教程网 | FLASH教程网 | PS教程网 |
HTML教程网 | DIV CSS教程网 | FLASH AS教程网 | ACCESS教程网 | SQL SERVER教程网 | C语言教程网 | JAVASCRIPT教程网 |
ASP教程网 | ASP.NET教程网 | CorelDraw教程网 |