2011-03-30 56 views
1

我認爲這段代碼受到了致命的傷害,但在採取新的方法之前,我想提出一些意見。通用接口的工廠方法

我正在爲以下接口編寫工廠方法。

public interface ITransformer<I, O> 
{ 
    O Transform(I input); 
} 

這裏是一個可能實現的接口

public class CarToTruckTransformer : ITransformer<Car, Truck> 
{ 
    public Truck Transform(Car input) 
    { 
     Truck output = new Truck(); 
     output.Seats = input.Seats - 2; 
     output.BedSize = input.TrunkSize; 
     output.Gunrack = true; 
     return output; 
    } 
} 

第一家工廠我確實是這樣的

static class TransformerFactory 
{ 
    public static ITransformer<I, O> GetTransformer<I, O>() 
    { 
     if (typeof(I) == typeof(Car) && typeof(O) == typeof(Truck)) 
     { 
      return (ITransformer<I, O>)new CarToTruckTransformer(); 
     } 
     else 
     { 
      return null; 
     } 
    } 
} 

,但我必須知道確切的類型時,我給工廠方法,所以它似乎不理想。

ITransformer<Car, Truck> transf = TransformerFactory.GetTransformer<Car, Truck>(); 

我也玩弄了以下內容,但恐怕這可能是對動態關鍵字的嚴重濫用。

public class TransformerFactory2 
{ 
    public static dynamic GetTransformer(VehicleBase input, VehicleBase output) 
    { 
     if (input.GetType() == typeof(Car) && output.GetType() == typeof(Truck)) 
     { 
      return (ITransformer<Car, Truck>)new CarToTruckTransformer(); 
     } 
     else 
     { 
      return null; 
     } 
    } 
} 

但它確實允許我得到我想要的工廠語法。

dynamic transf = TransformerFactory2.GetTransformer(car, truck); 

我也考慮過第一個選項,但用反射調用工廠方法,所以我可以動態地分配類型變量。最終,我希望整個「變換」過程被包含在一個可重用的方法中,並在需要時實現新的變換器,但我還沒有。
這種情況有沒有更好或更安全的方法?

感謝您的閱讀。

+0

這是最好通過像Ninject這樣的依賴注入庫解決的問題。這些庫允許您輕鬆地將具體實現綁定到接口,然後工廠可以在執行時輕鬆獲得正確的實現。 – 2011-03-30 20:31:46

回答

0

如果您有興趣探索麪向對象和模式,但是您所描述的這個特定示例可以使用Func<I,O>代表進行相當整潔的描述,那麼這就是主題。

例如

var car = getSomeCar(); 
car.select(c => new Truck{ 
    : 
    : 
}); 

你定義select作爲一種通用的擴展方法上I

例如

public static O select<I,O>(this I input, Func<I,O> project) 
{ 
    return project(input); 
} 

只是一個想法。

編輯

只是測試這一點,它應該工作的優良:) 更名爲transformselect突出的相似LINQ的運營商。

+0

我喜歡這個主意。我會試一試。 – johnnysim 2011-03-30 20:46:26