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

C# 为什么在C中需要UI、业务和数据访问之间的接口,c#,n-tier-architecture,3-tier,C#,N Tier Architecture,3 Tier,我在很多地方看到,当NC程序员使用3-tire架构时,他们倾向于在每一层之间使用接口。例如,如果解决方案是 SampleUI Sample.Business.Interface Sample.Business Sample.DataAccess.Interface Sample.DataAccess 在这里,UI通过接口调用业务层,业务以相同的方式调用数据访问。 如果这种方法是为了减少层之间的依赖关系,那么它已经在类库中就位,而不需要额外使用接口。 下面是代码示例 样品.业务 Sample.D

我在很多地方看到,当NC程序员使用3-tire架构时,他们倾向于在每一层之间使用接口。例如,如果解决方案是

SampleUI
Sample.Business.Interface
Sample.Business
Sample.DataAccess.Interface
Sample.DataAccess
在这里,UI通过接口调用业务层,业务以相同的方式调用数据访问。 如果这种方法是为了减少层之间的依赖关系,那么它已经在类库中就位,而不需要额外使用接口。 下面是代码示例

样品.业务 Sample.DataAccess 这两者之间的推论有什么了不起的作用吗? 如果我使用newSampleDataAccess.SampleData并删除完整的接口类库会怎么样?
您应该始终使用层的抽象来实现该功能

在单元测试中模拟接口 为了更快的开发而使用假实现 轻松开发替代实现 在不同的实现之间切换 ...
您应该始终使用层的抽象来实现该功能

在单元测试中模拟接口 为了更快的开发而使用假实现 轻松开发替代实现 在不同的实现之间切换 ... 代码合同 在设计过程中使用接口有一个显著的优点:它是一个契约

接口是合同的规范,其含义是:

如果我使用了这个接口,我就限制自己使用这个接口公开的内容。好吧,除非我想扮演肮脏的反射,等等

如果我实现了接口,我将限制自己提供接口公开的内容

这样做的好处是,它简化了开发团队中各层之间的工作划分。它允许一个层的开发人员提供一个cough接口,下一层可以使用它与之通信。。。甚至在实现这种接口之前

一旦他们就接口达成一致。至少在最小可行接口上。他们可以开始并行开发这些层,因为他们知道另一个团队将维护他们在合同中的角色

嘲笑 以这种方式使用接口的一个副作用是,它允许模拟组件的实现。这简化了单元测试的创建。通过这种方式,您可以单独测试层的实现。因此,您可以很容易地区分何时一个层因为有缺陷而失败,何时一个层因为它下面的层有缺陷而失败

对于由单个个人开发的项目,或者由一个团队开发的项目,他们不需要为单独的工作划清界限,模仿的能力可能是他们实现接口的主要动机

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

下面的图层还没有准备好。 数据库尚未提供数据。 这是失败的,他们不知道分页代码是否正确,因为缺陷来自代码中更深的一点 等等… 无论哪种方式,解决方案都是嘲弄。此外,如果您有要模拟的接口,则模拟更容易

更改实现 如果出于任何原因,一些开发人员决定更改其层的实现,那么他们可以信任接口强加的契约。这样,他们就可以交换实现,而无需更改其他层的代码

什么原因

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

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

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

当然,无论哪种情况,您都希望通过尽可能少的工作来实现这些更改。因此,您不希望更改上面的层以针对不同的实现。相反,您可能会有某种形式的工厂或反转控制容器,您可以将其配置为使用所需的实现进行依赖项注入

缓解变化传播 当然,他们可能会决定更改实际的接口。如果开发人员正在进行 一个层需要在接口上添加一些额外的东西,他们可以将它添加到接口中,只要团队设置了任何方法来批准这些更改,而不会弄乱其他团队正在处理的类的代码。在源代码版本控制中,这将减轻页边距的更改

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

代码合同 在设计过程中使用接口有一个显著的优点:它是一个契约

接口是合同的规范,其含义是:

如果我使用了这个接口,我就限制自己使用这个接口公开的内容。好吧,除非我想扮演肮脏的反射,等等

如果我实现了接口,我将限制自己提供接口公开的内容

这样做的好处是,它简化了开发团队中各层之间的工作划分。它允许一个层的开发人员提供一个cough接口,下一层可以使用它与之通信。。。甚至在实现这种接口之前

一旦他们就接口达成一致。至少在最小可行接口上。他们可以开始并行开发这些层,因为他们知道另一个团队将维护他们在合同中的角色

嘲笑 以这种方式使用接口的一个副作用是,它允许模拟组件的实现。这简化了单元测试的创建。通过这种方式,您可以单独测试层的实现。因此,您可以很容易地区分何时一个层因为有缺陷而失败,何时一个层因为它下面的层有缺陷而失败

对于由单个个人开发的项目,或者由一个团队开发的项目,他们不需要为单独的工作划清界限,模仿的能力可能是他们实现接口的主要动机

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

下面的图层还没有准备好。 数据库尚未提供数据。 这是失败的,他们不知道分页代码是否正确,因为缺陷来自代码中更深的一点 等等… 无论哪种方式,解决方案都是嘲弄。此外,如果您有要模拟的接口,则模拟更容易

更改实现 如果出于任何原因,一些开发人员决定更改其层的实现,那么他们可以信任接口强加的契约。这样,他们就可以交换实现,而无需更改其他层的代码

什么原因

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

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

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

当然,无论哪种情况,您都希望通过尽可能少的工作来实现这些更改。因此,您不希望更改上面的层以针对不同的实现。相反,您可能会有某种形式的工厂或反转控制容器,您可以将其配置为使用所需的实现进行依赖项注入

缓解变化传播 当然,他们可能会决定更改实际的接口。如果在一个层上工作的开发人员需要在接口上添加一些额外的东西,那么他们可以根据团队为批准这些更改而设置的任何方法将其添加到接口中,而不会弄乱其他团队正在处理的类的代码。在源代码版本控制中,这将减轻页边距的更改

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

可能是为了易于测试。你问的是“为什么”…我们无法读懂他们的想法来告诉他们动机或目标。然而,我们或许可以回答它有什么优势。虽然我认为,最好是问它有什么优势,而不是问他们为什么这样做。编辑:我想说的是,它工作得更好,这只是我的观点。读一读关于固态、松散耦合和依赖注入的书。基本上,如果您需要切换出一个层,那么只要新层实现了接口,就不需要进行其他更改。这使类更加独立。如果您使用特定的类SampleDataAccess,那么您的业务层将始终依赖于该特定实现。如果您使用该接口,以后可以在以不同方式实现ISampleDataAccess的类之间切换,例如,一个类从数据库获取数据,而另一个类仅读取xml文件。您需要了解。可能是为了易于测试。你问的是“为什么”…我们无法读懂他们的想法来告诉他们动机或目标。然而,我们或许可以回答它有什么优势。虽然我认为,最好是问它有什么优势,而不是问他们为什么这样做。编辑:我想说的是,它工作得更好,这只是我的观点。读一读关于固态、松散耦合和依赖注入的书。基本上,如果您需要切换出一个层,那么只要新层实现了接口,就不需要进行其他更改。这使类更加独立。如果您使用特定的类SampleDataAccess,那么您的业务层将始终依赖于该特定实现。如果您使用该接口,以后可以在以不同方式实现ISampleDataAccess的类之间切换,例如,一个类从数据库获取数据,而另一个类仅读取xml文件。您需要了解。
public class SampleBusiness{
   ISampleDataAccess dataAccess = Factory.GetInstance<SampleDataAccess>();
   dataAccess.GetSampledata();
}
public interface IsampleDataAccess{
   string GetSampleData();
}
public class SampleDataAccess:ISampleDataAccess{
  public string GetSampleData(){
     returns data;// data from database
  }
}