0

假設我們有一個超類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

回答

0

這裏沒有特殊的設計模式。把這些屬性放在各自的原型上是可以的,你甚至可以在Character.prototype上設置一些默認值。由於它們是應該由一個類的所有對象共享的實例的屬性,所以原型正是放置它們的正確位置。

如果你想在分配時避免重複,只要把它放在一個函數中即可。

1

我不會做出這樣的區分,完全依靠繼承。 我寧願將構圖放在繼承上,所以當更改發生時我不會鎖定在繼承框中。在這種情況下,還應該考慮過早的過度工程,你是否真的希望通過將這些屬性存儲在對象本身中來預期性能問題? 我的設計應該是你有一個字符,要麼是X,Y,心,寬度,高度,leftMargin,topMargin,類型屬性。因此,在這種方式,您有非常靈活的數據一致,這將滿足您未來的需求:

  • 敵人通過改變類型
  • 敵人還可以在某些時間點心中的朋友轉,爲什麼他們不應該?
  • 所有角色可以通過改變寬度/高度來增長/縮小
  • 所有角色都可以通過改變邊距來改變位置。

基本上,你將擁有一個通用的數據結構來操縱而不用拉毛來維護你的層次模型。 希望這會幫助你。

+0

偉大的建議和觀點,我會研究組成(我從來沒有聽說過這個)。我之所以「過度工程」是因爲它是一個學習項目,我對設計模式非常感興趣。 – sjbuysse

相關問題