AS3设计模式创建模式工厂方法

工厂方法解决Client和Product之间的紧耦合。通过把创建对象的过程委托给一个factory。

逻辑模式

Client ---uses----creator-----create---product

OOP的 open-closed思想  opened for extension ,closed for modication

简单工厂 只是属于初级的工厂设计模式。真正的工厂方法 需要用到接口,处理变化的需求非常实用,可以不影响之前已存在的代码。

IProduct 接口

Product1

Product2

AbstractorCreator

公用方法

带参数或者布带参数的工厂方法  fatoryMethod

Creator1

Creator2

Client 调用

工厂方法可以分离对象的创建和使用。减少依赖,降低耦合

软件设计中变化是不可避免的。工厂模式就是在互相依赖的类之间提供一个中间层,防火墙。当然,模式阻止不了类相互依赖,但是可以提供一个可以很好的管理这种依赖的框架。

以下是一个炮弹设计游戏中使用工厂模式的例子。其中炮弹是product,武器是factory可以创建炮弹,飞船携带武器,同时也是product。Client通过ShipCreator创建飞船。

Projectile

View Code
 1 package weapons
 2 {
 3     import flash.display.Sprite;
 4     import flash.events.Event;
 5     
 6     /**
 7      * ...
 8      * @author liuyong
 9      */
10     //抽象类  应该被继承而不能实例化
11     internal class Projectile extends Sprite    
12     {
13         internal var nSpeed:Number;    //速度
14         //抽象方法必须被子类重写
15         internal function drawProjectile():void { }
16         internal function arm():void {
17             //设置缺省速度 5pixels/per frame
18             nSpeed = 5;
19         }
20         internal function release():void {
21             //关联enterframe事件  doMoveProjectile
22             this.addEventListener(Event.ENTER_FRAME, this.doMoveProjectile);
23         }
24         internal function doMoveProjectile(event:Event):void {
25             this.y += nSpeed;//移动射弹
26             if (this.y < 0 || this.y > this.stage.stageHeight) {
27                 //移除事件监听
28                 this.removeEventListener(Event.ENTER_FRAME, this.doMoveProjectile);
29                 this.stage.removeChild(this);
30             }
31         }
32         internal function setLoc(xLoc:int,yLoc:int):void {
33             this.x = xLoc;
34             this.y = yLoc;    
35         }
36     
37     }
38     
39 }

AlienCannonBall

View Code
 1 package weapons
 2 {
 3     
 4     /**
 5      * ...
 6      * @author liuyong
 7      */
 8     internal class  AlienCannonBall extends Projectile
 9     {
10         public function AlienCannonBall() { }
11         override internal function drawProjectile():void 
12         {
13             this.graphics.lineStyle(3, 0xFF00FF);
14             this.graphics.drawCircle(0, 0, 5);
15         }
16         override internal function arm():void 
17         {
18             this.nSpeed = 8;
19         } 
20     }
21     
22 }

AlienMine

View Code
 1 package weapons
 2 {
 3     import flash.events.Event;
 4     
 5     /**
 6      * ...
 7      * @author liuyong
 8      */
 9     internal class AlienMine extends Projectile
10     {
11         public function AlienMine() { }
12         override internal function drawProjectile():void 
13         {
14             graphics.lineStyle(3, 0xFF0000);
15             graphics.drawRect( -5, -5, 10, 10);
16             graphics.endFill();
17         }
18         override internal function arm():void 
19         {
20             nSpeed = 2;
21         }
22         override internal function doMoveProjectile(event:Event):void 
23         {
24             super.doMoveProjectile(event);
25             this.rotation += 5;
26         }
27     }
28     
29 }

HeroCannonBall

View Code
 1 package weapons
 2 {
 3     
 4     /**
 5      * ...
 6      * @author liuyong
 7      */
 8     internal class  HeroCannonBall extends Projectile
 9     {
10         public function HeroCannonBall() { }
11         override internal function drawProjectile():void 
12         {
13             graphics.beginFill(0xFFFF00);
14             graphics.drawCircle(0, 0, 5);
15             graphics.endFill();
16         }
17         override internal function arm():void 
18         {
19             this.nSpeed = -10;
20         }
21     }
22     
23 }

AbstractWeapon

View Code
 1 package weapons
 2 {
 3     import flash.display.Stage;
 4     import flash.errors.IllegalOperationError;
 5     
 6     /**
 7      * ...
 8      * @author liuyong
 9      */
10     public class AbstracWeapon  
11     {
12         public function fire(cWeapon:int , target:Stage,xLoc:int,yLoc:int ):void {
13             var projectile:Projectile = this.createProjectile(cWeapon);
14             trace("fire" + projectile.toString())
15             //画炮弹
16             projectile.drawProjectile();
17             projectile.setLoc (xLoc , yLoc );//设置炮弹初始位置
18             projectile.arm();//装备炮弹 设置速度
19             target.addChild(projectile );//加入到舞台
20             projectile.release();//发射,绑定enterframe的事件处理,移动炮弹即发射
21         }
22         protected function createProjectile(cWeapon:int):Projectile {
23             throw new IllegalOperationError("Abstract Method:must be overridden in a subclass");
24             return null;
25         }
26     }
27     
28 }

HeroWeapon

View Code
 1 package weapons
 2 {
 3     
 4     /**
 5      * ...
 6      * @author liuyong
 7      */
 8     public class  HeroWeapon extends AbstracWeapon
 9     {
10         public function HeroWeapon() { }
11         public static const CANNON:uint = 0  ;
12         override protected function createProjectile(cWeapon:int):Projectile 
13         {
14             if (cWeapon == CANNON ) {
15                 trace("create a hero cannon")
16                 return new HeroCannonBall();
17             }else {
18                 throw new Error("Invalid kind of projectile specified");
19             }
20         }
21     }
22     
23 }

AlienWeapon

View Code
 1 package weapons
 2 {
 3     
 4     /**
 5      * ...
 6      * @author liuyong
 7      */
 8     public class  AlienWeapon extends AbstracWeapon
 9     {
10         public static const CANNON:uint = 0 ;
11         public static const MINE:uint = 1;
12         public function AlienWeapon() { }
13         override protected function createProjectile(cWeapon:int):Projectile 
14         {
15             if (cWeapon == CANNON ) {
16                 trace("create a alien cannonball")
17                 return new AlienCannonBall();
18             }else if (cWeapon == MINE ) {
19                 trace("create a alien mine")
20                 return new AlienMine();
21             }else {
22                 throw new Error("Invalid kind of projectile specified");
23                 return null;
24             }
25         }
26     }
27     
28 }

Ship

View Code
 1 package ships 
 2 {
 3     import flash.display.Sprite;
 4     
 5     /**
 6      * ...
 7      * @author liuyong
 8      */
 9     //抽象类  默认是实现方法 和两个抽象方法
10     internal class  Ship extends Sprite
11     {
12         public function Ship() { }
13         internal function setLoc(xLoc:int,yLoc:int):void {
14             this.x = xLoc;
15             this.y = yLoc;
16         }
17         internal function drawShip():void {
18             
19         }
20         //抽象飞船的行为
21         internal function initShip():void{}
22         
23     }
24     
25 }

HeroShip

View Code
 1 package ships
 2 {
 3     import flash.events.MouseEvent;
 4     import weapons.HeroWeapon;
 5     
 6     /**
 7      * ...
 8      * @author liuyong
 9      */
10     internal class HeroShip extends Ship
11     {
12         private var weapon:HeroWeapon;
13         public function HeroShip() { }
14         override internal function drawShip():void 
15         {
16             graphics.beginFill(0x00FF00); // green color
17             graphics.drawRect(-5, -15, 10, 10);
18             graphics.drawRect(-12, -5, 24, 10);
19             graphics.drawRect(-20, 5, 40, 10);
20             graphics.endFill( );
21         }
22         override internal function initShip():void 
23         {
24             weapon = new HeroWeapon();
25             //监听鼠标移动事件 移动飞船 监听MouseDown,发射
26             this.stage.addEventListener(MouseEvent.MOUSE_MOVE, doMoveShip);
27             this.stage.addEventListener (MouseEvent.MOUSE_DOWN, doFire);
28         }
29         protected function doMoveShip(event:MouseEvent):void {
30             this.x = event.stageX;
31             event.updateAfterEvent();
32         }
33         protected function doFire(event:MouseEvent):void {
34             weapon.fire(HeroWeapon.CANNON , this.stage, this.x, this.y - 15);
35             event.updateAfterEvent();//process the event first 先处理此事件
36         }
37     }
38     
39 }

AlienShip

View Code
 1 package ships
 2 {
 3     import flash.events.Event;
 4     import weapons.AlienWeapon;
 5     
 6     /**
 7      * ...
 8      * @author liuyong
 9      */
10     internal class  AlienShip extends Ship
11     {
12         private var weapon:AlienWeapon;
13         private const aProjectiles:Array = [AlienWeapon.CANNON,AlienWeapon.MINE];
14         public function AlienShip() { }
15         override internal function drawShip():void 
16         {
17             graphics.beginFill(0xFFFFFF); // white color
18             graphics.drawRect(-5, -10, 10, 5);
19             graphics.drawRect(-20, -5, 40, 10);
20             graphics.drawRect(-20, 5, 10, 5);
21             graphics.drawRect(10, 5, 10, 5);
22             graphics.endFill( );
23         }
24         override internal function initShip():void 
25         {
26             weapon = new AlienWeapon();
27             //绑定doFire方法到舞台的enterframe事件中
28             this.stage.addEventListener(Event.ENTER_FRAME, doFire);
29         }
30         protected function doFire(event:Event):void {
31             //fire randomly 4% chance of firing on each enterframe
32             if (Math.ceil(Math.random()*25)==1) {
33                 //随机产生一枚炮弹
34                 var cWeapon:uint = aProjectiles[Math.floor(Math.random() * aProjectiles.length)];
35                 weapon.fire(cWeapon , this.stage, this.x, this.y + 15);
36             }
37         }
38     }
39     
40 }

ShipCreator

View Code
 1 package ships 
 2 {
 3     import flash.display.Stage;
 4     /**
 5      * ...
 6      * @author liuyong
 7      */
 8     public class ShipCreator 
 9     {
10         public static const HERO:uint = 0 ;
11         public static const ALIEN:uint = 1;
12         public function ShipCreator() 
13         {
14             
15         }
16         
17         public function addShip(shipType:uint , target:Stage,xLoc:int,yLoc:int ):void {
18             var ship:Ship = this.createShip(shipType);
19             ship.drawShip();
20             target.addChild(ship);
21             ship.setLoc(xLoc, yLoc );
22             ship.initShip();
23         }
24         protected function createShip(shipType:uint):Ship {
25             if (shipType == HERO ) {
26                 return new HeroShip();
27             }else if (shipType == ALIEN) {
28                 return new AlienShip();
29             }else {
30                 throw new Error("Invalid kind of ship specified");
31                 return null;
32             }
33         }
34         
35     }
36 
37 }

Main

View Code
 1 package 
 2 {
 3     import flash.display.Sprite;
 4     import flash.events.Event;
 5     import ships.ShipCreator;
 6 
 7     /**
 8      * ...
 9      * @author liuyong
10      */
11     [Frame(factoryClass="Preloader")]
12     public class Main extends Sprite 
13     {
14         private var shipeCreator:ShipCreator = new ShipCreator();
15         public function Main():void 
16         {
17             if (stage) init();
18             else addEventListener(Event.ADDED_TO_STAGE, init);
19         }
20 
21         private function init(e:Event = null):void 
22         {
23             removeEventListener(Event.ADDED_TO_STAGE, init);
24             // entry point
25             //增加英雄船
26             shipeCreator.addShip(ShipCreator.HERO, this.stage, this.stage.width / 2, this.stage.height - 20);
27             //增加外星船
28             for (var i:Number = 0 ; i < 5; i++ ) {
29                 shipeCreator.addShip(ShipCreator.ALIEN, this.stage,
30                 120 + 80 * i, 100);
31             }
32         }
33 
34     }
35 
36 }
原文地址:https://www.cnblogs.com/YonguiL/p/2989159.html