おーみんブログ

C#, ASP.NET Core, Unityが大好きです。

VB.NETでPrototypeパターンを体験してみた。

はじめに

GoFデザインパターンの1つであるPrototypeパターンを体験してみました。

Prototypeパターンとは

通常、インスタンスを生成する際はnew クラス()などをしますが、Prototypeパターンはインスタンスをコピーして新たなインスタンスを生成するという内容になっています。

デザインパターンの名著『Java言語で学ぶデザインパターン入門 第3版』(結城 浩 著)では以下の場合に用いるのが良いと挙げられています。

  1. 種類が多すぎてクラスにまとめられない場合
  2. クラスからのインスタンス生成が難しい場合
  3. フレームワークと生成するインスタンスを分けたい場合

特に2つ目のクラスからのインスタンス生成が難しい場合というのはパッとイメージがしやすい内容でしょうか。 ユーザが図形を作成し、それをコピーする場合(ExcelやWordのようなイメージ)などにいちいちクラスからインスタンスを生成するよりは、単純にその形をコピーするほうが処理的にも軽そうです。

Prototypeパターンの構成要素は以下です。

Prototype: インスタンスをコピーして新しいインスタンスを生成するメソッドの定義 ConcretePrototype: Prototypeが定義したメソッドの具体的な処理 Client: 実際に新しいインスタンスをコピーするメソッドを使う側

サンプルコード

以下にサンプルコードを記載します。 Managerクラスで新しいインスタンスをコピーし、それぞれ朝昼夜の挨拶をコンソールに出していることが分かります。

Module Program
    Sub Main()
        Dim manager As New Manager()
        Dim morningGreet As New Greet("おはよう!")
        Dim afternoonGreet As New Greet("こんにちは!")
        Dim nightGreet As New Greet("こんばんは!")
        manager.Registor("morningGreet", morningGreet)
        manager.Registor("afternoonGreet", afternoonGreet)
        manager.Registor("nightGreet", nightGreet)

        Dim morningGreetCopy As IProduct = manager.Create("morningGreet")
        morningGreetCopy.Use()

        Dim afternoonGreetCopy As IProduct = manager.Create("afternoonGreet")
        afternoonGreetCopy.Use()

        Dim nightGreetCopy As IProduct = manager.Create("nightGreet")
        nightGreetCopy.Use()
    End Sub
End Module

' Prototype
Public Interface IProduct
    Sub Use()
    Function CreateCopy() As IProduct
End Interface

' Client
Public Class Manager
    Private greetCase As New Dictionary(Of String, IProduct)

    Public Sub Registor(name As String, protoType As IProduct)
        greetCase.Add(name, protoType)
    End Sub

    Public Function Create(prototypeName As String) As IProduct
        Dim p As IProduct = greetCase(prototypeName)
        Return p.CreateCopy()
    End Function
End Class

' ConcretePrototype
Public Class Greet
    Implements IProduct
    Private _greet As String

    Public Sub New(greet As String)
        _greet = greet
    End Sub

    Public Sub Use() Implements IProduct.Use
        Console.WriteLine(_greet)
    End Sub

    Public Function CreateCopy() As IProduct Implements IProduct.CreateCopy
        Return CType(MemberwiseClone(), IProduct)
    End Function
End Class
おはよう!
こんにちは!
こんばんは!

参考文献

Java言語で学ぶデザインパターン入門 第3版』(結城 浩 著)

おわりに

今まではインスタンスを生成するには必ずnew クラスをする、ということが個人的に当たり前になっていたのですが、なるほど、今回のようにコピーして生成する、というのもあるのですね。まだまだ知らないことばかりなので日々勉強していかねば!