デザインパターン-Prototype

Prototypeパターンとは

Prototypeパターンは、事前にクラスのインスタンス(オブジェクト)を用意しておき、そのコピー(クローン)を作りだすことで、以降のインスタンス生成を簡単にするパターンです。
通常、オブジェクトはクラスから作成(newを実行)しますが、Prototypeパターンではオブジェクトからオブジェクトを作成(複製)します。

簡単に言えば、Prototypeパターンは「クラスのインスタンスに自身をクローンする方法」を提供するパターンです。
インスタンスの生成は、Prototype(原型)となるオブジェクト自身によって行われます。
そして、生成されたオブジェクトは原型オブジェクトのクローンであり、原型オブジェクトと同じ構造、データを持つこととなります。


クローンの作成について

Prototypeパターンを適用する場合、「浅いコピー(shallow copy)」と「深いコピー(deep copy)」を意識して実装する必要があります。

「浅いコピー」とは、変数に格納された値がそのまま複製されるコピー方法です。
数値や文字列などの値として格納されている変数は値そのものがコピーされますが、値参照を格納した変数では参照がコピーされることになります。
これは、コピー元とコピー先で共通の変数内容を参照することになり、一方のオブジェクトの変更が他方のオブジェクトに影響します。

「深いコピー」とは、内部の参照もコピーする方法です。
オブジェクトをコピーすることで、独立した別オブジェクトとなります。
コピー元のオブジェクトを変更してもコピー先オブジェクトは変更されません。


Prototypeパターンの利点

  • 既存のインスタンスのコピーを使って、生成の複雑なインスタンスや少しだけ違うインスタンスを多数または効率的に生成することが可能となる。
  • 類似インスタンスを必要とする場合に、クラスからインスタンスを生成する手順を簡略化できます。
  • オブジェクトの生成処理を隠蔽できます。

構成要素

  • Client(利用者)
    • 「ConcretePrototype」が実装しているオブジェクト複製メソッドを利用して、新しいオブジェクトを返します。
  • Prototype(原型)
    • オブジェクト複製メソッドのインタフェースを定義します。
  • ConcretePrototype(具体的な原型)
    • 自身のオブジェクトを複製するメソッドを実装します。
  • PrototypeUser(使用者)
    • Prototypeパターンを適用したクラスを利用して処理します。

rubyによるPrototypeパターンの実装


#!/usr/bin/env ruby

class ConcretePrototype
  attr_accessor :name
  def initialize(name=nil)
    @name = name
  end

  def clone_create
    obj = ConcretePrototype.new
    obj.name = @name
    return(obj)
  end

  def clone_self
    obj = self.clone
    return(obj)
  end
end


関連ページ