среда, 23 марта 2016 г.

6 квадратов проектирования

В практике работы мне в основном выпадало работать системным программистом, а не прикладным. Хотя все работы в итоге были нацелены на успех прикладных разработок. Как-то давно я провел статистический анализ проблем, с которыми сталкивался. Можно сделать некоторые легкопонимаемые выводы о структуре программного кода и его построении так, чтобы мне как системному программисту, иногда работающему с прикладным кодом, возникало меньше проблем с модернизацией приложений.
Речь пойдет о принципах разбиения кода на квадраты. Общее построение систем практически всегда или в большинстве случаев может быть сведено к разбиению с двух точек зрения - является ли код специфичным для приложения или библиотечным и является ли код интерфейсным, кодом логики обработки или кодом хранения данных. Итого вырисовывается 6 квадратов, несколько малохудожественно изображенные на рисунке:


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

При построении кода таким образом возникает возможность заменять более левые и более верхние части по отношению к более правым и более нижним. Например, оставляя код специфики хранения данных, модернизировать логику приложения. Или оставляя логику приложения модернизировать или заменить полностью интерфейс, например сделать еще один интерфейс, на другой технологии.

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

Такое построение кода мне лично очень могло бы помочь добавлять к готовому приложению другой интерфейс, например если приложение построено в консольном варианте, то к нему добавить веб-интерфейс. Оставив при этом полностью отлаженную логику обработки и механизм хранения данных.

В действительности конечно при построении приложений если не были предусмотрены эти 6 квадратов, то модернизацию и наращивание придется делать с бОльшими трудозатратами. Возможно, с очень большими, в зависимости от того что за приложение было построено.

Кроме того, в реальном приложении зачастую возникает вопрос обратного взаимодействия, например по логике обработки требуется задать пользователю вопрос и вырисовывается стрелочка справа налево. По моему мнению, очень желательно было бы избавиться от такой стрелочки использованием механизма обратного вызова, например передав в модуль обработки из интерфейсного модуля некую инструкцию, которую должен выполнить модуль логики. Это или строка для косвенного выполнения или указатель на функцию, которую требуется выполнить для такого взаимодействия. Но сам по себе модуль логики обработки не должен предполагать явно ни в каком виде о способе построения приложения и его взаимодействии с внешней средой.

В частности, все функции Windows по перечислению некоторых объектов принимают указатель на функцию, которую они должны вызвать для передачи информации. А как именно построено приложение использующее такое перечисление, это уже его дело. Это может быть консольное или оконное приложение, или сервис, или просто dll со своими внутренними делами.

Кстати говоря, с квадратом "утилиты интерфейса" большинство программистов уже давно знакомы и регулярно их используют. Например, при построении GUI приложений это визуальные или невизуальные компоненты. Хороший компонент строится так, чтобы его можно было применять в любом приложении, вне зависимости от его назначения и он не должен требовать того, что на картинке обозначено как более верхние модули.

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

Есть еще одна тема, которая может быть обсуждаемой - это вызов слева направо, но через один квадрат. Например, обработчик кнопки напрямую лезет в базу данных и в этом коде явно прописаны способы хранения, а то и вообще, специфика конкретной СУБД. Думаю, этот случай вполне возможен, если утилита точно выполняет поставленную перед ней задачу и в планах не стоит замена других квадратов или их модернизация.

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

К недостаткам схемы 6-ти квадратов можно отнести то, что программисты прикладной системы в большинстве случаев имеют доступ к практически всем квадратам и для упрощения себе работы не структурируют код. Придерживаться методики может оказаться дополнительным трудом, и если программист заинтересован исключительно в выпуске своего приложения и считает что весь код который есть предназначен исключительно для него, то запросто может породиться целая фабрика.

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

Комментариев нет:

Отправить комментарий