有关泛型的体系结构/最佳实践问题

3
我正在学习《Head First设计模式》,并希望能立即将其应用于实践中。 我正在编写一段代码,将一个应用程序与其他应用程序连接起来。实际上,我需要生成一个包含XML文件的电子邮件,并通过电子邮件发送它。但是未来可能需要其他一些内容。
因此,我确定了“变化的事物”: - 传输的数据 - 传输方式(可以是电子邮件,也可以是FTP或另一种数据交换的Web服务)
所以,我: - 创建了一个抽象类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
}

这不是很好吗?但你们对这种方法有什么想法?在未来,人们可以创建新的dataObjects和新的sendmethods,代码仍将有效。我一直在尝试的是:针对接口进行编程并提取可变部分。你觉得怎样?


对我来说,这似乎有点牵强。我可能只会使用一个“枚举”来发送方法。而且你不需要一个泛型来保持数据对象。在我看来,这是一个过于复杂的代码,没有必要这样做。 - Yuck
4
我对Yuck的观点有些认同。仅仅因为某些事情可能会在未来发生改变,并不意味着您应该构建支持该变化的架构。我建议建立系统,使得如果需要时迁移到该架构不是不可能的,但不要全部构建出来。 - Harper Shelby
1
从你在这里写的内容来看,很难看出泛型的使用对你有什么好处。你最好使用DataObject和SendMethod的基类/接口。只有在使用泛型可以使事情变得更容易时才使用它们。 - Kristopher Johnson
感谢Harper和Yuck的建议 - “仅仅因为未来可能会发生变化,并不意味着你应该构建支持这种变化的架构。” 这是一个有趣的观点。读完这本书后,我一直认为必须尽可能地使所有内容都具有动态性,但指出如果没有必要,就不要使事情过于复杂是一件好事。谢谢,我会放弃这个设计,让我的生活更轻松。 - Jochen van Wylick
1个回答

5
这个方法可以解决问题,但你甚至可以更加分离关注点。以下是另一种方式 - 使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.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接