Powiedzmy, że mam darmową i płatną wersję aplikacji. Wersja płatna jest nadzbiorem bezpłatnej wersji dotyczącej funkcji dostępnych dla użytkowników, co oznacza, że wersja płatna będzie miała wszystkie funkcje darmowej aplikacji plus dodatkowe.
Czy istnieje wzorzec przełączania dostępności funkcji na podstawie flagi, która ładuje się przy starcie (np. Bezpłatny / płatny)?
Nie podoba mi się pomysł posiadania następujących bloków kodu wszędzie:
if(isFreeVersion){
// ...
} else {
// ...
}
Posiadanie 2 oddzielnych gałęzi git dla każdej wersji nie jest opcją, ponieważ oznaczałoby to utrzymanie 2 (lub więcej) źródeł kodu, wydaje się ogólnie niepraktyczne i jest omówione bardziej tutaj: Utrzymanie dwóch oddzielnych wersji oprogramowania z tej samej bazy kodów w Kontroli wersji .
Czy istnieje sposób, aby to zrobić, wciąż mając jedną bazę kodu i nie zaśmiecając kodu instrukcjami warunkowymi, które sprawdzają flagę darmową / płatną?
Jestem pewien, że było to omawiane wiele razy wcześniej i jestem pewien, że istnieją pewne wzorce podejścia do tego problemu, ale po prostu nie mogę go znaleźć.
Używamy Androida / Java.
źródło
if
sprawdzanie ukrywania elementów sterujących zabronionych funkcji lub wyświetlanie wyskakujących okien dialogowych, gdy użytkownik próbuje zrobić to, czego nie wolno mu robić. Mam nadzieję znaleźć sposób na uniknięcie wielu warunków warunkowych w kodzieOdpowiedzi:
Jeśli nie lubisz
if/else
bloków, możesz je refaktoryzować, aby użyć dziedziczenia (zobacz Zastąp warunkowe polimorfizmem z książki Refaktoryzacja Marin Fowler ). To by:Uczyń swój kod nieco prostszym.
Umożliwiają posiadanie dwóch klas, jednej dla wersji darmowej i drugiej dla wersji płatnej, co z kolei wywoływałoby wywołania do innych klas, zapewniając, że rozróżnienie między wersją bezpłatną i płatną jest ograniczone do dwóch klas (trzy liczą klasa podstawowa).
Ułatw później dodanie innych form oprogramowania, takich jak tani wariant lub wersja premium. Po prostu dodasz inną klasę i zadeklarujesz ją raz w kodzie, a będziesz wiedział, że cała baza kodu nadal będzie działać zgodnie z oczekiwaniami.
źródło
Warunki warunkowe
if(isFreeVersion)
powinny wystąpić tylko raz w kodzie. To nie jest wzorzec, ale jestem pewien, że już znasz jego nazwę: nazywa się to zasadą OSUSZANIA . Posiadanie kodu typu „if(isFreeVersion)
” w więcej niż jednym miejscu w kodzie oznacza, że powtórzyłeś ten wiersz / logikę w nim, co oznacza, że należy go zrefaktoryzować, aby uniknąć powtórzenia.if(isFreeVersion)
Do ustawienia listy opcji konfiguracji wewnętrznej dla różnych funkcji należy użyć „ ”. Wynikowy kod może wyglądać następująco:To odwzorowuje twoją pojedynczą flagę „isFreeVersion” na różne funkcje . Pamiętaj, że możesz zdecydować, czy wolisz używać pojedynczych flag boolowskich dla poszczególnych funkcji, czy też użyć innych parametrów, na przykład różnych obiektów strategii ze wspólnym interfejsem, jeśli kontrola funkcji wymaga bardziej złożonej parametryzacji.
Teraz masz kontrolę nad tym, co jest w wersji darmowej, a co w wersji płatnej w jednym miejscu, co sprawia, że utrzymanie tej logiki jest bardzo proste. Nadal będziesz musiał uważać, aby nie zaśmiecać kodu dużą ilością
if(feature1Enabled)
instrukcji (zgodnie z zasadą DRY), ale teraz utrzymanie tych kontroli nie jest już tak bolesne. Na przykład masz znacznie lepszą kontrolę nad tym, co musisz zmienić, aby uwolnić istniejącą płatną funkcję (lub odwrotnie).Na koniec rzućmy okiem na artykuł Fowlera na temat przełączania funkcji , w którym mówi on o punktach wejścia / przełączania funkcji. Przytoczę jeden centralny punkt:
Tak więc, jako ogólna strategia, skup się na interfejsie użytkownika i ogranicz swoje kontrole do minimalnej liczby punktów wymaganych do pojawienia się lub zniknięcia określonej funkcji. To powinno utrzymywać bazę kodu w czystości, bez zbędnego bałaganu.
źródło
isFreeVersion
do konkretnych parametrów funkcja usuwa większość bólu tych testów - będą rzeczywiście zaczynają sensu i nie powodują bałagan konserwacyjnych więcej.Wydaje mi się, że twoje pytanie można rozwiązać całkiem dobrze, stosując wzorzec przełączania cech .
Jak to często bywa, Pete Hodgson wyjaśnił w jednym artykule wszystkie scenariusze, z którymi możesz się spotkać stosując ten wzór, znacznie lepiej niż ja.
Istnieją również biblioteki obsługujące ten wzorzec. Miałem doświadczenie w pracy z FF4J w Javie, ale zgaduję, jeśli wpiszesz:
... w dowolnej wyszukiwarce otrzymasz kilka rozwiązań.
źródło
Jest na to więcej niż jeden sposób. Prostym i bezpośrednim sposobem jest użycie Wzorca Przełączania Funkcji, który był dostępny w tak wielu artykułach. Kolejne podejście dotyczy projektowania funkcji, które można podłączyć. Zarówno Android, jak i IOS mają płatności w aplikacji. Wraz z tą płatnością istnieje możliwość pobrania.
Kiedy patrzysz na Servlety, JAMES Mailets, a nawet wtyczki IDE, wszystkie one wykorzystują koncepcję architektury wtyczek:
Pozwala to również na posiadanie różnych klas funkcji dostępnych dla różnych odbiorców. Użytkownicy mają tylko funkcje, za które zapłacili.
Kod aplikacji jest utrzymywany jako jedna podstawa kodu, a wtyczka stanowi oddzielną podstawę kodu - ale zawiera tylko części istotne dla wtyczki. Aplikacja wie, jak radzić sobie z wtyczkami, gdy są one obecne, a wtyczka wie tylko, jak współpracować z interfejsem.
źródło