Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Ruby
Code

AntiPatterns-Grundlagen: Schienenmodelle

by
Length:LongLanguages:

German (Deutsch) translation by Valentina (you can also view the original English article)

Anti-was? Es klingt wahrscheinlich viel komplizierter als es ist. In den letzten Jahrzehnten konnten Programmierer eine nützliche Auswahl von Entwurfsmustern identifizieren, die häufig in ihren Codelösungen auftraten. Während sie ähnliche Probleme lösten, konnten sie Lösungen „klassifizieren“, die sie daran hinderten, das Rad ständig neu zu erfinden. Es ist wichtig anzumerken, dass diese Muster eher als Entdeckungen als als Erfindungen einer Gruppe fortgeschrittener Entwickler angesehen werden sollten.

Wenn dies für Sie ziemlich neu ist und Sie sich als Anfänger auf allen Seiten von Ruby/Rails sehen, dann ist dies genau das Richtige für Sie. Ich denke, es ist am besten, wenn Sie es als einen kurzen Einblick in ein viel tieferes Theme betrachten, dessen Beherrschung nicht über Nacht stattfinden wird. Trotzdem bin ich fest davon überzeugt, dass Anfänger und ihre Mentoren enorm davon profitieren werden, wenn sie so früh anfangen.

AntiPatterns sind - wie der Name schon sagt - so ziemlich das Gegenteil von Mustern. Sie sind Entdeckungen von Lösungen für Probleme, die Sie unbedingt vermeiden sollten. Sie repräsentieren oft die Arbeit unerfahrener Programmierer, die nicht wissen, was sie noch nicht wissen. Schlimmer noch, sie könnten das Ergebnis einer faulen Person sein, die Best Practices und Werkzeuge-Frameworks ohne guten Grund einfach ignoriert - oder sie denken, dass sie sie nicht brauchen. Was sie zu Beginn hoffen könnten, durch das Ausarbeiten schneller, fauler oder schmutziger Lösungen Zeit zu sparen, wird sie oder einen traurigen Nachfolger später im Projektlebenszyklus verfolgen.

Unterschätzen Sie nicht die Auswirkungen dieser schlechten Entscheidungen - sie werden Sie plagen, egal was passiert.

Themen

  • Fette Modelle
  • Fehlende Testsuite
  • Voyeuristische Modelle
  • Gesetz von Demeter
  • Spaghetti SQL

Fette Modelle

Ich bin mir sicher, dass Sie die "Fat Models, Skinny Controller" unzählige Male gesungen haben, als Sie mit Rails angefangen haben. OK, jetzt vergiss das! Sicher, die Geschäftslogik muss in der Modellebene gelöst werden, aber Sie sollten nicht geneigt sein, alles sinnlos hinein zu stopfen, nur um zu vermeiden, dass die Grenzen in das Gebiet der Controller überschritten werden.

Hier ist ein neues Ziel, das Sie anstreben sollten: "Skinny-Modelle, Skinny-Controller". Sie könnten fragen: "Nun, wie sollen wir Code arrangieren, um dies zu erreichen - schließlich ist es ein Nullsummenspiel?" Guter Punkt! Der Name des Spiels ist Komposition, und Ruby ist gut ausgestattet, um Ihnen viele Optionen zu bieten, um Fettleibigkeit bei Modellen zu vermeiden.

In den meisten (Rails) Webanwendungen, die datenbankgestützt sind, konzentriert sich der Großteil Ihrer Aufmerksamkeit und Arbeit auf die Modellebene - vorausgesetzt, Sie arbeiten mit kompetenten Designern zusammen, die in der Lage sind, ihre eigenen Inhalte in der Ansicht zu implementieren. Ihre Modelle haben von Natur aus mehr „Schwerkraft“ und ziehen mehr Komplexität an.

Die Frage ist nur, wie Sie diese Komplexität bewältigen wollen. Active Record gibt Ihnen definitiv viel Seil, an dem Sie sich aufhängen können, während Sie Ihr Leben unglaublich einfach machen. Es ist ein verlockender Ansatz, Ihre Modellebene zu entwerfen, indem Sie einfach dem Weg der höchsten unmittelbaren Bequemlichkeit folgen. Eine zukunftssichere Architektur berücksichtigt jedoch viel mehr, als große Klassen zu kultivieren und alles in Active Record-Objekte zu stopfen.

Das eigentliche Problem, mit dem Sie sich hier befassen, ist die Komplexität - unnötigerweise, würde ich sagen. Klassen, die Tonnen von Code ansammeln, werden allein aufgrund ihrer Größe komplex. Sie sind schwieriger zu pflegen, schwer zu analysieren und zu verstehen und zunehmend schwerer zu ändern, da ihre Zusammensetzung wahrscheinlich nicht entkoppelt ist. Diese Modelle überschreiten häufig die empfohlene Fähigkeit, eine einzelne Verantwortung zu übernehmen, und sind eher allgegenwärtig. Im schlimmsten Fall werden sie wie Müllwagen und behandeln den ganzen Müll, der träge auf sie geworfen wird.

Wir können es besser machen! Wenn Sie der Meinung sind, dass Komplexität keine große Sache ist - schließlich sind Sie etwas Besonderes, Kluges und Alles -, denken Sie noch einmal darüber nach! Komplexität ist der berüchtigtste Serienprojektkiller da draußen - nicht Ihre freundliche Nachbarschaft „Dark Defender“.

„Skinnier-Modelle“ erreichen eines, was fortgeschrittene Leute im Coding-Geschäft (wahrscheinlich viel mehr Berufe als Code und Design) schätzen und was wir alle unbedingt anstreben sollten - Einfachheit! Oder zumindest mehr davon, was ein fairer Kompromiss ist, wenn die Komplexität schwer zu beseitigen ist.

Welche Werkzeuge bietet Ruby an, um unser Leben in dieser Hinsicht zu erleichtern und das Fett aus unseren Modellen herauszuschneiden? Einfache, andere Klassen und Module. Sie identifizieren kohärenten Code, den Sie in ein anderes Objekt extrahieren können, und erstellen so eine Modellebene, die aus Agenten mit angemessener Größe besteht, die ihre eigenen eindeutigen Verantwortlichkeiten haben.

Denken Sie an einen talentierten Darsteller. Im wirklichen Leben könnte eine solche Person in der Lage sein, zu rappen, zu brechen, Texte zu schreiben und ihre eigenen Stücke zu produzieren. Beim Programmieren bevorzugen Sie die Dynamik einer Band - hier mit mindestens vier verschiedenen Mitgliedern -, bei der jede Person für so wenig Dinge wie möglich verantwortlich ist. Sie möchten ein Klassenorchester aufbauen, das die Komplexität des Komponisten bewältigen kann - keine geniale Maestro-Klasse für das Mikromanagement aller Branchen.

one man band

Schauen wir uns ein Beispiel für ein fettes Modell an und spielen mit einigen Optionen, um mit seiner Fettleibigkeit umzugehen. Das Beispiel ist natürlich ein Dummy, und wenn ich diese doofe kleine Geschichte erzähle, hoffe ich, dass es für Neulinge leichter zu verdauen und zu befolgen ist.

Wir haben eine Spectre-Klasse, die zu viele Aufgaben hat und daher unnötig gewachsen ist. Abgesehen von diesen Methoden ist es leicht vorstellbar, dass sich in einem solchen Exemplar bereits viele andere Dinge angesammelt haben - dargestellt durch die drei kleinen Punkte. Spectre ist auf dem besten Weg, eine god-Klasse zu werden. (Die Chancen sind sehr gering, einen solchen Satz bald wieder sinnvoll zu formulieren!)

Spectre stellt verschiedene Arten feindlicher Agenten zur Verfügung, Delegierte töten 007, grillen die Kabinettsmitglieder von Spectre, wenn sie versagen, und drucken auch operative Aufgaben aus. Ein klarer Fall von Mikromanagement und definitiv ein Verstoß gegen das „Prinzip der Einzelverantwortung“. Auch private Methoden stapeln sich schnell.

Diese Klasse muss nicht die meisten Dinge kennen, die sich derzeit darin befinden. Wir werden diese Funktionalität in ein paar Klassen aufteilen und sehen, ob die Komplexität, ein paar weitere Klassen/Objekte zu haben, die Fettabsaugung wert ist.

Ich denke, der wichtigste Teil, auf den Sie achten sollten, ist, wie wir eine einfache Ruby-Klasse wie Interrogator verwendet haben, um das Drehen von Agenten aus verschiedenen Agenturen zu handhaben. Beispiele aus der Praxis könnten einen Konverter darstellen, der beispielsweise ein HTML-Dokument in ein PDF umwandelt und umgekehrt. Wenn Sie nicht die volle Funktionalität von Active Record-Klassen benötigen, warum sollten Sie sie verwenden, wenn auch eine einfache Ruby-Klasse den Trick ausführen kann? Ein bisschen weniger Seil zum Aufhängen.

Die Spectre-Klasse überlässt das unangenehme Geschäft, Agenten an die Interrogator-Klasse zu übergeben, und delegiert nur an diese. Dieser hat nun die alleinige Verantwortung, gefangene Agenten zu foltern und einer Gehirnwäsche zu unterziehen.

So weit, ist es gut. Aber warum haben wir für jeden Agenten separate Klassen erstellt? Einfach. Anstatt die verschiedenen Turn-Methoden wie turn_mi6_agent direkt an Interrogator zu extrahieren, haben wir ihnen ein besseres Zuhause in ihrer jeweiligen Klasse gegeben.

Infolgedessen können wir den Polymorphismus effektiv nutzen und uns nicht um Einzelfälle für Drehmittel kümmern. Wir weisen diese verschiedenen Agentenobjekte nur an, sich umzudrehen, und jeder von ihnen weiß, was zu tun ist. Der Interrogator muss nicht genau wissen, wie sich jeder Agent dreht.

Da alle diese Agenten Active Record-Objekte sind, haben wir ein generisches Objekt, EnemyAgent, erstellt, das einen allgemeinen Eindruck davon vermittelt, was das Drehen eines Agenten bedeutet, und wir kapseln dieses Bit für alle Agenten an einer Stelle, indem wir es in Unterklassen unterteilen. Wir nutzen diese Vererbung, indem wir die turn-Methoden der verschiedenen Agenten mit super versorgen, und erhalten daher ohne Doppelarbeit Zugang zum Gehirnwäsche- und Foltergeschäft. Einzelne Verantwortlichkeiten und keine Doppelarbeit sind ein guter Ausgangspunkt, um weiterzumachen.

Die anderen Active Record-Klassen übernehmen verschiedene Aufgaben, um die sich Spectre nicht kümmern muss. "Nummer Eins" wird normalerweise von ausgefallenen Spectre-Kabinettsmitgliedern selbst gegrillt. Warum also nicht ein spezielles Objekt mit Stromschlägen umgehen lassen? Auf der anderen Seite wissen versagende Spectre-Mitglieder, wie sie selbst sterben müssen, wenn sie von NumberOne auf ihrem Stuhl geraucht werden. Operation druckt jetzt auch seine Aufgaben selbst aus - Sie müssen die Zeit von Spectre nicht mit solchen Erdnüssen verschwenden.

Last but not least wird das Töten von James Bond normalerweise von einem Agenten vor Ort versucht, sodass kill_james_bond jetzt eine Methode für SpectreAgent ist. Goldfinger hätte das natürlich anders gehandhabt - ich denke, ich muss mit diesem Laser-Ding spielen, wenn Sie eines haben.

Wie Sie deutlich sehen können, haben wir jetzt zehn Klassen, in denen wir bisher nur eine hatten. Ist das nicht zu viel? Es kann sicher sein. Es ist ein Problem, mit dem Sie sich die meiste Zeit auseinandersetzen müssen, wenn Sie solche Verantwortlichkeiten aufteilen. Sie können dies definitiv übertreiben. Aber dies aus einem anderen Blickwinkel zu betrachten, könnte helfen:

  • Haben wir Bedenken getrennt? Absolut!
  • Haben wir leichte, dünne Klassen, die besser für die Bewältigung einzelner Aufgaben geeignet sind? Ziemlich sicher!
  • Erzählen wir eine „Geschichte“, zeichnen wir ein klareres Bild davon, wer beteiligt ist und für bestimmte Aktionen verantwortlich ist? Hoffentlich!
  • Ist es einfacher zu verdauen, was jede Klasse tut? Sicher!
  • Haben wir die Anzahl der privaten Methoden reduziert? Jep!
  • Stellt dies eine bessere Qualität der objektorientierten Programmierung dar? Da wir Komposition verwendet und nur dann auf Vererbung Bezug genommen haben, wenn dies zum Einrichten dieser Objekte erforderlich ist, können Sie wetten!
  • Fühlt es sich sauberer an? Ja!
  • Sind wir besser gerüstet, um unseren Code zu ändern, ohne ein Chaos zu verursachen? Sichere Sache!
  • War es das wert? Was denken Sie?

Ich will damit nicht sagen, dass diese Fragen jedes Mal von Ihrer Liste gestrichen werden müssen, aber dies sind die Dinge, die Sie sich wahrscheinlich stellen sollten, während Sie Ihre Modelle verkleinern.

Das Entwerfen dünner Modelle kann schwierig sein, ist jedoch eine wesentliche Maßnahme, um Ihre Anwendungen gesund und agil zu halten. Dies sind auch nicht die einzigen konstruktiven Möglichkeiten, mit fetten Modellen umzugehen, aber sie sind ein guter Anfang, insbesondere für Neulinge.

Fehlende Testsuite

Dies ist wahrscheinlich das offensichtlichste AntiPattern. Wenn Sie von einer testgetriebenen Seite kommen, kann das Berühren einer ausgereiften App ohne Testabdeckung eine der schmerzhaftesten Erfahrungen sein. Wenn Sie die Welt und Ihren eigenen Beruf mehr als alles andere hassen möchten, verbringen Sie nur sechs Monate mit einem solchen Projekt, und Sie werden erfahren, wie viel Misanthrop möglicherweise in Ihnen steckt. Ein Scherz natürlich, aber ich bezweifle, dass es dich glücklicher macht und dass du es wieder tun willst - jemals. Vielleicht reicht auch eine Woche. Ich bin mir ziemlich sicher, dass Ihnen das Wort Folter öfter in den Sinn kommt, als Sie denken.

Wenn das Testen bisher nicht Teil Ihres Prozesses war und sich diese Art von Schmerz für Ihre Arbeit normal anfühlt, sollten Sie vielleicht in Betracht ziehen, dass das Testen weder so schlimm noch Ihr Feind ist. Wenn Ihre Code-bezogenen Freude mehr oder weniger konstant über Null liegt und Sie Ihren Code furchtlos ändern können, ist die Gesamtqualität Ihrer Arbeit viel höher als bei Ausgaben, die durch Angst und Leiden beeinträchtigt werden.

Überschätze ich? Das glaube ich wirklich nicht! Sie möchten eine sehr umfangreiche Testabdeckung haben, nicht nur, weil es ein großartiges Design-Werkzeug ist, um nur den Code zu schreiben, den Sie tatsächlich benötigen, sondern auch, weil Sie Ihren Code zu einem späteren Zeitpunkt ändern müssen. Sie sind viel besser gerüstet, um mit Ihrer Codebasis in Kontakt zu treten - und viel sicherer -, wenn Sie über ein Testkabel verfügen, das Refactorings, Wartung und Erweiterungen unterstützt und steuert. Sie werden sicher die Straße hinunter auftreten, ohne Zweifel.

Dies ist auch der Punkt, an dem sich eine Testsuite ab der zweiten Dividendenrunde auszahlt, da die höhere Geschwindigkeit, mit der Sie diese Qualitätsänderungen sicher vornehmen können, in Apps, die von Leuten erstellt werden, die denken, Tests zu schreiben, nicht lange erreicht werden kann ist Unsinn oder braucht zu viel Zeit.

Voyeuristische Modelle

Dies sind Modelle, die sehr neugierig sind und zu viele Informationen über andere Objekte oder Modelle sammeln möchten. Dies steht in krassem Gegensatz zu einer der grundlegendsten Ideen in der objektorientierten Programmierung - der Kapselung. Wir wollen uns eher um eigenständige Klassen und Modelle bemühen, die ihre inneren Angelegenheiten so weit wie möglich selbst verwalten. In Bezug auf Programmierkonzepte verstoßen diese voyeuristischen Modelle grundsätzlich gegen das „Prinzip des geringsten Wissens“, auch bekannt als das „Gesetz des Demeters“ - wie auch immer Sie es aussprechen möchten.

Gesetz von Demeter

Warum ist das ein Problem? Es ist eine Form der Vervielfältigung - eine subtile - und führt auch zu Code, der viel spröder ist als erwartet.

Das Gesetz von Demeter ist so ziemlich der zuverlässigste Code-Geruch, den Sie immer angreifen können, ohne sich über die möglichen Nachteile Gedanken zu machen.

Ich denke, dieses Gesetz als „Gesetz“ zu bezeichnen, war nicht so anspruchsvoll, wie es zunächst klingen mag. Erforschen Sie diesen Geruch, denn Sie werden ihn in Ihren Projekten sehr brauchen. Grundsätzlich heißt es, dass Sie in Bezug auf Objekte Methoden für den Freund Ihres Objekts aufrufen können, nicht jedoch für den Freund Ihres Freundes.

Dies ist eine gebräuchliche Methode, um dies zu erklären, und alles läuft darauf hinaus, nicht mehr als einen einzelnen Punkt für Ihre Methodenaufrufe zu verwenden. Übrigens ist es völlig in Ordnung, mehr Punkte oder Methodenaufrufe zu verwenden, wenn Sie sich mit einem einzelnen Objekt befassen, das nicht versucht, weiter zu gelangen. So etwas wie @weapons.find_by_name('Poison dart').formula ist in Ordnung. Finder können manchmal einige Punkte stapeln. Es ist dennoch eine gute Idee, sie in dedizierten Methoden zu kapseln.

Gesetz der Demeter-Verstöße

Schauen wir uns ein paar schlechte Beispiele aus den obigen Klassen an:

Um den Dreh raus zu bekommen, hier noch ein paar fiktive:

Bananen, richtig? Sieht nicht gut aus, oder? Wie Sie sehen können, werfen diese Methodenaufrufe zu viel Blick auf das Geschäft anderer Objekte. Die wichtigste und offensichtlichste negative Konsequenz ist die Änderung einer Reihe dieser Methodenaufrufe überall, wenn sich die Struktur dieser Objekte ändern muss - was sie schließlich tun werden, da die einzige Konstante in der Softwareentwicklung die Änderung ist. Außerdem sieht es wirklich böse aus, was die Augen überhaupt nicht schont. Wenn Sie nicht wissen, dass dies ein problematischer Ansatz ist, können Sie mit Rails sowieso sehr weit gehen - ohne Sie anzuschreien. Viel Seil, erinnerst du dich?

Was können wir dagegen tun? Schließlich wollen wir diese Informationen irgendwie bekommen. Zum einen können wir unsere Objekte so zusammenstellen, dass sie unseren Anforderungen entsprechen, und wir können die Delegierung geschickt einsetzen, um unsere Modelle gleichzeitig schlank zu halten. Lassen Sie uns in einen Code eintauchen, um Ihnen zu zeigen, was ich meine.

Dies ist definitiv ein Schritt in die richtige Richtung. Wie Sie sehen können, haben wir die Informationen, die wir erhalten wollten, in eine Reihe von Wrapper-Methoden gepackt. Anstatt viele Objekte direkt zu erreichen, haben wir diese Brücken abstrahiert und es den jeweiligen Modellen überlassen, mit ihren Freunden über die benötigten Informationen zu sprechen.

Der Nachteil dieses Ansatzes besteht darin, dass all diese zusätzlichen Wrapper-Methoden herumliegen. Manchmal ist es in Ordnung, aber wir möchten wirklich vermeiden, diese Methoden an mehreren Stellen beizubehalten, wenn sich ein Objekt ändert.

Wenn möglich, befindet sich der Ort, an dem sie sich ändern können, auf ihrem Objekt - und nur auf ihrem Objekt. Die Verschmutzung von Objekten mit Methoden, die wenig mit dem eigenen Modell selbst zu tun haben, ist ebenfalls zu beachten, da dies immer eine potenzielle Gefahr für die Verwässerung einzelner Verantwortlichkeiten darstellt.

Wir können es besser machen. Delegieren Sie nach Möglichkeit Methodenaufrufe direkt an die zuständigen Objekte und versuchen Sie, die Wrapper-Methoden so weit wie möglich zu reduzieren. Rails weiß, was wir brauchen, und bietet uns die praktische Methode für delegate-Klassen, mit der wir den Freunden unseres Objekts mitteilen können, welche Methoden wir aufrufen müssen.

Lassen Sie uns etwas aus dem vorherigen Codebeispiel vergrößern und sehen, wo wir die Delegierung richtig nutzen können.

Wie Sie sehen, könnten wir die Dinge mithilfe der Methodendelegation etwas vereinfachen. Wir haben Operation#spectre_member_name und Operation#spectre_member_number vollständig entfernt, und SpectreAgent muss keine number mehr bei spectre_member anrufen - number wird direkt an die Ursprungsklasse SpectreMember zurück delegiert.

Wenn dies zunächst etwas verwirrend ist, wie funktioniert das genau? Sie teilen dem Delegierten mit, an welchen :method_name er delegieren soll: to: welchen: :class_name (mehrere Methodennamen sind ebenfalls in Ordnung). Das prefix: true Teil ist optional.

In unserem Fall wurde dem schlangenverkleideten Klassennamen der empfangenden Klasse vor dem Methodennamen vorangestellt, und wir konnten operation.spectre_member_name anstelle der möglicherweise mehrdeutigen operation.name aufrufen, wenn wir die Präfixoption nicht verwendet hatten. Dies funktioniert sehr gut mit belongs_to und has_one Zuordnungen.

Auf der has_many Seite der Dinge wird die Musik jedoch aufhören und Sie werden in Schwierigkeiten geraten. Diese Zuordnungen bieten Ihnen einen Sammlungsproxy, der NameErrors oder NoMethodErrors auf Sie wirft, wenn Sie Methoden an diese „Sammlungen“ delegieren.

Spaghetti SQL

Um dieses Kapitel über das Modell von AntiPatterns in Rails abzurunden, möchte ich ein wenig Zeit darauf verwenden, was zu vermeiden ist, wenn SQL beteiligt ist. Active Record-Assoziationen bieten Optionen, die Ihr Leben erheblich erleichtern, wenn Sie wissen, wovon Sie sich fernhalten sollten. Finder-Methoden sind ein ganzes Theme für sich - und wir werden sie nicht in vollem Umfang behandeln -, aber ich wollte einige gängige Techniken erwähnen, die Ihnen helfen, selbst wenn Sie sehr einfache schreiben.

Dinge, über die wir uns Sorgen machen sollten, spiegeln das meiste wider, was wir bisher gelernt haben. Wir wollen absichtsvolle, einfache und vernünftig benannte Methoden, um Dinge in unseren Modellen zu finden. Tauchen wir gleich in den Code ein.

Sieht harmlos aus, nein? Wir suchen nur nach einer Reihe von Agenten, die die Lizenz zum Töten für unsere Ops-Seite haben. Denk nochmal. Warum sollte sich der OperationsController in die Interna von Agent vertiefen? Ist dies wirklich das Beste, was wir tun können, um einen Finder in Agent zu kapseln?

Wenn Sie denken, dass Sie eine Klassenmethode wie Agent.find_licence_to_kill_agents hinzufügen könnten, die die Finder-Logik kapselt, machen Sie definitiv einen Schritt in die richtige Richtung - allerdings nicht annähernd genug.

Wir müssen ein bisschen engagierter sein. Erstens werden die Assoziationen nicht zu unserem Vorteil genutzt, und auch die Einkapselung ist nicht optimal. Zuordnungen wie has_many bieten den Vorteil, dass wir sie dem zurückgegebenen Proxy-Array hinzufügen können. Wir hätten dies stattdessen tun können:

Das funktioniert zwar, ist aber auch nur ein kleiner Schritt in die richtige Richtung. Ja, der Controller ist ein bisschen besser, und wir nutzen Modellzuordnungen gut, aber Sie sollten immer noch misstrauisch sein, warum Operation sich mit der Implementierung der Suche nach einem bestimmten Agent-Typ befasst. Diese Verantwortung liegt beim Agent-Modell selbst.

Benannte Bereiche sind dabei sehr praktisch. Bereiche definieren verkettbare - sehr wichtige - Klassenmethoden für Ihre Modelle und ermöglichen es Ihnen, nützliche Abfragen anzugeben, die Sie als zusätzliche Methodenaufrufe zusätzlich zu Ihren Modellzuordnungen verwenden können. Die folgenden zwei Ansätze für das Scoping von Agent sind gleichgültig.

Das ist viel besser Falls die Syntax von Bereichen für Sie neu ist, handelt es sich nur um (stabby) Lambdas - übrigens nicht besonders wichtig, um sie sofort zu untersuchen - und sie sind die richtige Methode, um Bereiche aufzurufen, seit Rails 4. Agent jetzt verfügbar ist Die Verwaltung eigener Suchparameter und Assoziationen können sich nur auf das konzentrieren, was sie finden müssen.

Mit diesem Ansatz können Sie Abfragen als einzelne SQL-Aufrufe ausführen. Ich persönlich nutze gerne scope für seine Aussagekraft. Bereiche sind auch sehr praktisch, um bekannte Finder-Methoden zu verketten. Auf diese Weise erhöhen sie die Möglichkeit, Code und DRY-Code wiederzuverwenden. Nehmen wir an, wir haben etwas mehr zu tun:

Wir können jetzt alle diese Bereiche verwenden, um komplexere Abfragen individuell zu erstellen.

Sicher, das funktioniert, aber ich möchte vorschlagen, dass Sie noch einen Schritt weiter gehen.

Wie Sie sehen, profitieren wir durch diesen Ansatz von den Vorteilen einer ordnungsgemäßen Kapselung, Modellzuordnungen, Wiederverwendung von Code und einer aussagekräftigen Benennung von Methoden - und das alles bei einzelnen SQL-Abfragen. Kein Spaghetti-Code mehr, großartig!

Wenn Sie sich Sorgen machen, gegen das Demeter-Gesetz zu verstoßen, werden Sie erfreut sein zu hören, dass wir keine Demeter-Verbrechen begehen, da wir keine Punkte hinzufügen, indem wir in das zugehörige Modell greifen, sondern sie nur an ihr eigenes Objekt ketten.

Abschließende Gedanken

Aus Anfängersicht haben Sie meiner Meinung nach viel über den besseren Umgang mit Rails-Modellen gelernt und wie man sie robuster modelliert, ohne einen Henker zu fordern.

Lassen Sie sich jedoch nicht davon täuschen, dass es zu diesem speziellen Theme nicht viel mehr zu lernen gibt. Ich habe Ihnen einige Anti-Muster vorgestellt, die Neulinge meiner Meinung nach leicht verstehen und handhaben können, um sich frühzeitig zu schützen. Wenn Sie nicht wissen, was Sie nicht wissen, können Sie sich mit einem Seil um den Hals legen.

Obwohl dies ein solider Einstieg in dieses Theme war, bietet AntiPatterns in Rails-Modellen nicht nur mehr Aspekte, sondern auch mehr Nuancen, die Sie ebenfalls untersuchen müssen. Dies waren die Grundlagen - sehr wichtige und wichtige - und Sie sollten sich für eine Weile vollendet fühlen, dass Sie erst viel später in Ihrer Karriere darauf gewartet haben, sie herauszufinden.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.