Рефакторинг объектов с одинаковыми свойствами прототипа

Допустим, у нас есть суперкласс Character и 2 подкласса Player и Enemy.

var Character = function(x, y){
    this.x = x || 0;
    this.y = y || 0;
};
var Enemy = function() {
    // randomInt returns an integer value in between 0 and 505 (canvas width)
    var x = randomInt(0, 505);
    var y = this.getNewRow();
    Character.call(this, x, y);
};
var Player = function(x, y, hearts) {
    Character.call(this, x, y);
    this.hearts = hearts;
};

И Player, и Enemy будут иметь свойства прототипа, такие как width, height, leftMargin и topMargin.

Enemy.prototype.width = 96; 
Enemy.prototype.height = 65; 
Enemy.prototype.leftMargin = 2; 
Enemy.prototype.topMargin = 78; 

Player.prototype.width = 66; 
Player.prototype.height = 75;
Player.prototype.leftMargin = 18;
Player.prototype.topMargin = 64; 

Поскольку оба подкласса Player и Enemy имеют эти 4 свойства (тем не менее, с разными значениями), я чувствую, что это нужно как-то реорганизовать, но как? Поскольку каждый экземпляр этих классов будет иметь одинаковые значения свойств, я хочу использовать цепочку прототипов и хранить их в объекте-прототипе (если только вы не объясните мне, почему я не должен этого делать).


person sjbuysse    schedule 19.09.2016    source источник
comment
Если эти свойства являются общими для Player и Enemy, почему бы вам не добавить их в класс Character?   -  person Barmar    schedule 19.09.2016
comment
На данный момент нет ни суперклассов, ни подклассов, они не связаны...   -  person passion    schedule 19.09.2016
comment
@Barmar, потому что, если вы просто добавите их в класс Character, то КАЖДЫЙ экземпляр player и enemy будет хранить эти свойства как локальные значения (и это займет память), и мы не будем использовать возможности цепочек прототипов.   -  person sjbuysse    schedule 19.09.2016
comment
Вы хотите сказать, что эти значения одинаковы для всех Enemies? Итак, вам нужен способ указать, что каждый подкласс Character имеет эти общеклассовые свойства, но они специфичны для подкласса.   -  person Barmar    schedule 19.09.2016
comment
Да, ты понял! Значения одинаковы для всех врагов. Но поскольку оба подкласса Player и Enemy имеют эти свойства прототипа, мне кажется, что есть возможность для рефакторинга.   -  person sjbuysse    schedule 19.09.2016
comment
Ну, простой вариант - function setSize(obj, w, h, l, t) { obj.prototype.width = w; /*etc*/ }, а затем setSize(Enemy, 96, 65, 2, 78); setSize(Player, 66, 75, 18, 64);.   -  person nnnnnn    schedule 19.09.2016


Ответы (2)


Здесь нет специального шаблона проектирования. Размещение этих свойств в соответствующих прототипах — это нормально, вы даже можете установить некоторые значения по умолчанию для Character.prototype. Поскольку это свойства для экземпляров, которые должны быть общими для всех объектов класса, прототип — идеальное место для их размещения.

Если вы хотите избежать повторения при их назначении, просто поместите это в функцию.

person Bergi    schedule 19.09.2016

Я бы не делал таких различий и вообще не полагался бы на наследование. Я бы предпочел композицию наследованию, чтобы не запираться в ящике наследства, когда происходят изменения. Также подумайте о преждевременном перепроектировании в этом случае, вы действительно ожидаете проблем с производительностью, сохраняя эти свойства в самом объекте? Мой дизайн заключается в том, что у вас есть персонаж, который имеет свойства x, y, hearts, width, height, leftMargin, topMargin, type. Таким образом, у вас есть очень гибкие непротиворечивые данные, которые будут соответствовать вашим будущим требованиям:

  • Враги могут превратиться в друзей, изменив тип
  • У врагов также могут быть сердца в определенный момент времени, почему они не должны?
  • все персонажи могут увеличиваться/уменьшаться, изменяя ширину/высоту
  • все персонажи могут менять позицию, меняя поле.

По сути, у вас будет универсальная структура данных, с которой можно манипулировать, не выдергивая волосы, чтобы поддерживать свою модель иерархии. Надеюсь, что это поможет вам.

person Vlad Filimon    schedule 19.09.2016
comment
Отличный совет и точка зрения, я посмотрю на композицию (я никогда не слышал об этом). Причина, по которой я усложняю это, заключается в том, что это учебный проект, и меня действительно интересуют шаблоны проектирования. - person sjbuysse; 20.09.2016