重构具有相同原型属性的对象

问题描述:

假设我们有一个超类Character和2个子类PlayerEnemy重构具有相同原型属性的对象

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; 
}; 

两个PlayerEnemy将有原型性能如widthheightleftMargintopMargin

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; 

由于两个子类PlayerEnemy有这些4个属性(使用不同的值仍然),我觉得这应该得到某种重构,但如何?由于这些类的每个实例都具有相同的属性值,因此我希望利用原型链并将它们保存在原型对象中(除非您可以向我解释为什么我不应该这样做)。

+0

如果这些属性对'Player'和'Enemy'都是通用的,那么为什么不把它们添加到'Character'类中呢? – Barmar

+0

现在,没有超类和子类,它们是不相关的...... – passion

+0

@Barmar,因为如果你只是简单地将它们添加到'Character'类中,那么EVERY''''''''''''实例将会拥有这些属性作为本地价值(这将占用内存),我们不会利用原型链的力量 – sjbuysse

这里没有特殊的设计模式。把这些属性放在各自的原型上是可以的,你甚至可以在Character.prototype上设置一些默认值。由于它们是应该由一个类的所有对象共享的实例的属性,所以原型正是放置它们的正确位置。

如果你想在分配时避免重复,只要把它放在一个函数中即可。

我不会做出这样的区分,完全依靠继承。 我宁愿将构图放在继承上,所以当更改发生时我不会锁定在继承框中。在这种情况下,还应该考虑过早的过度工程,你是否真的希望通过将这些属性存储在对象本身中来预期性能问题? 我的设计应该是你有一个字符,要么是X,Y,心,宽度,高度,leftMargin,topMargin,类型属性。因此,在这种方式,您有非常灵活的数据一致,这将满足您未来的需求:

  • 敌人通过改变类型
  • 敌人还可以在某些时间点心中的朋友转,为什么他们不应该?
  • 所有角色可以通过改变宽度/高度来增长/缩小
  • 所有角色都可以通过改变边距来改变位置。

基本上,你将拥有一个通用的数据结构来操纵而不用拉毛来维护你的层次模型。 希望这会帮助你。

+0

伟大的建议和观点,我会研究组成(我从来没有听说过这个)。我之所以“过度工程”是因为它是一个学习项目,我对设计模式非常感兴趣。 – sjbuysse