Faule Initialisierung

In der Computerprogrammierung ist faule Initialisierung die Taktik, die Entwicklung eines Gegenstands, die Berechnung eines Werts oder einen anderen teuren Prozess bis zum ersten Mal zu verzögern, wenn es erforderlich ist.

Das wird normalerweise durch das Aufrechterhalten einer Fahne vollbracht, die anzeigt, ob der Prozess stattgefunden hat. Jedes Mal, wenn der gewünschte Gegenstand aufgefordert wird, wird die Fahne geprüft. Wenn es bereit ist, wird es zurückgegeben. Wenn nicht, es wird an Ort und Stelle initialisiert.

Sieh faule Einschätzung für eine allgemeine Behandlung dieser Idee. Auf schwer befehlenden Sprachen trägt dieses Muster verborgene Gefahren, wie jede Programmiergewohnheit tut, die sich auf den geteilten Staat verlässt.

Die "faule Fabrik"

In einer Softwaredesignmuster-Ansicht wird faule Initialisierung häufig zusammen mit einem Fabrikmethode-Muster verwendet. Das verbindet drei Ideen:

  • das Verwenden einer Fabrikmethode, Beispiele einer Klasse (Fabrikmethode-Muster) zu bekommen
wenn Sie
  • die Beispiele in einer Karte versorgen, so bekommen Sie dasselbe Beispiel das nächste Mal, bitten Sie um ein Beispiel mit demselben Parameter (Mehrtonne-Muster, das dem Singleton-Muster ähnlich ist)
  • mit der faulen Initialisierung, um den Gegenstand das erste Mal zu realisieren, wird es (faules Initialisierungsmuster) gebeten.

Beispiele

Java

Hier ist ein Beispiel in Java.

Import java.util. HashMap;

Import java.util. Karte;

Import java.util. Karte. Zugang;

Klassenprogramm {\

öffentliche statische leere Hauptsache (Schnur [] args) {\

Fruit.getFruitByTypeName ("Banane");

Fruit.showAll ;

Fruit.getFruitByTypeName ("Apfel");

Fruit.showAll ;

//Umsatz, der Beispiel vom ersten vorher existiert

//die Zeitfrucht mit "der Banane" wurde geschaffen

Fruit.getFruitByTypeName ("Banane"); Fruit.showAll ;

}\

}\

öffentliche Klassenfrucht {\

private Schnur typeName;

private statische Karte

//das Verwenden eines privaten Konstrukteurs, um Gebrauch der Fabrikmethode zu zwingen.

private Frucht (Spannen typeName), {\

this.typeName = typeName;

}\

/ * *

* Faule Fabrikmethode, ließ das Fruchtbeispiel mit einem bestimmten vereinigen

* Typ. Realisiert neue, wie erforderlich.

*

* @param-Typ

* Jede Schnur, die einen Fruchttyp, z.B "Apfel" beschreibt

* @return Das Fruchtbeispiel hat mit diesem Typ verkehrt.

*/

öffentliche statische Frucht getFruitByTypeName (Typ String) {\

Fruchtfrucht;

wenn (! types.containsKey (Typ)) {\

//Faule Initialisierung

Frucht = neue Frucht (Typ);

types.put (Typ, Frucht);

} sonst {\

//O.k. ist es zurzeit verfügbar

Frucht = types.get (Typ);

}\

geben Sie Frucht zurück;

}\

//Dasselbe oben, aber verwendet hat sich schließen lassendes Muster zweimal kontrolliert

//um in hoch gleichzeitigen Umgebungen zu verwenden

öffentliche statische Frucht getFruitByTypeNameHighConcurrentVersion (Typ String) {\

Fruchtfrucht; wenn (! types.containsKey (Typ)) {\

synchronisiert (Typen) {\

//Überprüfen Sie wieder, das Schloss erworben, um sich zu überzeugen

//das Beispiel wurde inzwischen durch einen anderen Faden nicht geschaffen

wenn (! types.containsKey (Typ)) {\

//Faule Initialisierung

types.put (Typ, neue Frucht (Typ));

}\

}\

}\

Frucht = types.get (Typ);

geben Sie Frucht zurück; }\

öffentliche statische Leere showAll {\

wenn (types.size > 0) {\

System.out.println ("Zahl von Beispielen gemacht =" + types.size );

für (Zugang

System.out.println (entry.getKey );

}\

System.out.println ;

}\ }\}\</Quelle>

Produktion

Zahl von Beispielen gemacht = 1

Banane

Zahl von Beispielen gemacht = 2

Apfel

BananeZahl von Beispielen gemacht = 2ApfelBanane

</pre>

C#

In.NET hat 4.0 Microsoft eine Klasse eingeschlossen, die verwendet werden kann, um das faule Laden zu tun.

Unten ist ein Scheincode, der das faule Laden der Klasse tut

Faul

Fruchtfrucht = lazyFruit. Wert;

</Quelle>

Hier ist ein Scheinbeispiel in

C#.

Die Klasse selbst tut nichts hier, Die Klassenvariable ist ein Wörterbuch/Karte, das verwendet ist, um Beispiele dadurch zu versorgen.

das Verwenden des Systems;

das Verwenden des Systems. Sammlungen;

das Verwenden des Systems. Sammlungen. Allgemein;

öffentliche Klassenfrucht

{\

private Schnur _typeName;

privates statisches Wörterbuch

private Frucht (Spannen typeName)

{\

das. _ typeName = typeName;

}\

öffentlicher statischer FruchtgetFruitByTypeName (spannen Typ)

{\

Fruchtfrucht;

wenn (! _typesDictionary. TryGetValue (Typ, Frucht))

{\

//Faule Initialisierung

Frucht = neue Frucht (Typ);

_typesDictionary. Tragen Sie (Typ, Frucht) bei;

}\

geben Sie Frucht zurück;

}\

öffentlicher statischer leerer ShowAll

{\

wenn (_typesDictionary. Graf> 0)

{\

Konsole. WriteLine ("Zahl von Beispielen gemacht = {0}", _typesDictionary. Graf);

foreach (KeyValuePair

{\

Konsole. WriteLine (kvp. Schlüssel);

}\

Konsole. WriteLine ;

}\ }\

öffentliche Frucht

{\

//erforderlich so kompiliert die Probe

}\}\

Klassenprogramm

{\

statische leere Hauptsache (Schnur [] args)

{\

Frucht. GetFruitByTypeName ("Banane");

Frucht. ShowAll ;

Frucht. GetFruitByTypeName ("Apfel");

Frucht. ShowAll ;

//Umsatz, der Beispiel vom ersten vorher existiert

//die Zeitfrucht mit "der Banane" wurde geschaffen

Frucht. GetFruitByTypeName ("Banane"); Frucht. ShowAll ;

Konsole. ReadLine ;

}\}\</Quelle>

Actionscript 3

Der folgende ist ein Beispiel einer Klasse mit der Faulen in Actionscript durchgeführten Initialisierung:

Paket examples.lazyinstantiation

{\

öffentliche Klassenfrucht

{\

privater var _typeName:String;

privater statischer var instancesByTypeName:Dictionary = neues Wörterbuch ;

öffentliche Funktionsfrucht (typeName:String): Leere

{\

das. _ typeName = typeName;

}\

öffentliche Funktion bekommt typeName : Schnur

{\

geben Sie _typeName zurück;

}\

öffentliche statische Funktion getFruitByTypeName (typeName:String): Frucht

{\

geben Sie instancesByTypeName [typeName] || = neue Frucht (typeName) zurück;

}\

öffentliche statische Funktion printCurrentTypes : Leere

{\

für jeden (var fruit:Fruit in instancesByTypeName)

{\

//wiederholt durch jeden Wert

Spur (fruit.typeName);

}\ }\ }\}\</Quelle>

Grundlegender Gebrauch:

Paket

{\

Import examples.lazyinstantiation;

öffentliche Klasse Wichtiger

{\

öffentliche Funktion Wichtig : Leere

{\

Fruit.getFruitByTypeName ("Banane");

Fruit.printCurrentTypes ;

Fruit.getFruitByTypeName ("Apfel");

Fruit.printCurrentTypes ; Fruit.getFruitByTypeName ("Banane"); Fruit.printCurrentTypes ; }\ }\}\</Quelle>

JavaScript

Hier ist ein Beispiel in JavaScript.

Var-Frucht = (Funktion {\

Var-Typen = {};

fungieren Sie Frucht {};

//zählen Sie eigene Eigenschaften im Gegenstand auf

fungieren Sie Zählung (obj) {\

var i = 0;

für (var Schlüssel in obj) {\

wenn (obj.hasOwnProperty (Schlüssel)) {\

++ ich;

}\

}\

kehren Sie i zurück;

}\

var _static = {\

getFruit: Funktion (Typ) {\

wenn (typeof Typen [Typ] == 'unbestimmt') {\

Typen [Typ] = neue Frucht;

}\

geben Sie Typen [Typ] zurück;

},

printCurrentTypes: Funktion {\

console.log ('Zahl von Beispielen hat gemacht:' + Zählung (Typen));

für (var Typ in Typen) {\

console.log (Typ);

}\ }\

};

geben Sie _static zurück;

}) ;

Fruit.getFruit ('Apfel');

Fruit.printCurrentTypes ;

Fruit.getFruit ('Banane');

Fruit.printCurrentTypes ;Fruit.getFruit ('Apfel');Fruit.printCurrentTypes ;</Quelle>Produktion

Die Zahl von Beispielen hat gemacht: 1

Apfel

Die Zahl von Beispielen hat gemacht: 2

ApfelBananeDie Zahl von Beispielen hat gemacht: 2ApfelBanane</pre>

C ++

Hier ist ein Beispiel in C ++.

  1. einschließen
einschließen einschließen

das Verwenden namespace std;

Klassenfrucht {\

Publikum:

statischer Fruit* getFruit (const Typ string&);

statische Leere printCurrentTypes ;

privat:

statische Karte

Schnur-Typ;

//Zeichen: Konstrukteur das private Zwingen von dasjenige, statischen getFruit zu verwenden

Frucht (const string& t): Typ (t) {}\

};

//Definition, die erforderlich ist, um jede statische Mitglied-Variable zu verwenden

Karte

/ *

* Faule Fabrikmethode, ließ das Fruchtbeispiel mit einem vereinigen

* bestimmter Typ. Realisiert neue, wie erforderlich.

* Vorbedingung: Typ. Jede Schnur, die einen Fruchttyp, z.B "Apfel" beschreibt

* Postbedingung: Das Fruchtbeispiel hat mit diesem Typ verkehrt.

*/

Fruit* Fruit:: getFruit (const Typ string&) {\

Karte

Frucht *f;

wenn (er == types.end ) {//, wenn kein Beispiel mit dem richtigen Typ gefunden wurde, einen machen Sie

f = neue Frucht (Typ);//fauler Initialisierungsteil

Typen [Typ] = f;//das Hinzufügen der kürzlich geschaffenen Frucht zu den Typen stellen für später lookup kartografisch dar

} sonst {//, wenn bereits gehabt, ein Beispiel

f = es-> zweit;//wird Der Rückwert die gefundene Frucht sein

}\

geben Sie f zurück;

}\/ *

* Zum Beispiel Zwecke, Muster in der Handlung zu sehen

*/

leere Frucht:: printCurrentTypes {\

wenn (! types.empty ) {\

cout

cout

Plausch

Hier ist ein Beispiel im Plausch von einer typischen Zugriffsberechtigter-Methode, den Wert einer variablen verwendenden faulen Initialisierung zurückzugeben.

Höhe

^height ifNil: [Höhe: = 2.0].

</Quelle>

Die 'nichtfaule' Alternative soll eine Initialisierungsmethode verwenden, die geführt wird, wenn der Gegenstand geschaffen wird und dann verwenden Sie eine einfachere Zugriffsberechtigter-Methode, den Wert herbeizuholen.

initialisieren Sie

Höhe: = 2.0

Höhe

^height

</Quelle>

Bemerken Sie, dass faule Initialisierung auch auf nichtobjektorientierten Sprachen verwendet werden kann.

Rubin

Hier ist ein Beispiel in Ruby, davon, träge einen Beglaubigungsjeton von einem entfernten Dienst wie Google zu initialisieren. Die Weise, wie @auth_token versteckt wird, ist auch ein Beispiel von memoization.

verlangen Sie 'net/http'

Klasse Blogger

def auth_token

@auth_token || =

(res = Netz:: HTTP.post_form (uri, params))

&&

get_token_from_http_response (res)

Ende

# werden get_token_from_http_response, uri und params später in der Klasse definiert

Ende

b = Blogger.new

b.instance_variable_get (:@auth_token) # gibt Null zurück

b.auth_token # gibt Jeton zurück

b.instance_variable_get (:@auth_token) # gibt Jeton zurück

</Quelle>

Pythonschlange

Hier ist ein Beispiel in der Pythonschlange.

Klassenfrucht:

def __ init __ (selbst, Sorte):

self.sort = Sorte

Klassenfrüchte:

def __ init __ (selbst):

self.sorts = {}\

def get_fruit (selbst, Sorte):

wenn Sorte nicht in self.sorts:

self.sorts [Sorte] = Frucht (Sorte)

geben Sie self.sorts [Sorte] zurück

wenn __ __ == '__ wichtig __' nennen:

Früchte = Früchte

Druckfrüchte get_fruit ('Apfel')

Druckfrüchte get_fruit ('Limone')

</Quelle>

PHP

Hier ist ein Beispiel der faulen Initialisierung in PHP 5:

}\

öffentliche statische Funktion getFruit ($type) {\

//Faule Initialisierung findet hier statt

wenn (! array_key_exists ($type, selbst:: $types)) {\

kehren Sie selbst zurück:: $types [$type] = neue Frucht ($type);

}\

kehren Sie selbst zurück:: $types [$type];

}\

öffentliche statische Funktion printCurrentTypes {\

werfen Sie 'Zahl von gemachten Beispielen zurück:'. Zählung (selbst:: $types). "\n";

foreach (array_keys (selbst:: $types) als $key) {\

Echo "$key\n";

}\

Echo "\n";

}\}\

Frucht:: getFruit ('Apfel');

Frucht:: printCurrentTypes ;

Frucht:: getFruit ('Banane');

Frucht:: printCurrentTypes ;Frucht:: getFruit ('Apfel');Frucht:: printCurrentTypes ;/ *

PRODUKTION:

Die Zahl von Beispielen hat gemacht: 1ApfelDie Zahl von Beispielen hat gemacht: 2ApfelBananeDie Zahl von Beispielen hat gemacht: 2ApfelBanane
  • /

?>

</Quelle>

Siehe auch

Links

C#

Vereinigungsgrafschaft, New Jersey / Sussex County, New Jersey
Impressum & Datenschutz