25 Stimmen

Wie verwalten Sie mehrere Versionen der gleichen Software für jeden Kunden?

Ich habe einen Quellcode, der zu 95 % für alle Kunden gleich ist. Einige Kunden verlangen jedoch etwas Bestimmtes. Wie kann ich das verwalten, ist das mit VisualSVN/Subversion möglich?

更新しました。

Einige Details über die Anwendung, es ist ein Web ASP.NET MVC mit NHibernate.

Die Anwendung besteht aus mehreren Projekten: dem Web-Teil, dem Repo-Teil (wo wir NHibernate für den Zugriff auf die Datenbank verwenden) und einem Service-Projekt.

Das Serviceprojekt verwendet das Repo-Projekt und das Serviceprojekt ist das Projekt mit den Geschäftsregeln.

11voto

ChrisF Punkte 130622

Ich kann mir zwei Ansätze vorstellen, die funktionieren könnten.

Bei der ersten wird der Code für jeden Kunden verzweigt. Jede Änderung, die Sie in der Hauptzeile vornehmen, kann dann in die Verzweigung des jeweiligen Kunden integriert werden, wenn sie benötigt wird. Wenn etwas im Kernprodukt in einer Verzweigung korrigiert wird, kann es in die Hauptlinie zurückgeführt werden, um es anschließend in die Verzweigungen der anderen Kunden zu übertragen. Auch wenn dies der beste Ansatz zu sein scheint, kann es schwierig sein, den Überblick darüber zu behalten, in welchem Zweig welche Änderungen vorgenommen wurden.

Der zweite und vielleicht bessere Ansatz besteht darin, Ihren Code so umzugestalten, dass der kundenspezifische Code in einer einzigen Baugruppe enthalten ist - eine pro Kunde. Diese wird dann bei der Installation des Produkts konfiguriert, z. B. mit Hilfe von Dependency Injection. Auf diese Weise haben Sie nur eine Codezeile und müssen nicht zwischen verschiedenen Zweigen zusammenführen. Voraussetzung ist allerdings, dass der kundenspezifische Code leicht zu trennen ist.

5voto

Mitch Wheat Punkte 287474

Platzieren Sie den kundenspezifischen Code in separaten Projekten/Assemblies. So etwas wie das Strategiemuster oder Plug-ins könnten der richtige Weg sein.

Die andere, weniger attraktive Möglichkeit (IMO) wäre, für jeden Kunden eine eigene Zweigstelle einzurichten, aber das kann schnell schwer zu pflegen werden.

5voto

Ando Punkte 10769

Wir haben uns für den folgenden Ansatz entschieden:

  • Einfügen von Hooks in die Anwendung, um das Standardverhalten anzupassen (z. B. wenn ein Save Aktion aufgerufen wird, ist das erste, was darin passiert, ein Aufruf an OnSaveHandler ).
  • Der Standard-Handler tut nichts, er gibt nur "continueWithNormalExecution" zurück. Alle Handler befinden sich in einem anderen Modul als die ursprüngliche Anwendung (andere Assembly), nennen wir es BehaviourModule
  • Bei clientbasierten Anfragen ändern wir dies BehaviourModule indem Sie das Standardverhalten "nichts tun" außer Kraft setzen. Der Rückgabecode dieses geänderten Handlers kann sein: ContinueNormalExecution , SkipNormalExecution , TerminateExecution , etc ...
  • In anderen Fällen fügen wir Haken auf der Grundlage von Schnittstellen ein. In der BehaviourModule werden wir mehr Handler haben, die diese Schnittstelle implementieren, z. B. DoStuffInterface die BehaviourModule wird zur Ladezeit mit Hilfe von Reflection geparst und alle Handler, die DoStuffInterface wird im System registriert werden. Dann werden wir in der ursprünglichen Anwendung etwas haben wie: Wenn GetDoStuffInterfaceHandler(handlerID) isnot Nothing entonces GetDoStuffInterfaceHandler(handlerID).DoStuff() . Die Definition der zu verwendenden handlerId ist konfigurierbar (z. B. über eine DB-Tabelle, eine XML-Datei usw.).

    Am Ende haben wir mehrere Handler, die DoStuffInterface mit verschiedenen IDs und rufen sie zu verschiedenen Zeiten an.

Mit diesem Ansatz haben wir:

  • die Basisanwendung mit dem Standardverhalten
  • ein konfigurierbares Modul (Assembly), das die Arbeitsweise der Anwendung anpasst

Die Herausforderung bei diesem Ansatz besteht darin, die "Süße Punkte" - Verhaltensweisen, die der Kunde möglicherweise anpassen möchte, und fügen dort Haken ein.

Ich hoffe, ich habe mich klar ausgedrückt, wenn nicht... hinterlasse einen Kommentar :)

1voto

Josef Jetmar Punkte 361

Wenn es keine große Sache ist, würde ich mit appp Einstellung und Werksmuster gehen. Oder spezifische Baugruppen pro Kunde.

Aber aus den Tags geht hervor, dass Sie das Problem über die Versionskontrolle lösen wollen. Aber das wird das Zusammenführen usw. stark beeinträchtigen. Sie müssen für jeden Kunden einen Zweig erstellen und Änderungen aus dem Stamm in diesen zusammenführen.

1voto

supercat Punkte 72939

Eine nützliche Ergänzung zu #ifdef ACME/#endif usw. ist die Definition von Makros für ACME_ONLY(), NON_ACME(), FROBOZCO_ONLY(), NON_FROBOZCO() usw. Makros. Die Sache kann immer noch unübersichtlich werden, wenn neue Versionen ins Spiel kommen (in welchen Fällen sollte sich die neue Version wie Acme, FrobozCo usw. verhalten), aber wenn es nur eine Zeile Unterschied zwischen der Acme- und der Nicht-Acme-Version gibt, vermeidet dieser Ansatz, dass diese Zeile von zwei Zeilen #Direktiven umgeben ist.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X