【问题标题】:Should an interface expose properties of an object or the object itself接口应该暴露对象的属性还是对象本身
【发布时间】:2017-10-06 13:42:00
【问题描述】:

我想知道,设计具有特定意图的界面的最佳做法是什么? 例如,假设我想实现一个接口来将一个对象标记为可发送电子邮件,即 IEmailable。最好在 ConvertToEmail() 的该接口上只使用一种方法,该方法将返回电子邮件类型的对象,并设置主题和正文,或者最好具有地址、正文、主题的接口属性,所以使用接口处理对象的方法可以随意操作和创建电子邮件?

【问题讨论】:

  • 这个问题比客观更主观。这实际上取决于用例,接口的典型用途是在多个类之间共享行为和属性
  • 我主要根据您是否需要其中一个功能而没有其他功能来决定这一点 - 如果您总是调用所有这些功能,只需调用一次
  • 看看 .NET 是如何做到的。可能会给你一些想法:msdn.microsoft.com/en-us/library/…

标签: c# interface coding-style standards


【解决方案1】:

将电子邮件功能拆分为自己的接口和类可能是值得的,例如

public interface IEmailConverter<T>
{
    Email ConvertToEmail(T source)
}

我会留下地址和主题。原因是

  • 如果您发送电子邮件的详细信息发生变化,您将发送电子邮件的任何对象都不必更改。
  • 在某些时候,您可能希望通过多种方式向同一个班级发送电子邮件。如果该类“拥有”自己的电子邮件转换,那么就没有办法支持它。
  • 在不知道具体细节的情况下,生成电子邮件可能是与班级主要职责分开的一项职责。

更进一步 - 如果您努力将对象格式化为电子邮件,然后发现您想做的不仅仅是通过电子邮件发送它,该怎么办?也许将对象格式化为文本应该是它自己的责任,比如

public interface ITextFormatter<T>
{  
    string ConvertToText(T source)
}

然后其他步骤 - 添加主题、地址、其他文本等 - 将更加可重用。只有与对象本身相关的部分(将其值提取到文本消息中)才属于新类。

在某些情况下甚至有一个默认实现可能会起作用(取决于您的类的外观以及覆盖 ToString 是否有意义。)

public class TextFormatter<T> : ITextFormatter<T>
{
    public virtual string ConvertToText(T source)
    {
        return source.ToString();
    }
}

然后您可以根据需要创建替代实现,例如

public class FooPlainTextFormatter : ITextFormatter<Foo>

public class FooHtmlFormatter : IHtmlFormatter<Foo>

【讨论】:

    猜你喜欢
    • 2018-06-19
    • 2017-08-23
    • 2016-05-14
    • 2012-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-01
    • 1970-01-01
    相关资源
    最近更新 更多