2008-10-05 72 views
3

我正在處理跨兩個名稱空間提供幾乎重複的代碼的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(); 
} 

這是留給我,有很多重複的代碼。有沒有辦法更動態地選擇一個名稱空間?

+0

HorseFeet.Feet和PigFeet.Feet是否有共同的基類?如果是這樣,我可以用更多的重構更新我的答案。 – 2008-10-05 17:34:19

回答

2

命名空間不是問題 - 只是這兩個類沒有關係,所以沒有可用於多態的繼承鏈。

您需要看看duck typingadapter pattern之類的東西,或者構建自己的代理類以使自己進入通用接口。爲了實現小的數字,我只建立一個單獨的適配器類委託給它的任何非空實例僥倖:

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來創建它們 - 但是這個概念和我上面展示的一樣。

3

在您的命名空間導入中,您可以將alias分配給特定的命名空間或成員。

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(); 
} 
+0

我不明白這是如何幫助代碼重複的問題。 – Cosmin 2015-02-20 13:42:28

0

命名空間只是一種組織類型的方法。在你的情況下,你有兩個或更多不同的類具有相同簽名但沒有通用接口的方法。如果您無法更改類的代碼,那麼避免重複的唯一方法就是在釋放編譯時類型安全性的同時使用反射。

0

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

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

兩種類型(PigsFeet和HorseFeet),也有一些similiar方法... 由於WashFeet具有共同簽名(空隙無PARAMS)之間,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() 
    } 
} 
相關問題