在程式設計中, 惰性初始是一種拖延戰術。在第一次需求出現以前,先延遲創建物件、計算值或其它昂貴程式。
這通常是以一個旗號來實現,用旗號來標示是否完成其程式。每次請求對象時,會先測試此旗號。如果已完成,直接傳回,否則當場執行。
對於此想法更一般的論述,可見惰性求值。
對指令式語言,這個模式可能潛藏著危險,尤其是使用共享狀態的程式習慣。
基本介紹
- 中文名:惰性初始模式
- 性質:是一種拖延戰術
- 學科:計算機
- 所屬:設計模式
簡介,工廠方法,示例,C#,Java,
簡介
"惰性工廠"
- 使用一個工廠去得到一個類別的實例(工廠方法模式)。
- 將實例存在一個雜湊中,所以下次要求一個實例卻有相同參數時,可以得到同一個實例(可和單例模式來做比較)。
- 在第一次時,使用惰性初始來實例化物件(惰性初始模式)。
工廠方法
工廠方法模式(英語:Factory method pattern)是一種實現了“工廠”概念的面向對象設計模式。就像其他創建型模式一樣,它也是處理在不指定對象具體類型的情況下創建對象的問題。工廠方法模式的實質是“定義一個創建對象的接口,但讓實現這個接口的類來決定實例化哪個類。工廠方法讓類的實例化推遲到子類中進行。”
創建一個對象常常需要複雜的過程,所以不適合包含在一個複合對象中。創建對象可能會導致大量的重複代碼,可能會需要複合對象訪問不到的信息,也可能提供不了足夠級別的抽象,還可能並不是複合對象概念的一部分。工廠方法模式通過定義一個單獨的創建對象的方法來解決這些問題。由子類實現這個方法來創建具體類型的對象。
對象創建中的有些過程包括決定創建哪個對象、管理對象的生命周期,以及管理特定對象的創建和銷毀的概念。
工廠對象通常包含一個或多個方法,用來創建這個工廠所能創建的各種類型的對象。這些方法可能接收參數,用來指定對象創建的方式,最後返回創建的對象。
有時,特定類型對象的控制過程比簡單地創建一個對象更複雜。在這種情況下,工廠對象就派上用場了。工廠對象可能會動態地創建產品對象的類,或者從對象池中返回一個對象,或者對所創建的對象進行複雜的配置,或者套用其他的操作。
示例
C#
Fruit類別本身在這裡不做任合事。_typesDictionary變數則是一個存Fruit實例的 Dictionary 或 Map ,其透過typeName來存取。
using System;using System.Collections;using System.Collections.Generic;public class Fruit{ private string _typeName; private static Dictionary<string, Fruit> _typesDictionary = new Dictionary<string, Fruit>(); private Fruit(String typeName) { this._typeName = typeName; } public static Fruit GetFruitByTypeName(string type) { Fruit fruit; if (!_typesDictionary.ContainsKey(type)) { // 惰性初始 fruit = new Fruit(type); _typesDictionary.Add(type, fruit); } else fruit = _typesDictionary[type]; return fruit; } public static void ShowAll() { if (_typesDictionary.Count > 0) { Console.WriteLine("Number of instances made = {0}", _typesDictionary.Count); foreach (KeyValuePair<string, Fruit> kvp in _typesDictionary) { Console.WriteLine(kvp.Key); } Console.WriteLine(); } }}class Program{ static void Main(string[] args) { Fruit.GetFruitByTypeName("Banana"); Fruit.ShowAll(); Fruit.GetFruitByTypeName("Apple"); Fruit.ShowAll(); // returns pre-existing instance from first // time Fruit with "Banana" was created Fruit.GetFruitByTypeName("Banana"); Fruit.ShowAll(); Console.ReadLine(); }}
Java
import java.util.*; public class Fruit{ private static final Map<String,Fruit> types = new HashMap<String,Fruit>(); private final String type; // using a private constructor to force use of the factory method. private Fruit(String type) { this.type = type; } /** * Lazy Factory method, gets the Fruit instance associated with a * certain type. Instantiates new ones as needed. * @param type Any string that describes a fruit type, e.g. "apple" * @return The Fruit instance associated with that type. */ public static synchronized Fruit getFruit(String type) { if(!types.containsKey(type)) types.put(type, new Fruit(type)); // Lazy initialization return types.get(type); }}