簡體   English   中英

考慮到 C# 或 Java 中的這種設計,哪種方式最好同時遵守 DRY 和限制意外功能?

[英]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 (您希望實現IColonizableBody的特化):

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM