面向对象编程:实现状态模式的另一种方法?

问题描述

在此Object-oriented design挑战中,我需要其他解决方案的帮助!技术负责人要求我提供其他解决方案。

这就是挑战

一支军队由部队组成。一个单位可以是长枪兵,弓箭手或骑士。长枪兵可以变成弓箭手;一个弓箭手可以变成一个骑士,一个骑士也不能变成。

这是我的解决方

class Unit {}

class Pikeman extends Unit {
  transform() {
    return new Archer();
  }
}

class Archer extends Unit {
  transform() {
    return new Knight();
  }
}

class Knight extends Unit {
  transform() {
    throw new Error('a Knight can not be transformed');
  }
}

class Army {
  constructor() {
    this.units = [] // a collection of units
  }
  addUnit(unit) {
     units.push(unit);
  }
  
  transformunits(units) {
     var unitsTransformed = units.map(u => u.transform())
  }
}

尽管技术主管问我是否还有另一种实现transform方法而不是返回新对象的方法

有人可以帮助我找到新的解决方案吗?

解决方法

这就是我要怎么做。我希望它能解决您的问题。

const PIKEMAN = 0;
    const ARCHER = 1;
    const KNIGHT = 2;


    class Unit {
      // list of possible type of units,ordered by its hierarchy
      types = ["pikeman","archer","knight"];
      
      // current type of the unit
      current_type = 0;
      
      constructor(type = PIKEMAN){
        // by default,unit type is a pikeman 
        this.current_type = type;
      }
      
      transform(){
        // try to check,if it has a next hierarchy or not,let nextType = this.current_type + 1;
        
        // if its possible to transform it into the next unit type,then transform it
        if (this.types[nextType]) {
          this.current_type++;
          
          // return back the instance
          return this;
        }
        
        // get its current type on what unit this is.
        const currentType = this.types[ this.current_type ];
        
        // throw that i cannot be transformed anymore
        throw new Error("A "+currentType+" cannot be transformed")
      }
      
    }


    class Army {
      constructor(units = []) {
        this.units = units // a collection of units
      }
      addUnit(unit) {
         this.units.push(unit);
      }
      
      transformUnits() {
         return this.units.map(u => u.transform())
      }
    }


    let army = new Army([
      new Unit(PIKEMAN),new Unit(ARCHER)
    ]);

    console.log(army.transformUnits());