Статьи

Ориентированный на сообщения объектный дизайн и вызов Джеймса Шора


Джеймс Шор опубликовал архитектурный вызов в своем блоге и лично бросил свою перчатку мне в лицо, чтобы ответить на вызов, используя этот дизайн, ориентированный на сообщения, который я разглагольствовал и бредил.
Конечно, когда я говорю «бросил свою перчатку в лицо», я действительно имею в виду, что он сказал, что было бы интересно посмотреть … но все же! Человек не может отступить от этого! Вот как я ответил на вызов.

 


Вы можете прочитать о его вызове подробно здесь: 
http://jamesshore.com/Blog/Architectural-Design-Challenge.html
 

Подводя итог, идея состоит в том, чтобы создать кодировщик файлов ROT13, TDD и красивый.
В его вызове было две части. Первым было просто сделать все, прочитав весь файл в память. Затем он хотел, чтобы мы усовершенствовали наш дизайн вокруг этой идеи. Как только это будет сделано, мы можем перейти ко второй части задачи, которая потребовала от нас обработки файла при загрузке его с диска и постепенного сохранения его на диск.
 

Чему я научился из этого опыта?
Я чрезвычайно доволен гибкостью и надежностью конструкций, которые я получаю, когда подхожу к вещам с точки зрения сообщений. Бывают моменты, когда это слишком много (не существует законов абсолютности, верно?), Но для любой системы, над которой я работаю, любой реальной сложности, это отличная направляющая рука для меня.
 

Это мое окончательное решение: 
http://github.com/jcbozonier/The-Jim-Shore-Architecture-Challenge
 

Чтобы получить общее представление о том, что я сделал, я представил способ соединения объектов ниже:
 
public class ROT13EncodingFileWriter
{
    public static void Do(ITextHandOff guiWriter, string fromFile, string toFile)
    {
        var configuration = new FileSystemConfiguration();
        var encoder = new ROT13Encoding();
        var fileReader = new OneLineAtATimeFileReader();
        var fileWriter = new OneLineAtATimeFileWriter();
        var encodedTextSubscribers = new[]
                                         {
                                             guiWriter,
                                             fileWriter
                                         }.CreateMultiObserver();

        configuration.SetFileReaderToConfigure(fileReader);
        configuration.SetFileWriterToConfigure(fileWriter);
        fileReader.OnNewTextAvailableNotify(encoder);
        encoder.OnNewEncodedTextAvailableNotify(encodedTextSubscribers);

        configuration.Configure();

        fileReader.SetFilePath(fromFile);
        fileWriter.SetFilePath(toFile);

        fileReader.Read();
    }
}

Первые мои ошибки:
 

1) Эта часть сбивает с толку.
В основном я просто создаю объект, который будет пересылать каждое полученное сообщение обоим другим объектам, но оно не выполняется должным образом:
 
var encodedTextSubscribers = new[]
{
   guiWriter,
   fileWriter
}.CreateMultiObserver();

2) Вместо того, чтобы иметь отдельную команду конфигурации, все, что я хотел настроить, должно было быть настроено на лету.
Задание их для настройки, а затем вызов для настройки происходит слишком хорошо.
 
configuration.SetFileReaderToConfigure(fileReader);
configuration.SetFileWriterToConfigure(fileWriter);
...
configuration.Configure();

3) Строка, где я вызываю fileReader.Read ();
здесь вся система оживает, но, боюсь, это не очевидно.
 

Теперь то, что мне нравится:
 

1) Всякий раз, когда я создаю дизайн, ориентированный на сообщения, я могу обсуждать всю систему, указывая место, где я настраиваю свои зависимости. Весь системный поток может быть не совсем хорошо усваиваемым, но если бы кто-то попытался создать блок-схему из этой конфигурации, им было бы очень легко (у меня есть, и это хорошо подходит для презентаций;)). Другое дело, вместо того, чтобы нуждаться в графике вызовов, который показывает, как объекты общаются друг с другом, те же идеи выпадают из представления о том, как объекты зависят друг от друга в моем опыте.
 

2) Всякий раз, когда я сталкиваюсь с слишком большой болью при таком подходе, это запах, я делаю что-то не так. Пример: во время работы над первой частью задачи я начал писать и тестировать класс, который, по сути, собирался объединить все другие классы вместе поверх класса, который настраивает, какие объекты взаимодействуют друг с другом. По сути, я строил маршрутизатор. Боль для меня заключалась в том, что я создавал ПУТЬ слишком много подделок и нуждался в ПУТИ слишком много о том, что они делают. Поэтому я сделал шаг назад и нарисовал свои объекты на листе бумаги, а затем снова соединил их в соответствии с новым рисунком, который я нарисовал. Вряд ли нужны были какие-либо изменения кода, и это была довольно короткая работа.
 

3) Я склонен писать крошечные объекты.
Некоторые люди ненавидят иметь слишком много предметов или предметов, которые делают мало, поэтому ваши вкусы могут отличаться. Однако я обнаружил, что меньшие, более сфокусированные занятия помогают мне Когда они охватывают буквально только одну ответственность, я считаю, что их легче заменить / изменить, когда они больше не соответствуют моим потребностям, и мне нужно издеваться только тогда, когда это абсолютно необходимо.
 

Если вы не разговаривали со мной или не читали то, что я писал о дизайн-объектах, ориентированных на сообщения, вот краткое краткое изложение:
 

Объектно-ориентированный дизайн сообщений — это философия объектно-ориентированного дизайна, в которой мы рассматриваем объекты как отправку неизменных сообщений / публикацию событий по каналам.
Системы MOOD также полагаются на конфигурацию объектных сетей, чтобы обеспечить взаимодействие между ними. Основным принципом является отсутствие методов получения объектов между объектами (будь то вызовы метода или свойства).
 

4) Мне нравится, как мало кода в моем консольном приложении.
 
namespace ConsoleGUI
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var guiWriter = new GuiWriter();

            ROT13EncodingFileWriter.Do(guiWriter, args[0], args[1]);
        }
    }
}

Это оно! Оставьте мне комментарий, если вы хотите дать свою собственную критику того, что я сделал. Я также призываю вас зайти на сайт Джеймса и надеть свою собственную шляпу на ринг и критиковать проекты других людей (хотя, конечно же, будьте жестче с другими проектами!).