java - 如何更好地创建复杂类的实例?

标签 java c# typescript oop

作为新手,我正在开发一款游戏,但对创建复杂对象的更好方法感到困惑。这个问题可以是关于OOP、设计模式和SOLID原则。对于这些问题,编程语言几乎没有限制。

情况很清楚:

  1. 一艘战舰由一个船体和多个炮塔组成。
  2. 一个炮塔由一个盾牌和多个炮管组成。

背景

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

代码

我可以简单地想出下面的 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. 上面的原始代码与工厂方法模式、构建器模式等更好的解决方案相比有哪些改进?

非常感谢。

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

  1. 传递一个复杂的配置对象而不是复杂的参数。
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)
    }
  }
}
  • 在其他地方创建组件实例,并传递这些实例而不是参数
  • class Turret {
      // constructor(texture, x, y, rotation, shieldCfg, barrelCfgList) {}
      constructor(x, y, rotation, shield, barrels) {
        /*...*/
        this.shield = shield
        this.barrels = barrels
      }
    }
    
  • 工厂方法模式?
  • 构建器模式?
  • ??

    • 更新1,添加一些关于背景的说明。
  • 最佳答案

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

    关于java - 如何更好地创建复杂类的实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55980956/

    相关文章:

    java - 来自 Java 的 SSL 连接

    java - 删除链表中的元素

    javascript - 错误 TypeError : _v. context.$implicit.toggle 不是函数

    java - 使用 Thymeleaf 作为模板的 Spring Boot 发送电子邮件 - 配置不起作用

    c# - 变焦相机 FOV 超时

    c# - CHAR(1) 字段中出现 ORA-12899 错误,但我只发送 'C'

    c# - 如何访问直接操作界面

    javascript - 使用 Vue、Typescript 和 Karma 进行单元测试

    javascript - 如何在 typescript 中导入js文件?

    java - 如何在 Java 中使用我的密码加密和解密字符串(PC 不是移动平台)?