Nehmen wir an, ich habe eine kostenlose und kostenpflichtige Version der App. Die kostenpflichtige Version ist eine Obermenge der kostenlosen Version in Bezug auf die Funktionen, die den Benutzern zur Verfügung stehen. Die kostenpflichtige Version bietet also alle Funktionen der kostenlosen App sowie zusätzliche Funktionen.
Gibt es ein Muster zum Umschalten der Funktionsverfügbarkeit basierend auf einem Flag, das beim Start geladen wird (z. B. kostenlos / kostenpflichtig)?
Ich mag die Idee nicht, überall folgende Codeblöcke zu haben:
if(isFreeVersion){
// ...
} else {
// ...
}
Es ist keine Option, zwei separate Git-Zweige für jede Version zu haben, da dies bedeuten würde, zwei (oder mehr) Codequellen zu verwalten . Dies erscheint im Allgemeinen unpraktisch und wird hier ausführlicher erläutert: Verwalten von zwei separaten Softwareversionen aus derselben Codebasis in der Versionskontrolle .
Gibt es eine Möglichkeit, dies zu tun, während Sie immer noch eine einzige Codebasis haben und den Code nicht mit bedingten Anweisungen verunreinigen, die das Flag für frei / bezahlt prüfen?
Ich bin mir sicher, dass dies schon oft diskutiert wurde und ich bin mir sicher, dass es einige Muster gibt, um dieses Problem anzugehen, aber ich kann es einfach nicht finden.
Wir verwenden Android / Java.
quelle
if
Überprüfungen, um Steuerelemente für verbotene Funktionen auszublenden, oder um Popup-Dialoge, wenn der Benutzer versucht, das zu tun, was er nicht darf. Ich hoffe, einen Weg zu finden, um viele Bedingungen im Code zu vermeidenAntworten:
Ein bedingtes Like
if(isFreeVersion)
sollte nur einmal im Code vorkommen. Dies ist kein Muster, aber ich bin sicher, dass Sie den Namen dafür bereits kennen: Es wird das DRY-Prinzip genannt . Wenn Sie Code wie "if(isFreeVersion)
" an mehr als einer Stelle in Ihrem Code haben, haben Sie diese Zeile / die darin enthaltene Logik wiederholt. Dies bedeutet, dass sie überarbeitet werden sollte, um die Wiederholung zu vermeiden."
if(isFreeVersion)
" sollte verwendet werden, um eine Liste der internen Konfigurationsoptionen für verschiedene Funktionen einzurichten. Der resultierende Code könnte dann folgendermaßen aussehen:Dadurch wird Ihr einzelnes "isFreeVersion" -Flag verschiedenen Funktionen zugeordnet . Beachten Sie, dass Sie hier entscheiden können, ob Sie einzelne Boolesche Flags für einzelne Features oder andere Parameter verwenden möchten, z. B. verschiedene Strategieobjekte mit einer gemeinsamen Schnittstelle, wenn die Feature-Steuerung eine komplexere Parametrisierung erfordert.
Jetzt haben Sie die Kontrolle darüber, was in der kostenlosen Version und was in der kostenpflichtigen Version an einem Ort enthalten ist, was die Wartung dieser Logik recht einfach macht. Sie müssen immer noch darauf achten, dass Ihr Code nicht mit vielen
if(feature1Enabled)
Anweisungen überfüllt ist (indem Sie dem DRY-Prinzip folgen), aber jetzt ist die Aufrechterhaltung dieser Überprüfungen nicht mehr so schmerzhaft. Sie haben beispielsweise eine viel bessere Kontrolle darüber, was Sie ändern müssen, wenn Sie eine vorhandene kostenpflichtige Funktion kostenlos machen möchten (oder umgekehrt).Lassen Sie uns zum Schluss einen Blick in Fowlers Blog-Artikel über Feature-Toggles werfen, in dem er über Feature-Einstiegspunkte / Toggle-Punkte spricht. Lassen Sie mich einen zentralen Punkt anführen:
Konzentrieren Sie sich als Gesamtstrategie auf die Benutzeroberfläche und beschränken Sie Ihre Überprüfungen auf die minimale Anzahl von Punkten, die erforderlich sind, damit eine bestimmte Funktion angezeigt oder ausgeblendet wird. Das sollte Ihre Codebasis sauber halten, ohne unnötige Unordnung.
quelle
isFreeVersion
zu bestimmten Funktionsparametern den größten Teil der Schmerzen dieser Tests beseitigt - sie werden tatsächlich sinnvoll und verursachen kein Wartungsproblem mehr.Wenn Sie
if/else
Blöcke nicht mögen , können Sie sie umgestalten, um die Vererbung zu verwenden (siehe Bedingtes Ersetzen durch Polymorphismus aus Marin Fowlers Refactoring- Buch). Das würde:Machen Sie es sich etwas einfacher, über Ihren Code nachzudenken.
Ermöglichen Sie zwei Klassen, eine für die kostenlose Version und eine für die kostenpflichtige Version, die wiederum die Anrufe an andere Klassen weiterleiten und sicherstellen, dass die Unterscheidung zwischen kostenlosen und kostenpflichtigen Versionen auf zwei Klassen beschränkt ist (drei zählen die Basisklasse).
Machen Sie es später einfach, andere Formen Ihrer Software hinzuzufügen, z. B. eine billige Variante oder eine Premium-Version. Sie fügen einfach eine weitere Klasse hinzu und deklarieren sie einmal in Ihrem Code. Sie wissen dann, dass die gesamte Codebasis weiterhin wie erwartet funktioniert.
quelle
Es scheint mir, dass Ihre Frage mit dem Feature Toggle Pattern ziemlich gut gelöst werden könnte .
Wie so oft erklärte Pete Hodgson in einem Artikel alle Szenarien, in denen Sie dieses Muster anwenden könnten, viel besser als ich.
Es gibt auch einige Bibliotheken, die dieses Muster unterstützen. Ich hatte Erfahrung mit FF4J in Java, aber ich würde raten, wenn Sie Folgendes eingeben :
... in jeder Suchmaschine erhalten Sie mehrere Lösungen.
quelle
Es gibt mehr als einen Weg, dies zu erreichen. Der einfache und unkomplizierte Weg besteht darin, das Feature-Toggle-Muster zu verwenden , das in so vielen Artikeln bereitgestellt wurde. Der nächste Ansatz hat mit dem Entwerfen für steckbare Funktionen zu tun. Sowohl Android als auch IOS haben In-App-Zahlungen. Zusammen mit dieser Zahlung besteht das Potenzial für einen Download.
Wenn Sie sich Servlets, JAMES Mailets und sogar IDE-Plugins ansehen, verwenden alle das Konzept einer Plug-In-Architektur:
Dies ermöglicht Ihnen auch die Möglichkeit, verschiedene Funktionsklassen für verschiedene Zielgruppen verfügbar zu machen. Die Benutzer haben nur die Funktionen, für die sie bezahlt haben.
Ihr Anwendungscode wird als eine Codebasis verwaltet, und Ihr Plug-In ist eine separate Codebasis - enthält jedoch nur die Teile, die für das Plugin relevant sind. Die App weiß, wie man mit Plugins umgeht, wenn sie vorhanden sind, und das Plugin weiß nur, wie man mit der Schnittstelle interagiert.
quelle