サーチ…


前書き

Prototypeパターンは、既存のプロトタイプオブジェクトを複製することによって新しいオブジェクトを作成する作成パターンです。プロトタイプパターンは、オブジェクトをコピーする方が速いクラスのインスタンス化を高速化します。

備考

プロトタイプパターンは、創造的なデザインパターンです。これは、作成するオブジェクトのタイプが、新しいオブジェクトを生成するために「複製」されたプロトタイプのインスタンスによって決定される場合に使用されます。

このパターンは、クラスが"多形(コピー)コンストラクタ"を必要とするときに使用されます。

プロトタイプパターン(C ++)

class IPrototype  {
public:
    virtual ~IPrototype() = default;

    auto Clone() const { return std::unique_ptr<IPrototype>{DoClone()}; }
    auto Create() const { return std::unique_ptr<IPrototype>{DoCreate()}; }

private:
    virtual IPrototype* DoClone() const = 0;
    virtual IPrototype* DoCreate() const = 0;
};

class A : public IPrototype {
public:
    auto Clone() const { return std::unique_ptr<A>{DoClone()}; }
    auto Create() const { return std::unique_ptr<A>{DoCreate()}; }
private:
    // Use covariant return type :)
    A* DoClone() const override { return new A(*this); }
    A* DoCreate() const override { return new A; }
};

class B : public IPrototype {
public:
    auto Clone() const { return std::unique_ptr<B>{DoClone()}; }
    auto Create() const { return std::unique_ptr<B>{DoCreate()}; }
private:
    // Use covariant return type :)
    B* DoClone() const override { return new B(*this); }
    B* DoCreate() const override { return new B; }
};


class ChildA : public A {
public:
    auto Clone() const { return std::unique_ptr<ChildA>{DoClone()}; }
    auto Create() const { return std::unique_ptr<ChildA>{DoCreate()}; }

private:
    // Use covariant return type :)
    ChildA* DoClone() const override { return new ChildA(*this); }
    ChildA* DoCreate() const override { return new ChildA; }
};

これにより、基本クラスポインタから派生クラスを構築することができます:

ChildA childA;
A& a = childA;
IPrototype& prototype = a;

// Each of the following will create a copy of `ChildA`:
std::unique_ptr<ChildA> clone1 = childA.Clone();
std::unique_ptr<A> clone2 = a.Clone();
std::unique_ptr<IPrototype> clone3 = prototype.Clone();

// Each of the following will create a new default instance `ChildA`:
std::unique_ptr<ChildA> instance1 = childA.Create();
std::unique_ptr<A> instance2 = a.Create();
std::unique_ptr<IPrototype> instance3 = prototype.Create();

プロトタイプパターン(C#)

プロトタイプパターンは、.NETのICloneableインターフェイスを使用して実装できます。

class Spoon {
}
class DessertSpoon : Spoon, ICloneable {
  ...
  public object Clone() {
    return this.MemberwiseClone();
  }
}
class SoupSpoon : Spoon, ICloneable {
  ...
  public object Clone() {
    return this.MemberwiseClone();
  }
}

プロトタイプパターン(JavaScript)

Java、C#、C ++などの古典的な言語では、まずクラスを作成してからクラスから新しいオブジェクトを作成するか、クラスを拡張できます。

JavaScriptではまずオブジェクトを作成し、そのオブジェクトを補強したり、そこから新しいオブジェクトを作成したりすることができます。だから私は、JavaScriptは、古典的な言語よりも実際のプロトタイプを示していると思います。

例:

var myApp = myApp || {};

myApp.Customer = function (){
    this.create = function () {
        return "customer added";
    }
};

myApp.Customer.prototype = {
    read: function (id) {
        return "this is the customer with id = " + id;
    },
    update: function () {
        return "customer updated";
    },
    remove: function () {
        return "customer removed";
    }
};

ここでCustomerという名前のオブジェクトを作成し、 新しいオブジェクトを作成せずにprototypeキーワードを使用して既存のCustomer objectを拡張しました。この技法はプロトタイプパターンとして知られています。



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow