Factory (ファクトリー)
工場
Factoryパターンは、「工場」という名の通り、インスタンスを作り出すクラスを定義するパターンです。
このパターンを適用することにより、インスタンスの生成方法を気にすることなく使用することができるようになり、オブジェクト間の結合が"疎"になります。
まずはSimple Factoryからやっていきます。Simple Factoryは実際はデザインパターンではないそうですが、Factoryの簡単なイメージが得られると思います。
では、コードを示します。
- 具象クラスの元となるInterfaceを定義します。
public interface IObject
{
void Output();
}
Public Interface IObject
Sub Output()
End Interface
- 1.のInterfaceを継承して具象クラスを定義します。
public class HogeObject : IObject
{
#region IObject メンバ
public void Output()
{
Console.WriteLine("ほげ");
}
#endregion
}
public class FooObject : IObject
{
#region IObject メンバ
public void Output()
{
Console.WriteLine("ふー");
}
#endregion
}
Public Class HogeObject
Implements IObject
Public Sub Output() Implements IObject.Output
Console.WriteLine("ほげ")
End Sub
End Class
Public Class FooObject
Implements IObject
Public Sub Output() Implements IObject.Output
Console.WriteLine("ふー")
End Sub
End Class
- 文字列を引数とし、その値によってインスタンスを生成する具象クラスを切り替えるFactoryクラスを定義します。
public class SimpleFactory
{
public IObject CreateHoge(string objectName)
{
if ( objectName == "ほげ" )
{
return new HogeObject();
}
else if ( objectName == "ふー" )
{
return new FooObject();
}
else
{
throw new ArgumentException();
}
}
}
Public Class SimpleFactory
Public Function CreateObject(ByVal objectName As String) As IObject
If objectName = "ほげ" Then
Return New HogeObject()
ElseIf objectName = "ふー" Then
Return New FooObject()
Else
Throw New ArgumentException()
End If
End Function
End Class
- 3.のFactoryを使用するクラスを定義します。
public class Program
{
private static SimpleFactory _simpleFactory = new SimpleFactory();
public static void Main(string[] args)
{
IObject obj;
obj = _simpleFactory.CreateHoge("ほげ");
obj.Output();
obj = _simpleFactory.CreateHoge("ふー");
obj.Output();
Console.ReadLine();
}
}
Public Class Program
Private Shared _simpleFactory As New SimpleFactory()
Public Shared Sub Main(ByVal args As String())
Dim obj As IObject
obj = _simpleFactory.CreateObject("ほげ")
obj.Output()
obj = _simpleFactory.CreateObject("ふー")
obj.Output()
Console.ReadLine()
End Sub
End Class
実行結果
ほげ
ふー
こんな感じです。
んで、どこが利点かといいますと、仮に「ほげ」、「ふー」の他に「ばー」を追加しようとしたとしましょう。
public class BarObject : IObject
{
#region IObject メンバ
public void Output()
{
Console.WriteLine("ばー");
}
#endregion
}
Public Class BarObject
Implements IObject
Public Sub Output() Implements IObject.Output
Console.WriteLine("ばー")
End Sub
End Class
この際、Simple Factoryを用いている場合、Programクラスの変更は必要なく、SimpleFactoryクラスの変更だけで済みます。
public class SimpleFactory
{
public IObject CreateHoge(string objectName)
{
if ( objectName == "ほげ" )
{
return new HogeObject();
}
else if ( objectName == "ふー" )
{
return new FooObject();
}
else if ( objectName == "ばー" )
{
return new BarObject();
}
else
{
throw new ArgumentException();
}
}
}
Public Class SimpleFactory
Public Function CreateObject(ByVal objectName As String) As IObject
If objectName = "ほげ" Then
Return New HogeObject()
ElseIf objectName = "ふー" Then
Return New FooObject()
ElseIf objectName = "ばー" Then
Return New BarObject()
Else
Throw New ArgumentException()
End If
End Function
End Class
つまり、「処理のメインとなるクラスに変更を及ぼさない」設計が可能となります。そして、これは今後エントリにするFactory Methodパターン、Abstract Factoryパターンにも共通する特徴です。
次回はFactory Methodパターンについてまとめます。