【问题标题】:How to create a factory object without violating OCP in Typescript如何在 Typescript 中创建工厂对象而不违反 OCP
【发布时间】:2019-08-21 04:01:36
【问题描述】:

我刚刚了解了工厂模式并想在 Typescript 中实现它。

我检查了许多网站,例如 this,并注意到所有示例都违反了 OCP,因为它们必须使用许多 if 语句才能找到合适的子类构造函数。

我还发现了a similar question 如何在 Java 中做到这一点。但我不知道它是否可以在打字稿中实现。

【问题讨论】:

    标签: typescript types factory-pattern open-closed-principle


    【解决方案1】:

    我不知道这是否是一个好习惯,但您可以通过随机访问而不是顺序访问来避免大量 if 语句。

    你可以试试这样的方法:

    enum Behaviour {
      Friendly = 0,
      Agressive
    }
    
    export abstract class BaseCharacter{
    
      protected strength: number;
    
      public canFightWith(character: BaseCharacter): Boolean{
        return this.getBehaviour() !== character.getBehaviour();
      }
    
      public getStrength():number{
        return this.strength;
      }
    
      public abstract getBehaviour():Behaviour;
    
    }
    
    export class Vilain extends BaseCharacter{
    
      private reduction;
    
      public Vilain(strength:number, reduction:number){
        this.strength = strength;
        this.reduction = reduction;
      }
    
      public getStrength():number{
        return super.getStrength()*this.reduction;
      }
    
      public getBehaviour(): Behaviour {
        return Behaviour.Agressive;
      }
    }
    
    export class Hero extends BaseCharacter{
    
      public Hero(strength:number){
        this.strength = strength
      }
    
      public getBehaviour(): Behaviour {
        return Behaviour.Friendly;
      }
    }
    
    export class StaticFactory{
    
      // in this example Hero and Vilain will extend BaseCharacter
    
      static definitions = {
        'hero':Hero,
        'vilain':Vilain
      }
    
      static instanciateCharacter(subClass: string, ...args):BaseCharacter {
        if(subClass in StaticFactory.definitions)
          return new StaticFactory.definitions[subClass](...args);
      }
    
    }
    
    export class Battle{
    
      public constructor(private first: BaseCharacter, private second: BaseCharacter){
          if(!this.first.canFightWith(second))
            throw new Error("These 2 characters fight for the same cause !");
      }
    
      public getWinner():BaseCharacter{
        if (this.first.getStrength() === this.second.getStrength())
          return !(Math.trunc(Math.random()*2))?this.first:this.second;
    
        return this.first.getStrength() > this.second.getStrength()?this.first:this.second;
    
      }
    
    }
    

    【讨论】:

    • 谢谢,它肯定比我提供的示例更好,但它仍然违反 OCP
    • 在我看来没有违规,你从工厂收到的是BaseCharacter的。我将编辑我的答案
    猜你喜欢
    • 1970-01-01
    • 2020-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-21
    • 2012-02-05
    • 2013-01-03
    相关资源
    最近更新 更多