遅延読み込み
遅延読み込み(ちえんよみこみ、英語: Lazy loading)とは実際にオブジェクトが必要とされたときに後から初期化を行うソフトウェアデザインパターンの一つである。
実装
[編集]以下の一般的な4つの遅延読み込みデザインパターンの実装方法がある[1]。これらは利点と欠点を併せ持つ。
- 遅延初期化(英語: lazy initialization)
- Virtual Proxyパターン
- Ghost パターン
- Value Holder パターン
遅延初期化
[編集]遅延初期化(英語: lazy initialization)とは、オブジェクトや値そしてその他の初期化の負荷が高いものの生成を後から行う戦略のことである。
これは初期化完了を示すフラグを持ち、オブジェクトが呼び出されるごとにこのフラグを調べる。初期化が完了されていれば実際のオブジェクトを返す。初期化がまだ行われていない場合はその時点で初期化を行う。マルチスレッドのプログラムでは競合状態を防ぐために初期化完了のフラグは排他制御を行う必要がある。
手続き型言語でこのパターンを用いることは、状態共有に依存する他のプログラミングパターンと同様に、潜在的な危険性を持つ。
lazy factory
[編集]デザインパターンの観点では遅延初期化はFactory Method パターンと共に用いられる。これは3つのアイデアの組み合わせである。
- クラスインスタンスを得るためにファクトリメソッドを利用する(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();
}
}
関連項目
[編集]参考文献
[編集]- ^ Martin Fowler, Patterns of Enterprise Application Architecture, Addison-Wesley, 2003, pp.200-214. ISBN 0-321-12742-0.