Сначала я прочитал отрывок из статьи Эдсгера В. Дейкстры 1974 года «О роли научной мысли»:
Позвольте мне попытаться объяснить вам, что на мой вкус характерно для всего разумного мышления. Дело в том, что человек желает углубленно изучать аспект своего предмета изолированно ради своей собственной последовательности, все время зная, что он занимает себя только одним из аспектов. Мы знаем, что программа должна быть правильной, и мы можем изучать ее только с этой точки зрения; мы также знаем, что он должен быть эффективным, и мы можем, так сказать, изучить его эффективность в другой день. В другом настроении мы можем спросить себя, а если да, то почему программа желательна. Но ничего не получается - наоборот! - одновременно занимаясь этими различными аспектами. Это то, что я иногда называю «разделением интересов», что, даже если это не вполне возможно, пока что это единственная доступная техника для эффективного упорядочения своих мыслей, о которой я знаю. Это то, что я имею в виду под «сосредоточением своего внимания на каком-то одном аспекте»: это не означает игнорирование других аспектов, это просто признание того факта, что с точки зрения этого аспекта другой не имеет значения. Это одно- и многодорожечный одновременно.
Я вижу, что современное разделение проблем говорит о модульности вашего кода. Однако, читая цитату выше, я понимаю, что фокусирую свой ум на одной конкретной задаче за раз, не сосредотачиваясь на других аспектах. Это не обязательно означает, что код должен быть разделен на модульные блоки.
То есть, скажем, перед вами код, который в одном файле содержит понятия представления, репозитория, контроллера, обработки событий, фабрики и т. Д. - все в одном файле.
Для краткого примера, вот код, который имеет доступ к данным и представление (вывод):
$sql = "SELECT * FROM product WHERE id = " . db_input($id);
$row = db_fetch_array(db_query($sql));
<option value="<?=$row['id']?>"<?= $row['ver'] == $row['ver'] ? ' selected="selected"' : '' ?>>Version <?=$row['ver']?></option>
Используя современную OO, я мог бы разместить доступ к данным в своем собственном файле, используя шаблон Repository, код View может перейти в собственный шаблон файла, и я могу связать их вместе для связи через контроллер (или Action или Request Handler), и я могу добавить фабрику для создания и подключения различных зависимостей. И у меня может быть файл конфигурации, который определяет эти фабрики. Конечно, это один шаг от одного файла-все.
Мой вопрос о разделении интересов выглядит так: читая цитату Дейкстры, я понял, что, возможно, он не обязательно подразумевал разделение задач как «модульное разделение кода (на файлы или их собственные функции / методы / и т. Д.)», и что он имел в виду больше, чтобы сосредоточить свое внимание на аспекте программы, не обременяя себя сосредоточением на других важных, но пока не рассматриваемых в настоящее время аспектах, независимо от того, физически они разделены в коде или нет.
Почему же тогда мы обременяем себя физическим модульным кодовым разделением и шаблонами проектирования? Будет ли недостаточно просто сосредоточиться на аспекте, независимо от того, как структурирован ваш код?
Я не говорю о написании самого ужасного кода для спагетти, а только о его аспекте, который, вероятно, будет обременительным. Но, в конце концов, я иду к тому, зачем выполнять физическое разделение кода, зачем разбивать код на отдельные файлы или порции (методы), когда нет необходимости мысленно фокусировать себя на аспекте?
Должно ли разделение интересов оставаться умственным упражнением, а не физическим?
Другими словами, должно ли существовать несоответствие между ментальными (фокус на) и физическими (код на бумаге) аспектами программирования?
IF
,WHILE
,FOR
аGOTO
. Modular = модули с четко определенным публичным API, строго отделенным от скрытой внутренней реализации и представления. (Например, Модула, Меса, Модула-2, Модула-3, более поздние диалекты Паскаля (UNIT
).)Ответы:
Дейкстра делает явное заявление о том, как думать. Модуляризация программы (и процесса) - и ее желательность - возможно, является результатом этого мышления, но ключевой момент, который он делает, заключается в том, как оценить проблему. Программа обычно является решением проблемы, и, выступая за «разделение интересов», он предлагает мудрый совет. Лучшим примером этого является, пожалуй, «оптимизация». Шутка была: «При планировании оптимизации программы, ваша первая стратегия должна быть: не надо». Другими словами, вы хотите сосредоточиться на том, чтобы сначала сделать программу правильной. Сделать его быстрым и модным - это проблема, которую следует отделить, но не полностью устранить.
источник
Разделение интересов - это абстрактный способ мышления, состоящий в том, чтобы рассматривать отдельно вещи, которые не должны быть связаны.
Модуляризация (разделение несвязанной группы функций на модули), инкапсуляция (скрытие внутренних деталей модулей) и абстракция (отделение общего от частного и идея от его реализации) - все это средства для реализации этого способа мышления в области программного дизайна.
источник
Я хотел бы предположить, что, хотя статья представляет исторический интерес, то, что Дейкстра имел в виду под термином «разделение интересов» более 40 лет назад, сегодня не особенно актуально. В настоящее время он широко используется в отношении модуляции.
Существует множество свидетельств того, что модуляция чрезвычайно полезна и что эти выгоды намного перевешивают «бремя», которое она возлагает на нас. Что бы Dijkstra имел в виду в то время, это не меняет того факта, что небольшие куски кода, каждый из которых ориентирован только на одну вещь, ведут к коду, который легче писать, читать, понимать, поддерживать и тестировать.
источник
Я могу привести вам личный пример разделения интересов, который, на мой взгляд, сопоставим с концепциями Дейкстры. Когда я анализирую конкретный предмет в программном обеспечении, я строю три представления.
В итоге получается трехгранный вид предмета, который затем может быть сформулирован в виде кода в любых группах, удобных для самого кода и его обслуживания. Три аспекта - это не просто умственное упражнение. Я делаю письменные описания всех аспектов. Почему? Потому что, если предмет достаточно велик, я не могу удержать даже один полный аспект в краткосрочной памяти. Если предмет небольшой, подойдет практически любой подход, потому что вы можете держать все это в своей голове.
Мотивация разделения проблем состоит в том, чтобы приспособиться к кратковременным ограничениям памяти людей. Мы просто не можем нести все в своих мыслях сразу, хотя программисты, как правило, более способны, чем большинство других людей, к количеству концепций, которыми они могут манипулировать в своей краткосрочной памяти. Чтобы быть эффективными, разделение интересов должно систематическиисключить один или несколько аспектов проблемы, чтобы сосредоточиться на каком-то другом конкретном аспекте. Конечно, исключение одного аспекта не делает его исчезающим из рассмотрения. Должны быть средства, позволяющие объединить все проблемные аспекты для достижения решения. Опыт показывает, что зачастую конечный результат разделения и рекомбинации дает более понятное решение, чем один гигантский скачок, в котором многие аспекты могут быть смешаны вместе. Это особенно верно, когда размер проблемы велик или сложен.
источник
Разделение интересов - это логическая концепция, которая будет распространяться на вашу модель организации кода независимо от того, как вы ее реализуете. Это правда, что файл кода - это просто техническая деталь, один из способов сохранить управляемость вашего программного обеспечения. Один файл с хорошим редактором, который позволяет свернуть расширение регионов, может работать на вас (на некоторое время). Или реляционная база данных, которая хранит классы и методы родительско-дочерним способом в отдельных таблицах, может работать как носитель данных. Но текстовые файлы трудно превзойти в мире, где требуется исходный код
Суть в том, что мы, люди, не очень хорошо думаем или имеем дело с разными вещами одновременно. Таким образом, нам нужна модель, которая позволяет думать и работать над одной вещью за один раз без опасности разрушить какую-то другую часть, которую мы не рассматриваем в то время. Поэтому мы строим, кладя по одному кирпичу за раз, следя за тем, чтобы кирпичи, которые мы заложили ранее, не мешали кирпичам, заложенным позже. И если мы хотим изменить кирпич позже, вещи не должны разрушаться. Это модель, которая работает для наших единомышленников.
Это не то, как растут грибы или водоросли ... Как это для смиренного факта?
источник
Я полагаю, что конкретный ответ на цитату Дейкстры был рассмотрен, поскольку вы заявляете «Используя современную ОО, я мог бы поместить доступ к данным в свой собственный файл» и спрашивали «Должно ли разделение интересов оставаться умственным упражнением, а не физическим?» позвольте мне обратить ваше внимание на то, куда нас направляют современные принципы ОО.
Следует следовать принципам SOLID при разработке с использованием ОО. Вот хорошая ссылка для них, но TLDR по «разделению интересов» в основном содержится в S в SOLID: Принцип единой ответственности или SRP.
Это, безусловно, физическое упражнение, а не умственное. В вашем конкретном примере MVC (или его родные MVVM и MVP) предписывает физически разделять концерты Model, View и Controller / Presenter / ViewModel в отдельные файлы. Я видел несколько реализаций MVVM, в которых они реализованы в виде отдельных сборок, чтобы еще больше ограничить тенденцию «смешивать концепции».
Но. Это выходит за рамки простого «это представление, а это модель», если вы следуете мнению дяди Боба об этом.
Необходимо также рассмотреть источник требований для любого конкретного элемента ОО. Если вы смешиваете, скажем, то, что хочет Заказчик, с тем, что хочет операционный персонал, вы также нарушаете SRP. Или, говоря словами дяди Боба: класс должен иметь одну-единственную причину для изменения.
Я настоятельно рекомендую вам исследовать это дальше, используя предоставленные ссылки, или выполнить поиск в Интернете для «твердых принципов».
источник