【问题标题】:Architectural/best-practices question about generics关于泛型的架构/最佳实践问题
【发布时间】:2011-11-04 23:09:35
【问题描述】:

我正在研究“头脑优先的设计模式”,并希望立即在实践中使用它。 我正在编写一段将应用程序与其他应用程序连接起来的代码。事实上,我需要生成一封包含 XML 文件的电子邮件并通过电子邮件发送。但将来可能需要其他东西。

因此,我确定了“改变的事物”: - 传输数据 - 传输方式(可以是电子邮件,但也可以是 FTP 或用于其他数据交换的网络服务)

所以,我: - 创建了一个抽象类DataObject - 创建了一个接口 ITransmissionMethod - 创建了一个dataExchange抽象类:

  abstract class DataExchange<T,U>
    {
        private T DataObject;
        private U SendMethod;
    }

SendViaMail 就像

class SendViaMail : ISendMethod<System.Net.Mail.Attachment>
{
    public override void Send(System.Net.Mail.Attachment dataItem)
    {
        throw new NotImplementedException();
    }
}

现在 - 我可以创建如下类:

class MyExchange : DataExchange<MyDataObject,SendViaMail> { }

您如何看待这种方法?现在我真正想做的是在 DataExchange 中创建一个抽象方法,看起来应该像

private abstract [the type of the T in ISendMethod<T>] PrepareObjectForSending(T dataObject) {
}

Visual Studio 会强制我实现如下方法:

private abstract System.Net.Mail.Attachment PrepareObjectForSendingMyDataObject dataObject) {
// Serialize XML file and make it into attachment object
}

那不是很甜蜜吗?但是你们如何看待这种方法?将来,人们可以创建新的数据对象和新的发送方法,并且代码仍然可以工作。我一直在尝试做的是:针对界面编程并提取变化的部分。怎么样?

【问题讨论】:

  • 对我来说似乎有点做作。我可能只是使用enum 作为发送方法。而且您不需要泛型来保留数据对象。恕我直言,这本身就是一个代码过于复杂的好例子。
  • 我半同意Yuck的观点。仅仅因为某些事情可能在未来发生变化并不意味着您应该构建架构来支持它。我建议对系统进行设置,以便在必要时迁移到该架构并非不可能,但不要全部构建。
  • 从您在此处所写的内容来看,很难看出仿制药的用途能为您带来什么。使用 DataObject 和 SendMethod 的基类/接口可能会更好。仅在使事情变得更容易时才使用泛型。
  • 感谢 Harper 和 Yuck - “仅仅因为某些事情可能会在未来发生变化并不意味着您应该构建架构来支持它。”这是一个有趣的观点。读这本书让我觉得我必须让一切都尽可能动态,但指出如果没有必要,你不想让事情变得太复杂是件好事。谢谢,我会放弃这个设计,让我的生活更轻松。

标签: c# design-patterns generics architecture


【解决方案1】:

这可行,但您可以进一步分离关注点。这只是另一个版本 - 让 DataExchange 变得非常简单,并将实际工作委托给工作人员:

class DataExchange<TDataObject, TTransmissionObject>
{
    IConverter<TDataObject, TTransmissionObject> conterver;
    ISendMethod<TTransmissionObject> sender;

    public Send(TDataObject dataObject)
    {
        TTransmissionObject tro = conterver.Convert(dataObject);
        sender.Send(tro);
    }
}

Converts 只会将数据对象转换为适合传输的对象:

class DataToAttachmentConverter : IConverter<DataObject, Attachment>
{
    Attachment Convert(DataObject) { }
}
class DataToXmlConverter : IConverter<DataObject, XmlDocument>
{
    XmlDocument Convert(DataObject) { }
}

发件人只会发送。

class MailSender : ISendMethod<Attachment>
{
    void Send(Attachment) {}
}
class FtpPublisher : ISendMethod<XmlDocument>
{
    void Send(XmlDocument) {}
}

综合起来:

var exchanges = new [] {
      new DataExchange<DataObject, Attachment>( new DataToAttachmentConverter(), new MailSender()),
      new DataExchange<DataObject, XmlDocument>( new DataToXmlConverter(), new FtpPublisher())
};

foreach(var ex in exchanges)
    ex.Send(dataObject); //send as an attachent and put to ftp site.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-26
    • 1970-01-01
    • 2018-03-08
    • 1970-01-01
    • 2019-06-07
    • 1970-01-01
    • 2013-01-04
    • 2013-07-22
    相关资源
    最近更新 更多