Допустим, у меня есть бесплатная и платная версия приложения. Платная версия - расширенный вариант бесплатной версии, касающийся функций, доступных пользователям. Это означает, что платная версия будет иметь все функции бесплатного приложения плюс дополнительные.
Есть ли шаблон для переключения доступности функции на основе флага, который загружается при запуске (например, бесплатно / платно)?
Мне не нравится идея иметь везде следующие блоки кода:
if(isFreeVersion){
// ...
} else {
// ...
}
Наличие 2-х отдельных веток git для каждой версии не вариант, потому что это означало бы поддержание 2 (или более) источников кода, в общем случае нецелесообразно и обсуждается более подробно здесь: Поддержка двух отдельных версий программного обеспечения из одной и той же базы кода в управлении версиями .
Есть ли способ сделать это, все еще имея единую кодовую базу и не засоряя код условными операторами, которые проверяют флаг free / paid?
Я уверен, что это обсуждалось много раз прежде, и я уверен, что есть некоторые подходы к решению этой проблемы, но я просто не могу найти это.
Мы используем Android / Java.
источник
if
проверки, чтобы скрыть элементы управления для запрещенных функций или всплывающее диалоговое окно, когда пользователь пытается сделать то, что ему запрещено. Я надеюсь найти способ избежать многих условныхОтветы:
Условное подобное
if(isFreeVersion)
должно встречаться в коде только один раз . Это не шаблон, но я уверен, что вы уже знаете его название: это называется принцип СУХОЙ . Наличие кода, подобного "if(isFreeVersion)
", в нескольких местах в вашем коде означает, что вы повторили эту строку / логику в ней, что означает, что ее следует реорганизовать, чтобы избежать повторения.«
if(isFreeVersion)
» следует использовать для настройки списка внутренних параметров конфигурации для различных функций. Полученный код может выглядеть следующим образом:Это сопоставляет ваш единственный флаг isFreeVersion с различными функциями . Обратите внимание, что здесь вы можете решить, предпочитаете ли вы использовать отдельные логические флаги для отдельных функций или использовать какие-то другие параметры, например, различные объекты стратегии с общим интерфейсом, если элемент управления функциями требует более сложной параметризации.
Теперь вы можете контролировать, что находится в бесплатной версии и в платной версии в одном месте, что делает обслуживание этой логики довольно простым. Вам все равно придется быть осторожным, чтобы ваш код не был загроможден множеством
if(feature1Enabled)
операторов (следуя принципу СУХОЙ), но теперь обслуживание этих проверок теперь не так уж и болезненно. Например, вы гораздо лучше контролируете, что вам нужно изменить, если хотите сделать существующую платную функцию бесплатной (или наоборот).Наконец, давайте посмотрим на статью Фаулера в блоге о переключателях функций , где он говорит о точках входа / переключателях функций. Позвольте мне привести одну центральную точку:
Таким образом, в качестве общей стратегии сфокусируйтесь на пользовательском интерфейсе и ограничьте количество проверок минимальным количеством точек, необходимых для появления или исчезновения определенной функции. Это должно поддерживать вашу базу кода в чистоте, без каких-либо ненужных помех.
источник
isFreeVersion
с параметрами конкретной функции, устраняет большинство трудностей этих тестов - они действительно начнут иметь смысл и больше не приведут к беспорядку обслуживания.Если вам не нравятся
if/else
блоки, то вы можете реорганизовать их, чтобы использовать наследование (см. « Заменить условный полиморфизмом» из книги « Рефакторинг Марина Фаулера» ). Это будет:Сделайте немного проще рассуждать о вашем коде.
Сделайте возможным иметь два класса, один для бесплатной версии, а другой для платной версии, которые, в свою очередь, будут передавать вызовы другим классам, гарантируя, что различие между бесплатной и платной версиями ограничено двумя классами (три считая базовый класс).
Позже упростите добавление других форм вашего программного обеспечения, таких как дешевый вариант или премиум-версия. Вы просто добавите еще один класс и объявите его один раз в своем коде, и вы будете знать, что вся база кода будет работать, как и ожидалось.
источник
Мне кажется, ваш вопрос мог бы быть решен довольно хорошо с помощью шаблона Feature Toggle .
Как часто бывает, в одной статье Пит Ходжсон объяснил все сценарии, с которыми вы можете столкнуться, применяя этот шаблон, гораздо лучше, чем я мог бы сделать.
Есть также некоторые библиотеки, которые поддерживают этот шаблон. У меня был опыт работы с FF4J на Java, но я думаю, если вы введете :
... в любой поисковой системе вы получите несколько решений.
источник
Есть несколько способов сделать это. Простой и прямой способ - использовать шаблон переключения функций, который был представлен во многих статьях. Следующий подход связан с проектированием подключаемых функций. И Android, и IOS имеют платежи в приложении. Наряду с этим возможна загрузка.
Когда вы смотрите на Servlets, JAMES Mailets и даже на плагины IDE, все они используют концепцию архитектуры плагинов:
Это также позволяет вам иметь различные классы функций, доступные для разных аудиторий. У пользователей есть только те функции, за которые они заплатили.
Код вашего приложения поддерживается как одна кодовая база, а ваш плагин - это отдельная кодовая база - но включает только те части, которые имеют отношение к плагину. Приложение знает, как обращаться с плагинами, когда они присутствуют, а плагин знает, как взаимодействовать с интерфейсом.
источник