デザインパターンのサンプルを掲載してます。このカテゴリの更新はかなり不定期です。
Simple Factoryパターン
このSimple Factoryパターンはよくプログラムで見かけるパターンです。
あまり難しくなく、使いどころも簡単に思いつくのでよく見かけます。

このパターンは、あるクラス(Factoryクラスとします)でインスタンスの
生成を行い、呼び出し元に返します。
ただ、このままだとFactoryクラスはどのクラスのインスタンスを生成して
よいか判断できません。判断条件となるデータは呼び出し元から受け取ります。

Factoryパターンの特徴としてはプログラムで直接new せず、クラスを介して間接的
にインスタンスを生成する点です。

利用例
データベースライブラリを例にします。
DataBaseが基本クラスで、MS-Access、SQLServer、Oracleが派生クラスです。
DB制御で必要となる、接続、解除、抽出、更新メソッドはDataBaseで定義しておき、
派生クラスで実装します。



まずはデザインパターンを使用しないときのサンプルコードです。
データベースはSQLServerを選択します。

デザインパターンを使わない
1
2
3
4
5
6
7
DataBase db = new SQLServer();

// データベースに接続します。
db.Open();

// データベース接続を解除します。
db.Close();

次は少しだけステップアップして、
動的にデータベースを切り替える場合のサンプルです。

デザインパターンを使わない2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
static void Main(string[] args)
{
    DataBase db = GetDataBaseInstance("MSAccess");
    
    // データベースに接続します。
    db.Open();

    // データベース接続を解除します。
    db.Close();
}

private static DataBase GetDataBaseInstance(string dbName)
{
    DataBase db = null;
    switch (dbName)
    {
        case "MSAccess":
            db = new MSAccess();
            break;
        case "SQLServer":
            db = new SQLServer();
            break;
        case "Oracle":
            db = new Oracle();
            break;
        default:
            db = new SQLServer();
            break;
    }
    return db;
}

GetDataBaseInstanceメソッドの引数の値によって使用するデータベースが
自由に選択できるようになりました。
次はデザインパターンのSimpleFactoryを使ってみます。




SimpleFactory.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
using System;
using System.Collections.Generic;
using System.Text;

namespace SimpleFactory
{
    public class SimpleFactory
    {
        public DataBase DataBaseFactory(string dbName)
        {
            switch (dbName)
            {
                case "MSAccess":
                    return new MSAccess();
                case "SQLServer":
                    return new SQLServer();
                case "Oracle":
                    return new Oracle();
            }
            return new SQLServer();
        }
    }
}

program.cs
1
2
3
4
5
6
7
8
9
10
11
static void Main(string[] args)
{
    SimpleFactory factory = new SimpleFactory();
    DataBase db = factory.DataBaseFactory("Oracle");
    
    // データベースに接続します。
    db.Open();

    // データベース接続を解除します。
    db.Close();
}

まず、SimpleFactoryクラスのインスタンスを生成しDataBaseFactoryメソッドを
介してOracleクラスのインスタンスを受け取ってます。


まとめ
デザインパターンを使うときと使わないときを比較すると、あまり違いが分かりません。
これがメリットなのかどうか私自身わかりませんが、、

複数のシステム、例えばA、B、C、Dシステムに同じようにライブラリを
使用したとします。デザインパターンを使わない場合は12〜31行目までの
GetDataBaseInstanceメソッドを各システムの中に実装しインスタンスを
生成する仕組みが必要となります。



Bシステムで扱うデータベースがPostgreSQLに変わったとします。
派生クラスPostgreSQLを作成し、BシステムのGetDataBaseInstanceメソッドに処理を
追加します。更にDシステムでもPostgreSQLに変えたとします。
ライブラリにはPostgreSQLクラスが用意されているので引数を"PostgreSQL"に変更して
実行します。GetDataBaseInstanceメソッドに処理を追加し忘れているので、
実行するとSQLServerクラスのインスタンスが返ってきます。



デザインパターンを使った場合は、PostgreSQLクラスとDataBaseFactoryメソッドを
1度だけ編集するだけで、DシステムのPostgreSQLに変更しても引数の"PostgreSQL"
だけでデータベースの切り替えが可能です。

ちょっとしたことですが、設計方法が違うだけで後々の改修やメンテナンスが
違ってきます。
この小さな積み重ねが設計スキルの 高い/低い の差となってくるのでしょうか。


Copyright (C) 2011 猫の気ままなC#日記