2011-09-21 73 views
0

現在我正在開發一個VB6開發的非常大的銀行解決方案。該應用程序是大規模的基於表單的,缺乏分層結構(數據訪問,業務邏輯和表單操作的所有代碼都在單一表單類中)。我的工作是現在重構這段代碼。我正在用C#編寫適當的業務邏輯層和數據訪問層,並且表單將保留在VB中。層架構的最佳實踐是什麼?

以下是代碼片段:

public class DistrictDAO 
{ 
    public string Id{get;set;} 
    public string DistrictName { get; set; } 
    public string CountryId { get; set; } 
    public DateTime SetDate { get; set; } 
    public string UserName { get; set; } 
    public char StatusFlag { get; set; } 
} 

區實體類,爲什麼它的擴展名是DAO,我不是不清楚。

public class DistrictGateway 
{ 
    #region private variable 
    private DatabaseManager _databaseManager; 
    #endregion 

    #region Constructor 
    public DistrictGateway(DatabaseManager databaseManager) { 
     _databaseManager = databaseManager; 
    } 
    #endregion 

    #region private methods 
    private void SetDistrictToList(List<DistrictDAO> dataTable, int index, DistrictDAO district){ 
     // here is some code for inserting 
    }  
    #endregion 

    #region public methods 
     try 
     { 
     /* 
     query and rest of the codes 
     */  

     } 
     catch (SqlException sqlException) 
     { 
      Console.WriteLine(sqlException.Message); 
      throw; 
     } 
     catch (FormatException formateException) 
     { 
      Console.WriteLine(formateException.Message); 
      throw; 
     } 
     finally { 
      _databaseManager.ConnectToDatabase(); 
     } 


    public void InsertDistrict() { 
     // all query to insert object 
    } 

    public void UpdateDistrict() { 

    } 
    #endregion 
} 

DistrictGateway類負責數據庫查詢處理 現在是業務層。

public class District 
{ 
    public string Id { get; set; } 
    public string DistrictName { get; set; } 
    public string CountryId { get; set; } 
} 


public class DistrictManager 
{ 
    #region private variable 
    private DatabaseManager _databaseManager; 
    private DistrictGateway _districtGateway; 
    #endregion 

    #region Constructor 
    public DistrictManager() { 
     // Instantiate the private variable using utitlity classes 
    } 
    #endregion 

    #region private method 
    private District TransformDistrictBLLToDL(DistrictDAO districtDAO) { 

     // return converted district with lots of coding here 
    } 

    private DistrictDAO TransformDistrictDLToBLL(District district) 
    { 

     // return converted DistrictDAO with lots of coding here 
    } 

    private List<District> TransformDistrictBLLToDL(List<DistrictDAO> districtDAOList) 
    { 

     // return converted district with lots of coding here 
    } 

    private List<DistrictDAO> TransformDistrictDLToBLL(List<District> district) 
    { 

     // return converted DistrictDAO with lots of coding here 
    } 


    #endregion 

    #region public methods 
    public List<District> GetDistrict() { 
     try 
     { 
      _databaseManager.ConnectToDatabase(); 
      return TransformDistrictBLLToDL( _districtGateway.GetDistrict()); 

     } 
     catch (SqlException sqlException) 
     { 
      Console.WriteLine(sqlException.Message); 
      throw; 
     } 
     catch (FormatException formateException) 
     { 
      Console.WriteLine(formateException.Message); 
      throw; 
     } 
     finally { 
      _databaseManager.ConnectToDatabase(); 
     } 
    } 

    #endregion 

這是業務層的代碼。

我的問題是:

  1. 它是一個完美的設計?
  2. 如果不是,這裏有什麼缺陷?
  3. 我認爲,這個代碼複製try catch塊
  4. 什麼可以很好的設計,這種實現
+3

可能在這裏有更多的運氣:http://codereview.stackexchange.com/ – Brook

回答

0

完美?沒有這樣的事。如果你不得不問,這可能是錯誤的。即使現在它「完美」了,也不會有一次和熵得到它。

當你需要擴展它的時候,你做得如何的措施將會到來。如果您的更改正確無誤,您表現良好。如果您覺得您要與遺留代碼添加更改,請弄清楚您做錯了什麼並重構它。

瑕疵?很難說。我現在沒有足夠的精力,時間或動力來深入挖掘。

無法弄清楚你的意思#3。

典型分層看起來像這樣,用箭頭示出的依賴關係:

view <- controller -> service +-> model <- persistence (service knows about persistence) 

有橫切關注各層:

  • 視圖知道介紹,定型,和定位。它做任何驗證都可以改善用戶體驗,但不包括業務規則。
  • 控制器與視圖密切相關。它關心來自視圖的綁定和驗證請求,路由到適當的服務,錯誤處理以及路由到下一個視圖。而已。業務邏輯屬於服務,因爲您希望它對於網頁,平板電腦,手機等是相同的。
  • 服務是業務邏輯所在的地方。它擔心根據業務規則進行驗證,並與模型和持久層協作來完成用例。它知道用例,工作單元和事務。
  • 模型對象可以是值對象,如果您更喜歡更實用的風格或者如果您傾向於使用更豐富的業務邏輯。
  • 持久性隔離了所有數據庫交互。

如果您使用像Spring這樣的包含面向方面編程的框架,您可以將安全,事務,監視,日誌記錄等橫切關注點視爲方面。

0

雖然,你並不是真的在這裏問一個具體的問題,但似乎你可能只需要一些一般指導,讓你走上正確的道路。由於我們對整個應用程序沒有深入的瞭解,因此爲您提供一種單一的方法論會很奇怪。

最近,n層體系結構似乎成爲一個受歡迎的問題,但它引發了我寫博客系列。檢查這些SO問題和博客文章。我認爲他們會對你有很大的幫助。

博客上N層架構系列(帶有示例代碼)

0

對於一個大的項目,我會推薦MVVM模式讓你將能夠完全測試您的代碼,並且稍後將更容易擴展或更改其部分內容。即使您可以更改UI,而無需更改其他圖層中的代碼。

0

如果你的工作是首先的重構代碼,然後問你的老闆,如果你要真的,真的應該只是重構它功能添加到它。在這兩種情況下,您都需要圍繞該代碼進行自動化測試。如果你很幸運,你應該增加功能,那麼你至少有一個起點和一個目標。否則,你必須自己挑選出發點,沒有目標。你可以無休止地重構代碼。如果沒有目標,這可能會非常令人沮喪。

沒有測試重構代碼的災難。重構代碼意味着改進其結構而不改變其行爲。如果你沒有做任何測試,你不能確定你沒有破壞什麼。由於您需要定期進行大量測試,因此這些測試必須是自動化的。否則,您會花費太多時間進行手動測試。

遺留代碼很難壓入某些測試工具。您需要修改它才能獲得可測試性。你在代碼中包裝測試的努力將隱含地導致一些分層的代碼結構。

現在有母雞和雞蛋的問題:你需要重構代碼才能測試它,但是你現在沒有測試。答案是從「防禦型」重構技術開始,並進行手動測試。你可以在Micheal Feather的書Working Effectively with Legacy Code中找到關於這些技術的更多細節。如果你需要重構很多遺留代碼,你應該閱讀它。這真是讓人大開眼界。

您的問題:

  1. 沒有完美的設計。只有潛在的更好的。
  2. 如果應用程序沒有任何單元測試,那麼這是最大的缺陷。首先介紹測試。另一方面:這些代碼片段一點也不差。看來DistrictDAO就像District的技術版本。也許有人嘗試引入一些領域模型。並且:至少DistrictGatewayDatabaseManager注入爲構造函數參數。我看到更糟。
  3. 是的,try-catch塊可以被看作代碼重複,但這並不是什麼不尋常的事情。您可以嘗試使用Exception類的明智選擇來減少catch子句。或者你可以使用委託或使用一些AOP技術,但是這會使代碼變得不可讀。欲瞭解更多信息,請參閱this other question
  4. 將遺留代碼放入一些測試工具。一個更好的設計將隱含出現。

任何方式:首先澄清你的老闆與重構代碼意味着什麼。只是在沒有某個目標的情況下重構代碼並不是富有成效的,不會讓老闆高興。