2012-03-14 82 views
1

我們通常在我們的項目中使用抽象函數/接口。爲什麼它真的需要?爲什麼我們不能只是去業務邏輯層,數據訪問和表示層只爲什麼在我們的項目中需要接口層/抽象類?

功能展示層:

abc(); 

功能在業務邏輯層:

public void abc() 
    { 
     //Preparing the list 
    } 

功能在數據訪問層:數據訪問SQLServer的層

public abstract void abc(); 

功能:

public override void abc() 
    { 
     //Connection with database 
    } 

問題是:爲什麼需要對數據訪問層?

回答

2

理解這個的最簡單方法是imo,它是一個超過DataLayer的抽象。

您已經設置了從xml文件檢索數據的功能。但有一天,您的產品會向外擴展,並且xml還不夠,就像數據存儲一樣。所以你傳遞給一些嵌入式數據庫:sqlite。但有一天你需要在一些企業環境中重用你的庫。所以,現在你需要制定訪問sqlserveroraclewebservice ....在所有這些變化,你將需要改變不僅實際訪問數據的代碼,但是代碼實際上消耗這一點。那麼在客戶端使用多年的第一個數據訪問代碼並滿意它的代碼呢?如何兼容?

具有抽象如果不是direcly解決了大多數的此類問題,但絕對會讓scallable您的應用程序和變化更有抵抗力,即,在我們的世界,有時發生過於頻繁。

+0

我的問題是改進的。對吧?需要投票重新打開它.... – Pankaj 2012-03-14 13:13:27

+0

我沒有投票結束它之前。 – Tigran 2012-03-14 13:21:46

+0

當你說「backcompatibility怎麼樣?」時無法理解。你能讓它更精確嗎? – Pankaj 2012-03-14 13:28:17

2

一般來說,如果你在代碼中使用的接口,那麼你將在依賴注入的形式獲得代碼manuverability。

這將幫助你更換你的實現部分在例如單元測試期間提供Mock對象特定情況下。

+0

你也可以在這裏聊天http://chat.stackoverflow.com/rooms/8875/discussion-between-pankaj-garg-and-tigran – Pankaj 2012-03-14 15:55:16

0

我想你是在談論Facade層。

這是一個可選層這將簡化業務層的功能。讓我們想象一下,你有一個ProductManager和CategoryManager和你想做的事,其中包括使用兩個(例如,讓我排名前5的產品在所有類別),那麼你可以使用使用ProductManager和CategoryManager一個門面層中的特定作用。

它的靈感來源於Facade Pattern

0

抽象有助於創建功能,無論是通過基類,接口還是組合,在正確使用時,它們都會爲維護,可讀性和代碼的可重用性帶來奇蹟。

關於問題中發佈的代碼,標記爲「數據訪問層」的代碼充當業務層使用的通用抽象。通過這樣做,DAL的特定實現(例如示例中的「數據訪問SQLServer層」下的內容)與業務層分離。現在,您可以訪問不同的數據庫,或者是自動送料測試數據DAL等實現

Repository模式是這個工作一個夢幻般的例子在DAL(例如簡化):

public interface IProductRepository 
{ 
    Product Get(int id); 
    ... 
} 

public class SqlProductRepository : IProductRepository 
{ 

    public Product Get(int id) { ... } 
    ... 
} 

public class MockProductRepository : IProductRepository 
{ 
    private IDictionary<int, Product> _products = new Dictionary<int, Product>() 
    { 
     { 1, new Product() { Name = "MyItem" } } 
    }; 

    public Product Get(int id) { return _products[id]; } 
    ... 
} 

public class AwesomeBusinessLogic 
{ 
    private IProductRepository _repository; 

    public AwesomeBusinessLogic(IProductRepository repository) 
    { 
     _repository = repository; 
    } 

    public Product GetOneProduct() 
    { 
     return _repository.GetProduct(1); 
    } 
} 

即使此示例使用接口,同樣適用於使用基類。美麗的是,現在我可以喂SqlProductRepositoryMockProductRepositoryAwesomeBusinessLogic不必改變任何關於AwesomeBusinessLogic。如果出現其他情況,所需的全部是IProductRepositoryAwesomeBusinessLogic的新實現將仍然處理它,因爲它只通過接口訪問存儲庫。

+0

**現在你可以製作訪問不同數據庫的DAL實現**微軟企業庫在DAL層爲我做這個工作。 – Pankaj 2012-03-19 05:01:58

+0

是的,MS企業庫將幫助您實現這一目標,但如果決定將您的存儲庫作爲WCF數據服務(又名ado.net數據服務)這樣的Web服務公開,那該怎麼辦?如果你已經創建了你的Repository作爲界面,那麼很容易替換它 - 這就是所有的故事......希望你現在明白。 – CSharpenter 2012-03-20 12:44:22

+0

老實說,你沒有得到你。在你的架構中包含WCF如何處理?好吧,爲什麼WCF不能直接與DataBase層交互?每一層都是一個獨立的項目。 – Pankaj 2012-03-21 09:01:57

0

所有以前的答案可能會解釋抽象層的需求,但我仍然想補充一些我的想法。

假設在我們的項目中,我們只是在每一層都有一個服務實現。舉例來說,我有一個接觸DAL和BLL接觸服務,我們可以做這樣的事情

namespace Stackoverflow 
{ 
    public class ContactDbService 
    { 
     public Contact GetContactByID(Guid contactID) 
     { 
      //Fetch a contact from DB 
     } 
    } 
} 

聯繫BLL服務:

namespace Stackoverflow 
{ 
    public class ContactBLLService 
    { 
     private ContactDbService _dbService; 
     public ContactBLLService() 
     { 
      _dbService = new ContactDbService(); 
     } 

     public bool CheckValidContact(Guid contactID) 
     { 
      var contact = _dbService.GetContactByID(contactID); 

      return contact.Age > 50; 

     } 
    } 
} 

沒有定義接口/抽象類。

如果我們這樣做,會有一些明顯的缺點。

  1. 代碼通訊: 試想一下,如果你的項目涉及您的服務可能有很多不同的方法,維護者(除了你)怎麼會知道你的服務怎麼辦?他是否必須閱讀您的整個服務才能修復像InvalidCastOperation這樣的小錯誤? 通過查看界面,人們將直接瞭解該服務的功能(至少)。
  2. 單元測試

    你可以使用一個假/模擬服務提前檢測錯誤,並防止迴歸bug從後來發生的測試邏輯。

  3. 容易改變:

    通過僅通過接口引用其他類/抽象類,你可以很容易地更換後的接口實現工作沒有太多的努力。

+0

**通過僅引用其他類中的接口/抽象類,您可以在以後輕鬆替換那些接口實現,而不需要太多工作。**這可以通過直接在DAL層中完成。爲什麼接口? **通過查看界面,人們可以直接瞭解服務的功能(至少)。**我們通常根據模塊創建功能名稱並根據具體需要創建功能名稱。爲什麼接口? – Pankaj 2012-03-19 04:53:43

+0

我們通常根據模塊和特定需要創建函數名稱。爲什麼接口?如果我沒有任何關於你的功能的描述,我怎麼知道你的班級可以做什麼?我是否需要搜索和閱讀你班級的所有功能,才能知道我應該從BLL打電話給我? – 2012-03-19 05:37:13

+0

你想在功能的標題部分說評論嗎? – Pankaj 2012-03-19 05:58:50

0

抽象類或接口是不是一個真正的單獨的層 - 它應該是你的業務邏輯層的一部分,它定義了實際的數據訪問層(SQL數據存儲庫,例如)需要實現接口爲您的業務層提供數據訪問服務。

如果沒有這個接口,您的業務層將直接依賴於SQL層,而接口將消除這種依賴關係:將抽象類或接口放入業務邏輯層。然後,SQL層(例如一個單獨的程序集)實現抽象類/接口。這樣SQL層依賴於業務層,而不是相反。

結果是一個靈活的應用程序,具有獨立的業務層,可以與多個數據存儲庫一起工作 - 它只需要一個實現業務層定義的接口的層。它不僅僅是關於數據存儲庫 - 你的業務層不應該依賴於上下文(asp.net與控制檯應用程序或服務等),它不應該依賴於用戶界面類,模塊接口與您的業務應用等

+0

爲什麼要爲Interface/Abstract類創建依賴項?基本需求是什麼?任何安全? – Pankaj 2012-03-20 06:45:48

1

爲什麼接口: 你曾經使用C#使用: 使用(FORM F =新表()) { }

在這裏,你會看到你只能使用內的那些類,使用實現IDisposable接口。

兩件彼此不認識的東西只能通過Interfaces進行交互。 接口保證「某些」功能確實已通過此類型實現。

爲什麼層:

所以,你可以有單獨的DLL,這將讓你在不同應用程序中重用。

基本上所有的代碼重用和性能增益。

+0

**接口保證「某些」功能肯定已經被這種類型實現**所以我需要在完整的項目中跟蹤接口的所有實現! – Pankaj 2012-03-21 08:13:52

+0

不是這樣。我們不爲自己寫自己的界面。實現接口的代碼/類告訴別人「嘿,看」,「我是這種類型的,你可以使用我」。 例如你的電腦USB插座。想象一下,你啓動一個數十億美元的公司,提供USB - 超高速,便宜等。但唯一的問題是你連接到PC的USB 的區域可以說是六角形。你也創建了自己的計算機,這個USB有六角形端口。現在告訴我,你的 USB是否被全世界使用?不是!您的USB提供的接口與其他PC不匹配。 – Dhananjay 2012-03-21 09:00:16

+0

但是,USB可以被你的電腦使用,因爲它有六口插座。只要將USB =數據訪問層和計算機作爲UI層即可。如果你不想讓你的數據訪問層被其他項目使用,那麼你就不需要任何接口了。 這個例子代表了爲什麼你需要接口的一小部分,它還有更多的東西......谷歌他們,你會發現更多。 您的USB將只與您同時使用,但速度快而且價格便宜,對其他人無用,只有您可以使用它。 – Dhananjay 2012-03-21 09:00:40

0

抽象使您能夠快速進行重構。考慮使用SQL服務器而不是使用SQL服務器,您決定使用其他提供程序;如果你沒有數據訪問層,那麼你需要做一個巨大的重構,因爲你直接調用數據訪問方法。但是,如果您有數據訪問層,則只需編寫一個新的數據訪問層,從抽象數據訪問層繼承,並且不會更改業務層中的任何內容。

相關問題