Vertical vs. Horizontal Decomposition of Responsibility

The following text is a partial translation of the original English article, performed by ChatGPT (gpt-3.5-turbo) and this Jekyll plugin:

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

Допустим, это наш код (он написан на Ruby):

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

Теперь он только сохраняет строки в файле, что идеально. Класс является связанным и небольшим. Давайте создадим экземпляр этого класса:

Далее, куда мы ставим строки с функциональностью форматирования, которые только что были извлечены? Есть два подхода к разделению ответственности: горизонтальный и вертикальный. Этот подход является горизонтальным:

Чтобы использовать Log и Line вместе, мы должны сделать следующее:

Видите, почему это горизонтально? Потому что этот скрипт видит оба объекта. Они оба находятся на одном уровне видимости. Мы всегда должны общаться с обоими объектами, когда хотим записать строку. Оба объекта Log и Line находятся перед нами. Чтобы записать строку, нам придется иметь дело с двумя классами:

[скрипт] -вниз-> [лог] [скрипт] -вниз-> [строка]

Наоборот, эта декомпозиция ответственности является вертикальной:

Класс TimedLog является декоратором, и вот как мы их используем вместе:

Теперь мы просто добавляем строку в журнал:

Ответственность разложена по вертикали. У нас все еще есть одна точка входа в объект log, но объект «состоит» из двух объектов, один из которых обернут в другой:

[script] -down-> [TimedLog] [TimedLog] -down-> [Log]

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

Translated by ChatGPT gpt-3.5-turbo/42 on 2023-11-17 at 14:40

sixnines availability badge   GitHub stars