LoginSignup
8
8

More than 5 years have passed since last update.

TypeScriptでのAbstract factory pattern

Last updated at Posted at 2013-05-23

暇すぎるから

書いてみた。が、
interfaceについてTypeScript (0.8.3)だと
public static〜という感じでプロパティ指定ができないので、
(new Slime).create();という感じになってしまう。

あとclass内でのプロパティとして持たせるのがだるいので
moduleを使ってしまった。

ES5で定義されているgetアクセサを利用しているので、

tsc hoge.tsc -target ES5 

という感じで対象を指定してコンパイルしてあげよう...

interface EnemyStatus {
  name: string;
  hitPoint: number;
  magicPoint: number;
  experiencePoint: number;
  gold: number;
}

interface Enemy {
  status: EnemyStatus;
  name: string;
  attaked: (attackPoint: number)=> void;
  isAlive: ()=> boolean;
}

interface EnemyFactory {
  create(): Enemy;
}

class BaseEnemy {
  myStatus: EnemyStatus;

  constructor(status: EnemyStatus) { 
    this.myStatus = status;
  };

  public get status() { return this.myStatus; }
  public get name(){ return this.myStatus.name; }
  public get hitPoint(){ return this.myStatus.hitPoint; }
  public get magicPoint(){ return this.myStatus.magicPoint; }
  public get experiencePoint(){ return this.myStatus.experiencePoint; }
  public get gold(){ return this.myStatus.gold; }

  public attaked(attackPoint: number): void {
    this.myStatus.hitPoint -= attackPoint;
  }

  public isAlive(): boolean {
    return this.myStatus.hitPoint > 0;
  } 
}

class SlimeFactory implements EnemyFactory {
  create(): Slime {
    return new Slime;
  }
}

class SlimeKnightFactory implements EnemyFactory {
  create(): SlimeKnight {
    return new SlimeKnight;
  }
}

class DrakeeFactory implements EnemyFactory {
  create(): Drakee {
    return new Drakee;
  }
}

class Slime extends BaseEnemy implements Enemy {
  constructor() {
    super({
      name: "Slime", 
      hitPoint: 6, 
      magicPoint: 2, 
      experiencePoint: 1,
      gold: 1
    });
  }
}

class SlimeKnight extends BaseEnemy implements Enemy {
  constructor() {
    super({
      name: "SlimeKnight",
      hitPoint: 194,
      magicPoint: 7,
      experiencePoint: 119,
      gold: 7
    });
  }
}

class Drakee extends BaseEnemy implements Enemy {
  constructor() {
    super({
      name: "Drakee",
      hitPoint: 13,
      magicPoint: 4,
      experiencePoint: 3,
      gold: 2
    });
  }
}

module BuildEnemy {
  var enemies: any[] = [
    (new SlimeFactory).create(), 
    (new SlimeKnightFactory).create(), 
    (new DrakeeFactory).create()
  ];

  export function singleSubstanceEnemy(): BaseEnemy {
    return enemies[randIndex()];
  }

  function randIndex(): number {
    return (parseInt(String(Math.random() * 10 % (enemies.length)), 10));
  }
}

module Runner {
  export function singleSubstanceEnemyScenario(): void {
    var enemy: BaseEnemy = BuildEnemy.singleSubstanceEnemy();
    console.log("Enemy name is: " + enemy.name);
    console.log("Enemy hit point is: " + enemy.hitPoint);
    enemy.attaked(1);
    console.log("Attacked! Damage is: " + 1);
    console.log("Enemy hit point is: " + enemy.hitPoint);
    console.log("Enemy is alived?: " + enemy.isAlive());
  }
}

Runner.singleSubstanceEnemyScenario();

実行した結果

こんな感じになる。

スクリーンショット 2013-05-23 23.20.14.png

いいよね?

8
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
8