In vielen Projekten erfolgt die Entwicklung von neuen Features in dem einen oder anderen Branching Modell wie zum Beispiel Git Flow: Features werden zunächst auf einem separaten Branch entwickelt und erst nach "Fertigstellung" des Features wieder integriert. Beim Mergen der Änderungen kommt es dann gelegentlich zu Konflikten und wenn man Pech hat, landet man in der "Merging Hell".
Moderne VCS wie GIT machen Branching + Merging zwar deutlich einfacher, ändern aber auch nichts daran, dass es gelegentlich schwierig ist, konkurrierende Änderungen zu einem lauffähigen Deployment zu integrieren. Das Hauptproblem mit Feature Branches ist aber ein anderes: Wann ist ein Feature "fertig", kann also integriert werden? Erfolgt die Abnahme einer Story auf Basis des Feature Branches, muss nach der Integration eine weitere Qualitätssicherung erfolgen - denn sonst könnten sich Fehler in der Kombination mit parallel entwickelten Features einschleichen. Erfolgt die Qualitätssicherung erst nach der Integration auf einem Release Branch, könnte sich herausstellen, dass das Feature eben doch nicht fertig ist, weil die eine oder andere Anforderung nicht erfüllt ist. Continuous Integration verfolgt daher einen anderen Weg: die Entwicklung erfolgt auf dem HEAD und jeder Commit wird direkt automatisiert integriert. Jenkins, TeamCity oder andere Tools helfen dabei, regelmässig alle paar Minuten einen aktuellen Build zu erstellen und auf einen CI Server zu deployen.
Eine sehr gute automatisierte Testabdeckung ist die Voraussetzung dafür, dass die Software jederzeit lauffähig ist und alle Anforderungen erfüllt bleiben. Feature Toggle stellen sicher, dass ein Feature erst dann aktiviert wird, wenn es fertig und von der Qualitätssicherung abgenommen ist. Dazu werden die neuen Funktionen der Software über einfache if-Statements geschaltet:
if (Features.NEW_FANCY_FEATURE.isActive()) { useMyFancyNewFeature(); } else { doTheOldBoringStuff() }
Mit der Verwendung von Feature Toggles erhalten wir ganz neue Möglichkeiten, Funktionen live zu stellen. Features lassen sich nämlich auch über "Ventile" (Valves, Activation Strategies) graduell aktivieren:
Die letzte Entscheidung, ob eine neue Funktion Online geht kann also in der Live Umgebung erfolgen, was dabei hilft, regelmässig und kurz getaktet zu deployen. Im Team "Entdecken" setzen wir Feature Toggles bereits seit einiger Zeit ein. Aktuell gehen wir alleine in unserem Team (das System besteht aus mehreren lose gekoppelten Anwendungen) mehrmals die Woche, teilweise auch mehrmals am Tag live. Die Integration von Feature Toggles in die Software ist einfach. Eine rudimentäre Lösung ist schnell selbst entwickelt, es gibt aber auch fertige Lösungen. Wir haben vor einiger Zeit von einer Eigenentwicklung auf die Togglz Library umgestellt: eine schicke, schlanke Library, die sich sehr leicht in alle möglichen Arten von Java-Anwendungen integrieren lässt und auch eine Console zur Verwaltung der Toggle mitbringt. Die oben genannten "Activation Strategies" werden (unter anderem) unterstützt, es lässt sich leicht eine Rechte-Verwaltung anbinden und auch die Persistenz der Toggle-Einstellungen ist leicht möglich.
Togglz Administration Console
Toggles verwenden wir dabei in verschiedenen Situationen:
Die Togglz Library unterstützt derartige Gruppierungen über die FeatureGroup Annotation. Wir haben uns für die verschiedenen Anwendungsfälle eigene Annotationen geschrieben. Features, die noch in der Entwicklung sind, werden beispielsweise über die InDevelopment geschaltet:
@FeatureGroup @Label("Features in development") @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface InDevelopment { } public enum Features implements Feature { @Label("Only load product recommendations asynchronously using AJAX") @InDevelopment USE_AJAX_FOR_PRODUCT_RECOMMENDATIONS, ...
In der Togglz Console werden die FeatureGroups als Tabs dargestellt, in denen die zur Gruppe gehörenden Features automatisch einsortiert werden.An die Entwicklung mit Feature Toggles mussten wir uns erst einmal gewöhnen: Bei zu wenig Toggles können existierende Funktionen durch Seiteneffekte beeinträchtigt werden. Wenn wir es aber übertreiben, leidet die Lesbarkeit und Testbarkeit des Codes. Vor allem aber ist es wichtig, nicht mehr benötigte Toggles auch wieder aus dem Code zu entfernen.Die Vorteile überwiegen diese anfänglichen Schwierigkeiten jedoch bei weitem. Neben den neuen Möglichkeiten der Livestellung können wir mit Hilfe der Toggles kontinuierlich integrieren und häufig in Produktion gehen. Die Feedback-Zyklen werden auf diese Weise sehr kurz und wir können direkt auf dem HEAD häufige kleine Commits pushen, die aufwändige Merges vermeiden: Ein neuer Test, eine kleine Änderung, ein Commit. In der Kombination mit BDD, TDD, Build Pipelines, unterbrechungsfreien Deployments und einer rollbackfähigen Anwendung sind wir mit Feature Toggles auf dem besten Weg in Richtung Continuous Delivery.
We have received your feedback.