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

Joc*_*ick 3 c# architecture generics design-patterns

我正在通过“从头开始的设计模式”进行工作,并希望立即在实践中使用它。我正在编写一段代码,将一个应用程序与其他应用程序连接起来。实际上,我需要生成包含XML文件的电子邮件,然后通过电子邮件发送它。但是将来可能需要其他东西。

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

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

  abstract class DataExchange<T,U>
    {
        private T DataObject;
        private U SendMethod;
    }
Run Code Online (Sandbox Code Playgroud)

而SendViaMail就像

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

现在-我可以创建类似的类:

class MyExchange : DataExchange<MyDataObject,SendViaMail> { }
Run Code Online (Sandbox Code Playgroud)

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

private abstract [the type of the T in ISendMethod<T>] PrepareObjectForSending(T dataObject) {
}
Run Code Online (Sandbox Code Playgroud)

Visual Studio会强迫我实现类似的方法:

private abstract System.Net.Mail.Attachment PrepareObjectForSendingMyDataObject dataObject) {
// Serialize XML file and make it into attachment object
}
Run Code Online (Sandbox Code Playgroud)

那不是很甜蜜吗?但是你们如何看待这种方法呢?将来,人们可以创建新的dataObjects和新的sendmethod,并且代码仍然可以使用。我一直试图做的是:针对接口编程并提取变化的部分。这个怎么样?

mik*_*lai 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

class DataToAttachmentConverter : IConverter<DataObject, Attachment>
{
    Attachment Convert(DataObject) { }
}
class DataToXmlConverter : IConverter<DataObject, XmlDocument>
{
    XmlDocument Convert(DataObject) { }
}
Run Code Online (Sandbox Code Playgroud)

发件人只会发送。

class MailSender : ISendMethod<Attachment>
{
    void Send(Attachment) {}
}
class FtpPublisher : ISendMethod<XmlDocument>
{
    void Send(XmlDocument) {}
}
Run Code Online (Sandbox Code Playgroud)

放在一起:

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.
Run Code Online (Sandbox Code Playgroud)