まさるblog

越後在住子持ちプログラマー奮闘記 - Author:まさる(高野 将、TAKANO Sho)

目次

Blog 利用状況

ニュース

著書

2010/7発売


Web掲載記事

@IT

.NET開発を始めるVB6プログラマーが知るべき9のこと

CodeZine

実例で学ぶASP.NET Webフォーム業務アプリケーション開発のポイント

第1回 3層データバインドを正しく活用しよう(前編)

ブログパーツ


書庫

日記カテゴリ

コミュニティ

デザインパターンを学ぶ~その15:Factoryパターン(2)~

#色々あって間が空きましたが、ようやくこのシリーズを再開します。

 

さて、前回はFactoryの基本ということで、Simple Factoryを取り上げました。今回はFactory Methodパターンを取り上げます。

 

Factory Methodパターンはインスタンス化するクラスをサブクラスに決定させるため、インスタンス化をサブクラスに先送りできます。これにより、実際にオブジェクトを使用するクラスから具象クラスへの依存がなくなります。

 

といってもよくわからないので、コードを書いてみましょう。

 

  1. まず、生成されるオブジェクトのインタフェイスとなる抽象クラスAbstractMemberを定義します。ここで、インタフェイスとは広義の意味であり、interface(VBならInterface)で定義するインタフェイスのことではありません。
    C# Code
    public abstract class AbstractMember
    {
        protected string name;
    
        public abstract void Speak();
    }
    
    VB Code
    Public MustInherit Class AbstractMember
    
        Protected name As String
    
        Public MustOverride Sub Speak()
    
    End Class
    
  2. AbstractMemberを継承した具象クラスMasaru, Epistemeを定義します。
    C# Code
    public class Masaru : AbstractMember
    {
        public Masaru()
        {
            this.name = "まさる";
        }
    
        public override void Speak()
        {
            Console.WriteLine("名前は{0}です。", this.name);
            Console.WriteLine("越後のとあるSIerで働いています。");
        }
    }
    
    public class Episteme : AbstractMember
    {
        public Episteme()
        {
            this.name = "επιστημη";
        }
    
        public override void Speak()
        {
            Console.WriteLine("名前は{0}です。", this.name);
            Console.WriteLine("わんくま茶藝部顧問です。");
        }
    }
    
    VB Code
    Public Class Masaru
        Inherits AbstractMember
    
        Sub New()
    
            Me.name = "まさる"
    
        End Sub
    
        Public Overrides Sub Speak()
    
            Console.WriteLine("名前は{0}です。", Me.name)
            Console.WriteLine("越後のとあるSIerで働いています。")
    
        End Sub
    
    End Class
    
    Public Class Episteme
        Inherits AbstractMember
    
        Sub New()
    
            Me.name = "επιστημη"
    
        End Sub
    
        Public Overrides Sub Speak()
    
            Console.WriteLine("名前は{0}です。", Me.name)
            Console.WriteLine("わんくま茶藝部顧問です。")
    
        End Sub
    
    End Class
    
  3. AbstractMemberを生成するための抽象クラスAbstractCreatorを定義します。
    C# Code
    public abstract class AbstractCreator
    {
        public abstract AbstractMember CreateMember();
    }
    
    VB Code
    Public MustInherit Class AbstractCreator
    
        Public MustOverride Function CreateMember() As AbstractMember
    
    End Class
    
  4. AbstractCreatorを継承したインスタン生成のための具象クラスNormalMemberCreator、SuperMemberCreatorを定義します。
    C# Code
    public class NormalMemberCreator : AbstractCreator
    {
        public override AbstractMember CreateMember()
        {
            return new Masaru();
        }
    }
    
    public class SuperMemberCreator : AbstractCreator
    {
        public override AbstractMember CreateMember()
        {
            return new Episteme();
        }
    }
    
    VB Code
    Public Class NormalMemberCreator
        Inherits AbstractCreator
    
        Public Overrides Function CreateMember() As AbstractMember
    
            Return New Masaru()
    
        End Function
    
    End Class
    
    Public Class SuperMemberCreator
        Inherits AbstractCreator
    
        Public Overrides Function CreateMember() As AbstractMember
    
            Return New Episteme()
    
        End Function
    
    End Class
    

 

以上のコードを実行してみましょう。

 

実行コード

C# Code
public static class Program
{
    public static void Main(string[] args)
    {
        {
            NormalMemberCreator memberCreator = new NormalMemberCreator();
            AbstractMember member = memberCreator.CreateMember();
            member.Speak();
        }

        Console.WriteLine("");

        {
            SuperMemberCreator memberCreator = new SuperMemberCreator();
            AbstractMember member = memberCreator.CreateMember();
            member.Speak();
        }

        Console.Read();
    }
}
VB Code
Public Class Program

    Private Shared Block As Object = Nothing

    Public Shared Sub Main(ByVal args As String())

        With Block

            Dim memberCreator As New NormalMemberCreator()
            Dim member As AbstractMember = memberCreator.CreateMember()
            member.Speak()

        End With

        Console.WriteLine("")

        With Block

            Dim memberCreator As New SuperMemberCreator()
            Dim member As AbstractMember = memberCreator.CreateMember()
            member.Speak()

        End With

        Console.ReadLine()

    End Sub

End Class

実行結果

名前はまさるです。
越後のとあるSIerで働いています。

名前はεπιστημηです。
わんくま茶藝部顧問です。

 

上記の実行コードはSpeakメソッドを実装している具象クラスのことを知りません。これが依存性をなくしたということです。

これによって何が良いのかというと、例えばMasaruクラスでなく、Torikobitoクラスに変更したい場合、実行コードに変更が必要ありません。あくまでTorikobitoクラスの追加と、NormalMemberCreatorの変更だけで済みます。

変更点

C# Code
public class Torikobito : AbstractMember
{
    public Torikobito()
    {
        this.name = "とりこびと";
    }

    public override void Speak()
    {
        Console.WriteLine("名前は{0}です。", this.name);
        Console.WriteLine("Memo(Of T)管理人です。");
    }
}

public class NormalMemberCreator : AbstractCreator
{
    public override AbstractMember CreateMember()
    {
        //return new Masaru();
        return new Torikobito();
    }
}
VB Code
Public Class Torikobito
    Inherits AbstractMember

    Sub New()

        Me.name = "とりこびと"

    End Sub

    Public Overrides Sub Speak()

        Console.WriteLine("名前は{0}です。", Me.name)
        Console.WriteLine("Memo(Of T)管理人です。")

    End Sub
End Class

Public Class NormalMemberCreator
    Inherits AbstractCreator

    Public Overrides Function CreateMember() As AbstractMember

        'Return New Masaru()
        Return New Torikobito()

    End Function

End Class

実行結果

名前はとりこびとです。
Memo(Of T)管理人です。

名前はεπιστημηです。
わんくま茶藝部顧問です。

 

ということで、今回はFactory Methodパターンをお送りしましたが、私自身まだこのパターンの有用性が理解し切れていません。実際に「こんなときに使ったよ」などありましたらコメントで教えてください。

投稿日時 : 2007年11月7日 0:57

Feedback

# re: デザインパターンを学ぶ~その15:Factoryパターン(2)~ 2007/11/07 1:09 まさる

επιστημηさん、勝手に名前使ってごめんなさい。

# re: デザインパターンを学ぶ~その15:Factoryパターン(2)~ 2007/11/07 9:04 まさる

とりこびとさんも勝手に名前使ってごめんなさい。

# re: デザインパターンを学ぶ~その15:Factoryパターン(2)~ 2007/11/07 9:12 とりこびと

↑この上のコメント2つの時間差が気になってしかたありませんwww

# re: デザインパターンを学ぶ~その15:Factoryパターン(2)~ 2007/11/07 9:20 επιστημη

ちっちっち。"芸"ではありません、"藝"です"藝"!

# re: デザインパターンを学ぶ~その15:Factoryパターン(2)~ 2007/11/07 9:24 まさる

>↑この上のコメント2つの時間差が気になってしかたありませんwww
時間も時間で寝ようかなぁと布団に入ってから、「はあぁっ!?」と気付いたのでした。

>ちっちっち。"芸"ではありません、"藝"です"藝"!
これもさっき気付いて「は(ry

直しておきます。

# LV時計コピー 2013/01/23 11:28 http://shop.luxurybrandcopy.com/

大島がリーダーになってからAKBはそういうグループの色眼鏡で見られてる

タイトル
名前
Url
コメント