Как новичок, я разрабатываю игру, но ломаю голову над лучшим способом создания сложных объектов . Эта проблема может быть о ООП, шаблоне проектирования и SOLID-принципе . Для этих вопросов существует несколько ограничений языка программирования.
Ситуация понятна:
- Один военный корабль состоит из одного корпуса и нескольких башен.
- Одна башня состоит из одного щита и нескольких стволов.
Фон
Я разрабатываю браузерную 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
},
/*...*/
]
},
/*...*/
]
Мои вопросы:
- Как решить сложный параметр вложенных объектов выше?
- Каковы улучшения между необработанным кодом, приведенным выше, и лучшими решениями в Factory Method Pattern, Builder Pattern и т. Д.?
Большое спасибо.
Я не очень уверен, использовать ли код ниже. Просто для справки.
- Передайте один сложный объект конфигурации вместо сложных параметров.
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, добавить несколько инструкций по поводу фона.