遅延読み込み

遅延読み込み（ちえんよみこみ、）とは実際にオブジェクトが必要とされたときに後から初期化を行うソフトウェアデザインパターンの一つである。

実装 

以下の一般的な４つの遅延読み込みデザインパターンの実装方法がある。これらは利点と欠点を併せ持つ。
 遅延初期化（）
 Virtual Proxyパターン
 Ghost パターン
 Value Holder パターン

遅延初期化 

遅延初期化（）とは、オブジェクトや値そしてその他の初期化の負荷が高いものの生成を後から行う戦略のことである。

これは初期化完了を示すフラグを持ち、オブジェクトが呼び出されるごとにこのフラグを調べる。初期化が完了されていれば実際のオブジェクトを返す。初期化がまだ行われていない場合はその時点で初期化を行う。マルチスレッドのプログラムでは競合状態を防ぐために初期化完了のフラグは排他制御を行う必要がある。

手続き型言語でこのパターンを用いることは、状態共有に依存する他のプログラミングパターンと同様に、潜在的な危険性を持つ。

lazy factory
デザインパターンの観点では遅延初期化はFactory Method パターンと共に用いられる。これは３つのアイデアの組み合わせである。
 クラスインスタンスを得るためにファクトリメソッドを利用する（Factory Method パターン）
 インスタンスを連想配列に保存し、これにより次回から同じパラメータで「同じ」インスタンスを得られる（Multiton パターン）
 初めてオブジェクトが必要とされた時点でインスタンス化を行う（遅延初期化パターン）

コード例 
遅延初期化では、オブジェクトはまずnullをセットされる。そしてオブジェクトの要求イベントごとにオブジェクトがnullかを調べ、nullの場合は動的にオブジェクトを生成して要求元に渡す。以下にC#で記述した例を上げる。
private int myWidgetID;
private Widget myWidget = null;
 
public Widget MyWidget 
{
    get 
    {
        if (myWidget == null) 
        {
            myWidget = Widget.Load(myWidgetID);
        }
        
        return myWidget;
    }
}

C# にはnull合体代入演算子??=があるのでこれを用いると以下のように書ける。
private int myWidgetID;
private Widget myWidget = null; 

public Widget MyWidget 
{
   get { return myWidget ??= Widget.Load(myWidgetID); }
}

このメソッドはシンプルな実装であるが戻り値にnullを許容する場合は初期化されていないことを示すために placeholder オブジェクトを利用することもある。

Virtual proxy 
Virtual Proxy は実際のオブジェクトと同じインタフェースのオブジェクトである。初めてそのインタフェースのメソッドの一つが呼ばれるとき実際のオブジェクトを読み込み、委譲する。

Ghost 

Ghostは部分的な状態で読み込まれるオブジェクトである。これはオブジェクトの識別子しか含まないかもしれないが、そのなかのプロバティに初めてアクセスされた時に読み込みが行われる。

Value holder 

Value Holderは遅延読み込みの振る舞いを取り扱う上で汎用性があるオブジェクトである。代表例として、Android開発手法のViewHolderパターンなどがある。

コード例 
private ValueHolder<Widget> valueHolder;
 
public Widget MyWidget 
{
    get
    {
        return valueHolder.GetValue();
    }
}

関連項目 
 デザインパターン
 Proxy パターン

 遅延評価

参考文献 

ソフトウェアパターン