2012-12-10 33 views
1

當前我的應用程序的UI層與我的DAL dll耦合。 Dal初始化如下:從用戶界面刪除數據訪問層耦合

//Initialize Data Access for AS400 
Dal = JDE8Dal.Instance; 
Dal.conString = Properties.Settings.Default.conAS400; 

DAL被設定爲單身人士。我認爲強制應用程序有一個實例是一個好主意。

DAL:

public class JDE8Dal 
    { 
     public string conString { get; set; } 
     private static readonly JDE8Dal _instance = new JDE8Dal(); 
     private JDE8Dal() 
     { 
     } 
     public static JDE8Dal Instance 
     { 
      get { return _instance; } 
     } 
     // Methods 
    } 

我BLL會是這個樣子:

namespace YLA.Barcode 
{ 
    public static class YlaBarcodeUtil 
    { 
     public static string LotStripZeroes(string str) 
     { 
      var ret = str; 
      if (str.Trim().StartsWith("00")) 
      { 
       ret = YlaGeneralUtilities.StripLeadingNumofChars(str, 2); 
      } 
      return ret; 
     } 
    } 

public class BarcodeBLL 
{ 
    //DAL INIT HERE? 
} 
} 

現在,我需要建立更多的應用程序,我需要移動到3層架構,並開始閱讀DDD 。

1)如何在BLL中移動DAL處理?只需在我的BLL部分添加初始化?

2)我應該保持我的DAL設計爲單例或不?

+1

我建議你開始閱讀DDD之前試圖想出一個實施。特別是,藍皮書和DDD很快就有關於分層體系結構的一章,可能會有所幫助。調查存儲庫也可能是一個好主意。 – guillaume31

+0

@ guillaume31我真的被迫走向ioc嗎?我的意思是特定的dal不會改變,因爲改變意味着新的ERP和新的erp意味着完全重新設計。所以我認爲在我的情況下,IoC不是必須的 – e4rthdog

+0

根據應用程序的大小和複雜性,如果您想要正確測試代碼,IoC/DI可能是必需的。看到我的答案。 – guillaume31

回答

3

您應該使用控制反轉模式來減少圖層之間的依賴關係。在你的情況下,我會使用構造函數注入作爲您的類所需的數據上下文:

public class BarcodeBLL 
{ 
    private JDE8Dal _context; 

    public BarcodeBLL(JDE8Dal context) 
    { 
     _context = context; 
    } 
} 

數據上下文應該是短暫的對象。如果你正在開發一個Web應用程序,你應該爲每個請求實例化一個數據上下文。我還建議使用ORM(實體框架/ NHibernate)。

+0

當你說短命你究竟是什麼意思?我的dal方法開放時間較晚,每個方法都儘快關閉。我還應該在每一種方法操作中處理dal對象? – e4rthdog

+0

儘可能短暫。例如,完成邏輯操作。 ORM正在緩存數據,如果讓它們長時間保持活動狀態,則本地緩存將處於與數據庫不同的狀態,並且在提交更改時最終會發生衝突。 – Gabriel

+0

而我會在哪裏創建我的JDE8Dal上下文?在這裏傳遞?我無法在我的用戶界面中執行此操作。我應該在哪裏做?在DAL類中?怎麼樣?你能詳細說明嗎? – e4rthdog

0

1:通常情況下,你只需要一個基礎設施層來完成組合。

2:NO BY ALL MEANS。這與「學習編程」接近。使用IOC容器。

0
//Initialize Data Access for AS400 
Dal = JDE8Dal.Instance; 
Dal.conString = Properties.Settings.Default.conAS400; 

該評論具有誤導性。此代碼實際上不初始化數據訪問,但僅設置數據庫連接字符串。這應該在DAL本身而不是在UI中完成。

public class JDE8Dal 
    { 
     public string conString { get; set; } 
     private static readonly JDE8Dal _instance = new JDE8Dal(); 
     private JDE8Dal() 
     { 
     } 
     public static JDE8Dal Instance 
     { 
      get { return _instance; } 
     } 
     // Methods 
    } 

圖層通常不是以這種方式定義的,DAL是程序集/ dll,而不是類。就像你寫的那樣,似乎你想要一個上帝對象,其中定義了所有的持久性邏輯。數據訪問層中的類更加細化和專門化:例如,Repositories/DAO管理一個特定域對象的持久性。

此外,它通常是not a good idea訴諸單身「只是因爲它感覺只有一個實例是正確的」。尤其不是一個可變的單身人士。在你的例子中,任何人都可以更改Dal.Instance.conString,這對單身人士的其他消費者可能會造成嚴重後果。除其他缺點之外。

即使可能會有DAL的一個實現(AS400,看起來),但對於使用依賴注入進行單元測試的合理複雜項目來說,這是個好主意。 DI使您可以輕鬆地將具體的DAL對象實現替換爲在單元測試中更輕量且更實用的假DAL對象。

public class BarcodeBLL 
{ 
    //DAL INIT HERE? 
} 

非,沒有DAL INIT這裏)

業務邏輯層(在DDD域層)不應該DAL的一個參考,DAL應具有對BLL的參考。域對象不應該知道如何堅持自己(持久性無知原則),因爲它有太多的責任(單一職責原則),並且會在BLL和DAL之間產生緊密的耦合,使得重用和維護非常尷尬BLL。

+0

我得到了有關單身人士和DI目的的觀點。我真的沒有得到的是你最後的想法,DAL應該有一個BLL的參考,而不是其他的方式。如果我想在BLL中有一個CheckLotValid邏輯需要2-3個dal方法來運行並返回數據,我將如何執行它,如果我不在BLL中創建我的dal對象? – e4rthdog

+1

DDD將給定的所有業務邏輯都在域圖層中。當您想要從數據庫中提取對象或保留它們時,只需轉到DAL,這通常在應用程序層中完成,或者作爲ORM工具的一部分工作。但是,如果Domain層確實需要訪問DAL,比如說一個Repository,那麼您總是可以將具體的Repository注入到Domain對象中,從而保持BLL和DAL之間的鬆散耦合。 – guillaume31