Как создать экземпляры сложного класса в лучшей практике? - PullRequest
0 голосов
/ 04 мая 2019

Как новичок, я разрабатываю игру, но ломаю голову над лучшим способом создания сложных объектов . Эта проблема может быть о ООП, шаблоне проектирования и SOLID-принципе . Для этих вопросов существует несколько ограничений языка программирования.

Ситуация понятна:

  1. Один военный корабль состоит из одного корпуса и нескольких башен.
  2. Одна башня состоит из одного щита и нескольких стволов.

Фон

Я разрабатываю браузерную 2D-игру, используя Pixi.js с TypeScript. Следующие классы унаследованы от Sprite или Container, нативных классов Pixi.js, но я пропустил эти расширенные предложения в приведенном ниже коде для удобства и ясности.

Код

Я могу просто придумать код для 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. Передайте один сложный объект конфигурации вместо сложных параметров.
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 голосов
/ 04 мая 2019

Наилучшим подходом является использование Entity Component System .Это лучшее средство для разработки игр, дающее вам прекрасную возможность объединить различные части системы в одном объекте / здании / других игровых объектах.Вы можете использовать любой способ, чтобы объединить это: определенные классы, фабрика или строитель.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...