[英]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.