Codestruktur für mehrere Märkte? (unterschiedliche Geschäftsregeln für jeden Staat in den USA)


8

Wir entwickeln eine App, die für jeden Geschäftsmarkt (Länder und Staaten), in dem sie erhältlich ist, leicht unterschiedliche Anforderungen hat. Es scheint eine häufige Situation zu sein, aber ich kann anscheinend keinen guten Artikel über die Strukturierung von Code / Modulen für dieses Szenario finden.
Es ist eine C # -App und wir diskutieren zwischen Strategie- und Vorlagenmustern, aber es werden auch die Ordnerstruktur und die Namenskonventionen berücksichtigt. Es scheint, als würde ein separates Projekt für jeden Status schnell nicht mehr verwaltet werden können (z. B. 5 Kerndienste x 50 benutzerdefinierte Projekte) = 250 Projekte !!) Vielleicht 1 benutzerdefiniertes Projekt pro Service, das Spezialisierungen behandelt, die in Unterordnern pro Status organisiert sind?


Können Sie weitere Einzelheiten darüber hinzufügen, was genau zwischen Staaten unterschiedlich ist?
paj28

Antworten:


8

Haben Sie eine einzige App und entwerfen Sie die entsprechende Konfigurationslösung.

JacquesB deutet darauf hin, aber ich möchte es stärker ausdrücken. Sie müssen dies durch Konfiguration tun, anstatt mehr als 50 Versionen der Codebasis zu entwickeln. Alles andere wird wahnsinnig unüberschaubar sein.

Wenn es komplexe Anforderungen gibt, die mit einfachen Konfigurationsparametern nicht bewältigt werden können, entwerfen Sie eine komplexere Konfigurationslösung.

Ihre Konfiguration verfügt möglicherweise sogar über eine einfache Skriptsprache, die die logischen Anforderungen definiert. Das ist ok. Der Schlüssel ist, dass die "Konfiguration" sauber von der Codebasis der App getrennt werden muss.

Andernfalls werden Dinge wie das Erkennen und Beheben von Fehlern ein Chaos sein. Mit normaler Versionierung zusätzlich zu länderspezifischen Versionen haben Sie Hunderte von Versionen im Feld. Und Sie werden nicht leicht erkennen können, ob ein Fehler mit dem länderspezifischen Code oder dem Basiscode zusammenhängt.

Denken Sie jetzt über Randfälle nach.

Dies ist eine Situation, in der ein hohes Risiko besteht, schlechte Annahmen zu treffen, die unglaublich kostspielig sind. Beispiel: "Jeder App-Benutzer muss immer nur innerhalb eines Gebietsschemas arbeiten." Ist das wahr? Stellen Sie sicher, dass Sie so früh wie möglich über solche Themen nachdenken.


Wir richten eine Konfigurationslösung mit AutoFac Multitenancy ein. Irgendwelche Ratschläge zum Organisieren und Benennen der Komponenten (Klassen / Projekte)?
Kim

Ja. Ich wollte kommentieren, dass dies ein großartiges Beispiel für die Abhängigkeitsinjektion ist. Sie können die gemeinsame Schnittstelle definieren und bestimmte Komponenten erstellen, die dann gemäß einer bestimmten Konfiguration übergeben werden. Dies sollte eine viel bessere Testbarkeit und Wartung ermöglichen als benutzerdefinierte Skripte, wie in einer anderen Antwort erwähnt.
Fran

6

Es kommt wirklich darauf an, was anders ist. Ist es etwas, das nur durch Konfiguration ausgedrückt werden kann (z. B. Steuersätze), oder benötigen Sie wirklich eine separate Codelogik für jeden Staat? Je mehr Sie rein durch Konfiguration handhaben können, desto besser!

Sie benötigen höchstwahrscheinlich keinen separaten Code nach Status. Sie erwähnen beispielsweise, dass einige Märkte Rückerstattungen ausstellen, während andere Ersetzungen ersetzen. Dies sind immer noch nur zwei Codepfade, die Sie testen müssen. Anschließend können Sie in einer Konfiguration angeben, welcher Pfad für welchen Status verwendet werden soll. Dies ist viel besser als ein separater Code für jeden Status. Sie müssen immer noch nur zwei Codepfade mit einem Wert von weniger als 50 testen.

Wenn Sie jemals das Bedürfnis haben, individuellen Code für jeden der 50 Zustände zu schreiben, machen Sie es wahrscheinlich falsch. Sie sollten definitiv keine separaten Projekte pro Status haben oder sogar "50 verschiedene" von irgendetwas außer Konfigurationsabschnitten.


Es ist mehr als nur eine Besteuerung, aber das Ausmaß der Unterschiede ist derzeit nicht bekannt. Wir haben es auch mit mehreren Ländern zu tun. Es gibt Workflows, die auch geringfügig abweichen können, z. B. wenn einige Märkte Einkäufe erstatten, während andere Ersatzausgaben ausstellen. Und sicherlich unterschiedliche Preise pro Markt.
Kim

Was JacquesB vorhat, sind Abstraktionen. IOW, wie könnten Dinge, die anders aussehen, tatsächlich gleich sein? "Alle Staaten erheben Steuern" Jetzt habe ich ein allgemeines Konzept, das ich universell kodieren kann: "CalcTax ()". Und dann brauchen Sie nur noch die spezifischen Steuersätze (Steuertabelle) - das ist die Konfiguration. Hören Sie mich jetzt und glauben Sie mir später "Konfigurationsdaten" - das abstrakte Konzept! - vereinfacht den Code erheblich.
Radarbob

Wenn sich die Funktionalität zwischen den Zuständen stark überschneidet (über eine effektive "Standard" -Option hinaus), ist dies ein guter Rat. Wenn Staaten zu Nuancen neigen, die es schwierig / gefährlich machen, sie als eine Art "Option B" zusammenzufassen, ist dies nicht der Fall. Das OP muss das herausfinden. Es besteht auch die Gefahr von Kopfschmerzen, wenn ein Staat neue Gesetze verabschiedet, die Code-Updates erzwingen. Dies gilt jedoch für alle Bedingungen, in denen mehrere Staaten denselben Code verwenden.
BlairHippo

5

Ich habe einige praktische Erfahrungen mit solchen Projekten gesammelt und kann zumindest einige allgemeine Richtlinien anbieten.

  • JacquesB hat absolut Recht, dass die Konfiguration Ihr bester Freund ist. Ob Sie diese Konfiguration in Dateien oder in Datenbanktabellen ablegen, ist eine stilistische Entscheidung (obwohl ich mich eher auf Konfigurationsdateien neige, da ich wetten werde, dass sich daran nicht viel ändert, wenn Sie einen Dienst eingerichtet haben).

  • Erwarten Sie Code, der viel indirekter aussieht als Sie es wahrscheinlich gewohnt sind. Es wird viele Stellen geben, an denen Sie anstatt "Mach das nächste" sagen, "Frag die Konfiguration, was wir als nächstes tun sollen, dann mach das" sagen. Das kann ein Entwicklungskopfschmerz sein, aber Sie werden sich daran gewöhnen.

  • Ich würde eine Struktur empfehlen: "Dies sind die gemeinsamen Elemente, die wahrscheinlich jeder möchte, und dies sind die maßgeschneiderten Elemente, die für einzelne Staaten von Hand entworfen wurden." Zu diesem Zweck wird die korrekte Identifizierung dieser Standardfunktionalität einen großen Teil dazu beitragen, wie einfach / schrecklich es ist, mit dem Code in Zukunft zu arbeiten. Seien Sie bereit, einige Umgestaltungen vorzunehmen, wenn Sie feststellen, dass mehr Dinge konfiguriert werden müssen, als Sie gedacht haben.

  • Stellen Sie immer sicher, dass alle Fehlermeldungen der benutzerdefinierten Elemente genau angeben, woher sie stammen. Die große Anzahl unterschiedlicher Ausführungspfade bedeutet, dass das Debuggen auf jeden Fall nicht funktioniert. Alles, was Sie tun können, um die Ostereiersuche zu reduzieren, wird sich mehr als lohnen.

  • Investieren Sie die Zeit, um eine gute automatisierte Testsuite zu erstellen. Eine wirklich gute automatisierte Testsuite. Dies ist immer eine gute Praxis, aber für Sie könnte es buchstäblich den Unterschied zwischen Erfolg und Misserfolg bedeuten. Auch hier ist es die große Vielfalt an Ausführungspfaden; Änderungen am allgemeinen Code machen Sie anfällig für Fehler mit Schmetterlingseffekten in Zweigen, die Sie nicht erwartet haben. Sie müssen diese Fehler erkennen, bevor sie die Produktion erreichen.


Vielen Dank. Irgendwelche Vorschläge zum Benennen von Klassen, Gruppieren von Projekten? Sollten die Implementierungen mit dem Marktnamen versehen sein oder versuchen, die verschiedenen Funktionen zu beschreiben?
Kim

Ich bin kein AC # -Typ, daher kann ich nicht mit Einzelheiten darüber sprechen, wie Sie Klassen benennen. Aber ehrlich gesagt würde ich denken, Sie möchten einen Paketnamen, der sowohl Markt- als auch Funktionalität enthält, damit Sie auf einen Blick erkennen können, was er tun soll. So etwas wie ourproject.calculations.taxfür die Standardeinstellung und ourproject.florida.calculations.taxfür alle benutzerdefinierten Mods, die Ihnen das Florida-Gesetz aufgezwungen hat (falls vorhanden). Wo Sie diesen Marktnamen platzieren, ist ein Diskussionspunkt, aber ich würde gerne leicht erkennen, welche Anpassungen ein bestimmter Markt Ihnen aufzwingt.
BlairHippo

2

Obwohl config helfen kann, nicht alle Ihre Probleme zu lösen, kann es neue erstellen.

Nach meiner Erfahrung ist es bei weitem der beste Weg, eine Lösung für mehrere Mandanten zu erstellen, die alle oder einige der Staaten (Mieter) handhaben kann.

Dies erfordert eine Konfiguration. dh Umsatzsteuerprozentsatz nach Bundesland, aber auch Bedingungscode LegalMethodOfCalculatingWorkingHoursA vs B.

Wenn Ihre App gehostet / online ist, können Sie den bedingten Code von Microservices verwenden, aber eine Offline-Lösung muss alle optionalen Module bündeln und zwischen ihnen auswählen

Sie werden einige Module finden, die in allen Bundesstaaten wiederverwendet werden, wie z. B. die Umsatzsteuer und einige verrückte Gesetze, die nur in einem einzelnen Bundesstaat verwendet werden. Sie werden auch feststellen, dass sich Gesetze im Laufe der Zeit ändern. Daher variieren die verwendeten Module innerhalb eines einzelnen Zustands zeitlich

Ich würde also eher nach Funktionalität als nach Status benennen.


Ich mag das - Code-Zweige basierend auf Funktionalität, zB "Adresse fragen müssen" "Lieferung ist steuerfrei". Die Konfiguration dazu ordnet jeden Status einer Reihe von Funktionen zu.
paj28
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.