[英]What way would be best to adhere to both DRY and limit unintended functionality given this kind of design in C# or Java?
請原諒我有限的繪畫技巧,但我將如何最好地創建這里描述的對象(鑒於語言的單類 inheritance 性質):
Moon、Rocky Planet 和 Asteroid 類應該實現 IColonizable,但問題是它們將以完全相同的方式實現它,例如,使用簡單的 getter。 在這種情況下,我認為將功能放入父 class 主體會更好。 但是,當我不希望此功能存在時,我將賦予 GasGiant class getOwner() 的能力。
我能想出的最佳解決方案是在 Body class 中實現 getOwner,但只在所需的類中繼承 IColonizable 接口,然后也許當在 GasGiant 中調用 getOwner() 時,我可以用異常覆蓋。 有什么想法嗎?
您可以創建一個中間基類,它派生自或擴展Body
並實現IColonizable
(您希望實現IColonizable
的Body
的特化):
interface IColonizable
{
Owner GetOwner():
}
abstract class Body
{
}
abstract class ColonizableBody : Body, IColonizable
{
public Owner GetOwner()
{
}
}
class Planet : Body
{
}
class ColonizablePlanet : ColonizableBody
{
}
class GasGiant : Planet
{
}
class RockyPlanet : ColonizablePlanet
{
}
class Moon : ColonizableBody
{
}
class Asteroid : ColonizableBody
{
}
如前所述,您通常應該喜歡組合而不是 inheritance。 而不是"An object is"你 go 像"An object has" : "A Planet
has a Body
"或"A Moon
has a ColonizableBody
" 。 這更自然。 更自然意味着創建的數據結構及其關系更易於理解、維護、測試和擴展:
interface IBody
{
double GetMass();
}
interface IColonizable
{
Owner GetOwner();
}
interface IColonizableBody : IColonizable, IBody
{
}
interface IPlanet : IBody
{
IBody GetBody();
}
class Body : IBody
{
public Body()
{
}
// Implementation of IBody
public double GetMass() { return 10000; }
}
class Planet : IPlanet
{
private IBody _body;
public Planet()
{
this._body = new Body();
}
// Implementation of IPlanet
public IBody GetBody() { return this._body; }
// Implementation of IBody
public double GetMass() { return this._body.GetMass(); }
}
class ColonizableBody : IColonizableBody
{
private Owner _owner;
private IBody _body;
private ColonizableBody(Owner owner)
{
this._owner = owner;
this._body = new Body();
}
// Implementation of IBody
public double GetMass() { return this._body.GetMass(); }
// Implementation of IColonizable
public Owner GetOwner() { return this._owner; }
}
class Moon : IColonizableBody
{
private IColonizableBody _colonizableBody;
public Moon(Owner owner)
{
this._colonizableBody = new ColonizableBody(owner);
}
// Implementation of IColonizable
public double GetOwner() { return this._colonizableBody.GetOwner(); }
// Implementation of IBody
public double GetMass() { return this._colonizableBody.GetMass(); }
}
class RockyPlanet : IColonizableBody, IPlanet
{
private IColonizableBody _colonizableBody;
public RockyPlanet(Owner owner)
{
this._colonizableBody = new ColonizableBody(owner);
}
// Implementation of IColonizable
public Owner GetOwner() { return this._colonizableBody.GetOwner(); }
// Implementation of IBody
public double GetMass() { return this._colonizableBody.GetMass(); }
// Implementation of IPlanet
public IBody GetBody() { return this._colonizableBody.GetBody(); }
}
class GasGiant : IPlanet
{
private IBody _body;
public GasGiant()
{
this._body = new Body();
}
// Implementation of IPlanet
public IBody GetBody() { return this._body; }
// Implementation of IBody
public double GetMass() { return this._body.GetMass(); }
}
class Asteroid : IColonizableBody
{
private IColonizableBody _colonizableBody;
public Moon(Owner owner)
{
this._colonizableBody = new ColonizableBody(owner);
}
// Implementation of IColonizable
public double GetOwner() { return this._colonizableBody.GetOwner(); }
// Implementation of IBody
public double GetMass() { return this._colonizableBody.GetMass(); }
}
在高級場景中,您將使用構造函數注入組合對象,而不是使用new
關鍵字顯式創建實例。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.