程序到接口而不是实现混淆

时间:2012-06-29 11:02:26

标签: c# oop interface

我正在努力养成编写接口而不是实现的习惯,而在大多数情况下,我可以看到有一些原因让我感到困难。

举一个非常简单的例子:

public interface IAuditLog
{
    void AddLog(string log);
}

public class AuditLog : IAuditLog
{
    public void AddLog(string log)
    {
        //implementation
    }
}

调用审计日志类:

public partial class AuditLogPage : System.Web.UI.Page
{
    protected void btnAddLog_Click(object sender, EventArgs e)
    {
        IAuditLog objAuditLog = new AuditLog();
        objAuditLog.AddLog("test log");
    }
}

我在实例化时仍然需要使用AuditLog,那么重点是什么?如果AddLog方法签名发生变化,我仍然需要浏览所有使用它的页面并修改代码。我错过了这一点吗?

先谢谢你的帮助, Wilky。

4 个答案:

答案 0 :(得分:5)

在示例中,如果您使用FileAuditLogger()DatabaseAuditLogger()切换EventLogAuditLogger(),则无需重写代码即可切换实施。

通常,您使用IoC容器(Autofac,StructureMap,Unity等)自动连接对象实例。因此,您可以拨打new AuditLog()

,而不是致电IoC.Container.Resolve<IAuditLog>()

如果您想了解更多信息,请与我们联系。

答案 1 :(得分:4)

假设有两个AuditLog类

class AuditLogToDatabase : IAuditLog // writes to database

而另一个是

class AuditLogToFile : IAuditLog // writes to file

protected void btnAddLog_Click(object sender, EventArgs e)
{
    IAuditLog objAuditLog = AuditLogFactory.GetAuditLog();
    objAuditLog.AddLog("test log");
}

现在您可以在运行时根据某些配置注入任何类,而无需更改实际实现

答案 2 :(得分:3)

这并不一定意味着您必须实际使用C#interface。 OOP术语中的接口是API的公开可见外观。这是一份合同,应规定外部可见的操作结果。它在表面下的工作原理应该是无关紧要的,这样你就可以随时更换实现。

当然,在这方面,interface是一种能够使用不同实现的方法,但是抽象基类甚至是其他人可以派生的非抽象类也是如此。

但更多的是你的问题的确切点:当然,在实例化一个类时,必须知道它的类型,但你不一定要在那里创建类实例。您可以从外部设置IAuditLog或通过工厂类等获取它,在代码中的确切位置您不知道的是,您获得的确切类型(除了它与之兼容) IAuditLog)。

答案 3 :(得分:1)

当您从类似AuditLog方法的方法创建Factory实例并且从AuditLogXXX接口派生了多个IAuditLog类时,这实际上非常有用。

所以,不要使用这段代码:

IAuditLog objAuditLog = new AuditLog();

在编程接口时,实际上会使用此代码:

IAuditLog objAuditLog = LogFactory.GetAuditLog(); //This call is programmed to an interface

其中GetAuditLog()是在LogFactory类上定义的接口类型方法,如下所示:

class LogFactory
{    
    public IAuditLog GetAuditLog() // This method is programmed to an interface
    {
        //Some logic to make a choice to return appropriate AuditLogXXX instance from the factory
    }    
}