为什么我们需要在C#中的UI,业务和数据访问之间的接口

时间:2017-05-24 09:33:14

标签: c# n-tier-architecture 3-tier

我在许多地方看到,当c#程序员使用3轮胎架构时,他们倾向于使用每层之间的接口。例如,如果解决方案是

SampleUI
Sample.Business.Interface
Sample.Business
Sample.DataAccess.Interface
Sample.DataAccess

此处UI通过接口调用业务层,业务以相同的方式调用数据访问。 如果这种方法是为了减少层之间的依赖性,那么它已经与类库一起使用而无需额外使用接口。 代码示例如下,

Sample.Business

public class SampleBusiness{
   ISampleDataAccess dataAccess = Factory.GetInstance<SampleDataAccess>();
   dataAccess.GetSampledata();
}

Sample.DataAccess.Interface

public interface IsampleDataAccess{
   string GetSampleData();
}

Sample.DataAccess

public class SampleDataAccess:ISampleDataAccess{
  public string GetSampleData(){
     returns data;// data from database
  }
}
  1. 介于两者之间有什么好处?
  2. 如果我使用newSampleDataAccess()。SampleData()并删除完整的接口类库怎么办?

2 个答案:

答案 0 :(得分:4)

代码合同

使用接口作为设计过程的一部分有一个显着的优点:它是一份合同。

接口是合同的规范,意思是:

  • 如果我使用(使用)界面,我限制自己使用界面公开的内容。好吧,除非我想玩脏(反射,等等)。

  • 如果我实现界面,我限制自己提供界面公开的内容。

这样做的好处是可以简化开发团队之间的工作分工。它允许层的开发人员提供 cough 接口 cough ,即使在实现此接口之前,下一层也可以使用它来与之通信。

一旦他们同意接口。至少在最小可行接口上。他们可以开始并行开发这些层,已知其他团队将坚持他们的合同。

嘲讽

以这种方式使用接口的一个副作用是,它允许模拟组件的实现。这简化了单元测试的创建。这样,您可以隔离地测试图层的实现。因此,当图层出现故障时,您可以轻松区分 ,因为它有缺陷,并且当图层失败时,因为它下面的图层有缺陷。

对于由单个人开发的项目,或者由于在绘制清晰的线条以分离工作时没有太多困扰的团队,模拟的能力可能是他们的主要动机实现接口。

例如,考虑一下,如果您想测试您的表示层是否可以正确处理分页......但您需要请求数据来填充这些页面。可能是这样的情况:

  • 下面的图层尚未就绪。
  • 数据库尚未提供数据。
  • 它失败了,他们不知道分页代码是否正确,缺陷来自代码中更深层的一点
  • 等等...

无论哪种方式,解决方案都是嘲弄。此外,如果你有模拟接口,那么模拟会更容易。

更改实施

如果由于某种原因,某些开发人员决定他们想要更改其层的实现,他们可以信任接口强加的合同。这样,他们就可以交换实现而无需更改其他层的代码。

是什么原因?

  • 也许他们想测试一项新技术。在这种情况下,他们可能会创建一个替代实现作为实验。此外,他们希望两个版本都能正常工作,以便测试哪一个更好。

    附录:不仅可以测试两个版本,还可以轻松回滚到主版本。当然,他们可以通过源版本控制实现这一目标。因此,我不会考虑回滚作为使用接口的动机。然而,对于任何不使用版本控制的人来说,这可能是一个优势。对于任何不使用它的人......开始使用它!

  • 或许他们需要将代码移植到不同的平台或不同的数据库引擎。在这种情况下,他们可能不想丢弃旧代码......例如,如果他们有运行Windows和SQL Server的客户端以及运行Linux和Oracle的其他客户端,那么维护这两个版本是有意义的。

当然,在任何一种情况下,您都希望能够通过尽可能少的工作来实现这些更改。因此,您不希望更改上面的图层以定位不同的实现。相反,您可能会有某种形式的 factory 反转控制容器,您可以将其配置为使用所需的实现进行依赖注入

减轻变化传播

当然,他们可能决定改变实际的界面。如果在一个层上工作的开发人员在界面上需要额外的东西,他们可以将它添加到界面(给定团队设置的任何方法来批准这些更改),而不会弄乱其他团队正在工作的类的代码上。在源版本控制中,这将减少边际更改。

最后,使用层架构的目的是分离关注点。这意味着改变原因的分离......如果您需要更改数据库,您的更改不应传播到专用于向用户呈现信息的代码中。当然,团队可以通过具体课程来实现这一目标。然而,接口提供了良好且明显的,定义明确的语言支持,阻止了变化的传播。特别是如果团队有关于责任的良好规则(不,我不是指代码问题,我的意思是,开发人员负责做什么)。

答案 1 :(得分:1)

你应该总是使用图层的抽象来具备

的能力
  • 模拟单元测试中的接口
  • 使用虚假实施来加快开发速度
  • 轻松开发替代实施
  • 在不同的实现之间切换
  • ...