Für Menschen ist es schwierig, das Gesamtbild eines Problems zu erkennen, ohne viel Zeit und Mühe zu investieren. Dies gilt vor allem bei der Arbeit mit großen und komplexen Anwendungen. Was sind die Nebeneffekte meiner Änderungen? Warum wirkt sich diese Zeile hier auf die Tests in einem anderen Teil der Codebasis aus? Eine perfekte oder vollständige Lösung gibt es nicht, aber Shopify hat ein Tool entwickelt, das Ihnen und Ihrem Team wahrscheinlich helfen wird.
Einführung
Um über folgende Themen zu sprechen Packwerkmüssen wir zunächst ein paar Begriffe einführen.
- Kohäsion: bezieht sich auf das Maß der Zusammengehörigkeit von Elementen in einem Modul oder einer Klasse.
- Kupplung: bezieht sich auf den Grad der Abhängigkeit zwischen Modulen oder Klassen.
- Grenzen: bezieht sich auf Barrieren zwischen Code. In diesem Fall bezieht sich eine Code-Grenze auf verschiedene Bereiche innerhalb derselben Code-Basis.
- ModularisierungDer Prozess der Aufteilung eines Softwaresystems in mehrere separate Module, wobei jedes Modul unabhängig arbeitet.
Probleme
Wie wir wissen, Rubinrot bietet keine gute Lösung zur Durchsetzung von Codegrenzen. Wir können zwar die Sichtbarkeit festlegen, aber alle Abhängigkeiten werden in den globalen Namespace geladen. In großen oder monolithischen Anwendungen führt dieser Mangel an Grenzen zu folgenden Problemen.
- Geringer Zusammenhalt,
- Hohe Kopplung,
- Spaghetti-Code.
In dem Versuch, den Shopify-Monolithen zu modularisieren und Grenzen durchzusetzen, wurden verschiedene Lösungen ausprobiert, ohne die erwarteten Ergebnisse zu erzielen:
- Einstellung privater Konstanten,
- Festlegung von Grenzen durch Edelsteine,
- Verwendung von Tests, um komponentenübergreifende Assoziationen zu verhindern,
- Verwendung des Ruby-Modulations-Gems,
- Erstellung von Microservices.
Mit all dem Wissen aus früheren Versuchen beschlossen sie, ihr eigenes Werkzeug zu entwickeln: Packwerk.
Packwerk
Was ist Packwerk?
Packwerk ist ein statisches Analysewerkzeug, das zur Durchsetzung von Grenzen zwischen Gruppen von Rubinrot Dateien namens Pakete.
Was ist ein Paket?
A Paket ist ein Ordner, der automatisch geladenen Code enthält. Shopify's Team ermutigt dazu, bei der Erstellung von Paketen die besten Designpraktiken anzuwenden.
- Wir sollten Dinge zusammenpacken, die eine hohe Funktionalität haben Kohäsion,
- Die Pakete sollten relativ lose miteinander gekoppelt sein.
Arten von Grenzkontrollen
Wir können Privatsphäre und Abhängigkeitsgrenzen durchsetzen, Verletzungen der Grenzen und zyklische Abhängigkeiten überprüfen.
Packwerk in der Praxis
Es gibt keine bestimmte Art und Weise, Ihre Anwendung bei der Erstellung von Paketen zu strukturieren oder umzustrukturieren. In diesem Artikel werden wir dem Ansatz folgen, der von
Stephan Hagemann in Schrittweise Modularisierung für Ruby on Rails.
Wählen Sie das Projekt
Sie können eine neue Projekt oder wählen Sie eines Ihrer Projekte. Ich habe mich für ein Open-Source-Projekt namens CodeTriage. Es ist wichtig zu erwähnen, dass wir eine Rails 6 Anwendung benötigen, da Packwerk verwendet Zeitwerk.
Packwerk initialisieren
Zuerst müssen wir den Gem in unser Gemfile einfügen wie Edelstein 'Packwerk'
und führen Sie dann Bündel
in der Konsole. Dann sind wir bereit, den Edelstein zu initialisieren, indem wir packwerk init
.
Danach stellen wir fest, dass Packwerk drei Dateien für uns erstellt:
-
packwerk.yml
-
paket.yml
-
inflections.yml
packwerk.yml ist die Konfigurationsdatei von Packwerk wo wir u.a. ein- und ausgeschlossene Dateien definieren, die Ladepfade auflisten und die Beugungsdatei definieren;
paket.yml ist die Konfigurationsdatei eines Pakets. In dieser Datei werden wir die Konfiguration für die Grenzen unseres Pakets hinzufügen. Jeder Ordner mit package.yml wird als Paket erkannt von Packwerk. Das war's, Packwerk schuf unser erstes
Paket und wir nennen es das Wurzel Paket.
inflections.yml ist der Ort, an dem wir unsere benutzerdefinierten Beugungen und Akronyme platzieren werden, falls wir sie verwenden.
Weitere Informationen über die Dateien und ihre Konfiguration finden Sie unter
Packwerk.
Packwerk-Eigenschaften
Damit die Modularisierung funktioniert, benötigen wir drei grundlegende Eigenschaften: einen benannten Container, seine Inhaltund ausdrücklich Abhängigkeiten auf andere Container. Definieren wir also diese Eigenschaften in Packwerk:
-
Name: Der Name eines Pakets ist sein relativer Pfad von der Wurzel des
Anwendung.
-
Inhalt: Wenn wir eine package.yml in einen Ordner legen, sind alle Dateien in diesem Ordner nun der Inhalt des Pakets.
-
Abhängigkeiten: Wir können Abhängigkeiten von anderen Paketen definieren, indem wir den Schlüssel dependencies zum paket.yml.
Eine weitere Datei, die standardmäßig nicht enthalten ist, aber empfohlen wird, ist README. Sie ist wichtig, um Informationen über die Verwendung des Pakets bereitzustellen.
Das Ende von Episode I
Mehr lesen
GraphQL Ruby. Wie sieht es mit der Leistung aus?
Eisenbahnen und andere Transportmittel
Rails-Entwicklung mit TMUX, Vim, Fzf + Ripgrep