2011-05-11 81 views
8

我面臨着設計挑戰,我無法以令人滿意的方式解決問題。我有一個包含所有共享ORM對象的類庫程序集(使用EntitySpaces框架)。這些對象用於2個或更多不同的應用程序,這就是它們在自己的程序集中的原因。這個設置對我來說工作正常4年以上。在應用程序中使用DI與共享庫

我還有一些應用程序構建於Microsoft的Patterns &實踐組(P & P)的複合應用程序塊(CAB)上。是的,我知道這真的很老,但我是一名兼職開發人員,一人一店,無法更新現有框架。

這裏是我的問題出現的地方:我一直在行使OO設計技巧,每當做了大量的重構工作時,我都試圖從一種程序方法轉向更多的面向對象方法。當然,面向對象設計的一個主要方面是將操作放在與它們一起工作的數據附近,這意味着我的ORM對象需要在適當的時候添加功能。當我也考慮在CAB中使用P的Object Builder DI容器時,這被證明是一個真正的頭疼者,而且我將移入我的ORM對象的大部分功能都需要訪問我的應用程序公開的服務。

換句話說,假設我有一個名爲「Person」的共享業務對象(原文,我知道),而且我有兩個應用程序與人完全不同。應用程序A提供了一組服務,Person對象需要進行DI'ed以便採取一些當前遍佈我的服務層的方法。應用程序B還具有一組不同的服務,IT需要將其刪除到人員對象中。

考慮到P Object Builder如何使用屬性裝飾和類型反射來解決依賴關係,我沒有看到我能做到這一點。簡而言之,我有一個共享對象,在各種應用程序中使用時,我需要注入依賴關係,以便它可以執行特定於該應用程序的特定操作。

我能想出的唯一方法是從Person對象繼承應用程序A & B中的新類型。然後,我會將我的非共享功能和DI代碼添加到此特定於應用程序的專用Person對象中。現在我寫這個看起來很明顯,但它仍然是我能想出的唯一解決方案,我想在這裏問一下,看看是否有其他人有他們想提出的不同解決方案?

我的解決方案會遇到的一個問題是,我可以看到自己被命名爲我的繼承類型 - 我的意思是......這是一個人,那麼你還會稱它爲什麼?無論如何,希望你會對我有一些想法。另外,我對現有的技術並不在意,說實話,我只是幾乎沒有把握目前我正在使用的技術。所以,如果我說過一些矛盾或混淆的話,我希望你能從後面的文章中明白我的要求。

+0

爲了確保我的理解,由自定義屬性引起的耦合是主要問題? – Brook 2011-05-11 03:04:24

+1

儘管您可以將實現放在OO中的數據附近,但我不確定這是否需要良好的OO設計。事實上有時候這是一個糟糕的主意。 – 2011-05-11 06:17:29

+0

@Brook我認爲問題其實是我想要做的只是不可能(或明智的)!我試圖找到一種將功能添加到共享對象(「Person」)的方法,無需將對象耦合到特定於應用程序的(非共享)接口。當然,我需要將Person對象耦合到它所需要的接口。 – 2011-05-13 17:50:39

回答

3

這聽起來像你打破了Single Responsibility Principle

A Person對象應該只是保存個人記錄的數據。然後這些服務將接收一個Person對象並對其進行操作,而不是在執行該操作的Person對象上使用方法。

一個典型的例子是填充Person對象。假設應用程序A從WebService獲取數據,並且應用程序B從數據庫中獲取數據。在這些情況下,我會提供某種Storage服務,您可以撥打以獲取您的Person對象。然後,該存儲的實現可以針對每個應用程序而定,並由應用程序放入您的IOC中,而不是嘗試在共享程序集中使用通用接口。

+0

我認爲我對你的帖子有一個很好的迴應,直到我閱讀SRP;)我必須承認我現在有點困惑,我一直非常自信地認爲向對象添加行爲是「很好的OO設計」。 例如,如果我想要加載客戶訂單,我可以調用aCustomer.GetOrders()而不是aOrderService.GetCustomerOrders(aCustomer) 後者我正在執行;我有一大堆服務對象,我注入我的Presenter對象以及注入其他服務。 – 2011-05-13 17:35:26

0

我可以想到幾種方法來解決這個問題。

  • 分別將每個人/應用程序的行爲分開。在應用程序本身中使用setter執行依賴注入。

Apporach1


public interface IPerson 
{ 
IPersonApp1 Person1 {get; set;} 
IPersonApp2 person2 {get; set;} 
} 

class Person : IPerson 
{ 
IPerson1 Person1 {get; set;} 
IPerson2 Person2 {get; set;} 
} 

public interface IPerson1 
    { 
    // App1 specific behavior here 
    void App1SpecificMethod1(); 
    } 
    class Person1: IPerson1 
    { 
    void App1SpecificMethod1() 
     { 
     // implementation 
     } 
    } 

class App1 
{ 
    IPerson objPerson; 
    // Dependency injection using framework 
    App1(IPerson objPerson) 
    { 
    this.objPerson = objPerson; 
    // Dependency injection using setter 
    this.objPerson.Person1 = new Person1(); 
    } 
} 

  • 分離出特定於每個人/單獨應用的行爲。在Person構造函數中執行依賴注入。

Apporach2


class Person : IPerson 
{ 
IPerson1 Person1 {get; private set;} 
IPerson2 Person2 {get; private set;} 
// DI through constructor. If the type IPerson1 or IPerson2 are not registered, it will be set to null. 
Person(IPerson1 objPerson1, IPerson2 objPerson2) 
{ 
    this.Person1 = objPerson1; 
    this.Person2 = objPerson2; 
} 
} 

Person接口的項目需要有參考IPerson1和IPerson2或者你可以在個人界面項目本身申報IPerson1和IPerson2。

1

我同意卡梅隆麥克法蘭對此:你破壞SRP。

當然OO設計 的一個重要方面是將接近他們一起工作的 數據的操作,這意味着 我的ORM的對象需要有添加到他們那裏 適當

功能

從A放置數據和功能並且B的功能太多是兩個責任。認識SRP幾乎總是會導致在分離的類(數據結構和對象)中分離數據和功能。因此,使用Cameron MacFarlands消化可能是最好的選擇。

+0

我也同意我打破SRP。正如我在對卡梅隆的評論中提到的那樣,我對此感到非常驚訝,並且感覺有點愚蠢,因爲我錯過了這個標記。 我有一些閱讀要做,我必須弄清楚爲什麼我認爲行爲應該添加到對象而不是使用服務對象 – 2011-05-13 17:42:21