JS-Entwurfsmuster: Objekterstellungsmuster

Also, Chabrowsk-Bürger, schon diesen Donnerstag in OTUS wird der Kurs "Fullstack JavaScript Developer" beginnen. Und heute teilen wir Ihnen die Veröffentlichung eines anderen Autors im Vorgriff auf den Beginn des Kurses mit.



Artikelautor : Pavel Yakupov


In diesem Artikel werden wir über die einfachsten und gebräuchlichsten Entwurfsmuster in der Javascript-Sprache sprechen - und versuchen zu erklären, welche wann angewendet werden sollen.
Was sind Designmuster im Allgemeinen? Entwurfsmuster ist ein Begriff, der für häufig verwendete Lösungen für häufig auftretende Probleme beim Erstellen von Programmen verwendet wird.

Einfach ausgedrückt sind Entwurfsmuster erfolgreiche Lösungen, die häufig genug verwendet werden. Entwurfsmuster als Konzept, das selbst zu einer Zeit entstand, als die Programmiersprache JavaScript nicht erwähnt wurde, wurden im Bereich der Softwareentwicklung 1994 von den Big Four ausführlich beschrieben. In unserem Artikel werden wir uns jedoch der Implementierung einiger einfacher Muster in der Programmiersprache JavaScript zuwenden.

Lassen Sie uns kurz auf die wichtigsten Arten von Entwurfsmustern eingehen:

Entwurfsmuster für die Erstellung


Wie der Name schon sagt, werden diese Muster hauptsächlich zum Erstellen neuer Objekte verwendet. Dazu gehören Muster wie Constructor, Factory, Prototype und Singleton.

Strukturelle Entwurfsmuster


Diese Muster sind mit Klassen und der Zusammensetzung von Objekten verbunden. Sie helfen, Objekte oder deren Teile zu strukturieren oder umzustrukturieren, ohne den Betrieb des gesamten Systems zu stören.

Verhaltensentwurfsmuster


Diese Art von Entwurfsmuster zielt darauf ab, die Kommunikation zwischen verschiedenen Objekten zu verbessern. Zu den Verhaltensentwurfsmustern gehören Commander, Iterator, Mediator, Observer, State Pattern, Strategy und Template.

In diesem Artikel analysieren wir nur Entwurfsmuster, die sich auf das Erstellen von Objekten beziehen. Diese sind etwas einfacher und besser für Anfänger geeignet, um ihre Aufgabenanwendungen, Text-RPGs in der Konsole, einfache Spiele auf Leinwand usw. zu erstellen.

Muster "Modul"


Dieses Entwurfsmuster erschien sozusagen unfreiwillig in der JavaScript-Sprache. Anfangs dachte die Sprache nicht daran, solchen Phänomenen wie der Verschmutzung des globalen Bereichs entgegenzuwirken (und in anderen Sprachen wie C # oder C ++ gibt es einen Namespace, der dieses Problem sofort löst). Darüber hinaus sind die Module teilweise für die Wiederverwendung des Codes erforderlich, da sie nach ihrer erstmaligen Erstellung und Verwendung viel kompetenter mit Projekten anderer Teams verbunden werden können.
Das Modul Modul während seiner gesamten Existenz (bereits in ES5 war es weit verbreitet) verwendete IIFE (sofort als funktionale Ausdrücke bezeichnet).

Hier ist ein einfaches Beispiel für das Muster „Modul“:

const first_Module = (function() { let Surname = "Ivanov"; let Nickname = "isakura313"; function declare_Surname() { console.log(Surname); } return { declare_Nickname: function() { alert(Nickname); } } })(); first_Module.declare_Nickname(); console.log(Surname); //       

Das "Modul" -Muster kapselt die darin enthaltenen Daten vollständig ein. Wir können nur mit öffentlichen Methoden darauf zugreifen, und bis JavaScript-Implementierungen von öffentlichen und privaten Methoden "out of the box" auf diese Weise implementiert werden müssen.

Konstruktormuster


Dies ist ein Entwurfsmuster zum Erstellen eines Objekts. Ein Konstruktor ist eine Funktion, die neue Objekte erstellt. In JavaScript können Objekte jedoch auch ohne Konstruktorfunktion oder Klassendefinition im laufenden Betrieb erstellt werden.
Der Konstruktor ist eines der am häufigsten verwendeten Entwurfsmuster. Es wird verwendet, um Objekte eines bestimmten Typs zu erstellen.

 //     to-do  //,    ,           class ItemDeal { constructor(name, color) { this.name = name; this.color = color; } } //     ,       localStorage  ? let item = new ItemDeal(`${text}`, `${select.value - 1}`); // text -   , a select.value -    let myJson = JSON.stringify(item); //        //localStorage,        //localStorage.setItem(item.name, myJson); 

Fabrikmuster


Das Factory-Muster ist ein weiteres Muster, das sich auf das Erstellen eines Objekts aus einer Klasse konzentriert. Darin stellen wir allgemeine Schnittstellen bereit, die die Erstellung eines Unterklassenobjekts delegieren.

Dieses Entwurfsmuster wird am häufigsten verwendet, um eine Sammlung von Objekten zu bearbeiten, die sowohl unterschiedliche als auch dieselben Eigenschaften aufweisen.
Im folgenden Beispiel erstellen wir eine feindliche Klasse (EnemyFactory) für unsere Textquest. Ja, das Beispiel ist recht einfach, aber dies ist das Problem von Entwurfsmustern: Sie werden für "große" Anwendungen benötigt. Wenn Sie nur drei Bilder haben, die durch Klicken auf die Seite herausfliegen, sind keine Entwurfsmuster für Sie besonders nützlich.

Okay, zeigen Sie einfach einen Code für unser Text-Rollenspiel in der Konsole:

 class EnemyFactory{ constructor() { this.createEnemy = function(type) { let enemy; if (type === 'goblin' || type === 'ork') enemy = new Infantry(); else if (type === 'elf') enemy = new Archer(); enemy.attack = function() { return `The ${this._type} is attack`; }; return enemy; }; } } class Infantry { constructor() { this._type = 'goblin'; this.scream = function() { return 'AAAAAAAAA! Za ordu!!!'; }; } } class Archer { constructor() { this._type = 'elf'; this.magic_attack = function() { return 'Magic fog around you! You cant see!!'; }; } } const enemy_army = new EnemyFactory(); let newGoblin = enemy_army.createEnemy('goblin'); let newElf = enemy_army.createEnemy('elf'); console.log(newGoblin.attack()); console.log(newElf.attack()); console.log(newGoblin.scream()); console.log(newElf.magic_attack()); //  

Prototypmuster


Hier verwenden wir eine Art „Skelett“ eines realen Objekts, um ein neues Objekt zu erstellen. Und Prototyping ist die häufigste Art, OOP in JavaScript zu erstellen.

 //,     to-do  const itemDeal = { colorOfHeader: blue; //     .    ? create() { console.log("our item create"); //  item }, delete() { console.log("our item delete now"); //   item }, }; //     ,  to-do  //  ,   Trello. const newDeal = Object.create(itemDeal, { owner: { value: 'Paul' } }); console.log(newDeal.__proto__ === itemDeal); //true 

Das Prototypmuster ist nützlich, wenn Ihre Anwendung die Funktionalität irgendwie erweitern oder reduzieren kann.

Das Einzelgängermuster


Oder, wie er besser bekannt ist, "Singleton". Ein "Einzelgänger" ist ein spezielles Muster, in dem nur eine Instanz einer Klasse existieren kann. Das Muster funktioniert wie folgt: Die Initialisierung des Objekts funktioniert, wenn keine einzelne Instanz erstellt oder zurückgegeben wird. Wenn vorhanden, wird das ausgelöste Objekt zurückgegeben.
Angenommen, wir erstellen eine Klasse der Hauptfigur und möchten, dass sie 1 und nicht 4 ist, wie in Jumanji.

 class Hero { constructor(name) { if (Hero.exists) { return Hero.instance; } this._name = name; Hero.instance = this; Hero.exists = true; return this; } getName() { return this._name; } setName(name) { this._name = name; } } //    const smolder = new Hero('Smolder!'); console.log(smolder.getName()); // Smolder! const ruby = new Hero('Ruby'); console.log(ruby.getName()); // Smolder! // ,       .         . //            

Vielen Dank für Ihre Aufmerksamkeit! Ich hoffe, dass dieser Artikel als guter Start für OOP in JavaScript dient (obwohl, um ehrlich zu sein, mein Kollege mit langjähriger Erfahrung in Java und JavaScript, OOP dort, gelinde gesagt, nicht sehr entwickelt ist). In den neuen Standards hat sich die Sprache jedoch erheblich verbessert, und ich bin sicher, dass diese Methode nur häufiger verwendet wird (oder Dart wird kommen und alles ersetzen).

Nützliche Links:

developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/create
learn.javascript.ru/class
developer.mozilla.org/en/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript

Source: https://habr.com/ru/post/de468723/


All Articles