簡體   English   中英

相同的類,不同的命名空間,一種簡化的方法?

[英]Same class, different namespaces, a way to simplify?

我正在使用一個Web服務,它在兩個名稱空間中提供幾乎重復的代碼。 讓我們說例如PigFeet和HorseFeet,兩個名稱空間都包含一個Feet類,而其他與Feet類一起使用的代碼要求它成為同一名稱空間的一部分。

現在在我的代碼中我被迫做這樣的事情:

if( _animalType == AnimalType.Pig )
{ 
     //namespace is pigfeet
     PigFeet.Feet feet = new Feet();
     feet.WashFeet();
}

if( _animalType == AnimalType.Horse )
{
     //namespace is horsefeet
     HorseFeet.Feet feet = new Feet();
     feet.WashFeet();
 }

這給我留下了許多重復的代碼。 有沒有辦法更動態地選擇命名空間?

在命名空間導入中,您可以為特定命名空間或成員分配別名

using PigFeet = PigFeet.Feet;
using HorseFeet = HorseFeet.Feet;

//now your sample code should look something like

if( _animalType == AnimalType.Pig )
{ 
     //namespace is pigfeet
     PigFeet feet = new PigFeet();
     feet.WashFeet();
}

if( _animalType == AnimalType.Horse )
{
     //namespace is horsefeet
     HorseFeet feet = new HorseFeet();
     feet.WashFeet();
 }

命名空間不是問題 - 只是兩個類沒有關聯,因此沒有可用於多態的繼承鏈。

您需要查看類似於鴨子類型適配器模式的內容 ,或者構建自己的代理類以使自己進入通用接口。 對於少量的實現,我已經完成了構建一個適配器類,該類委托給它擁有的任何非null實例:

interface IFeet {
   void WashFeet();
}

class FeetAdapter : IFeet {
   private PigFeet.Feet _pigFeet;
   private HorseFeet.Feet _horseFeet;

   private FeetAdapter(PigFeet.Feet pigFeet) {
      _pigFeet = pigFeet;
   }

   private FeetAdapter(HorseFeet.Feet horseFeet) {
      _horseFeet = horseFeet;
   }

   public void WashFeet() {
      if (_pigFeet != null) {
         _pigFeet.WashFeet();
      } else {
         _horseFeet.WashFeet();
      }
   }

   public static FeetAdapter Create(AnimalType animalType) {
      switch (animalType) {
         case AnimalType.Pig:
            return new FeetAdapter(new PigFeet.Feet());
         case AnimalType.Horse:
            return new FeetAdapter(new HorseFeet.Feet());
      }
   }
}

對於較大的情況,你最好使用一個單獨的PigFeetAdapter和HorseFeetAdapter來實現IFeet,以及一個FeetAdapterFactory來創建它們 - 但這個概念與我在上面顯示的相同。

命名空間只是一種組織類型的方法。 在您的情況下,您有兩個或更多不同的類,這些類具有相同簽名但沒有公共接口的方法。 如果你不能改變類的代碼,這里避免重復的唯一方法是在失去編譯時類型安全的同時使用反射。

這讓我在讓它們變得更好之前讓事情變得更糟。

您可以將所有AnimalType決策邏輯封裝在一個類中。

在兩種類型(PigsFeet和HorseFeet)之間,有一些類似的方法......由於WashFeet有一個共同的簽名(void沒有參數),System.Action可以用來引用該方法。 具有公共簽名(和參數)的其他方法可能需要System.Func(T)。 沒有共同簽名的其他方法可能需要被強制轉換為共同簽名。

這是客戶端代碼:

AnimalFeetFacade myFacade = new AnimalFeetFacade(_animalType);
myFacade.WashFeet();

這是封裝類。

public class AnimalFeetFacade
{
  public AnimalFeetFacade(AnimalType theType)
  {
    if (theType == AnimalType.Pig)
    {
      _washFeet = WashPigFeet;
      //TODO reference more PigFeet methods here
    }
    else if (theType == AnimalType.Horse)
    {
       _washFeet = WashHorseFeet;
       //TODO reference more HorseFeet methods here
    }
    else
    {
       throw new NotImplementedException("AnimalFeetFacade only works with PigFeet and HorseFeet");
    }
  }

  protected Action _washFeet;

  public void WashFeet()
  {
    _washFeet.Invoke();
  }

  protected void WashPigFeet()
  {
    PigFeet.Feet = new PigFeet.Feet()
    feet.WashFeet()
  } 

  protected void WashHorseFeet()
  {
    HorseFeet.Feet = new HorseFeet.Feet()
    feet.WashFeet()
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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