Архитектурный / передовой вопрос о дженериках - PullRequest
3 голосов
/ 16 августа 2011

Я пробираюсь сквозь «шаблоны проектирования с первого взгляда» и хочу немедленно использовать это на практике. Я пишу кусок кода, который связывает приложение с другими приложениями. На самом деле мне нужно сгенерировать электронное письмо, содержащее файл 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
}

Разве это не было бы мило? Но что вы, ребята, думаете об этом подходе? В будущем люди могут создавать новые dataObjects и новые методы отправки, и код все равно будет работать. То, что я пытался сделать, это: запрограммировать интерфейс и извлечь изменяющиеся части. Как насчет этого?

1 Ответ

4 голосов
/ 04 ноября 2011

Это бы сработало, но вы могли бы разделить проблемы еще больше. Вот еще одна версия - сделать DataExchange очень простым и делегировать реальную работу работникам:

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

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

Преобразование будет просто преобразовывать объекты данных в объекты, пригодные для передачи:

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.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...