考慮下面的類層次結構在複雜層次注射運行時依賴抽象工廠
- ClassA的需要ClassB的
- ClassB的需要ClassC
我們得到了一個依賴關係圖如下:
ClassA --> ClassB --> ClassC
所以如果我們使用DI,我們將ClassC和ClassB注入到ClassA中。
但是現在讓我們假設ClassC是一個運行時依賴項(例如某種策略)。建議的方式注入運行時的依賴是引入一個抽象工廠就像一個
ClassCFactory
現在我們可以注入ClassCFactory到ClassB的,並得到如下圖
ClassA --> ClassB --> ClassCFactory
現在我們有一個方法ClassB的其中我們可以打電話讓工廠做好工作。例如
ObjB.SelectC(MyRuntimeValue)
但是現在在我們的應用中,我們不知道什麼ClassB的(或許還有一些涉及更多層)。一種解決方案可能是有SelectC在ClassA的
ObjA.SelectC(MyRuntimeValue) -(calls)-> ObjB.SelectC(MyRuntimeValue)
,或者我們乾脆違反法律德米特和做類似
ObjA.ObjB.SelectC(MyRuntimeValue)
我認爲每個人都同意,第二個解決方案是不是要走的路。但第一個解決方案也有一些缺點,特別是如果我們之間有更多的層。
我們也可以拉出工廠的一個層次來創建ClassB,但是ClassB真的是運行時的依賴關係嗎? 你建議什麼解決方案?或者它甚至是一個糟糕的課程設計?
恕我直言,總是更好地依賴於對象實際需要做的工作,而不是創建所需對象的工廠。但有了這個想法一記DI容器將是無用的...
好的,我會給你更具體的含義:ClassC是一個抽象類Encrytption,它對不同類型的加密有不同的實現。 ClassB是一個裝飾器,用Encryption裝飾FileStream。而ClassA是某種可序列化的對象,需要序列化一個流。 – 2013-03-26 10:43:17
什麼決定使用哪種類型的加密?您可以讓ClassA的消費者決定並將3個俄羅斯娃娃放在一起(加密,FileStreeamDecorator和ClassA),或者一些外部對象可以選擇一個加密,將其放入FileStreamDecorator並將其全部傳遞給ClassA的消費者......真的取決於您的上下文。 – guillaume31 2013-03-26 11:28:52
選擇正確的加密取決於我們加載或我們保存。加載時,我們詢問標題,使用哪種加密,然後我們詢問用戶密碼並開始閱讀和解密。在保存時,我們必須使用與加載時相同的加密。有一種特殊的導出方式,用戶最終可以決定使用哪種加密方式。 – 2013-03-26 11:54:56