Lazy initialization
Encyclopedia
In computer programming
Computer programming
Computer programming is the process of designing, writing, testing, debugging, and maintaining the source code of computer programs. This source code is written in one or more programming languages. The purpose of programming is to create a program that performs specific operations or exhibits a...

, lazy initialization is the tactic of delaying the creation of an object, the calculation of a value, or some other expensive process until the first time it is needed.

This is typically accomplished by maintaining a flag indicating whether the process has taken place. Each time the desired object is summoned, the flag is tested. If it is ready, it is returned. If not, it is initialized on the spot.

See lazy evaluation
Lazy evaluation
In programming language theory, lazy evaluation or call-by-need is an evaluation strategy which delays the evaluation of an expression until the value of this is actually required and which also avoids repeated evaluations...

 for a general treatment of this idea. In heavily imperative languages this pattern carries hidden dangers, as does any programming habit that relies on shared state.

The "lazy factory"

In a software design pattern view, lazy initialization is often used together with a factory method pattern
Factory method pattern
The factory method pattern is an object-oriented design pattern to implement the concept of factories. Like other creational patterns, it deals with the problem of creating objects without specifying the exact class of object that will be created.The creation of an object often requires complex...

. This combines three ideas:
  • using a factory method to get instances of a class (factory method pattern
    Factory method pattern
    The factory method pattern is an object-oriented design pattern to implement the concept of factories. Like other creational patterns, it deals with the problem of creating objects without specifying the exact class of object that will be created.The creation of an object often requires complex...

    )
  • storing the instances in a map, so you get the same instance the next time you ask for an instance with same parameter (Multiton pattern
    Multiton pattern
    In software engineering, the multiton pattern is a design pattern similar to the singleton, which allows only one instance of a class to be created. The multiton pattern expands on the singleton concept to manage a map of named instances as key-value pairs....

    , similar to the singleton pattern
    Singleton pattern
    In software engineering, the singleton pattern is a design pattern used to implement the mathematical concept of a singleton, by restricting the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system...

    )
  • using lazy initialization to instantiate the object the first time it is requested (lazy initialization pattern).

Java

Here is an example in Java
Java (programming language)
Java is a programming language originally developed by James Gosling at Sun Microsystems and released in 1995 as a core component of Sun Microsystems' Java platform. The language derives much of its syntax from C and C++ but has a simpler object model and fewer low-level facilities...

.


import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

class Program {
public 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;
}
}

public class Fruit {
private String typeName;
private static Map types = new HashMap;

// using a private constructor to force use of the factory method.
private Fruit(String typeName) {
this.typeName = typeName;
}

/**
* 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 Fruit getFruitByTypeName(String type) {
Fruit fruit;

if (!types.containsKey(type)) {
// Lazy initialization
fruit = new Fruit(type);

types.put(type, fruit);
} else {
// Okay, it's available currently
fruit = types.get(type);
}

return fruit;
}

// Same above but used double-checked locking pattern
// for using in highly concurrent environments
public static Fruit getFruitByTypeNameHighConcurrentVersion(String type) {
Fruit fruit;

if (!types.containsKey(type)) {
synchronized (types) {
// Check again, after having acquired the lock to make sure
// the instance was not created meanwhile by another thread
if (!types.containsKey(type)) {
// Lazy initialization
types.put(type, new Fruit(type));
}
}
}

fruit = types.get(type);

return fruit;
}

public static void showAll {
if (types.size > 0) {
System.out.println("Number of instances made = " + types.size);

for (Entry entry : types.entrySet) {
System.out.println(entry.getKey);
}

System.out.println;
}
}
}

Output


Number of instances made = 1
Banana

Number of instances made = 2
Apple
Banana

Number of instances made = 2
Apple
Banana

C#

In .NET 4.0 Microsoft has included a Lazy class which can be used to do lazy loading.
Below is a dummy code which does lazy loading of Class Fruit

Lazy lazyFruit = new Lazy;
Fruit fruit = lazyFruit.Value;


Here is a dummy example in C#.

The Fruit class itself doesn't do anything here, The class variable _typesDictionary is a Dictionary/Map used to store Fruit instances by typeName.


using System;
using System.Collections;
using System.Collections.Generic;

public class Fruit
{
private string _typeName;
private static Dictionary _typesDictionary = new Dictionary;

private Fruit(String typeName)
{
this._typeName = typeName;
}

public static Fruit GetFruitByTypeName(string type)
{
Fruit fruit;

if (!_typesDictionary.TryGetValue(type, out fruit))
{
// Lazy initialization
fruit = new Fruit(type);

_typesDictionary.Add(type, fruit);
}
return fruit;
}

public static void ShowAll
{
if (_typesDictionary.Count > 0)
{
Console.WriteLine("Number of instances made = {0}", _typesDictionary.Count);

foreach (KeyValuePair kvp in _typesDictionary)
{
Console.WriteLine(kvp.Key);
}

Console.WriteLine;
}
}

public Fruit
{
// required so the sample compiles
}
}

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;
}
}

Actionscript 3

The following is an example of a class with Lazy initialization implemented in Actionscript
ActionScript
ActionScript is an object-oriented language originally developed by Macromedia Inc. . It is a dialect of ECMAScript , and is used primarily for the development of websites and software targeting the Adobe Flash Player platform, used on Web pages in the form of...

:

package examples.lazyinstantiation
{
public class Fruit
{
private var _typeName:String;
private static var instancesByTypeName:Dictionary = new Dictionary;

public function Fruit(typeName:String):void
{
this._typeName = typeName;
}

public function get typeName:String
{
return _typeName;
}

public static function getFruitByTypeName(typeName:String):Fruit
{
return instancesByTypeName[typeName] ||= new Fruit(typeName);
}

public static function printCurrentTypes:void
{
for each (var fruit:Fruit in instancesByTypeName)
{
// iterates through each value
trace(fruit.typeName);
}
}
}
}

Basic Usage:

package
{
import examples.lazyinstantiation;

public class Main
{
public function Main:void
{
Fruit.getFruitByTypeName("Banana");
Fruit.printCurrentTypes;

Fruit.getFruitByTypeName("Apple");
Fruit.printCurrentTypes;

Fruit.getFruitByTypeName("Banana");
Fruit.printCurrentTypes;
}
}
}

JavaScript

Here is an example in JavaScript
JavaScript
JavaScript is a prototype-based scripting language that is dynamic, weakly typed and has first-class functions. It is a multi-paradigm language, supporting object-oriented, imperative, and functional programming styles....

.


var Fruit = (function {
var types = {};
function Fruit {};

// count own properties in object
function count(obj) {
var i = 0;
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
++i;
}
}
return i;
}

var _static = {
getFruit: function(type) {
if (typeof types[type] 'undefined') {
types[type] = new Fruit;
}
return types[type];
},
printCurrentTypes: function {
console.log('Number of instances made: ' + count(types));
for (var type in types) {
console.log(type);
}
}
};

return _static;

});

Fruit.getFruit('Apple');
Fruit.printCurrentTypes;
Fruit.getFruit('Banana');
Fruit.printCurrentTypes;
Fruit.getFruit('Apple');
Fruit.printCurrentTypes;


Output


Number of instances made: 1
Apple

Number of instances made: 2
Apple
Banana

Number of instances made: 2
Apple
Banana

C++

Here is an example in C++
C++
C++ is a statically typed, free-form, multi-paradigm, compiled, general-purpose programming language. It is regarded as an intermediate-level language, as it comprises a combination of both high-level and low-level language features. It was developed by Bjarne Stroustrup starting in 1979 at Bell...

.

  1. include
  2. include
  3. include


using namespace std;

class Fruit {
public:
static Fruit* getFruit(const string& type);
static void printCurrentTypes;

private:
static map types;
string type;

// note: constructor private forcing one to use static getFruit
Fruit(const string& t) : type( t ) {}
};

//definition needed for using any static member variable
map Fruit::types;

/*
* Lazy Factory method, gets the Fruit instance associated with a
* certain type. Instantiates new ones as needed.
* precondition: type. Any string that describes a fruit type, e.g. "apple"
* postcondition: The Fruit instance associated with that type.
*/
Fruit* Fruit::getFruit(const string& type) {
map::iterator it = types.find(type); // try to find an existing instance; if not found std::map will return types.end

Fruit *f;
if (it types.end) { // if no instance with the proper type was found, make one
f = new Fruit(type); // lazy initialization part
types[type] = f; // adding the newly created Fruit to the types map for later lookup
} else { //if already had an instance
f = it->second; //The return value will be the found fruit
}
return f;
}

/*
* For example purposes to see pattern in action
*/
void Fruit::printCurrentTypes {
if (!types.empty) {
cout << "Number of instances made = " << types.size << endl;
for (map::iterator iter = types.begin; iter != types.end; ++iter) {
cout << (*iter).first << endl;
}
cout << endl;
}
}

int main(void) {
Fruit::getFruit("Banana");
Fruit::printCurrentTypes;

Fruit::getFruit("Apple");
Fruit::printCurrentTypes;

// returns pre-existing instance from first
// time Fruit with "Banana" was created
Fruit::getFruit("Banana");
Fruit::printCurrentTypes;

return 0;
}

/*
OUTPUT:
Number of instances made = 1
Banana

Number of instances made = 2
Apple
Banana

Number of instances made = 2
Apple
Banana

Smalltalk

Here is an example in Smalltalk
Smalltalk
Smalltalk is an object-oriented, dynamically typed, reflective programming language. Smalltalk was created as the language to underpin the "new world" of computing exemplified by "human–computer symbiosis." It was designed and created in part for educational use, more so for constructionist...

, of a typical accessor method to return the value of a variable using lazy initialization.


height
^height ifNil: [height := 2.0].

The 'non-lazy' alternative is to use an initialization method that is run when the object is created and then use a simpler accessor method to fetch the value.


initialize
height := 2.0

height
^height


Note that lazy initialization can also be used in non-object-oriented languages.

Ruby

Here is an example in Ruby
Ruby (programming language)
Ruby is a dynamic, reflective, general-purpose object-oriented programming language that combines syntax inspired by Perl with Smalltalk-like features. Ruby originated in Japan during the mid-1990s and was first developed and designed by Yukihiro "Matz" Matsumoto...

, of lazily initializing an authentication token from a remote service like Google. The way that @auth_token is cached is also an example of memoization
Memoization
In computing, memoization is an optimization technique used primarily to speed up computer programs by having function calls avoid repeating the calculation of results for previously processed inputs...

.


require 'net/http'
class Blogger
def auth_token
@auth_token ||=
(res = Net::HTTP.post_form(uri, params)) &&
get_token_from_http_response(res)
end

# get_token_from_http_response, uri and params are defined later in the class
end

b = Blogger.new
b.instance_variable_get(:@auth_token) # returns nil
b.auth_token # returns token
b.instance_variable_get(:@auth_token) # returns token

Python

Here is an example in Python
Python (programming language)
Python is a general-purpose, high-level programming language whose design philosophy emphasizes code readability. Python claims to "[combine] remarkable power with very clear syntax", and its standard library is large and comprehensive...

.


class Fruit:
def __init__(self, sort):
self.sort = sort

class Fruits:
def __init__(self):
self.sorts = {}

def get_fruit(self, sort):
if sort not in self.sorts:
self.sorts[sort] = Fruit(sort)

return self.sorts[sort]

if __name__ '__main__':
fruits = Fruits
print fruits.get_fruit('Apple')
print fruits.get_fruit('Lime')


PHP

Here is an example of lazy initialization in PHP
PHP
PHP is a general-purpose server-side scripting language originally designed for web development to produce dynamic web pages. For this purpose, PHP code is embedded into the HTML source document and interpreted by a web server with a PHP processor module, which generates the web page document...

 5:

header('Content-type:text/plain; charset=utf-8');

class Fruit {
private $type;
private static $types = array;

private function __construct($type) {
$this->type = $type;
}

public static function getFruit($type) {
// Lazy initialization takes place here
if (!array_key_exists($type, self::$types)) {
self::$types[$type] = new Fruit($type);
}

return self::$types[$type];
}

public static function printCurrentTypes {
echo 'Number of instances made: ' . count(self::$types) . "\n";
foreach (array_keys(self::$types) as $key) {
echo "$key\n";
}
echo "\n";
}
}

Fruit::getFruit('Apple');
Fruit::printCurrentTypes;

Fruit::getFruit('Banana');
Fruit::printCurrentTypes;

Fruit::getFruit('Apple');
Fruit::printCurrentTypes;

/*
OUTPUT:

Number of instances made: 1
Apple

Number of instances made: 2
Apple
Banana

Number of instances made: 2
Apple
Banana

?>

See also

  • Proxy pattern
    Proxy pattern
    In computer programming, the proxy pattern is a software design pattern.A proxy, in its most general form, is a class functioning as an interface to something else...

  • Singleton pattern
    Singleton pattern
    In software engineering, the singleton pattern is a design pattern used to implement the mathematical concept of a singleton, by restricting the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system...

  • Double-checked locking
    Double-checked locking
    In software engineering, double-checked locking is a software design pattern used to reduce the overhead of acquiring a lock by first testing the locking criterion without actually acquiring the lock...

  • Lazy loading
    Lazy loading
    Lazy loading is a design pattern commonly used in computer programming to defer initialization of an object until the point at which it is needed. It can contribute to efficiency in the program's operation if properly and appropriately used...


External links
The source of this article is wikipedia, the free encyclopedia.  The text of this article is licensed under the GFDL.
 
x
OK