Чистая архитектура
Ниже представлены выдержки (к некоторым также мои комментарии) к пока ещё не прочитанной мной полностью книге. На текущий момент я уже не помню, откуда я узнал о ней.
Предисловие
... они [прямоугольники в Powerpoint] представляют определённый взгляд на архитектуру, но принимать прямоугольники за общую картину, отражающую архитектуру, значит не получить ни общей картины, ни понятия об архитектуре: архитектура программного обеспечения ни на что не похожа.
Возможно, нет смысла говорить о законах физики и физических масштабах применительно к АПО, но мы действительно учитываем некоторые физические ограничения.
ПО можно сравнить с такой материей, как мечты, но ему приходится работать в реальном, физическом мире.
Архитектура отражает важные проектные решения по формированию системы, где важность определяется стоимостью изменений.
Она [система координат[1]] помогает дать качественную оценку архитектуре - хорошая она или нет: хорошая архитектура отвечает потребностям пользователей, разработчиков и владельцев не только сейчас, но продолжит отвечать им в будущем.
Если вы думаете, что хорошая архитектура стоит дорого, попробуйте плохую архитектуру.
Типичные изменения, происходящие в процессе разработки системы, не должны быть дорогостоящими, сложными в реализации; они должны укладываться в график развития проекта и в рамки дневных или недельных заданий.
Архитектура - это набор верных решений, которые хотелось бы принять на ранних этапах работы над проектом, но которые не более вероятны, чем другие.
Здесь Рольф указывает на то, что сложно предугадать, какие именно решения окажутся верными. |
Анализ прошлого сложен; понимание настоящего в лучшем случае переменчиво; предсказание будущего нетривиально.
К цели ведёт много путей.
Вспоминается "Задачи можно решать по-разному". |
Он [третий, чистый путь - два других чуть выше по тексту]:
учитывает природную гибкость программного обеспечения и стремится сохранить её как основное свойство системы.
учитывает, что мы оперируем неполными знаниями, и, будучи людьми, неплохо приспособились к этому.
играет больше на наших сильных сторонах, чем на слабостях.
Хорошая архитектура основывается
скорее
на понимании движения к цели как непрерывного процесса исследований, а не на понимании самой цели как зафиксированного артефакта.
Архитектура - это гипотеза, которую требуется доказать реализацией и оценкой.
Чтобы пойти по этому [третьему, чистому] пути, нужно быть усердным и внимательным, нужно уметь думать и наблюдать, приобретать практические навыки и осваивать принципы. Сначала кажется, что это долгий путь, но в действительности всё зависит от темпа вашей ходьбы.
Поспешай не торопясь.
Об этом автор упоминает ещё на стр. 31 в строках "чем больше спешишь, тем меньше успеваешь." |
Получайте удовольствие от путешествия.
Вступление
Все архитектуры подчиняются одним и тем же правилам!
Правила создания архитектур не зависят от любых других переменных.
Выводы, к которым Роберт С. Мартин пришёл благодаря опыту, накопленному им в процессе создания очень многих систем. |
... важное сходство современного ПО и прошлого ПО: и то и другое сделано из того же материала. Оно состоит из инструкций
if
, инструкций присваивания и цикловwhile
.... программный код до сих пор состоит из последовательностей операций, условных инструкций и итераций, как и в 1950-х и 1960-х годах.
... основные строительные блоки компьютерных программ остались прежними.
... неизменность принципов программирования - вот причина общности правил построения программных архитектур для систем разных типов.
[Эти] Правила определяют последовательность и порядок компоновки программ из строительных блоков.
И поскольку сами строительные блоки являются универсальными и не изменились с течением времени, правила их компоновки также являются универсальными и постоянными.
Именно указанным в цитате выше правилам, не стареющим и не изменяющимся, посвящена эта книга. |
Часть I
Введение
... заставить что-то работать - один раз - не очень сложно.
... когда создатся правильный программный код, происходит что-то необычное:
вам не требуются толпы программистов для поддержки его работоспособности;
вам не нужна объёмная документация с требованиями и гигантские баг-трекеры;
вам не нужны огромные опенспейсы, работающие круглые сутки без выходных.
Правильный программный код не требует больших трудозатрат на своё создание и сопровождение.
Изменения вносятся легко и быстро.
Ошибки немногочислены.
Трудозатраты минимальны, а функциональность и гибкость - максимальны.
Хорошая архитектура оказывает на систему, проект и коллектив разработчиков невероятный эффект.
Выше немного изменил исходный текст автора. |
Плохой код и неудачный дизайн обладают сопротивлением.
В нашей среде чаще встречается опыт борьбы с плохим дизайном, чем получение удовольствия от воплощения хорошо продуманной архитектуры.
1. Что такое дизайн и архитектура?
Прежде всего, я утверждаю, что между этими понятиями [дизайн и архитектура] нет никакой разницы. Вообще никакой.
Слово "архитектура" часто используется в контексте общих рассуждений, когда не затрагиваются низкоуровневые детали, а слово "дизайн" обычно подразумевает организацию и решение на более низком уровне.
Но такое разделение бессмысленно, когда речь идёт о том, что делает настоящий архитектор.
... низкоуровневые детали и высокоуровневые решения вместе составляют дизайн дома.
То же относится к архитектуре ПО. Низкоуровневые детали и высокоуровневая структура являются частями одного целого. Они образуют сплошное полотно, определяющее форму системы. Одно без другого невозможно; нет никакой чёткой линии, которая разделяла бы их.
Есть просто совокупность решений разного уровня детализации.
Я бы сказал так: "Архитектура определяется одновременно низкоуровневыми деталями и высокоуровневой структурой, вместе составляющими совокупность решений разного уровня детализации". |
Цель?
Цель архитектуры ПО - уменьшить человеческие трудозатраты на создание и сопровождение системы.
Мерой качества дизайна может служить простая мера трудозатрат, необходимых для удовлетворения потребностей клиента.
Если трудозатраты невелики и остаются небольшими в течение эксплуатации системы, система имеет хороший дизайн. Если трудозатраты увеличиваются с выходом каждой новой версии, система имеет плохой дизайн.
Таким образом, хорошая архитектура системы - это та архитектура, при которой трудозатраты на:
|
Причины неприятностей
Когда системы создаются второпях, когда увеличение штата программистов - единственный способ продолжать выпускать новые версии и когда чистоте кода или дизайну уделяется минимум внимания или не уделяется вообще, можно даже не сомневаться, что такая тенденция рано или поздно приведёт к краху.
С точки зрения разработчиков, такая ситуация [2] выглядит очень удручающе, потому все они продолжают трудиться с полной отдачей сил. Никто не отлынивает от работы.
... несмотря на сверхурочный труд и самоотверженность, они просто не могут произвести больше. Все их усилия теперь направлены не на реализацию новых функций, а на борьбу с беспорядком.
Большую часть времени они заняты тем, что переносят беспорядок из одного места в другое, раз за разом, чтобы получить возможность добавить ещё одну мелочь.
Что не так?
Притча [басня Эзопа о Зайце и Черепахе] подчеркивает глупость самонадеянности.
Часть их [разработчиков] мозга спит - та часть, которая знает, что хороший, чистый, хорошо проработанный код играет немаловажную роль.
... разработчики никогда не переключают режим работы [см. причину на стр. 31]. Они не могут вернуться и навести порядок, потому что должны реализовать следующую новую функцию, а потом ещё одну, и ещё, и ещё. В результате беспорядок нарастает, а продуктивность стремится к своему пределу около нуля.
... многие разработчики излишне уверены в своей способности оставаться продуктивными.
... ползучий беспорядок в коде, иссушающий их [разработчиков] продуктивность, никогда не спит и никогда не бездействует. Если впустить его, он уменьшит производительность до нуля за считанные месяцы.
Самая большая ложь … - что грязный код поможет им [разработчикам] быстро выйти на рынок, но в действительности он затормозит их движение в долгосрочной перспективе. Разработчики, уверовавшие в эту ложь, проявляют самонадеянность Зайца, полагая, что в будущем смогут перейти от создания беспорядка к наведению порядка. Но они допускают простую ошибку.
Дело в том, что создание беспорядка всегда оказывается медленнее, чем неуклонное соблюдение чистоты, независимо от выбранного масштаба времени.
"создание беспорядка … медленнее" - здесь можно подумать, что переводчик ошибся и что здесь вместо "медленнее" должно быть "быстрее" - но это не так. Ниже автор показывает, что в перспективе соблюдение порядка (чистоты) приведёт к более высокой скорости разработки. |
... они [те, кто не поддался обману самонадеянности Зайца] знают простую истину разработки ПО:
Поспешай не торопясь
.И она же является ответом на дилемму, стоящую перед руководством. Единственный способ обратить вспять снижение продуктивности и увеличение стоимости - заставить разработчиков перестать думать как самонадеянный Заяц и начать нести ответственность за беспорядок, который они учинили.
Та же самонадеянность [Зайца], которая прежде уже привела к беспорядку, теперь снова говорит им [разработчикам], что они смогут построить лучшую систему, если только вновь вступят в гонку [начав всё с самого начала и перепроектировав всю систему целиком].Однако в действительности не всё так радужно: Самонадеянность, управляющая перепроектированием, приведёт к тому же беспорядку, что и прежде.
Заключение
Любой организации, занимающейся разработкой, лучше всего избегать самонадеянных решений и с самого начала со всей серьёзностью отнестись к качеству архитектуры её продукта.
Серьёзное отношение к архитектуре ПО подразумевает знание о том, что такое хорошая архитектура. Чтобы создать систему, дизайн и архитектура которой способствуют уменьшению трудозатрат и увеличению продуктивности, нужно знать, какие элементы архитектуры ведут к этому.
Определение хорошей архитектуры
Вычитал выше, указываю явно: Хорошие дизайн и архитектура - те, которые способствуют уменьшению трудозатрат и увеличению продуктивности. |
2. История о двух ценностях
Всякая программная система имеет две разные ценности: поведение и структуру. Разработчики отвечают за высокий уровень обеих этих ценностей.
Поведение
Программистов нанимают на работу, чтобы они заставили компьютеры экономить деньги или приносить прибыль заинтересованной стороне.
Многие программисты полагают, что этим [3] их работа ограничивается. Они уверены, что их задача - заставлять компьютеры соответствовать требованиям и исправлять ошибки. Они жестоко ошибаются.
Архитектура
Идея ПО состоит в том, чтобы дать простую возможность изменять поведение компьютеров.
Для достижения этой цели [способность дать простую возможность изменять поведение компьютеров] ПО должно быть податливым - т.е. должна быть возможность легко изменить его.
Сложность в таких случаях [когда необходимо изменить что-то в ПО по требованию заинтересованных сторон] должна быть пропорциональна лишь масштабу изменения, но никак не его [изменения] форме <1>.
С точки зрения разработчиков, заинтересованные стороны формируют поток фрагментов, которые они должны встраивать в мозаику со все возрастающей сложностью. Каждый новый запрос [от заинтересованных сторон на внесение изменений] сложнее предыдущего, потому что форма системы не соответствует форме запроса.
Автор комментирует, что слово "форма" здесь использует не в традиционном его понимании (но ему кажется такая метафора уместной), так как, как он говорит, у разработчиков ПО часто складывается ощущение, что их заставляют затыкать круглые отверстия квадратными пробками. |
Чем чаще архитектура отдает предпочтение какой-то одной форме, тем выше вероятность, что встраивание новых особенностей в эту структуру будет даваться все сложнее и сложнее. Поэтому архитектуры должны быть максимально независимыми от формы.
Наибольшая ценность
Я могу доказать ошибочность этого взгляда [что важнее правилььная работа, а не простота ее изменения] простым логическим инструментом исследования экстремумов.
Если правильно работающая программа не допускает возможность ее изменения, она перестанет работать правильно, когда изменятся требования, и ы не сможете заставить ее работать правильно. Т.е. программа станет бесполезной.
Если программа работает неправильно, но легко поддается изменению, вы сможете заставить работать ее правильно и поддерживать ее работоспособность по мере изменения требований. Т.е. программа постоянно будет оставаться полезной.
... хотел бы он [руководитель] иметь возможность вносить изменения ... безусловно хотел бы ... но тут же может уточнить, что работоспособность в данный момент для него важнее гибкости в будущем.
Матрица Эйзенхауэра
У меня есть два вида дел, срочные и важные. Срочные дела, как правило, не самые важные, а важные - не самые срочные. [4]
Первая ценность программного обеспечения - поведение - это нечто срочное, но не всегда важное. Вторая ценность - архитектура - нечто важное, но не всегда срочное.
... имеются также задачи важные и срочные одновременно и задачи не важные и не срочные.
Все четыре вида задач можно расставить по приоритетам.
Срочные
и важныеНесрочные и важные
Срочные
и не важныеНе срочные и не важные.
Руководители и разработчики часто допускают ошибку, поднимая пункт 3 ("срочные и не важные") до уровня пункта 1. Иными словами, они неправильно отделяют срочные и не важные дела от задач, которые по-настоящему являются срочными и важными.
Разработчики программного обеспечения оказываются перед проблемой, обусловленной неспособностью руководителей оценить важность архитектуры. Но именно для её решения они и были наняты.
Поэтому разработчики должны всякий раз подчеркивать приоритет важности архитектуры перед срочностью поведения.
Как я понял, вывод "… именно для её решения они и были наняты" сделан автором на базе следующего умозаключения: Смотри чуть ниже о борьбе разработчиков 2 - там автор говорит о том, что защита своего интереса в ПО - "одна из причин, почему вас [разработчиков] наняли". Т.е. защита интересов в ПО также ведёт опосредованно к тому, чтобы обеспечивались хорошие дизайн и архитектура. |
Команда разработчиков должна бороться за то, что, по их мнению, лучше для компании.
... как разработчик программного обеспечения вы тоже являетесь заинтересованной стороной. У вас есть свой интерес в программном обеспечении, который вы должны защищать. Это часть вашей роли и ваших обязанностей. И одна из основных причин, почему вас наняли.
Важность этой задачи [защищать свой интерес в ПО] удваивается, если вы выступаете в роли архитектора ПО.
Архитекторы, в силу своих профессиональных обязанностей, больше сосредоточены на структуре системы, чем на конкретных её особенностях и функциях.
Архитекторы создают архитектуру, помогающую быстрее и проще:
создавать эти особенности и функции,
изменять их и дополнять.
Выше автор явно не говорит, но это следует из контекста - к задаче архитектора также относится и защита своих интересов в ПО. |
... помните, что если поместить архитектуру на последнее место, разработка системы будет обходиться всё дороже, и в конце концов внесение изменений в такую систему или в отдельные её части станет практически невозможным.
Если это случилось, значит, команда разработчиков сражалась недостаточно стойко за то, что они считали необходимым.
Часть II. Начальные основы: парадигмы программирования
Алан Тьюринг первым понял, что программы - это всего лишь данные.
С тех пор [с 1945 года, как я понял] в программированиии произошло несколько революций. Одна из самых известных - революция языков.
Другая, ещё более важная, как мне кажется, революция [в программировании] произошла в парадигмах программирования. Парадигма - это способ программирования, не зависящий от конкретного языка.
Парадигма определяет:
какие структуры использовать
и когда их использовать.
До настоящего времени было придумано три такие парадигмы.
3. Обзор парадигм
Структурное программирование
Структурное программирование накладывает ограничение на
прямую
передачу управления [через посредство инструкций перехода goto].
Парадигму структурного программирования предложил Эдсгер Вибе Дейкстра в 1968 году. Он показал вред goto и предложил заменить goto более понятными коснтрукциями |
Объектно-ориентированное программирование
В результате [перемещения кадра стека вызова функции в динамическую память (кучу), приводящую к тому, что локальные переменные, объявленные внутри функции, могут сохраняться после выхода из неё] функция превращалась в конструктор класса, локальные переменные - в переменные экземпляра, а вложенные функции - в методы.
Это привело к открытию полиморфизма через строгое использование указателей на функции.
Парадигма ООП появилась двумя годами ранее, в 1966 году. Предложена Оле-Йоханом Далем и Кристеном Нюгором. |
Функциональное программирование
TBD Продолжить отсюда