C#設計模式之簡單工廠篇

C#設計模式之簡單工廠篇
大雜燴-.NET

<script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"> </script>

案例】公司準備開發一套產品訂單系統,客戶強烈要求該系統能適應不同的數據庫,即能讓客戶十分方便的決定到底是用SqlServer數據庫還是Oracle數據庫,或者其它數據庫,而且數據庫切換應該簡單,決不能讓客戶麻煩得手忙腳亂。

 

遇到這種情況,最愚蠢的辦法就是開發不同數據庫版本的系統,即一套SqlServer版的訂單系統,一套Oracle版的訂單系統,但要真是這樣乾的話,我相信項目經理一定會獲得千古蠢名。

 

 

 

“具體情況具體分析”,此時如果設計模式運用得恰到好處,省時、省力的高效軟件工程就會立馬出爐,且看我如何過招。

UML圖如下:

 

 

 

首先定義一個接口,具體名爲Idatabase,在這個接口中,定義好數據庫操作的方法名和參數,以及返回值,本案例中我定義如下方法:

 

public interface IDatabase

 

{

 

    bool Connect(string ConnectString);

 

    bool Open();

 

    bool Command(string SQL);

 

    void Close();

 

}

 

重要提醒:“接口一生唯謹慎,定義大事不糊塗”,編寫接口時一定要考慮周全,並對參數、返回值進行反覆推敲,爲什麼?因爲所有的實現類都是要根據該接口的規範進行代碼具體編寫,也即接口的定義是公用的,一旦改動了接口,後果就是所有的實現類也都必須相應調整。

 

 

 

然後就是編寫具體的實現類了,客戶要求多少不同類型的數據庫,你就定義多少個Idatabase的實現類,雖然工作量大了點,可當你看到客戶滿意的笑容時,你心裏也就會有一種由衷的幸福感,好了,SqlServer實現類代碼如下:

 

public class SqlServer : IDatabase

 

    {

 

        SqlConnection conn;

 

        SqlCommand command;

 

 

 

        public bool Connect(string ConnectString)

 

        {

 

            try

 

            {

 

                conn = new SqlConnection(ConnectString);

 

                return true;

 

            }

 

            catch(SqlException)

 

            {

 

                return false;

 

            }

 

           

 

        }

 

 

 

        public bool Open()

 

        {

 

            try

 

            {

 

                conn.Open();

 

                return true;

 

            }

 

            catch(SqlException)

 

            {

 

                return false;

 

            }

 

        }

 

 

 

        public bool Command(string SQL)

 

        {

 

            try

 

            {

 

                command = new SqlCommand(SQL,conn);

 

                command.ExecuteNonQuery();

 

                return true;

 

            }

 

            catch(SqlException)

 

            {

 

                return false;

 

            }

 

        }

 

 

 

        public void Close()

 

        {

 

            conn.Close();

 

            conn.Dispose();

 

        }

 

    }

 

 

 

呵呵,有點長,咬着牙讀完,心裏明白了就會很舒服的,如果你現在有這種感覺了,好,再接再厲,再爲Oracle實現類編寫具體代碼吧,依葫蘆畫瓢,大家有空就畫一下吧,我就畫個雛形了:

 

public class Oracle : IDatabase

 

    {

 

        public Oracle()

 

        {          

 

        }

 

 

 

        public bool Connect(string ConnectString)

 

        {

 

            return true;

 

        }

 

 

 

        public bool Open()

 

        {

 

            return true;

 

        }

 

 

 

        public bool Command(string SQL)

 

        {

 

            return true;

 

        }

 

 

 

        public void Close()

 

        {

 

 

 

        }

 

    }

 

 

 

嗯,不錯,你有多少種數據庫就編寫不同的實現類代碼吧,這裏就不贅述了,接下來呢?聰明的讀者一定會想到這個問題:這個接口和這麼多的實現類怎麼用啊?我們再定義一個稱之爲工廠的類,由它來決定選用哪種數據庫爲進行操作,這個類比較簡單:

 

public class Factory

 

    {

 

        public static IDatabase SelectDatabase(string DatabaseType)

 

        {

 

            switch(DatabaseType)

 

            {

 

                case "SqlServer":

 

                    return new SqlServer();                  

 

                case "Oracle":

 

                    return new Oracle();

 

                default:

 

                    return new SqlServer();

 

            }

 

        }

 

    }

 

看明白了嗎?好了,我們該讓尊敬的、永遠高貴的客戶出場了,只有他,唯有他纔有決定用哪種數據庫的最高權限,你看,他這樣用:

 

public class Client

 

    {

 

        public static void Main()

 

        {

 

            //Get the database information from Web.Config.

 

            string DBType = ConfigurationSettings.AppSettings["DBType"];

 

            string DBConnectString = ConfigurationSettings.AppSettings["DBConn"];                                 

 

 

 

            IDatabase DB = Factory.SelectDatabase(DBType);

 

 

 

            //Connect the selected database.

 

            if(DB.Connect(DBConnectString)==false)

 

            {

 

                Console.WriteLine("The database {0} can't be connected.",DBType);

 

                return;

 

            }

 

 

 

            //Open database.

 

            if(DB.Open()==false)

 

            {

 

                Console.WriteLine("The database {0} can't be opened, the connect string is {1}.",DBType,DBConnectString);

 

                return;

 

            }

 

 

 

            //Execute SQL Command.

 

            string SQL = "update Order set price = price * 0.07 where productID = '002'";           

 

            if(DB.Command(SQL))

 

            {

 

                //Do something...             

 

            }

 

            else

 

            {

 

                Console.WriteLine("The Operator is not success. SQL statament is {0}",SQL);

 

                DB.Close();

 

                return;

 

            }

 

 

 

            DB.Close();

 

        }

 

    }

 

 

 

好了,工程峻工了,你們明白了沒有?

 

思考題:簡單工廠的應用場合和侷限性?

 

作業題:假如要開發一個多媒體播放器,既能用Window MediaPlayer播放,又能用RealPlayer播放,還能用QuickTime播放,具體用什麼播放器,由客戶選擇,請你畫出UML圖並寫出代碼。  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發佈了49 篇原創文章 · 獲贊 1 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章