我正在用 Java 構建一個簡單的游戲。我有幾個類,我省略了與我的問題無關的欄位:
public class Character {
//stores relics and artifacts
public Set<Collectable> inventory;
public void collect(Collectable collectable) {
collectable.collect(this);
}
}
public class Artifact extends Collectable {
@Override
public void collect(Character character) {
character.inventory.add(this);
}
}
public class Relic extends Collectable {
@Override
public void collect(Character character) {
character.inventory.add(this);
}
}
public class Spell extends Collectable {
@Override
public void collect(Character character) {
Wizard wizard = (Wizard) character;
wizard.spellBook.add(this);
}
}
public class Wizard extends Character {
//stores spells
public Set<Collectable> spellBook;
}
public class Warrior extends Character {
//fields and methods ommited
}
就目前而言,當我收集法術時,它必須進入巫師的法術書。戰士不能收集法術,他們沒有法術書。如果我從 OOP POV 中正確理解,則收藏品必須能夠決定它在收集時的去向(庫存或法術書),因此我的解決方案是上面的。
我的問題是我必須在 Spell.collect(Character) 中使用型別轉換才能將 Spell 放入向導的 SpellBook 中,因為默認情況下,SpellBook 在 Character 上不可見,我認為它不應該如此,因為那樣勇士隊也會有咒語書。這違背了開放封閉原則,因為如果我想添加一個術士,他也可以收集法術,我必須修改法術以嘗試將其施放給術士。
您能否提出一個解決方案或設計模式,以便我可以在不違反開閉原則的情況下收集我的收藏品?
uj5u.com熱心網友回復:
想到這一點很有趣。這里的其他答案肯定已經解決了您的問題,但我認為在總體方案中,您需要將架構更改為 MVC(模型視圖控制器)或 SAM(狀態動作模型)之類的東西。這些將使您更好地了解如何組成類,b/c 現在似乎您正在嘗試根據物理物件對您的世界進行建模,這不是 OOP 的內容。OOP 是關于資料的傳輸。
使用 MVC,它可能看起來像:
模型:
public class Spell extends MagicCollectable {
// attributes like damage or healing
}
public class Relic extends PhysicalCollectable {
// attributes
}
public class Wizard extends Character {
//stores spells
public Set<Collectable> spellBook;
}
public class Warrior extends Character {
//fields and methods ommited
}
控制器:
public class WizardController {
private Wizard wizard;
public void collect(MagicCollectable collectable);
}
public class WarriorController {
private Warrior warrior;
public void collect(PhysicalCollectable collectable);
}
所以在你的游戲回圈中,你實際上會實體化 WizardController 來體現你的角色。另請注意,與其他答案一樣,我正在創建更具體的模型。
uj5u.com熱心網友回復:
沒有理由public Set<Collectable> spellBook;不應該public Set<Spell> spellBook;
最好的辦法是制作一個介面:
interface SpellCaster{
void addSpell();
//other methods
}
并使任何應該能夠收集咒語的角色實作此介面。
編輯:然后 Spell 中的 collect 方法應該如下所示:
@Override
public void collect(SpellCaster character) {
character.addSpell(this);
}
盡管您可能應該重命名該方法。您有兩種執行完全不同的操作的 collect 方法。
uj5u.com熱心網友回復:
我覺得有趣的是你決定讓收藏品決定它的去向。在現實世界的場景中,角色不會收集收藏品,例如巫師收集咒語嗎?
public class Wizard extends Character {
//stores spells
private Set<Spell> spellBook;
public void addSpell(Spell spell) {
spellBook.add(spell);
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/351387.html
上一篇:型別同義詞實體
