Kev*_*vin 21 c# oop design-patterns interface
几年前我被迫进入一个工作中的软件项目,并被迫快速学习C#.我的编程背景很弱(经典ASP).
多年来我学到了很多东西,但由于我学习C#的强制性,我还有很多基本概念.
具体来说,一个界面.我理解基础知识,但在编写应用程序时,我很难弄清楚它的实际用途.为什么要为他们的应用程序编写接口?
谢谢凯文
And*_*mer 16
界面说明了某些东西应该如何运作.将其视为合同或模板.它是Inverson of Control或Dependancy Injection等关键.
我使用Structure Map作为我的IoC容器.这允许我为我的所有类定义一个接口.你可能会说的地方
Widget w = new Widget();
Run Code Online (Sandbox Code Playgroud)
我会说
IWidget w = ObjectFactory.GetInstance<IWidget>();
Run Code Online (Sandbox Code Playgroud)
这是非常强大的,因为我的代码并不一定说Widget真正是什么.它只知道Widget可以基于IWidget的界面做什么.
这有一些很强大的功能,因为现在我使用的是IoC容器,我可以做一些更好的东西.在我需要使用Widget的单元测试中,我可以为Widget创建一个模拟器.所以说我的Widget通过连接到数据库或Web服务来做一些非常强大的功能,我的模拟可以模拟连接到这些资源并返回给我的存根数据.这使我的测试运行得更快,并且行为更加可靠.因为我正在使用StructureMap,所以我可以告诉StructureMap在我的代码的生产使用期间加载我的Widget的实际实现,并且在测试期间以编程方式或通过配置来加载Widget的模拟版本.
此外,因为我使用的是IoC容器,所以我可以为我的应用程序提供很酷的新功能,例如编写三种不同的缓存数据的方法.我可以使用Lucene.NET等工具为本地缓存创建一个本地开发人员框缓存.我可以让开发服务器使用.NET缓存,它可以在一个盒子上运行.然后我可以为生产服务器提供第三个选项,使用缓存层,如MemCache Win32或Velocity.只要所有三个缓存实现都符合相同的接口,它们的实际实现根本不涉及我(或我的代码).我只是要求StructureMap获取当前的环境实现,然后开始工作.
如果您完全遵循依赖注入,那么接口在这里也可以使用诸如StructureMap之类的IoC容器,因为我可以在我的类的构造函数中通过接口声明类的用法.
public class Widget(IWidgetRepository repository, IWidgetService service) : IWidget
{
//do something here using my repository and service
}
Run Code Online (Sandbox Code Playgroud)
然后当我通过StructureMap这样创建一个Widget实例时
IWidget widget = ObjectFactory.GetInstance<IWidget>();
Run Code Online (Sandbox Code Playgroud)
请注意,我没有在构造函数中指定存储库或服务.StructureMap通过构造函数中指定的接口知道如何获取适当的实例并将其传递给它们.这使得代码非常强大和干净!
所有这些都来自Interfaces的简单定义以及它们的一些巧妙用法!
基本情况是"IWriter"案例.
假设您正在创建一个可以写入控制台的类,它具有各种有用的函数,如write()和peek().
然后,您想编写一个可以写入打印机的类,因此您不必重新创建新类,而是使用IWriter接口.
现在关于接口的很酷的事情是你可以编写所有的编写代码,而不必事先知道你的写入目标是什么,然后当用户决定(在运行时)天气他想要写入控制台或打印机时,你只需要定义作为控制台/打印机编写器的对象,您不需要更改编写代码中的任何内容,因为它们都使用相同的前端(接口).
一个简单的答案: 使用接口来编写合同而不是实现.
怎么可能有帮助? 开始使用接口将(希望)让你习惯于更松散地耦合类.当您针对自己的具体类进行编码时,很容易开始调用数据结构而不必严格分离关注点.你最终得到的课程"知道"关于其他课程的一切,事情会变得非常混乱.通过将自己限制为接口,您只能确保它满足接口的合同.它注入了一种有时有助于紧密耦合的摩擦力.