Dehnbarkeitsmuster

In der Computerprogrammierung ist das Dehnbarkeitsmuster ein Designmuster, das ein Fachwerk für die aufrichtige Hinzufügung der Funktionalität zu einem System zu einem späteren Zeitpunkt zur Verfügung stellt.

Dehnbarkeit wird häufig gewünscht, wenn eine Anwendung im Stande sein muss, neue Eigenschaften, wie Netzwerkanschluss von Protokollen oder Dateiformaten zu unterstützen, die noch nicht bestehen. Das verlangt, dass die Anwendung ein Fachwerk für das allgemeine Problem ohne Sorge für die Details von Details liefert.

Fachwerk

Ein Fachwerk verwendet andere Module. Normale Module haben einen festen Satz von Abhängigkeiten, und werden nur durch das Subklassifizieren laut des Erbes erweitert. Ein Fachwerk kann aus mehreren Teilen bestehen, die geerbt werden müssen, um viel wie mehrere Fälle der abstrakten Klasse verwendet zu werden. Es können auch passierte Verweisungen auf andere Gegenstände sein, wie eine Klasse würde, die ist, stellt einen Muster-Ansicht-Kontrolleur auf. Es kann Namen von Klassen von einer Konfigurationsdatei oder vom Benutzer, als in BeanPattern lesen. Statt des Codes, der durch anderen Code wird verwendet, wird es anderen Code im Fluge verwenden. Es ist oben auf der Nahrungsmittelkette statt des Bodens.

Konfigurationsdateien als Erweiterungen

ConfigFile kann genug sein, um das Modul für angemessene Bedürfnisse kundengerecht anzufertigen. Es kann auch Module namentlich angeben, um geschaffen und in einem Fachwerk verwendet zu werden.

  1. die config.pl Datei definiert @listeners, um eine Liste von Klasse Namen zu enthalten
  2. das sollte Benachrichtigungen von einem Fernsehsprecher von EventListener, erhalten
  3. Verweise angebracht durch den $broadcaster.

verlangen Sie 'config.pl';

foreach mein $listener (@listeners) {\

verlangen Sie $listener;

mein $list_inst = $listener-> neu;

$broadcaster-> add_listener ($list_inst);

}\</Quelle>

Sieh Ereignis-Zuhörer für das Idiom des Fernsehsprechers/Zuhörers. Das vermeidet, die Namen von Zuhörer-Modulen in die Anwendung einzubauen. Ein unabhängiger Autor konnte einen Steck-dieser Anwendung schreiben: Sie würde nur den Benutzer//config.pl//modifizieren lassen müssen, um Erwähnung des Steck-einzuschließen. Natürlich konnte Modifizierung//config.pl//automatisiert werden. Das installieren Programm für den Steck-würde den Benutzer fragen müssen, wo//config.pl//ist, und verwenden Sie das Idiom von ConfigFile, um es zu aktualisieren.

Das Verlängern durch scripting

Eine Hauptbeschwerde gegen GUIs ist, dass sie ihn schwierig zur Schrift wiederholende Aufgaben machen. Befehl-Linienschnittstellen sind für die meisten Menschen schwierig, damit zu arbeiten. Keiner gibt reichen Zugang zur Anwendung, Schnittstelle programmierend (API) eines Programms. Ein gut bestimmtes Programm ist einige Linien von Perl im Hauptprogramm, die mehrere Module verwenden - sieh das Schaffen CPAN Module. Das macht es leichter, die Programm-Logik in anderen Programmen wiederzuverwenden. Komplizierte Programme, die auf den vorhandenen Teil-Vorteil davon ohne Frage bauen. Wie steht's mit dem anderen Fall - bedeutete eine kleine Schrift, eine Aufgabe zu automatisieren? Das verlangt, dass die Schrift Kenntnisse über die Struktur der Anwendung hat - muss es wissen, wie man die Module sammelt, sie und so weiter initialisiert. Es wird gezwungen, mit Aspekten der API zu arbeiten, mit der es fast sicher nicht betroffen wird. Es muss selbst das Fachwerk sein.

Das ist eine Art Abstraktionsinversion - wo etwas Abstraktes auf etwas Konkretes grafisch dargestellt wird, oder etwas Einfaches auf die Spitze von etwas Kompliziertem gepfropft wird.

Es würde mehr Sinn in diesem Fall für die Anwendung haben, eine Art Besuchermuster durchzuführen, und sich zu erlauben, ganz passiert, bereits zu einer anderen Gamasche des Codes gesammelt zu werden, der weiß, wie man spezifische Operationen darauf durchführt. Das leiht sich zur folgenden Natur der Schrift: Die benutzerbestimmte Erweiterung konnte eine Reihe von einfachen Anrufen sein:

Paket UserExtention1;

wie man
  1. erwartet, haben wir eine "run_macro" Methode

U-Boot run_macro {\

mein $this = Verschiebung;

mein $app = Verschiebung;

$app-> place_cursor (0, 0);

$app-> set_color ('weiß');

$app-> draw_circle (Radius => 1);

$app-> set_color ('rot');

$app-> draw_circle (Radius => 2);

# machen und so weiter... ein Auge eines kleinen Stiers

kehren Sie 1 zurück;

}\</Quelle>

Die Hauptanwendung konnte den Benutzer für ein Modul auffordern, alle Module in einem plugins Verzeichnis zu laden, oder zu laden, sie dann als Menüpunkte in einem "Erweiterungs"-Menü bereitstellen. Wenn eine der Erweiterungen aus dem Menü ausgesucht ist, wird eine Verweisung auf die Anwendung - oder ein Fassade-Muster, das eine Schnittstelle ihm zur Verfügung stellt - zum run_macro Methode eines Beispiels dieses Pakets passiert.

Viele Anwendungen werden Benutzer haben, die einfache Automation tun wollen, ohne die Mühe gemacht zu werden, sogar kleinen Perl zu erfahren (schrecklich, aber wahr!). Einige Anwendungen (wie Mathematica, zum Beispiel) werden Funktionalität zur Verfügung stellen, die zu Perl nicht sauber kartografisch darstellt. In diesem Fall würden Sie im Stande sein wollen, Ausdrücke grammatisch zu analysieren und sie zu manipulieren. In diesen Fällen kann eine kleine Sprache gerade das Ding sein.

Eine kleine Sprache ist eine kleine Programmiersprache, geschaffen spezifisch für die Aufgabe in der Nähe. Es kann anderen Sprachen ähnlich sein. Etwas Sauberes und am Problem spezifisch ins Visier genommenes Einfaches zu haben, kann bessere Lösung sein als das Werfen einer überwältigten Sprache daran. Gerade durch das Vernachlässigen nicht benötigter Eigenschaften wird Benutzerverwirrung reduziert.

place_cursor (0, 0)

set_color (weißer)

draw_circle (radius=1)

set_color (roter)

draw_circle (radius=2)

Einige Optionen bestehen: Wir können das direkt zu Perl bytecode, mit B kompilieren:: Erzeugen Sie (passend, um Vermächtnis-Sprachen ohne Leistungsverlust zu integrieren), oder wir können munge das in Perl und || eval || er. Lassen Sie uns es in Perl verwandeln.

  1. lesen Sie im Benutzerprogramm

meine $input = schließen sich an

  1. 0, wenn wir einen Funktionsnamen, 1 erwarten, wenn wir ein Argument, erwarten
  2. 2, wenn wir annehmen, dass ein Komma Argumente trennt

mein $state = 0;

  1. perl codieren wir schaffen

mein $perl ='

Paket UserExtention1;

U-Boot run_macros {\

mein $this = Verschiebung;

mein $app = Verschiebung;

';

während (1) {\

# Funktionsanruf nennen

wenn ($state == 0 && $input = ~/\g\s * (\w +)\s* \(/cgs) {\

$perl. = '$app->'. 1 $.' (';

$state = 1;

# a=b Stil-Parameter

} elsif ($state == 1 && $input = ~/\g\s * (\w +)\s * =\s * (\w +)/cgs) {\

$perl. = "1 $ =>' 2 $'";

$state = 2;

# einfacher Parameter

} elsif ($state == 1 && $input = ~/\g\s * (\w +)/cgs) {\

$perl. = "'1 $'";

$state = 2;

# Komma, um Rahmen zu trennen

} elsif ($state == 2 && $input = ~/\g\s *,/cgs) {\

$perl. =', ';

$state = 1;

# Ende des Parameters verzeichnen

} elsif (($state == 1 || $state == 2) && $input = ~/\g\s* \)/cgs) {\

$perl. ="); \n";

$state = 0;

# Syntax-Fehler oder Ende des Eingangs

} sonst {\

kehren Sie 1 wenn $input = ~/\g./cgs zurück;

drucken Sie "Operationsnamen expected\n" wenn $state == 0;

drucken Sie "Parameter expected\n" wenn $state == 1;

drucken Sie "Komma, oder Ende des Parameters verzeichnen expected\n" wenn $state == 2;

kehren Sie 0 zurück;

}\

}\

$perl. ='

kehren Sie 1 zurück;

}\';

Eval-$perl; wenn ($) {\

# zeigen diagnostische Information dem Benutzer

}\</Quelle>

Wir verwenden den \G regex metacharacter, der zusammenpasst, wo der letzte globale regex auf dieser Schnur aufgehört hat. Das hat uns mehrere kleine Bissen von der Schnur wegnehmen lassen, anstatt all das in einem großem Bissen tun zu müssen. Die Fahnen auf dem Ende des regex sind:

  • g - global - erforderlich für den \G Jeton, um zu arbeiten
  • c - nicht sicher, aber lässt es g arbeiten
  • s - Teilkette - behandelt die komplette Schnur als eine Schnur. Newlines werden regelmäßige Charaktere und vergleichen whitespace.

Aus dem Zusammenhang konnte die Schnur "xyzzy" entweder ein Parameter oder der Name einer Methode sein zu rufen. Die Lösung ist einfach, den Zusammenhang nachzugehen: Das ist, wohin $state eingeht. Jedes Mal, wenn wir etwas finden, aktualisieren wir den $state, um anzuzeigen, welche Klasse des Dings gültig sein würde, wenn es als nächstes käme. Nachdem wir einen Funktionsnamen und eine öffnende Parenthese, entweder ein Kuddelmuddel-Stil-Parameter oder ein einzelner, einsamer Parameter finden, oder eine nahe Parenthese gültig sein würde. Wir suchen nach dem Anfang einer anderen Funktion [nicht sogar, obwohl vielleicht wir sein sollten. Wenn geändert, das in unserem Code, würde es uns Nest-Funktionsanrufen in einander erlauben. Wir würden unser Niveau des Nistens verfolgen müssen, wenn wir Fehler ausgeben wollten, wenn es zu viele oder zu wenige richtige Parenthese gab. Übung ist nach dem Leser abgereist.].

Nach einem Parameter suchen wir entweder nach der nahen Parenthese oder nach einem anderen Parameter.

Jedes Mal, wenn wir etwas vergleichen, hängen wir eine Perl-ized Version genau desselben Dings auf den $perl an. All dieser wird in ein Paket und Methode-Behauptung gewickelt. Schließlich wird $perl bewertet. Das Ergebnis des Auswertens sollte sein, dieses neue Paket zu unserem Code, bereit bereitzustellen, genannt zu werden.

Bohnen als Erweiterungen

Kerben als Erweiterungen

Wenn eine Grundanwendung oder geteilte Codebasis, in verschiedenen Richtungen für verschiedene Kunden kundengerecht angefertigt wird, sollte schwerer Gebrauch aus Schablone-Methoden und abstrakten Fabriken gemacht werden, kundenspezifischen Code in ein Modul oder Baum von Modulen unter einem kundenspezifischen namespace lokalisierend, aber nicht, "wo es gehört".


Syrischer Katholik / Unteroffizier
Impressum & Datenschutz