如何在更好的实践中创建复杂类的实例?

时间:2019-05-04 08:52:55

标签: java c# typescript oop

作为一个新手,我正在开发游戏,但困惑于一种创建复杂对象的更好方法。这个问题可能与 OOP,设计模式和SOLID原理有关。对于这些问题,编程语言的限制很少。

情况很明显:

  1. 一艘军舰由一个尸体和几个炮塔组成。
  2. 一个炮塔由一个盾牌和几个枪管组成。

背景

我正在使用带有TypeScript的Pixi.js开发基于浏览器的2D游戏。以下类继承自Pixi.js的本机类Sprite或Container,但是为了清楚起见,在下面的代码中我省略了这些extend子句。

代码

我可以在下面简单地考虑一下Barrel,Shield和Body的代码:(在TypeScript中,但是与Java和C#几乎没有区别,是吗?)

class Barrel {
  constructor(texture, x, y, rotation){
    /*...*/
  }
}
class Shield {
  constructor(texture, x, y, rotation){
    /*...*/
  }
}
class Body {
  constructor(texture, x, y, rotation){
    /*...*/
  }
}

这是一个问题,炮塔和军舰怎么样?

大致来说,1座炮塔= 1盾+ N枪管,而1艘战舰= 1机体+ N炮塔。

无需进一步详细思考,即可轻松获得以下代码:

class Turret {
  private shield: Shield
  private barrels: Barrel[]
  constructor(x, y, rotation, shieldCfg, barrelCfgList) {
    /*...*/
    this.shield = new Shield(shieldCfg.texture, shieldCfg.x, shieldCfg.y, shieldCfg.rotation)
    for(let cfg of barrelCfgList){
      const barrel = new Barrel(cfg.texture, cfg.x, cfg.y, cfg.rotation)
      this.barrels.push(barrel)
    }
  }
}

class Warship {
  private body: Body
  private turrets: Turret[]
  constructor(x, y, rotation, bodyCfg, turretCfgList) {
    /*...*/
    this.body = new Body(bodyCfg.texture, bodyCfg.x, bodyCfg.y, bodyCfg.rotation)
    for(let cfg of turretCfgList){
      const turret = new Turret(cfg.x, cfg.y, cfg.rotation, cfg.shieldCfg, cfg.barrelCfgList)
      this.turrets.push(turret)
    }
  }
}

不难想象 turretCfgList 会多么复杂。

const turretCfgList = [
  {
    x: 1,
    y: 2,
    rotation: 3.14,
    shieldCfg: {
      texture: 'gun-shield'
      x: 4,
      y: 5,
      rotation: 6.28
    },
    barrelCfgList: [
      {
        texture: 'gun-barrel'
        x: 7,
        y: 8,
        rotation: 9.42
      },
      /*...*/
    ]
  },
  /*...*/
]

我的问题是:

  1. 如何解决上述嵌套对象的复杂参数?
  2. 上面的原始代码与Factory Method Pattern,Builder Pattern等更好的解决方案之间有什么改进?

非常感谢您。

我不太确定是否要使用下面的代码。仅供参考。

  1. 传递一个复杂的configurationObject而不是复杂的参数。
class Turret {
  // constructor(texture, x, y, rotation, shieldCfg, barrelCfgList) {}
  constructor(cfg) {
    /*...*/
    this.shield = new Shield(cfg.shieldCfg.texture, cfg.shieldCfg.x, shieldCfg.y, cfg.shieldCfg.rotation)
    for(let barrelCfg of barrelCfgList){
      const barrel = new Barrel(cfg.barrelCfg.texture, cfg.barrelCfg.x, cfg.barrelCfg.y, cfg.barrelCfg.rotation)
      this.barrels.push(barrel)
    }
  }
}
  1. 在其他位置创建组件的实例,然后传递这些实例而不是参数
class Turret {
  // constructor(texture, x, y, rotation, shieldCfg, barrelCfgList) {}
  constructor(x, y, rotation, shield, barrels) {
    /*...*/
    this.shield = shield
    this.barrels = barrels
  }
}
  1. 工厂方法模式?
  2. 构建器模式?
  3. ??

    • 更新1,添加一些有关背景的说明。

1 个答案:

答案 0 :(得分:0)

最好的方法是使用Entity Component System。这是游戏开发的最佳选择,它为您提供了将系统的不同部分组合到一个单元/建筑物/其他游戏对象中的绝佳机会。您可以使用任何方式进行组合:特定的类,工厂或构建器。