2012-03-14 83 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服务器,您决定使用其他提供程序;如果你没有数据访问层,那么你需要做一个巨大的重构,因为你直接调用数据访问方法。但是,如果您有数据访问层,则只需编写一个新的数据访问层,从抽象数据访问层继承,并且不会更改业务层中的任何内容。

相关问题