Comments 15
Ваш пример с двумя шкафами (особенно "анализ"), нмв, неудачен. Поскольку это съемная квартира, то избавиться от одного шкафа вы не можете. А оставлять пустым странно. Поскольку семья из двух взрослых, то они тупо делятся по гендерному признаку. И еще жена со временем в ваш шкаф залезет:)
Вы написали много букв. Но есть бритва Оккама и анализ обратной связи, на основе которого принимаются решения по уточнению/изменению в т.ч. архитектуры.
Когда-то я участвовал в двухнедельном семинаре "Наука управления". К концу пришел к выводу, что особой науки там нет, есть искусство управления в реализации данного конкретного индивида. Собственно, вы это же подтверждаете цитатой "Нет неверных ответов, есть дорогие ".
Хорошо, что вы сослались на фундаментальный труд Fundamentals of Software Architecture . А почему вы думаете, что ваш текст что-то к нему добавил? вообще может добавить? Вы себя не переоцениваете?
Пример со шкафами конечно же неудачный. Если нам дают вводную что в квартире всего два шкафа для одежды да ещё явно намекают, что есть одежда верхняя и нижняя; то в реальности у всех верхняя одежда в одном общем шкафу у входа. И никого в реальной жизни не смущает, что трусы он берёт в одном шкафу, а шубу в другом.
И что 2 плотно набитых одеждой шкафа при наличии 8 пустых — это оптимально, тоже не сказать, что соответствует массовым представлениям.
Вводную с аналогиями стоит вообще убрать из статьи.
Пример со шкафом как раз и служит искусственным простейшим примером на подумать о том как люди принимают решения интуитивно и общепринято, но не всегда оптимально.
Потому что часто не сформулирован вопрос - "а что вы собственно оптимизируйте"? Как это померять?
В примере со шкафами как метрику можно взять тупо количество шагов, которые ты тратишь каждый день на пользование шкафами.
Переставил вещи - сократил эту метрику. Круто? Круто. И главное понятно что оптимизируем.
8 пустых шкафов оптимально? Интуитивно не знаю, но если сокращают метрику, то видимо да!
Аналогично мне хотелось показать, что похожая логика может работать в совершенно разных вопросах.
Спасибо за комментарий.
Ниже подробно расписал цель примера со шкафами. https://habr.com/ru/articles/986164/#comment_29407700 . Я хотел сделать фокус не на правильности решения, а прежде всего на вопросе о том "Что мы оптимизируем?". Как это измерять? Чтоб как раз НЕ действовать интуитивно и на опыте.
Хорошо, что вы сослались на фундаментальный труд Fundamentals of Software Architecture . А почему вы думаете, что ваш текст что-то к нему добавил
В статье я хотел обратить внимание, что знания из разных областей имеют очень много общего. И попытался нащупать эти связи.
А если учесть, что всё это очень сильно друг на друга влияет, например оргструктура влияет на архитектуру (фактически её устанавливает), то рано или поздно всё это будет рассматриваться в связке с единым механизмом и процессом перестройки (как в условном Togaf, но для массового потребителя). И скорее всего по очень схожим принципам.
Поэтому я хотел взять ряд областей, с которыми мне довелось поработать, взять условно ряд книг (их конечно сильно больше):
Организационная структура: Реализация стратегии на практике Ицхак Адизес
О разделении на команды разработки - https://teamtopologies.com/
И в том числе Fundamentals of Software Architecture
Всевозможные книги по SOLID
и сказать - "Ребята, вы все пишете про одно и то же. Про разделение. Просто на разных уровнях. А ещё вы крайне сильно влияете друг на друга. Поэтому может быть начнем шарить экспертизу и использовать схожие принципы?".
Про последний абзац. Если все пишут одно и тоже - то что же тут "шарить", когда все давно "расшарено"? Поэтому я и усомнился в новизне вашего текста. Понимаю, что вы, типа, про свой выстраданный опыт. Но разве тот факт, что вода мокрая, а если наступить на грабли, то можно получить по лбу - заслуживают публикации?.. Это древняя закономерность. Каждая несчастная семья несчастна по-своему. А каждый чел уникален. Но "на круг", статистически получаются закономерности. Банальные!..
***
Вы не увидели главного. Нельзя научиться быть архитектором (и кем угодно еще), прочитав даже самый хороший учебник. Профи становятся. И то, что вы (и все остальные) "расшариваете" - это следствие. Которое никому не поможет, пока он сам лично не наступит на все мыслимые грабли. Кстати, именно поэтому я и остаиваю цикл гипотеза-опыт-анализ-уточнение гипотезы. Модель хорошей архитектуры выстраивается в сознании индивида лишь после многих таких итераций. Это гипотеза высокой степени проработки/зрелости данной конкретной личности. А когда он - страшно гордый - ее обнародует, но обнаруживает, что он уже неизвестно какой по счету:)
<дубль>
Единый принцип деления в архитектуре
Какой именно? Я так и не понял.
Когда я был разработчиком, я задавался вопросами:
как разделить код на классы?
какие модули выделить?
GUI,, на C++, и потоки, конечно, не имеются в виду?
Там, кстати, например, в WTL, основные графические компоненты уже поделены на классы. Программисту остается только организовать оптимальные связи между ними. Соответственно, построить свою иерархию классов, на базе стандартных классов.
Делить здесь нужно саму концепцию реализуемой модели, на уровне алгоритма базовой программной логики.
Демо-примеров, в «стратегических» статьях, ждать не приходится (как в анекдоте: «Сова: Ёжики – станьте птицами! – Ура! А как? – Отстаньте, глупые! Я не тактик я стратег!»).
Кстати, на тему разделения кода пользовательского интерфейса, у меня есть статья: «Модульное программирование в C++. Статические и динамические плагины» в https://habr.com/ru/articles/566864/ . Там использовались интерфейсы (статические и динамические плагины) для создания GUI, что, в принципе позволяет разрабатывать и отлаживать их независимо.
Вообще-то, главная проблема в разделении кода на независимые модули, это их «сильные связи». Полностью преодолеть её – почти невозможно. Только, на основе «метода здравого смысла», можно в той или иной мере упростить себе жизнь исходя из контекста задачи. Примерно, как я этого добился в решении задачи по оптимальному структурированию классов, в собственной обучающей программе (см. мою статью: «Новая компьютерная программа для запоминания иностранных слов и фраз» в https://habr.com/ru/articles/848836/ ). Там я себе чуть мозги не сломал, пока не достиг, более-менее, непротиворечивой работы основного алгоритма. Это еще не оптимальный код, но, по крайней мере, рабочий.
Резюмирую. «Разделение» – не самоцель. Главное, добиться прозрачной структуры программной логики, которую легко понять и модифицировать, даже, через продолжительное время, после ее реализации.
Спасибо за комментарий. Представьте что ваша программа выросла и теперь её разрабатывают 10 команд (так вышло). У каждой команды есть свое направление работы, есть продакт менеджер, который готов наносить пользу.
Важная часть эффективности команды это владение. Владение своей областью ответственности, своим куском кода, своими метриками, своим беклогом и возможностью его катить независимо.
А теперь вопрос - как разделить вашу программу и команды оптимальным образом? Ведь придумать можно десятки способов:
давай одни за Frontend / GUI, а другие за бекенд
давай одни за Английский, а другие за Испанский
давай одна из бизнес-логику, а другие за платформенные низкоуровневые решения
Все эти решения определят архитектуру и "модульность" по закону Конвея. "If you have 4 groups working on a compiler, you’ll get a 4-pass compiler. " (тут я подробно про эту пишу - https://habr.com/ru/articles/986164/#comment_29407762 ).
И я как раз хотел в статье задаться вопросом, а как лучше? а как оптимальнее? а как вы поймете что сделали лучше? на какую метрику посмотрите, если реализуете не интуитивно? а точно ли не лучше распустить 8 команд из 10? :)
И когда на эти вопросы начнут появляться ответы, я хотел обратить внимание, что принципы будут использоваться примерно те же что вы используйте когда делите программу на модули.
как разделить вашу программу и команды оптимальным образом? Ведь придумать можно десятки способов:
давай одни за Frontend / GUI, а другие за бекенд
давай одни за Английский, а другие за Испанский
давай одна из бизнес-логику, а другие за платформенные низкоуровневые решения
Обучающих систем множество. Поэтому, команды для них и так существуют, которые развивают свои проекты исходя из собственных представлений о «прекрасном».
Естественно, что мне были бы интересны те «команды», которые разделяют мою концепцию самостоятельного обучения иностранным языкам на базе соответствующей .компьютерной технологии.
Если говорить о моих предпочтениях в этих вопросах, то я бы делал акцент на архитектуре, под которой понимаю соответствующее дерево классов. Как делить «дерево» на «ветки» и нужно ли его вообще делить, отдельный вопрос. По крайней мере, я бы начал разработку с целостного («монолитного») дерева классов.
Теоретически, каждый режим работы программы определяется своим «поддеревом» или «веткой». Они могут иметь различную визуализацию, но общие принципы генерации.
Расширение программы, это добавление нового режима работы (например, к шести уже имеющимся, добавить режим случайного вывода данных, вместо последовательного).
«Frontend / GUI» и «бекенд» это тоже иерархия стандартных классов WTL либо их расширений, которые взаимодействуют с главным окном приложения через оконные сообщения, и, может быть, через потоки (пока у меня режимы «Видео» основаны на таймере).
Самой программе безразлично, с какими данными работать. Так в моём архиве демо-данных имеются четыре языка: французский, английский, немецкий и испанский. Все слова, переводы, транскрипция и озвучка находятся в файлах данных, формата SQLite. Вы загружаете любой, в любом режиме и получает нужный вам вариант работы. Здесь «команды» могли бы работать над данными как таковыми, все-таки, чтобы их готовить, в языке нужно, хоть немного, разбираться.
«Бизнес-логики» у меня нет. Этот термин подходит, скорее, для учетных систем. Я предпочитаю аналог: «программная логика». Опять же, она «зашита» в обработчиках сообщений. А сами обработчики встроены в общее дерево классов, скорее, даже несколько «деревьев», которые «общаются» между собой по «радиосвязи», то бишь, оконным сообщениям.
Кроссплатформенность мне не интересна, как-то прожил всю жизнь без нее, и начинать смотреть туда не вижу смысла. Тоже касается мобильных версий. Этим вполне могут заниматься другие команды, без меня. Я им, в данном случае, не нужен.
Что может быть востребовано, но будет иметь некоторые проблемы при реализации, так это желание изучать русский язык иностранцами. Это может иметь смысл, если будет какая-то внешняя поддержка. Для родной аудитории – все бесплатно.
а как лучше? а как оптимальнее? а как вы поймете что сделали лучше? на какую метрику посмотрите, если реализуете не интуитивно? а точно ли не лучше распустить 8 команд из 10? :)
В моем случае, все просто. Программа должна нравиться мне, данные должны быть восприимчивы для освоения их взрослыми, в любом возрасте. Уроки должны быть полными и упорядоченными. Я набираю руками, примерно по сто озвученных фраз в день (в интерактивном режиме), проговариваю фразы вслед, при необходимости, возвращаюсь к пройденным урокам и так до тех пор, пока я не смогу воспринимать и понимать на слух мои любимые видосики, из «народного» видеохостинга, вроде описанных в моей статье: «Создание двуязычных субтитров к видео, распознавание и перевод речи» в https://habr.com/ru/articles/862716/ .
А так, я ведь не в команде и вряд ли в ней буду, поэтому, зачем мне бизнес метрики? У меня только пет-проект, предел которого – индивидуальный стартап. Бизнес задачами я занимался на официальной работе, а в статусе «свободного художника» можно и расслабиться.
«метода здравого смысла»
"Там я себе чуть мозги не сломал, пока не достиг, более-менее, непротиворечивой работы"
Я как раз хотел адресовать это проблему. Мы действуем на опыте и интуиции "мучительно" рождая из себя решения.
Вместо этого в случае программы возможно стоило бы действовать по алгоритму:
представить себе все те доработки, которые вероятно в будущем будут для вас актуальны (это делается исходя из анализа программ-конкурентов, общего представления о том какую нишу вы хотите занять). Например:
точно буду добавлять новые языки
почти наверняка буду портировать на мобилку
почти наверняка потребуется обновлять заливать новые базы иностранных слов
почти наверняка потребуется перевод интерфейса
и так далее (конечно оценить на реалистичность всё это, поэтому и нужна четкая стратегия развития)
теперь выбрать что для вас в случае доработки считается "аварией", худшим случаем. Например для вас это может быть когда придется "переписывать пол-программы", иначе говоря когда изменения пойдут как выстрел из дробовика, что менять придется кучу мест сразу и не всегда очевидно где.
а теперь прикинуть как разделить вашу программу на модули (ну условно на 5 относительно независимых модулей) так, чтобы КАЖДАЯ из доработок которые вы планировали в 1 пункте изменяла минимальное количество модулей.
Посчитать сумму затронутых модулей для каждого из предложенных решений о разделении и выбрать то разделение, где сумма минимальна.
Вот предлагаю поступить так, вместо ломания мозгов и вытаскивания решения "методом здравого смысла" :) и поделиться результатами. Будет вполне практический осмысленный пример.
UPD: Забыл добавить важный пункт, что пока вы 1 и у вас всё прекрасно умещается в голове, то возможно никакие деления на модули не нужны. Вынуждать должна возрастающая неподъемная сложность.
Вместо этого в случае программы, возможно, стоило бы действовать по алгоритму:
Дело в том, что «алгоритма» никакого нет. Откуда ему взяться, если вы сначала даже не знаете, толком, чего вы хотите. Потом, довольно долго вынашиваете концепцию своей, допустим, как у меня, обучающей, иностранному языку, программы. Делаете одну версию, она вам не понравилась, потом другую, со сменой парадигмы, но там тоже не все идеально. Затем возникают новые идеи, и вы реализуете их. Да, появились технические сложности при реализации, потому, что мы взялись «съесть слона» за раз. И, главное, даже не то что, рабочий код, как «первый блин комом», оказался не слишком оптимальным. Гораздо важнее то, что он вообще заработал и, более-менее, нормально. По нему уже можно учить иностранные языки, но возникает другая проблема – данные (компьютерные уроки). Рабочая неоптимальность может подождать, а вот без данных учить языки не получится.
Хорошо, работаем с данными, тем более, что с ними, относительно, проще. Но, все равно, это время. Потом, материала накопилось так много, что пора уже делать упорядочивание и интеграцию. Лучший способ для этого, создание своих бесплатных сайтов, желательно, несколько, га случай форс-мажора (вдруг, что-то перестанет работать, по необъяснимым причинам).
Разработка сайтов требует новых навыков, которых раньше не было. Но, постепенно, процесс идет, включая организацию обучающих видео, создание которых, тоже непросто.
Ну, и какой алгоритм применить сюда, хотя бы в принципе? Это на официальной работе платят, по большому счету, за «присутствие», а когда ты сам по себе, то нужно иметь самодостаточный продукт, который еще надо как-то «распиарить» и «продвинуть» в массы. Иначе, ничего не «взлетит». Оно и так, скорее всего, не «взлетит», зато будет совесть чиста перед самим собой: «Я сделал всё, что мог!».
Вывод, концепцию за вас не разработает никто, если вы не в «команде». Но, чтобы влиться в какую-нибудь команду, тоже надо исходить из какой-то собственной концепции. А тут даже ИИ не слишком поможет, поскольку, он не может знать больше вас, чего вы, на самом деле, хотите.
Я понимаю ваши рассуждения о «лучших практиках» программирования. Только это разговор «вообще». Я ведь дал ссылку на свой демо-проект по реализации модульности в GUI, на C++. У других я вижу только общие рассуждения, без демонстрации результатов.
Если бы мою любимую фирму не ликвидировали бы, то я бы занимался развитием своего проекта «модульного учёта». Те же конфигурации «1С», это «монолиты». Поэтому, у меня был интерес написать свою «семерку» (а-ля «1С77») на C++ / WTL, с поддержкой модульности, как я ёё понимаю. Это не должна была быть большая система, в качестве движка БД меня бы вполне устроил SQLite. Как раньше говорили: «для малых и средних предприятий». Однако, не судьба. Раз нет полигона для испытаний (моей фирмы), то ваять «сферического коня в вакууме», как то нет желания, да и смысла.
А рассуждения, которые вы приводите, для меня не являются каким-то откровением. Все это, более-менее, очевидно, но, разработке концепции как-то слабо помогает.
Про low coupling, high cohession -- классно. Если вспоминать какой-то первый-единственный "принцип", то именно его.
В остальном организационные вопросы и "микросервисы" смешивать с создаем архитектуры кода, имхо, не надо. При хорошем разделении (ну там "information expert" и пр.) разделение обычно ничего не стоит.
организационные вопросы и "микросервисы" смешивать с создаем архитектуры кода, имхо, не надо
Попробую вас убедить, что надо смешивать :)
Есть закон Конвея - «Организации проектируют системы, которые копируют структуру коммуникаций в этой организации».
Выводы из закона Конвея:
Команды воссоздадут в технической архитектуре свою оргструктуру. “If you have 4 groups working on a compiler, you’ll get a 4-pass compiler.”
Проектируя оргструктуру команд, ты проектируешь техническую архитектуру компании.
Нельзя навязать техническую архитектуру. Если она не будет совпадать с оргструктурой, то оргструктура победит. (!)
Постоянные реорганизации оргструктуры под нужды менеджмента разрушительным образом влияют на функцию разработки в компании, так как вызывают масштабные перестроения.
Reverse Conway Maneuver – способ построения архитектуры, когда организация фокусируется на построении оргструктуры таким образом, чтобы она соответствовала желаемой архитектуре. (это из Team Topologies)
Таким образом при построении оргструктуры стоит в том числе опираться на принципы построения технической архитектуры. Так как это всё крайне сильно связано.
Посмотрите на картинку: вот он организационный low coupling, high cohession.

В общем моя мысль, что оргструктура, архитектура, код - очень плотно связаны и игнорировать это опасно.
Простой пример, если у тебя 1 команда разработки со своим беклогом разрабатывает 1 ПО, которое условно умещается в 1 архитектурный квант (ну условно сервис), то это прекрасно - ей ничего не мешает. Но например изменили оргструктуру и теперь у тебя 2 команды. Что будет?
Автор, похоже, внезапно открыл для себя давным давно, ещё до разработки UML, известные методологии анализа и проектирования систем - use case model и общепринятые принципы рационального распределения обязанностей среди компонентов системы.
Спасибо за статью, в целом текст поддерживает common sense. Пожалуй только слово Единый вызывает у меня головную боль, а так да, напоминает нам что всегда стоит задаваться вопросом «зачем?».
Единый принцип деления в архитектуре