Как проектировать программы: Создание архитектуры программы или как проектировать табуретку / Хабр

Содержание

Создание архитектуры программы или как проектировать табуретку / Хабр

Взявшись за написание небольшого, но реального и растущего проекта, мы «на собственной шкуре» убедились, насколько важно то, чтобы программа не только хорошо работала, но и была хорошо организована. Не верьте, что продуманная архитектура нужна только большим проектам (просто для больших проектов «смертельность» отсутствия архитектуры очевидна). Сложность, как правило, растет гораздо быстрее размеров программы. И если не позаботиться об этом заранее, то довольно быстро наступает момент, когда ты перестаешь ее контролировать. Правильная архитектура экономит очень много сил, времени и денег. А нередко вообще определяет то, выживет ваш проект или нет. И даже если речь идет всего лишь о «построении табуретки» все равно вначале очень полезно ее спроектировать.

К моему удивлению оказалось, что на вроде бы актуальный вопрос: «Как построить хорошую/красивую архитектуру ПО?» — не так легко найти ответ. Не смотря на то, что есть много книг и статей, посвященных и шаблонам проектирования и принципам проектирования, например, принципам SOLID (кратко описаны тут, подробно и с примерами можно посмотреть тут, тут и тут) и тому, как правильно оформлять код, все равно оставалось чувство, что чего-то важного не хватает. Это было похоже на то, как если бы вам дали множество замечательных и полезных инструментов, но забыли главное — объяснить, а как же «проектировать табуретку».

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

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

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


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

Эффективность системы. В первую очередь программа, конечно же, должна решать поставленные задачи и хорошо выполнять свои функции, причем в различных условиях. Сюда можно отнести такие характеристики, как надежность, безопасность, производительность, способность справляться с увеличением нагрузки (масштабируемость) и т.п.

Гибкость системы. Любое приложение приходится менять со временем — изменяются требования, добавляются новые. Чем быстрее и удобнее можно внести изменения в существующий функционал, чем меньше проблем и ошибок это вызовет — тем гибче и конкурентоспособнее система. Поэтому в процессе разработки старайтесь оценивать то, что получается, на предмет того, как вам это потом, возможно, придется менять. Спросите у себя: «А что будет, если текущее архитектурное решение окажется неверным?», «Какое количество кода подвергнется при этом изменениям?». Изменение одного фрагмента системы не должно влиять на ее другие фрагменты. По возможности, архитектурные решения не должны «вырубаться в камне», и последствия архитектурных ошибок должны быть в разумной степени ограничены. "

Хорошая архитектура позволяет ОТКЛАДЫВАТЬ принятие ключевых решений" (Боб Мартин) и минимизирует «цену» ошибок.

Расширяемость системы. Возможность добавлять в систему новые сущности и функции, не нарушая ее основной структуры. На начальном этапе в систему имеет смысл закладывать лишь основной и самый необходимый функционал (принцип YAGNI — you ain’t gonna need it, «Вам это не понадобится») Но при этом архитектура должна позволять легко наращивать дополнительный функционал по мере необходимости. Причем так, чтобы внесение наиболее вероятных изменений требовало наименьших усилии.

Требование, чтобы архитектура системы обладала гибкостью и расширяемостью (то есть была способна к изменениям и эволюции) является настолько важным, что оно даже сформулировано в виде отдельного принципа — «

Принципа открытости/закрытости» (Open-Closed Principle — второй из пяти принципов SOLID): Программные сущности (классы, модули, функции и т.п.) должны быть открытыми для расширения, но закрытыми для модификации.

Иными словами: Должна быть возможность расширить/изменить поведение системы без изменения/переписывания уже существующих частей системы.

Это означает, что приложение следует проектировать так, чтобы изменение его поведения и добавление новой функциональности достигалось бы за счет написания нового кода (расширения), и при этом не приходилось бы менять уже существующий код. В таком случае появление новых требований не повлечет за собой модификацию существующей логики, а сможет быть реализовано прежде всего за счет ее расширения. Именно этот принцип является основой «плагинной архитектуры» (Plugin Architecture). О том, за счет каких техник это может быть достигнуто, будет рассказано дальше.

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

Тестируемость. Код, который легче тестировать, будет содержать меньше ошибок и надежнее работать. Но тесты не только улучшают качество кода. Многие разработчики приходят к выводу, что требование «хорошей тестируемости» является также направляющей силой, автоматически ведущей к хорошему дизайну, и одновременно одним из важнейших критериев, позволяющих оценить его качество: "Используйте принцип «тестируемости» класса в качестве «лакмусовой бумажки» хорошего дизайна класса. Даже если вы не напишите ни строчки тестового кода, ответ на этот вопрос в 90% случаев поможет понять, насколько все «хорошо» или «плохо» с его дизайном" (Идеальная архитектура).

Существует целая методология разработки программ на основе тестов, которая так и называется — Разработка через тестирование (Test-Driven Development, TDD).

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

Хорошо структурированный, читаемый и понятный код. Сопровождаемость. Над программой, как правило, работает множество людей — одни уходят, приходят новые. После написания сопровождать программу тоже, как правило, приходится людям, не участвовавшем в ее разработке. Поэтому хорошая архитектура должна давать возможность относительно легко и быстро разобраться в системе новым людям. Проект должен быть хорошо структурирован, не содержать дублирования, иметь хорошо оформленный код и желательно документацию. И по возможности в системе лучше применять стандартные, общепринятые решения привычные для программистов. Чем экзотичнее система, тем сложнее ее понять другим (Принцип наименьшего удивления — Principle of least astonishment. Обычно, он используется в отношении пользовательского интерфейса, но применим и к написанию кода).

Ну и для полноты критерии плохого дизайна:

  1. Его тяжело изменить, поскольку любое изменение влияет на слишком большое количество других частей системы. (Жесткость, Rigidity).
  2. При внесении изменений неожиданно ломаются другие части системы. (Хрупкость, Fragility).
  3. Код тяжело использовать повторно в другом приложении, поскольку его слишком тяжело «выпутать» из текущего приложения. (Неподвижность, Immobility).

Не смотря на разнообразие критериев, все же главной при разработке больших систем считается задача снижения сложности. А для снижения сложности ничего, кроме деления на части, пока не придумано. Иногда это называют принципом «разделяй и властвуй» (divide et impera), но по сути речь идет об иерархической декомпозиции. Сложная система должна строится из небольшого количества более простых подсистем, каждая из которых, в свою очередь, строится из частей меньшего размера, и т.д., до тех пор, пока самые небольшие части не будут достаточно просты для непосредственного понимания и создания.

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

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

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

  • Масштабируемость (Scalability)
    возможность расширять систему и увеличивать ее производительность, за счет добавления новых модулей.
  • Ремонтопригодность (Maintainability)
    изменение одного модуля не требует изменения других модулей
  • Заменимость модулей (Swappability)
    модуль легко заменить на другой
  • Возможность тестирования (Unit Testing)
    модуль можно отсоединить от всех остальных и протестировать / починить
  • Переиспользование (Reusability)
    модуль может быть переиспользован в других программах и другом окружении
  • Сопровождаемость (Maintenance)
    разбитую на модули программу легче понимать и сопровождать

Можно сказать, что в разбиении сложной проблемы на простые фрагменты и заключается цель всех методик проектирования. А термином «архитектура», в большинстве случаев, просто обозначают результат такого деления, плюс "некие конструктивные решения, которые после их принятия с трудом поддаются изменению" (Мартин Фаулер «Архитектура корпоративных программных приложений»). Поэтому большинство определений в той или иной форме сводятся к следующему:

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

"Архитектура — это организация системы, воплощенная в ее

компонентах, их отношениях между собой и с окружением.
Система — это набор компонентов, объединенных для выполнения определенной функции."

Таким образом, хорошая архитектура это, прежде всего, модульная/блочная архитектура. Чтобы получить хорошую архитектуру надо знать, как правильно делать декомпозицию системы. А значит, необходимо понимать — какая декомпозиция считается «правильной» и каким образом ее лучше проводить?


1. Иерархическая

Не стоит сходу рубить приложение на сотни классов. Как уже говорилось, декомпозицию надо проводить иерархически — сначала систему разбивают на крупные функциональные модули/подсистемы, описывающие ее работу в самом общем виде. Затем, полученные модули, анализируются более детально и, в свою очередь, делятся на под-модули либо на объекты.

Перед тем как выделять объекты разделите систему на основные смысловые блоки хотя бы мысленно. Для небольших приложений двух уровней иерархии часто оказывается вполне достаточно — система вначале делится на подсистемы/пакеты, а пакеты делятся на классы.

Эта мысль, при всей своей очевидности, не так банальна как кажется. Например, в чем заключается суть такого распространенного «архитектурного шаблона» как Модель-Вид-Контроллер (MVC)? Всего навсего в отделении представления от бизнес-логики, то есть в том, что любое пользовательское приложение вначале делится на два модуля — один из которых отвечает за реализацию собственно самой бизнес логики (Модель), а второй — за взаимодействие с пользователем (Пользовательский Интерфейс или Представление). Затем, для того чтобы эти модули могли разрабатываться независимо, связь между ними ослабляется с помощью паттерна «Наблюдатель» (подробно о способах ослабления связей будет рассказано дальше) и мы фактически получаем один из самых мощных и востребованных «шаблонов», которые используются в настоящее время.

Типичными модулями первого уровня (полученными в результате первого деления системы на наиболее крупные составные части) как раз и являются — «бизнес-логика», «пользовательский интерфейс», «доступ к БД», «связь с конкретным оборудованием или ОС».

Для обозримости на каждом иерархическом уровне рекомендуют выделять от 2 до 7 модулей.

2. Функциональная

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

Модуль = Функция + Данные, необходимые для ее выполнения.

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

Модуль — это не произвольный кусок кода, а отдельная функционально осмысленная и законченная программная единица (подпрограмма), которая обеспечивает решение некоторой задачи и в идеале может работать самостоятельно или в другом окружении и быть переиспользуемой. Модуль должен быть некой "целостностью, способной к относительной самостоятельности в поведении и развитии" (Кристофер Александер).

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

3. High Cohesion + Low Coupling
Самым же главным критерием качества декомпозиции является то, насколько модули сфокусированы на решение своих задач и независимы. Обычно это формулируют следующим образом: "Модули, полученные в результате декомпозиции, должны быть максимально сопряженны внутри (high internal cohesion) и минимально связанны друг с другом (low external coupling)."

  • High Cohesion, высокая сопряженность или «сплоченность» внутри модуля, говорит о том, модуль сфокусирован на решении одной узкой проблемы, а не занимается выполнением разнородных функций или несвязанных между собой обязанностей. (Сопряженностьcohesion, характеризует степень, в которой задачи, выполняемые модулем, связаны друг с другом )

    Следствием High Cohesion является принцип единственной ответственности (Single Responsibility Principle — первый из пяти принципов SOLID), согласно которому любой объект/модуль должен иметь лишь одну обязанность и соответственно не должно быть больше одной причины для его изменения.

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

    Это значит, что при правильном проектировании, при изменении одного модуля, не придется править другие или эти изменения будут минимальными. Чем слабее связанность, тем легче писать/понимать/расширять/чинить программу.


Считается, что хорошо спроектированные модули должны обладать следующими свойствами:
  • функциональная целостность и завершенность — каждый модуль реализует одну функцию, но реализует хорошо и полностью; модуль самостоятельно (без помощи дополнительных средств) выполняет полный набор операций для реализации своей функции.
  • один вход и один выход — на входе программный модуль получает определенный набор исходных данных, выполняет содержательную обработку и возвращает один набор результатных данных, т.е. реализуется стандартный принцип IPO — вход–процесс–выход;
  • логическая независимость — результат работы программного модуля зависит только от исходных данных, но не зависит от работы других модулей;
  • слабые информационные связи с другими модулями — обмен информацией между модулями должен быть по возможности минимизирован.

Грамотная декомпозиция — это своего рода искусство и гигантская проблема для многих программистов. Простота тут очень обманчива, а ошибки обходятся очень дорого. Если выделенные модули оказываются сильно сцеплены друг с другом, если их не удается разрабатывать независимо или не ясно за какую конкретно функцию каждый из них отвечает, то стоит задуматься а правильно ли вообще производится деление. Должно быть понятно, какую роль выполняет каждый модуль. Самый же надежный критерий того, что декомпозиция делается правильно, это если модули получаются самостоятельными и ценными сами по себе подпрограммами, которые могут быть использованы в отрыве от всего остального приложения (а значит, могут быть переиспользуемы).

Делая декомпозицию системы желательно проверять ее качество задавая себе вопросы: "Какую функцию выполняет каждый модуль?", “Насколько модули легко тестировать?”, “Возможно ли использовать модули самостоятельно или в другом окружении?”, “Как сильно изменения в одном модуле отразятся на остальных?

В первую очередь следует, конечно же, стремиться к тому, чтобы модули были предельно автономны. Как и было сказано, это является ключевым параметром правильной декомпозиции. Поэтому проводить ее нужно таким образом, чтобы модули изначально слабо зависели друг от друга. Но кроме того, имеется ряд специальных техник и шаблонов, позволяющих затем дополнительно минимизировать и ослабить связи между подсистемами. Например, в случае MVC для этой цели использовался шаблон «Наблюдатель», но возможны и другие решения. Можно сказать, что техники для уменьшения связанности, как раз и составляют основной «инструментарий архитектора». Только необходимо понимать, что речь идет о всех подсистемах и ослаблять связанность нужно на всех уровнях иерархии, то есть не только между классам, но также и между модулями на каждом иерархическом уровне.


Для наглядности, картинка из неплохой статьи "Decoupling of Object-Oriented Systems", иллюстрирующая основные моменты, о которых будет идти речь.

1. Интерфейсы. Фасад


Главным, что позволяет уменьшать связанность системы, являются конечно же Интерфейсы (и стоящий за ними принцип Инкапсуляция + Абстракция + Полиморфизм):
  • Модули должны быть друг для друга "черными ящиками" (инкапсуляция). Это означает, что один модуль не должен «лезть» внутрь другого модуля и что либо знать о его внутренней структуре. Объекты одной подсистемы не должны обращаться напрямую к объектам другой подсистемы
  • Модули/подсистемы должны взаимодействовать друг с другом лишь посредством интерфейсов (то есть, абстракций, не зависящих от деталей реализации) Соответственно каждый модуль должен иметь четко определенный интерфейс или интерфейсы для взаимодействия с другими модулями.

Принцип «черного ящика» (инкапсуляция) позволяет рассматривать структуру каждой подсистемы независимо от других подсистем. Модуль, представляющий собой черный ящик, можно относительно свободно менять. Проблемы могут возникнуть лишь на стыке разных модулей (или модуля и окружения). И вот это взаимодействие нужно описывать в максимально общей (абстрактной) форме — в форме интерфейса. В этом случае код будет работать одинаково с любой реализацией, соответствующей контракту интерфейса. Собственно именно эта возможность работать с различными реализациями (модулями или объектами) через унифицированный интерфейс и называется полиморфизмом. Полиморфизм это вовсе не переопределение методов, как иногда ошибочно полагают, а прежде всего — взаимозаменяемость модулей/объектов с одинаковым интерфейсом, или «один интерфейс, множество реализаций» (подробнее тут). Для реализации полиморфизма механизм наследования совсем не нужен. Это важно понимать, поскольку наследования вообще, по возможности, следует избегать.

Благодаря интерфейсам и полиморфизму, как раз и достигается возможность модифицировать и расширять код, без изменения того, что уже написано (Open-Closed Principle). До тех пор, пока взаимодействие модулей описано исключительно в виде интерфейсов, и не завязано на конкретные реализации, мы имеем возможность абсолютно «безболезненно» для системы заменить один модуль на любой другой, реализующий тот же самый интерфейс, а также добавить новый и тем самым расширить функциональность. Это как в конструкторе или «плагинной архитектуре» (plugin architecture) — интерфейс служит своего рода коннектором, куда может быть подключен любой модуль с подходящим разъемом. Гибкость конструктора обеспечивается тем, что мы можем просто заменить одни модули/«детали» на другие, с такими же разъемами (с тем же интерфейсом), а также добавить сколько угодно новых деталей (при этом уже существующие детали никак не изменяются и не переделываются). Подробнее про Open-Closed Principle и про то, как он может быть реализован можно почитать тут + хорошая статья на английском.

Интерфейсы позволяют строить систему более высокого уровня, рассматривая каждую подсистему как единое целое и игнорируя ее внутреннее устройство. Они дают возможность модулям взаимодействовать и при этом ничего не знать о внутренней структуре друг друга, тем самым в полной мере реализуя принцип минимального знания, являющейся основой слабой связанности. Причем, чем в более общей/абстрактной форме определены интерфейсы и чем меньше ограничений они накладывают на взаимодействие, тем гибче система. Отсюда фактически следует еще один из принципов SOLID — Принцип разделения интерфейса (Interface Segregation Principle), который выступает против «толстых интерфейсов» и говорит, что большие, объемные интерфейсы надо разбивать на более маленькие и специфические, чтобы клиенты маленьких интерфейсов (зависящие модули) знали только о методах, которые необходимы им в работе. Формулируется он следующим образом: "Клиенты не должны зависеть от методов (знать о методах), которые они не используют" или “Много специализированных интерфейсов лучше, чем один универсальный”.

Итак, когда взаимодействие и зависимости модулей описываются лишь с помощью интерфейсов, те есть абстракций, без использования знаний об их внутреннем устройстве и структуре, то фактически тем самым реализуется инкапсуляция, плюс мы имеем возможность расширять/изменять поведения системы за счет добавления и использования различных реализаций, то есть за счет полиморфизма. Из этого следует, что концепция интерфейсов включает в себя и в некотором смысле обобщает почти все основные принципы ООП — Инкапсуляцию, Абстракцию, Полиморфизм. Но тут возникает один вопрос. Когда проектирование идет не на уровне объектов, которые сами же и реализуют соответствующие интерфейсы, а на уровне модулей, то что является реализацией интерфейса модуля? Ответ: если говорить языком шаблонов, то как вариант, за реализацию интерфейса модуля может отвечать специальный объект — Фасад.

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

Таким образом, мы получаем первый, самый важный паттерн, позволяющий использовать концепцию интерфейсов при проектировании модулей и тем самым ослаблять их связанность — «Фасад». Помимо этого «Фасад» вообще дает возможность работать с модулями точно также как с обычными объектами и применять при проектировании модулей все те полезные принципы и техники, которые используются при проектирования классов.

Замечание: Хотя большинство программистов понимают важность интерфейсов при проектировании классов (объектов), складывается впечатление, что идея необходимости использовать интерфейсы также и на уровне модулей только зарождается. Мне встретилось очень мало статей и проектов, где интерфейсы бы применялись для ослабления связанности между модулями/слоями и соответственно использовался бы паттерн «Фасад». Кто, например, видел «Фасад» на схемах уже упоминавшегося «архитектурного шаблона» Модель-Вид-Контроллер, или хотя бы слышал его упоминание среди паттернов, входящих в состав MVC (наряду с Observer и Composite)? А ведь он там должен быть, поскольку Модель это не класс, это модуль, причем центральный. И у создателя MVC Трюгве Реенскауга он, конечно же, был (смотрим «The Model-View-Controller (MVC ). Its Past and Present», только учитываем, что это писалось в 1973 году и то, что мы сейчас называем Представлением — Presentaition/UI тогда называлось Editior). Странным образом «Фасад» потерялся на многие годы и вновь обнаружить его мне удалось лишь недавно, в основном, в обобщенном варианте MVC от Microsoft («Microsoft Application Architecture Guide»). Вот соответствующие слайды:

А разработчикам, к сожалению, приходится заново «переоткрывать» идею, что к объектам Модели, отвечающей за бизнес-логику приложения, нужно обращаться не напрямую а через интерфейс, то есть «Фасад», как например, в этой статье, откуда для полноты картины взят еще один слайд:

2. Dependency Inversion. Корректное создание и получение зависимостей


Формально, требование, чтобы модули не содержали ссылок на конкретные реализации, а все зависимости и взаимодействие между ними строились исключительно на основе абстракций, то есть интерфейсов, выражается принципом Инвертирования зависимостей (Dependency Inversion — последний из пяти принципов SOLID):
  • Модули верхнего уровня не должны зависеть от модулей нижнего уровня. И те, и другие должны зависеть от абстракций.
  • Абстракции не должны зависеть от деталей. Реализация должна зависеть от абстракции.

У этого принципа не самая очевидная формулировка, но суть его, как и было сказано, выражается правилом: «Все зависимости должны быть в виде интерфейсов». Подробно и очень хорошо принцип инвертирования зависимостей разбирается в статье Модульный дизайн или «что такое DIP, SRP, IoC, DI и т.п.». Статья из разряда must-read, лучшее, что доводилось читать по архитектуре ПО.

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

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

В каком-то смысле такое решение следует Принципу единственного выбора (Single Choice Principle), который говорит: "всякий раз, когда система программного обеспечения должна поддерживать множество альтернатив, их полный список должен быть известен только одному модулю системы". В этом случае, если в будущем придется добавить новые варианты (или новые реализации, как в рассматриваемом нами случае создания новых объектов), то достаточно будет произвести обновление только того модуля, в котором содержится эта информация, а все остальные модули останутся незатронутыми и смогут продолжать свою работу как обычно.

Ну а теперь разберем подробнее, как это делается на практике и каким образом модули могут корректно создавать и получать свои «зависимости», не нарушая принципа Dependency Inversion.

Итак, при проектировании модуля должны быть определены следующие ключевые вещи:

  • что модуль делает, какую функцию выполняет
  • что модулю нужно от его окружения, то есть с какими объектами/модулями ему придется иметь дело и
  • как он это будет получать

Крайне важно то, как модуль получает ссылки на объекты, которые он использует в своей работе. И тут возможны следующие варианты:
  1. Модуль сам создает объекты необходимые ему для работы.

    Но, как и было сказано, модуль не может это сделать напрямую — для создания необходимо вызвать конструктор конкретного типа, и в результате модуль будет зависеть не от интерфейса, а от конкретной реализации. Решить проблему в данном случае позволяет шаблон Фабричный Метод (Factory Method).

    "Суть заключается в том, что вместо непосредственного инстанцирования объекта через new, мы предоставляем классу-клиенту некоторый интерфейс для создания объектов. Поскольку такой интерфейс при правильном дизайне всегда может быть переопределён, мы получаем определённую гибкость при использовании низкоуровневых модулей в модулях высокого уровня".

    В случаях, когда нужно создавать группы или семейства взаимосвязанных объектов, вместо Фабричного Метода используется Абстрактная Фабрика (Abstract factory).

  2. Модуль берет необходимые объекты у того, у кого они уже есть (обычно это некоторый, известный всем репозиторий, в котором уже лежит все, что только может понадобиться для работы программы).

    Этот подход реализуется шаблоном Локатор Сервисов (Service Locator), основная идея которого заключается в том, что в программе имеется объект, знающий, как получить все зависимости (сервисы), которые могут потребоваться.

    Главное отличие от фабрик в том, что Service Locator не создаёт объекты, а фактически уже содержит в себе инстанцированные объекты (или знает где/как их получить, а если и создает, то только один раз при первом обращении). Фабрика при каждом обращении создает новый объект, который вы получаете в полную собственность и можете делать с ним что хотите. Локатор же сервисов выдает ссылки на одни и те же, уже существующие объекты. Поэтому с объектами, выданными Service Locator, нужно быть очень осторожным, так как одновременно с вами ими может пользоваться кто-то еще.

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

    Вообще говоря, Service Locator иногда называют антипаттерном и не рекомендуют использовать (главным образом потому, что он создает неявные связности и дает лишь видимость хорошего дизайна). Подробно можно почитать у Марка Симана:
    Service Locator is an Anti-Pattern
    Abstract Factory or Service Locator?

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

    Это так и называется — Внедрение Зависимостей (Dependency Injection). Обычно требуемые зависимости передаются либо в качестве параметров конструктора (Constructor Injection), либо через методы класса (Setter injection).

    Такой подход инвертирует процесс создания зависимости — вместо самого модуля создание зависимостей контролирует кто-то извне. Модуль из активного элемента, становится пассивным — не он делает, а для него делают. Такое изменение направления действия называется Инверсия Контроля (Inversion of Control), или Принцип Голливуда — «Не звоните нам, мы сами вам позвоним».

    Это самое гибкое решение, дающее модулям наибольшую автономность. Можно сказать, что только оно в полной мере реализует «Принцип единственной ответственности» — модуль должен быть полностью сфокусирован на том, чтобы хорошо выполнять свою функцию и не заботиться ни о чем другом. Обеспечение его всем необходимым для работы это отдельная задача, которой должен заниматься соответствующий «специалист» (обычно управлением зависимостями и их внедрениями занимается некий контейнер — IoC-контейнер).

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


Более подробно и с примерами о способах создания и получения зависимостей можно почитать, например, в этой статье (только надо иметь ввиду, что хотя автор пишет о Dependency Inversion, он использует термин Inversion of Control; возможно потому, что в русской википедии содержится ошибка и этим терминам даны одинаковые определения). А принцип Inversion of Control (вместе с Dependency Injection и Service Locator) детально разбирается Мартином Фаулером и есть переводы обеих его статей: "Inversion of Control Containers and the Dependency Injection pattern" и “Inversion of Control”.

Не будет преувеличением сказать, что использование интерфейсов для описания зависимостей между модулями (Dependency Inversion) + корректное создание и внедрение этих зависимостей (прежде всего Dependency Injection) являются центральными/базовыми техниками для снижения связанности. Они служат тем фундаментом, на котором вообще держится слабая связанность кода, его гибкость, устойчивость к изменениям, переиспользование, и без которого все остальные техники имеют мало смысла. Но, если с фундаментом все в порядке, то знание дополнительных приемов может быть очень даже полезным. Поэтому продолжим.

3. Замена прямых зависимостей на обмен сообщениями


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

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

  • Наблюдатель (Observer). Применяется в случае зависимости «один-ко-многим», когда множество модулей зависят от состояния одного — основного. Использует механизм рассылки, который заключается в том, что основной модуль просто осуществляет рассылку одинаковых сообщений всем своим подписчикам, а модули, заинтересованные в этой информации, реализуют интерфейс «подписчика» и подписываются на рассылку. Находит широкое применение в системах с пользовательским интерфейсом, позволяя ядру приложения (модели) оставаться независимым и при этом информировать связанные с ним интерфейсы о том что произошли какие-то изменения и нужно обновиться.

    Организация взаимодействия посредством рассылки сообщений имеет дополнительный «бонус» — необязательность существования «подписчиков» на «опубликованные» (т.е. рассылаемые) сообщения. Качественно спроектированная подобная система допускает добавление/удаление модулей в любое время.

  • Посредник (Mediator). Применяется, когда между модулями имеется зависимость «многие ко многим. Медиатор выступает в качестве посредника в общении между модулями, действуя как центр связи и избавляет модули от необходимости явно ссылаться друг на друга. В результате взаимодействие модулей друг с другом («все со всеми») заменяется взаимодействием модулей лишь с посредником («один со всеми»). Говорят, что посредник инкапсулирует взаимодействие между множеством модулей.

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


Дополнение: Модули могут пересылать друг другу не только «простые сообщения, но и объекты-команды. Такое взаимодействие описывается шаблоном Команда (Command). Суть заключается в инкапсулировании запроса на выполнение определенного действия в виде отдельного объекта (фактически этот объект содержит один единственный метод execute()), что позволяет затем передавать это действие другим модулям на выполнение в качестве параметра, и вообще производить с объектом-командой любые операции, какие могут быть произведены над обычными объектами. Кратко рассмотрен тут, соответствующая глава из книги банды четырех тут, есть также статья на хабре.

4. Замена прямых зависимостей на синхронизацию через общее ядро


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

Ядро-посредник может как знать о модулях-клиентах и управлять ими (пример — архитектура apache ), так и может быть полностью, или почти полностью, независимым и ничего о клиентах не знать. В сущности именно этот подход реализован в «шаблоне» Модель-Вид-Контроллер (MVC), где с одной Моделью (являющейся ядром приложение и общим хранилищем данных) могут взаимодействовать множество Пользовательских Интерфейсов, которые работают синхронно и при этом не знают друг о друге, а Модель не знает о них. Ничто не мешает подключить к общей модели и синхронизировать таким образом не только интерфейсы, но и другие вспомогательные модули.

Очень активно эта идея также используется при разработке игр, где независимые модули, отвечающие за графику, звук, физику, управление программой синхронизируются друг с другом через игровое ядро (модель), где хранятся все данные о состоянии игры и ее персонажах. В отличие от MVC, в играх согласование модулей с ядром (моделью) происходит не за счет шаблона «Наблюдатель», а по таймеру, что само по себе является интересным архитектурным решением весьма полезным для программ с анимацией и «бегущей» графикой.

5. Закон Деметры (law of Demeter)


Закон Деметры запрещает использование неявных зависимостей: "Объект A не должен иметь возможность получить непосредственный доступ к объекту C, если у объекта A есть доступ к объекту B и у объекта B есть доступ к объекту C". Java-пример.

Это означает, что все зависимости в коде должны быть «явными» — классы/модули могут использовать в работе только «свои зависимости» и не должны лезть через них к другим. Кратко этот принцип формулируют еще таким образом: "Взаимодействуй только с непосредственными друзьями, а не с друзьями друзей". Тем самым достигается меньшая связанность кода, а также большая наглядность и прозрачность его дизайна.

Закон Деметры реализует уже упоминавшийся «принцип минимального знания», являющейся основой слабой связанности и заключающийся в том, что объект/модуль должен знать как можно меньше деталей о структуре и свойствах других объектов/модулей и вообще чего угодно, включая собственные подкомпоненты. Аналогия из жизни: Если Вы хотите, чтобы собака побежала, глупо командовать ее лапами, лучше отдать команду собаке, а она уже разберётся со своими лапами сама.

6. Композиция вместо наследования


Одну из самых сильных связей между объектами дает наследование, поэтому, по возможности, его следует избегать и заменять композицией. Эта тема хорошо раскрыта в статье Герба Саттера — «Предпочитайте композицию наследованию».

Могу только посоветовать в данном контексте обратить внимание на шаблон Делегат (Delegation/Delegate) и пришедший из игр шаблон Компонет (Component), который подробно описан в книге «Game Programming Patterns» (соответствующая глава из этой книги на английском и ее перевод).


Статьи в интернете:

Замечательный ресурс — Архитектура приложений с открытым исходным кодом, где "авторы четырех дюжин приложений с открытым исходным кодом рассказывают о структуре созданных ими программ и о том, как эти программы создавались. Каковы их основные компоненты? Как они взаимодействуют? И что открыли для себя их создатели в процессе разработки? В ответах на эти вопросы авторы статей, собранных в данных книгах, дают вам уникальную возможность проникнуть в то, как они творят". Одна из статей полностью была опубликована на хабре — «Масштабируемая веб-архитектура и распределенные системы».

Интересные решения и идеи можно найти в материалах, посвященных разработке игр. Game Programming Patterns — большой сайт с подробным описанием многих шаблонов и примерами их применения к задаче создания игр (оказывается, есть уже его перевод — «Шаблоны игрового программирования», спасибо strannik_k за ссылку). Возможно будет полезна также статья «Гибкая и масштабируемая архитектура для компьютерных игр» (и ее оригинал. Нужно только иметь ввиду что автор почему-то композицию называет шаблоном "Наблюдатель").

По поводу паттернов проектирования:


Есть еще принципы/паттерны GRASP, описанные Крэгом Лэрманом в книге «Применение UML 2.0 и шаблонов проектирования», но они больше запутывают чем проясняют. Краткий обзор и обсуждение на хабре (самое ценное в комментариях).

Ну и конечно же книги:

Проектирование программного обеспечения / Хабр

Сегодня процесс создания сложных программных приложений невозможно представить без разделения на этапы жизненного цикла. Под жизненным циклом программы будем понимать совокупность этапов:
  • Анализ предметной области и создание ТЗ (взаимодействия с заказчиком)
  • Проектирование структуры программы
  • Кодирование (набор программного кода согласно проектной документации)
  • Тестирование и отладка
  • Внедрение программы
  • Сопровождение программы
  • Утилизация

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

UML — является графическим языком для визуализации, описания параметров, конструирования и документирования различных систем (программ в частности). Диаграммы создаются с помощью специальных CASE средств, например Rational Rose (http://www-01.ibm.com/software/rational/) и Enterprise Architect (http://www.sparxsystems.com.au/). На основе технологии UML строится единая информационная модель. Приведенные выше CASE средства способны генерировать код на различных объектно-ориентированных языках, а так же обладают очень полезной функцией реверсивного инжиниринга. (Реверсивный инжиниринг позволяет создать графическую модель из имеющегося программного кода и комментариев к нему.)

Рассмотрим типы диаграмм для визуализации модели (это must have, хотя типов гораздо больше):

  • Диаграмма вариантов использования (use case diagram)
  • Диаграмма классов (class diagram)
  • Диаграмма состояний (statechart diagram)
  • Диаграмма последовательности (sequence diagram)
  • Диаграмма кооперации (collaboration diagram)
  • Диаграмма компонентов (component diagram)
  • Диаграмма развертывания (deployment diagram)
Диаграмма вариантов использования (use case diagram)

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

Диаграмма классов (class diagram)

Диаграмма классов служит для представления статической структуры модели системы в терминологии классов объектно-ориентированного программирования. Диаграмма классов может отражать, в частности, различные взаимосвязи между отдельными сущностями предметной области, такими как объекты и подсистемы, а также описывает их внутреннюю структуру (поля, методы…) и типы отношений (наследование, реализация интерфейсов … ). На данной диаграмме не указывается информация о временных аспектах функционирования системы. С этой точки зрения диаграмма классов является дальнейшим развитием концептуальной модели проектируемой системы. На этом этапе принципиально знание ООП подхода и паттернов проектирования.

Диаграмма состояний (statechart diagram)

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

Диаграмма последовательности (sequence diagram)

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

Диаграмма кооперации (collaboration diagram)

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

Диаграмма компонентов (component diagram)

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

Диаграмма развертывания (deployment diagram)

Диаграмма развертывания предназначена для визуализации элементов и компонентов программы, существующих лишь на этапе ее исполнения (runtime). При этом представляются только компоненты-экземпляры программы, являющиеся исполнимыми файлами или динамическими библиотеками. Те компоненты, которые не используются на этапе исполнения, на диаграмме развертывания не показываются.
Диаграмма развертывания содержит графические изображения процессоров, устройств, процессов и связей между ними. В отличие от диаграмм логического представления, диаграмма развертывания является единой для системы в целом, поскольку должна всецело отражать особенности ее реализации. Эта диаграмма, по сути, завершает процесс ООАП для конкретной программной системы и ее разработка, как правило, является последним этапом спецификации модели.

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

Я убежден, что программист в первую очередь это кодер – он НЕ должен общаться с заказчиком, НЕ должен задумываться об архитектуре системы, не должен изобретать интерфейс к программе, он только должен кодировать – реализовывать алгоритмы, функционал, внешний вид, юзабилити, но не более…. Проектировщик же должен начиная от абстрактных диаграмм (описывающих предметную область) до диаграмм представляющих структуру данных, классов и процессов их взаимодействия, детально шаг за шагом все расписать. То есть сложность работы и зарплата проектировщика должна быть на порядок выше чем у программиста == кодера. Простите за крамолу....

проектирование, дизайн и разработка — Разработка на vc.ru

{"id":146268,"url":"https:\/\/vc.ru\/dev\/146268-etapy-sozdaniya-mobilnogo-prilozheniya-proektirovanie-dizayn-i-razrabotka","title":"\u042d\u0442\u0430\u043f\u044b \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f: \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435, \u0434\u0438\u0437\u0430\u0439\u043d \u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430","services":{"facebook":{"url":"https:\/\/www.facebook.com\/sharer\/sharer.php?u=https:\/\/vc.ru\/dev\/146268-etapy-sozdaniya-mobilnogo-prilozheniya-proektirovanie-dizayn-i-razrabotka","short_name":"FB","title":"Facebook","width":600,"height":450},"vkontakte":{"url":"https:\/\/vk.com\/share.php?url=https:\/\/vc.ru\/dev\/146268-etapy-sozdaniya-mobilnogo-prilozheniya-proektirovanie-dizayn-i-razrabotka&title=\u042d\u0442\u0430\u043f\u044b \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f: \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435, \u0434\u0438\u0437\u0430\u0439\u043d \u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430","short_name":"VK","title":"\u0412\u041a\u043e\u043d\u0442\u0430\u043a\u0442\u0435","width":600,"height":450},"twitter":{"url":"https:\/\/twitter.com\/intent\/tweet?url=https:\/\/vc.ru\/dev\/146268-etapy-sozdaniya-mobilnogo-prilozheniya-proektirovanie-dizayn-i-razrabotka&text=\u042d\u0442\u0430\u043f\u044b \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f: \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435, \u0434\u0438\u0437\u0430\u0439\u043d \u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430","short_name":"TW","title":"Twitter","width":600,"height":450},"telegram":{"url":"tg:\/\/msg_url?url=https:\/\/vc.ru\/dev\/146268-etapy-sozdaniya-mobilnogo-prilozheniya-proektirovanie-dizayn-i-razrabotka&text=\u042d\u0442\u0430\u043f\u044b \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f: \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435, \u0434\u0438\u0437\u0430\u0439\u043d \u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430","short_name":"TG","title":"Telegram","width":600,"height":450},"odnoklassniki":{"url":"http:\/\/connect.ok.ru\/dk?st.cmd=WidgetSharePreview&service=odnoklassniki&st.shareUrl=https:\/\/vc.ru\/dev\/146268-etapy-sozdaniya-mobilnogo-prilozheniya-proektirovanie-dizayn-i-razrabotka","short_name":"OK","title":"\u041e\u0434\u043d\u043e\u043a\u043b\u0430\u0441\u0441\u043d\u0438\u043a\u0438","width":600,"height":450},"email":{"url":"mailto:?subject=\u042d\u0442\u0430\u043f\u044b \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f: \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435, \u0434\u0438\u0437\u0430\u0439\u043d \u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430&body=https:\/\/vc.ru\/dev\/146268-etapy-sozdaniya-mobilnogo-prilozheniya-proektirovanie-dizayn-i-razrabotka","short_name":"Email","title":"\u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043d\u0430 \u043f\u043e\u0447\u0442\u0443","width":600,"height":450}},"isFavorited":false}

2787 просмотров

С чего начать проектирование программы? Часть 1

С чего начать проектирование программы? Классический объектно-ориентированный подход даёт нам однозначный ответ на этот вопрос: с выявления ключевых абстракций и построения объектной модели предметной области.

Джеймс Рамбо, один из создателей языка UML и Rational Unified Process'а, в своей книге "UML 2.0. Объектно-ориентированное моделирование и разработка" предлагает нам такой алгоритм проектирования:

  1. Изучить предметную область и выделить классы предметной области.
  2. Удалить лишние классы (несущественные или избыточные).
  3. Связать классы ассоциациями.
  4. Выделить в классах атрибуты.
  5. Реструктуризовать классы при помощи наследования.
  6. Добавить классы приложения.
  7. Добавить операции.
Дж. Рамбо, М. Блаха. UML 2.0. Объектно-ориентированное моделирование и разработка. 2-е изд. – СПб.: Питер, 2007, стр. 218 – 285.

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

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

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

Попытки подсмотреть архитектуру (а если выражаться точнее – конструкцию) программы в реальной жизни или в предметной области настолько же бесплодны, насколько бесплодно копирование крыльев птицы, навешивание их на руки человека и отправка последнего в полёт. Разработка новой техники идёт по противоположному пути: сначала разрабатывается теория функционирования устройства и лишь затем устройство реализуется "в металле".

Вернёмся к вопросу, вынесенному в заголовок. С чего начать проектирование программы?

Чтобы ответить на этот вопрос, сделаем небольшое отступление. Это отступление важно, потому что многие начинающие программисты о нём забывают. Его суть – любая техника разрабатывается для выполнения какой-либо полезной функции. Например, функция автомобиля – перемещение его владельца из пункта А в пункт Б. И программы здесь – не исключение. У каждой программы тоже должно быть определённое назначение, например, редактирование текста, редактирование таблиц или развлечение пользователя. Приступая к проектированию программы, разработчик должен чётко понимать её назначение.

Проектирование любой программы должно начинаться:

1)      с составления списка полезных функций, которые должна выполнять программа;

2)      с проектирования технологии реализации каждой полезной функции.

Иными словами, прежде чем проектировать конструкцию программы, нужно сначала спроектировать технологический процесс.

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

Его можно описать в текстовом виде при помощи вариантов использования (см.:  Коберн, Алистер. Современные методы описания функциональных требований к системам/Пер. с англ. – М.: Издательство «Лори», 2002 г. – 263 с.: ил.) и в виде диаграммы (например, блок-схемы, flowchart'а).

Рассмотрим предложенноый подход на примере. В качестве примера возьмём задачу про датчики и метеостанцию из книги Гради Буча и продемонстрируем, как можно подойти к решению данной задачи иным образом, чем это изложено у Г. Буча.

Требования к метеорологической станции Система должна обеспечивать автоматический мониторинг следующих первичных погодных параметров:
  • скорость и направление ветра;
  • температура;
  • барометрическое давление;
  • влажность воздуха.
Система также должна вычислять некоторые производные параметры, в число которых входят:
  • коэффициент резкости погоды;
  • точка росы;
  • относительное изменение температуры;
  • относительное изменение барометрического давления.
В системе должна быть предусмотрена возможность определения текущего времени и даты, которые будут использоваться при генерации сообщении о максимальных и минимальных значениях первичных параметров за последние 24 часа. Система должна обеспечивать постоянный вывод на дисплей текущих значений всех восьми первичных и производных параметров, а также текущее время и дату. Пользователь должен иметь возможность увидеть максимальные и минимальные значения любого из первичных параметров за 24 часа, сопровождаемые информацией о времени произведения соответствующего замера.
Система должна позволять пользователю проводить калибровку датчиков по известным опорным значениям, а также устанавливать текущие время и дату.
Буч Г. Объектно-ориентированный анализ и проектирование с примерами приложений на C++, 2-е изд./Пер с англ. – М.: "Издательство Бином", СПб: "Невский диалект", 1998 г., стр. 284, или: http://www.helloworld.ru/texts/comp/other/oop/ch08.htm

Начнём проектирование системы с описания процесса измерения и отображения температуры.

Первая диаграмма будет довольно простой:

На диаграмме показано, что температура считывается с датчика температуры напрямую и отображается на экране. Понятно, что это неверно. Скорее всего, датчик подключён к какому-нибудь порту, и его показания считываются программой через порт.

Внесём в диаграмму изменения:

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

Внесём соответствующие изменения:

Сообщение от датчика температуры, скорее всего, закодировано в определённом формате (например, в формате json или в специализированном XML). Соответственно, потребуется парсер, который понимает этот формат:

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

Отобразим этап преобразования градусов на диаграмме:

Наконец, температуру нужно показать в определённом месте экрана (или в определённом окне).

Внесём изменения в схему:

Получилось достаточно подробное описание процесса измерения и отображения температуры.

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

В этом случае, диаграмма процесса будет выглядеть так:

Наряду с такими компонентами, как:

  • парсер атмосферного давления,
  • конвертер атмосферного давления (например, из кило-паскалей в мм. ртутного столба) и
  • окном для вывода давления,

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

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

Приведём список классов и операций:

Читает данные, пришедшие на порт.

Читает данные с порта по определённому протоколу.

Определяет, от какого датчика поступило сообщение, и пересылает его соответствующему обработчику.

Разбирает сообщение от датчика температуры.

Barometric Pressure Parser

Разбирает сообщение от датчика атмосферного давления.

Преобразует температуру из одних единиц в другие.

Barometric Pressure Converter

Преобразует атмосферное давление из одних единиц в другие.

Отображает температуру в специальном окне.

Barometric Pressure Window

Отображает атмосферное давление в специальном окне.

Отображает окна на экране.

ЛИТЕРАТУРА:

1.      Буч Г. Объектно-ориентированный анализ и проектирование с примерами приложений на C++, 2-е изд./Пер с англ. – М.: "Издательство Бином", СПб: "Невский диалект", 1998 г. Или: http://www.helloworld.ru/texts/comp/other/oop/index.htm 4.      Рамбо Дж., Блаха М. UML 2.0. Объектно-ориентированное моделирование и разработка. 2-е изд./Пер. с англ. – СПб.: Питер, 2007. – 544 с.: ил.

7 лучших программ для менеджмента проектов

Адаптированный перевод статьи Мэтью Гуая «The Best Free Project Management Software».

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

Что делает программы для менеджмента проектов хорошими?

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

  • ПО должно быть бесплатным для неограниченного количества проектов.
  • Разнообразие. Мы включили варианты для различных методологий менеджмента – kanban, диаграммы Гантта, списки to-do. А некоторые приложения в наш список не вошли просто потому что были доступны лучшие альтернативы, использующие такие же методологии.
  • Хостинг. Есть много отличных бесплатных инструментов для менеджмента проектов, которые можно установить самостоятельно, но это потребует больше времени на настройку. Поэтому мы предлагаем приложения с хостингом в компаниях, предоставляющих эти инструменты.

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

7 лучших бесплатных приложений для менеджмента проектов

  • Trello (Web, macOS, Windows, iOS, Android) — для людей и команд, которым нужен рабочий канал связи.
  • MeisterTask (Web, Windows, macOS, iOS, Android) — для объединения идей по проекту, планирования и выполнения.
  • KanbanFlow (Web) — объединяет доску kanban, тайм-трекер и Pomodoro.
  • Freedcamp (Web, iOS) — единый инструмент для управления всеми проектами и всей коммуникацией.
  • Asana (Web, iOS, Android) — для создания списков to-do.
  • Paymo (Web, Windows, macOS, Linux, iOS, Android) — для фрилансеров с почасовой оплатой.
  • Bitrix24 (Web, Windows, macOS, iOS, Android) — для классического менеджмента проектов с диаграммами Гантта.

Trello

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

Начните с нескольких списков ваших задач и кастомизируйте эти списки в соответствии со стадиями вашего рабочего процесса (например, «to-do», «в процессе», «сделано»). Или же они могут быть отдельными частями вашего проекта (например, «разработка», «дизайн», «дистрибуция»).

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

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

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

Цена Trello: бесплатный план включает неограниченное количество досок и пользователей, один Power-Up на доску, вложения файлов до 10MB. За $9,99 с пользователя в месяц можно подключить план Business Class с неограниченными Power-Ups, вложениями до 250MB и более тонкими настройками контроля доступа.

MeisterTask

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

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

Цена MeisterTask: Basic plan бесплатный. Он включает неограниченное число проектов и пользователей, две нативных интеграции приложения и вложения файлов до 20MB. Pro plan за $8,25 с пользователя в месяц включает неограниченное количество интеграций, вложения до 200MB и архив задач с возможностью поиска по нему.

KanbanFlow

Вам любопытно, сколько времени занимает у вас выполнение задач? KanbanFlow это еще одно «kanban-доска»-приложение, включающее таймер. Этот таймер ведет логи того, сколько времени вы тратите на выполнение каждой задачи и сколько времени она остается в определенном списке. Таймер также имеет режим Pomodoro, который поможет вашей команде работать спринтами и будет напоминать каждому о перерывах, чтобы поддерживать продуктивность в течение всего дня.

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

Цена KanbanFlow: бесплатный план включает неограниченное количество задач и досок, таймер Pomodoro и отчеты о продуктивности. Premium план за $5 с пользователя в месяц включает возможность вложения файлов, поддержку приоритетов и сторонние интеграции.

Freedcamp

Freedcamp дает вам пространство для управления задачами, а также предоставляет календарь и инструменты отметок времени для планирования расписания вашего проекта. Задачи могут быть организованы в стандартный список to-do или kanban-доску. Самые важные даты могут быть разбиты между отметками времени в календаре – это помогает осуществлять краткосрочное и долгосрочное планирование.

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

Цена Freedcamp: бесплатный план включает неограниченное число пользователей и проектов, вложения до 10MB. Следующий тарифный план, Minimalist, за $1,49 с пользователя в месяц, включает премиум-поддержку, вложения файлов до 25MB и неограниченную вложенность задач.

Asana

Ваш to-do список не плох, просто вам нужно немного больше функционала для управления командными проектами? Именно это и предлагает Asana. Это инструмент для менеджмента проектов, который позволяет разбивать проект на разделы и под-списки, а также предоставляет панель инструментов, где вы можете видеть, какая часть проекта уже завершена. Вы будете добавлять, перемещать и закрывать задачи точно так же, как делали бы это в любом другом аналогичном приложении, но у вас будут дополнительные функции для сотрудничества и организации, если вам нужно работать в команде.

Для ваших личных задач (или рабочих, но не относящихся к проекту) в Asana вы можете завести дополнительные списки. Ими можно делиться с отдельными людьми. Задачи, которые должны выполнить лично вы, будут показываться в просмотре My Tasks – это позволит быстро увидеть все, о чем нужно позаботиться.

Цена Asana: бесплатный план включает неограниченное количество проектов, количество пользователей — до 15, базовые функции поиска. Premium план за $9,99 с пользователя в месяц включает расписание проекта, улучшенный поиск и зависимости задач.

Paymo

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

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

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

Когда приходит пора выставить клиентам счет, используйте отчеты по времени, чтобы извлечь нужные вам данные. Экспортируйте, распечатайте или поделитесь своим отчетом с клиентами в виде детального списка или диаграммы. Также можно просто взять данные и использовать их для создания брендированного счета прямо в Paymo. Можно даже настроить свои счета для онлайн-платежей через Stripe или PayPal.

Цена Paymo: бесплатный план для одного пользователя и неограниченного количества проектов, 1GB пространства и до трех счетов. План Small Office за $9,56 с пользователя в месяц включает неограниченное количество счетов, 50GB пространства и шаблоны проектов.

Bitrix24

У вас большая или распределенная команда, занимающаяся одним проектом? Bitrix24 это прекрасное решение, комбинирующее классический функционал менеджмента проектов с нативными инструментами для сотрудничества. Bitrix24 создан быть приложением «всё-в-одном» для управления проектами, командами, да и компанией в целом. В нем есть все: от социальной интрасети, видеоконференций и возможности поделиться экраном до HR-инстурментов и инструментов для менеджмента клиентов.

Организуйте задачи внутри ваших проектов, а затем используйте вид диаграммы Гантта, чтобы отслеживать все сразу. Вы даже можете отслеживать загруженность сотрудников и дедлайны, чтобы избежать выгорания членов команды. А если вы планируете купить premium-план, то вам стоит знать, что Bitrix24 это одно из немногих приложений с твердой ставкой оплаты (т. е., не «с пользователя в месяц»), а это может быть довольно экономно.

Цена Bitrix24: бесплатный план включает неограниченное число проектов, до 12 пользователей и 5GB онлайн-хранилища. За $39/месяц можно улучшить условия до 24 пользователей и 24GB пространства.



Лучшие программы для проектирования домов, квартир и интерьеров

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

Общий рейтинг Общие сведения Функциональные возможности

Общий рейтинг

Общие сведения

Функциональные возможности

Общие сведения:

Лицензия

Windows

MacOS

Русский язык

Удобство интерфейса

Качество 3D-моделей

Рейтинг

бесплатно / pro

9

10

9

12 лучших приложений для дизайна комнат и инструменты для домашнего планирования

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

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

12 лучших бесплатных приложений для дизайна дома

Это наши любимые инструменты и приложения для декоратора комнат:

  1. Планировщик 5D
  2. Roomstyler
  3. Ikea Home Planner Tools
  4. Дизайн комнаты
  5. Homestyler
  6. Ремонтник дома
  7. Sweet Home 3D
  8. SmartDraw
  9. HomeByMe
  10. MagicPlan
  11. Amikasa
  12. DecorM .Планировщик 5D

    Planner 5D позиционирует себя как самое обширное бесплатное приложение для дизайна помещений на рынке. С легкостью проектируйте комнаты до мельчайших архитектурных деталей, включая окна, лестницы и перегородки. Не останавливайтесь на интерьерах; он также позволяет заниматься ландшафтным дизайном и бассейнами - все с потрясающей 3D-графикой.

    Вы также можете почерпнуть вдохновение из их галереи. Изучите новые модные дизайны, созданные другими дизайнерами виртуальных комнат.

    Рейтинг: 4,3 звезды в App Store и Google Play Store.

    Загрузите Planner 5D в App Store или в Google Play .

    2. Roomstyler

    Используйте это замечательное приложение для дизайна комнат, чтобы загрузить свой собственный план этажа или поэкспериментировать с предварительно загруженными макетами комнат. Планировщик дома Roomstyler 3D позволяет вставлять стены, двери и окна и выбирать из галереи отделки интерьера.

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

    Если вам нравится декор, который вы добавили в свою визуализированную модель, нажмите кнопку «Доступно для покупки», чтобы узнать цену и варианты приобретения. Вы можете использовать программу бесплатно, не присоединяясь к ней. Но если вы присоединитесь, вы можете загрузить свою модель на Facebook, чтобы ваши друзья увидели ее.

    Рейтинг: 2,0 звезды в App Store.

    Загрузите Roomstyler из App Store .

    3. Инструменты для планировки дома Ikea

    Когда вы листаете каталог Ikea, хотели бы вы когда-нибудь увидеть, как определенная книжная полка и стол будут выглядеть в вашем пространстве? Вы можете! С помощью бесплатного, простого в использовании инструмента Ikea Home Planner вы можете настроить план этажа, выбрать мебель и декор из галереи магазина, рассчитать стоимость и распечатать список желаний для просмотра в магазине.

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

    Рейтинг: НЕТ

    Загрузите Ikea Home Planner Tools . Обратите внимание, что они недоступны в App Store или Google Play.

    4. Дизайн комнаты

    Прекратите брать домой десятки образцов материалов, чтобы опробовать все комбинации в вашем помещении. Вместо этого попробуйте приложение Armstrong для 3D-дизайна комнат, которое позволяет вам увидеть различные цветовые сочетания полов, мебели, потолков, стен и столешниц, не выходя из дома.

    Design a Room позволяет вам выбрать комнату в своем доме, выбрать стиль (например, современный, традиционный, глобальный фьюжн) и поиграть с цветами, текстурами и отделкой. Вы даже можете согласовать цвета краски Шервина Уильямса, PPG и Бенджамина Мура, чтобы они соответствовали вашему дизайну.

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

    Рейтинг: НЕТ

    Загрузка не требуется. Попробуйте онлайн-инструмент Armstrong Design a Room .

    5. Помощник по дому

    Autodesk, создатель AutoCAD, REVIT и 3ds Studio Max, хорошо известен своими профессиональными программами для проектирования. Также было создано приложение для дизайна комнат Homestyler, которое они продали Easyhome в 2017 году.

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

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

    Рейтинг: 4.5 звезд в App Store и 3,9 звезды в Google Play Store.

    Загрузите Homestyler в App Store или Google Play .

    6. Ремонтник дома

    Приложения

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

    Рейтинг: НЕТ

    Загрузка не требуется. Воспользуйтесь инструментом онлайн по телефону The Home Renovator .

    7. Милый дом 3D

    Это приложение для 3D-дизайна комнат предназначено для тех, кому нужно больше возможностей настройки планировки комнаты. Онлайн-программное обеспечение является бесплатным, хотя требуется информация для входа. Вы также можете загрузить более продвинутую версию Sweet Home 3D (за дополнительную плату), которая позволяет вам сохранять, экспортировать и изменять ваши планы дома. Интерфейс состоит из четырех разделов:

    • Каталог мебели позволяет вам выбирать компоненты по имени, а затем перетаскивать их прямо на план этажа.
    • В списке домашней мебели указаны размеры каждого предмета по названию и размеру.
    • План дома показывает вам в формате 2D, где расположены стены, окна, двери и мебель (если смотреть сверху).
    • Домашний 3D-вид показывает ваш план в трех измерениях, так что вы можете визуализировать план в процессе разработки.

    Чтобы добавить план этажа, импортируйте его в Sweet Home 3D, отмасштабируйте его и обведите свой план, чтобы избежать предположений. Эта программа может быть простой, но в ней есть расширенные функции для тех, кто хочет большего от своего опыта виртуального трехмерного планирования.

    Стоимость: Бесплатно скачать или использовать онлайн можно здесь. 13,99 долларов США в App Store.

    Рейтинг: 3,5 звезды в App Store.

    Загрузите Sweet Home 3D в App Store . Нет версии для Google Play.

    8. SmartDraw

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

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

    Стоимость: Попробовать бесплатно.$ 9.95 / мес. или 297 долларов за одну лицензию.

    Рейтинг: НЕТ

    Загрузите SmartDraw или попробуйте онлайн-версию на веб-сайте SmartDraw .

    9. HomeByMe

    HomeByMe - это веб-приложение для дизайна комнат. Начните в 2D и стройте свою комнату с нуля, заканчивая мебелью и аксессуарами. Когда вы будете готовы, преобразуйте его в 3D, где стены упадут, и вы сможете заглянуть внутрь созданного вами плана дизайна интерьера.

    Стоимость: Попробовать бесплатно. 14,99 долларов за полную версию.

    Рейтинг: НЕТ

    HomeByMe - это , полностью подключенный к Интернету .

    10. MagicPlan

    MagicPlan - это приложение для дизайна помещений для iOS и Android, которое создает планы этажей из отсканированных пользователями фотографий. Это упрощает создание дизайна комнаты, без необходимости измерять или рисовать. Это идеальное приложение для новичков в проектировании поэтажных планов. Как и следовало ожидать, он не так детализирован в своих творениях, как более сложные приложения, но он полезен для быстрого создания макетов интерьера.

    Стоимость: Бесплатно (первые два проекта), затем $ 9,99 / мес.

    Рейтинг: 4,7 звезды в App Store и 4,4 звезды в Google Play Store

    Загрузите MagicPlan в App Store или в Google Play .

    11. Amikasa

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

    После того, как вы закончите свой дизайн, появится функция трехмерного пошагового руководства, которая позволит вам совершить виртуальный тур по новому пространству. Кроме того, вы можете поделиться дизайном в социальных сетях, чтобы получить обратную связь. Версия для iOS недавно была добавлена ​​по цене 0,99 доллара США, а версии для Android нет. Существует бета-версия Windows, которую можно скачать бесплатно.

    Стоимость: 0,99 доллара США за версию для iOS; бесплатная версия для Windows.

    Рейтинг: 2,9 звезды в App Store.Нет версии для Android.

    Загрузите Amikasa в App Store или с веб-сайта Amikasa .

    12. DecorMatters

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

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

    Рейтинг: 4,7 звезды в App Store.

    Загрузите DecorMatters в App Store .Версия Android недоступна.

    Рейтинги и цены на 7 января 2021 г.

    Чистая прибыль

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

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

    Часто задаваемые вопросы

    Вопрос:

    Какое приложение для дизайна интерьера лучше всего?

    А:

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

    Вопрос:

    Как мне использовать приложение для дизайна комнаты?

    А:

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

    Вопрос:

    Где найти вдохновение для дизайна интерьера?

    А:

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

    Стивен Уолтерс внес вклад в создание этого сообщения.

    Как создать приложение - (2020) Создание приложения за 10 шагов

    , Крис Чинг