• 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 }
  • 相关阅读:
    DataNucleus Access Platform 3.2 M2 发布
    dnsjava 2.1.4 发布,Java 的 DNS 解析包
    deltasql 1.5.5 发布,数据库模型版本控制
    Mezzanine 1.3 和 Cartridge 0.7 发布!
    Spring Framework 3.2 GA版发布,Spring MVC焕然一新
    Filemonitor 2.2.0 发布,文件监控工具
    Rudiments 0.40 发布,C++ 常用工具包
    脚本编程语言 Felix
    JRuby 1.7.2 发布
    OfficeFloor 2.7.0 发布,IoC 框架
  • 原文地址:https://www.cnblogs.com/YonguiL/p/2989159.html
Copyright © 2020-2023  润新知