Как сделать код модульным? - PullRequest
23 голосов
/ 18 сентября 2009

У меня есть несколько программ на Java, теперь я хочу выяснить, является ли он модульным или нет, если он модульный, то до какой степени, потому что модульность никогда не может быть двоичным термином, то есть 0 или 1. Как я могу решить, что конкретный код является модульным до такой степени. Я хочу знать, как сделать код гораздо более модульным?

Ответы [ 10 ]

37 голосов
/ 18 сентября 2009

Некоторые критерии модульности:

  1. Сколько раз вы переписываете подобный код для выполнения конкретной задачи?
  2. Сколько кода у вас есть рефакторинг вашего кода на случай, если вы что-то измените в какой-то части вашей программы?
  3. Файлы меньше и проще для навигации?
  4. Работают ли прикладные модули адекватно и независимо, как и когда требуется?
  5. Насколько менее катастрофично Ваш код? Неужели весь адский разрыв теряется, когда вы удаляете только одну функцию или переменную? Получаете ли вы 20 с лишним ошибок при переименовании класса? (Для Instance вы можете реализовать механизм стеков , чтобы отслеживать все прыжки в вашем приложении)
  6. Насколько близок код к использованию естественного языка (т.е. модули и их подкомпоненты представляют больше объектов реального мира, не уделяя большого внимания чистому размеру исходного файла).

Для получения дополнительных идей проверьте это и этот на качество программного обеспечения

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

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

Каждый метод в вашем приложении должен выполнять не более минимальных необходимых квантов обработки . Объединение этих методов во все больше и больше методов макроуровня должно вернуть вас к вашему приложению

25 голосов
/ 18 сентября 2009

Ключевые моменты:

  • Разделение интересов
  • Сплоченность
  • Инкапсуляция (связывается через интерфейс)
  • подставляемость
  • 1012 * Повторное использование *

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

Чтобы ответить на ваш вопрос: «Как я могу решить, что конкретный код является модульным до такой степени», мы можем сформировать вопросы для проверки модульности. Можете ли вы легко заменить ваши модули чем-то другим, не затрагивая другие части вашего приложения?

XML-парсеры могут быть еще одним примером. Получив интерфейс DOM, вам действительно все равно, какая реализация синтаксического анализатора XML используется ниже (например, Apache Xerces или JAXP).

В Java другой вопрос может быть: Доступны ли все функции через interface s? Интерфейс в значительной степени заботится о слабой связи.

Кроме того, можете ли вы описать каждый модуль в вашей системе одним предложением? Например, автомобильная стереосистема воспроизводит музыку и радио. Дисковые тормоза безопасно замедляют автомобиль.


(Вот что я написал Что такое разработка на основе компонентов? )

Согласно Википедии, разработка на основе компонентов является псевдонимом для Разработка программного обеспечения на основе компонентов (CBSE) .

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

Это немного расплывчато, поэтому давайте рассмотрим более подробно.

Отдельным компонентом является программное обеспечение пакет или модуль, который инкапсулирует набор связанных функции (или данные).

Все системные процессы размещены в отдельные компоненты, так что все данные и функции внутри каждого компонент семантически связан (так же, как с содержанием классы). Из-за этого принципа часто говорят, что компоненты модульные и связные .

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

Относительно всей системы координация, компоненты сообщают друг с другом через интерфейсы . [...] Этот принцип приводит к компонентам, именуемым encapsulated .

Так что все больше и больше похоже на то, как мы думаем о хорошем API или SOA.

Предоставленные интерфейсы представлены леденцом на палочке, а необходимые интерфейсы представлены символом открытого сокета, прикрепленным к внешнему краю компонента в UML.

alt text

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

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

Заменимость и возможность повторного использования - вот что делает компонент компонентом. Так в чем же разница между этим и объектно-ориентированным программированием?

Идея в объектно-ориентированном программирование (ООП) это программное обеспечение должно быть написано в соответствии с ментальная модель фактического или воображаемого объекты, которые он представляет. [...]

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

3 голосов
/ 18 сентября 2009

Чтобы ответить на ваш конкретный вопрос , как сделать код более модульным, пара подходов:

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

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

2 голосов
/ 27 сентября 2009

Хей,

См. «Как инкапсулировать программное обеспечение (часть 1)» здесь:

http://www.edmundkirwan.com/encap/overview/paper7.html

С уважением,

Под ред.

1 голос
/ 19 сентября 2009

Поскольку это было помечено как 'osgi', я могу добавить перспективу, связанную с OSGi.

Краткий ответ: за несколько шагов можно перейти от полностью спагетти-кода к модульному; это не должен быть большой взрыв. Например, даже код спагетти зависит от какой-либо библиотеки логирования логов, поэтому в некотором смысле он уже модульный, только с одним очень большим Metball (извините, модуль).

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

Что касается OSGi, все еще можно положить uber-jar в пакет. На самом деле, вы можете сделать это без изменения битов; либо изменив файл Manifest.MF на месте, либо поместив его в другой JAR-файл и указав в манифесте Bundle-ClassPath: metaball.jar.

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

0 голосов
/ 19 сентября 2009

Идея пакетная функция помогает сделать код более модульным.

Многие примеры, встречающиеся в Интернете, сначала делят приложения на слои, а не на функции

  • модель
  • доступ к данным
  • пользовательский интерфейс

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

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

Обычно удаление функции в таком приложении может быть реализовано в одной операции - удалении одного каталога.

0 голосов
/ 18 сентября 2009

Вы можете использовать инструмент анализа кода, такой как CAP , чтобы проанализировать зависимости между типами и пакетами.Они помогут вам найти и удалить любые циклические зависимости, которые часто являются проблемой при разработке модульного кода.Если циклических зависимостей нет, вы можете начать разделять ваш код на дискретные jar-файлы.

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

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

0 голосов
/ 18 сентября 2009

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

ИМХО, если у вас есть 3 модуля A B и C, и вы хотите полностью заменить или заменить модуль C, если это ПРОСТАЯ задача, то у вас есть модульный код.

0 голосов
/ 18 сентября 2009

Как вы говорите, модульность - это не двоичная вещь, поэтому она зависит от вашего относительного определения.

Я бы сказал: вы можете использовать данный метод в любой программе, где вам нужно выполнить эту функцию? Это «черный ящик», где вам не нужно знать, что он делает под капотом? Если ответ «нет», т. Е. Метод будет правильно работать только в этой программе, он не будет по-настоящему модульным.

0 голосов
/ 18 сентября 2009

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

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

...