• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-91  評(píng)論-137  文章-0  trackbacks-0

            抽象工廠模式

            前序

            “這么晚才回來(lái),都11點(diǎn)了。”大鳥(niǎo)看著剛推門(mén)而入的小菜問(wèn)道。

            “嗨,沒(méi)辦法呀,工作忙。”小菜嘆氣說(shuō)道。

            “怎么會(huì)這么忙,加班有點(diǎn)過(guò)頭了呀。”

            “都是換數(shù)據(jù)庫(kù)惹的禍唄。”

            “怎么了?”

            “我本來(lái)寫(xiě)好了一個(gè)項(xiàng)目,是給一家企業(yè)做的電子商務(wù)網(wǎng)站,是用SQL Server作為數(shù)據(jù)庫(kù)的,應(yīng)該說(shuō)上限后除了開(kāi)始有些小問(wèn)題,基本都還可以。而后,公司截到另外一家公司類(lèi)似需求的項(xiàng)目,但這家公司想省錢(qián),租用了一個(gè)空間,只能用Access,不能用SQL Server,于是就要求我今天改造原來(lái)那個(gè)項(xiàng)目的代碼。”

            “哈哈,你的麻煩來(lái)了。”

            “是呀,那是相當(dāng)?shù)穆闊5_(kāi)始我覺(jué)得很簡(jiǎn)單呀,因?yàn)榈厍蛉硕贾溃?/span>SQL ServerAccessADO.NET上的使用是不同的。我以為只要做一個(gè)全體替換就可以了,哪知道,替換后,錯(cuò)誤百出。”

            “以后你還有的是班要加了。”

            “為什么?”

            “只要網(wǎng)站要維護(hù),比如修改或增加一些功能,你就得改兩個(gè)項(xiàng)目吧,至少在數(shù)據(jù)庫(kù)中做改動(dòng),響應(yīng)的程序代碼都要改,甚至和數(shù)據(jù)庫(kù)不想干的代碼也要改,你既然有兩個(gè)不同的版本,兩倍的工作量也是必然的。”

            “是呀,如果哪天要用Oracle數(shù)據(jù)庫(kù),估計(jì)我要改動(dòng)的地方更多了。”

            “那是當(dāng)然,OracleSQL語(yǔ)法與SQL Server的差別更大。你的改動(dòng)將是空前的。”

            最基本的數(shù)據(jù)訪問(wèn)程序

            “你先寫(xiě)一段你原來(lái)的數(shù)據(jù)庫(kù)訪問(wèn)的做法給我看看。”

            “那就用‘新增用戶’和‘得到用戶’為例吧。”

            #include <stdio.h>

             

            class User

            {

            public:

                   int id;

                   char* name;

            };

             

            class SqlserverUser

            {

            public:

                   void Insert(User* user)

                   {

                          printf("SQL Server中給User表添加一條記錄\n");

                   }

             

                   User* GetUser(int id)

                   {

                          printf("SQL Server中根據(jù)ID得到User表一條記錄\n");

                          return 0;

                   }

            };

             

            int main()

            {

                   User* user = new User();

                   SqlserverUser* su = new SqlserverUser();

                   su->Insert(user);

                   su->GetUser(1);

                   delete user;

                   delete su;

                   return 0;

            }

            “我最開(kāi)始就是這樣寫(xiě)的,非常簡(jiǎn)單。”

            “這里之所以不能換數(shù)據(jù)庫(kù),原因就在于SqlserverUser* su = new SqlserverUser();使得su這個(gè)對(duì)象被框死在SQL Server上了。如果這里是靈活的,專(zhuān)業(yè)點(diǎn)的說(shuō)法,是多態(tài)的,那么在執(zhí)行‘su->Insert(user);’和‘su->GetUser(1);’時(shí)就不用考慮是在用SQL Server還是在用Access了。”

            用工廠方法模式的數(shù)據(jù)訪問(wèn)程序

            #include <stdio.h>

             

            class User

            {

            public:

                   int id;

                   char* name;

            };

             

            class IUser

            {

            public:

                   virtual void Insert(User* user)=0;

                   virtual User* GetUser(int id)=0;

            };

             

            class SqlserverUser : public IUser

            {

            public:

                   virtual void Insert(User* user)

                   {

                          printf("SQL Server中給User表添加一條記錄\n");

                   }

             

                   virtual User* GetUser(int id)

                   {

                          printf("SQL Server中根據(jù)ID得到User表一條記錄\n");

                          return 0;

                   }

            };

             

            class AccessUser : public IUser

            {

            public:

                   virtual void Insert(User* user)

                   {

                          printf("Access中給User表添加一條記錄\n");

                   }

             

                   virtual User* GetUser(int id)

                   {

                          printf("Access中根據(jù)ID得到User表一條記錄\n");

                          return 0;

                   }

            };

             

            class IFactory

            {

            public:

                   virtual IUser* CreateUser()=0;

            };

             

            class SqlServerFactory : public IFactory

            {

            public:

                   virtual IUser* CreateUser()

                   {

                          return new SqlserverUser();

                   }

            };

             

            class AccessFactory : public IFactory

            {

            public:

                   virtual IUser* CreateUser()

                   {

                          return new AccessUser();

                   }

            };

             

            int main()

            {

                   User* user = new User();

                   IFactory* factory = new SqlServerFactory();

                   IUser* iu = factory->CreateUser();

                   iu->Insert(user);

                   iu->GetUser(1);

                   delete user;

                   delete factory;

                   delete iu;

                   return 0;

            }

            “非常好。現(xiàn)在如果要換數(shù)據(jù)庫(kù),只需要把new SqlServerFactory()改成new AccessFactory(),此時(shí)由于多態(tài)的關(guān)系,使得聲明IUser接口的對(duì)象iu實(shí)現(xiàn)根本不知道是在訪問(wèn)哪個(gè)數(shù)據(jù)庫(kù),卻可以在運(yùn)行時(shí)很好的完成工作,這就是所謂的業(yè)務(wù)邏輯與數(shù)據(jù)訪問(wèn)的解耦。”

            “但是,大鳥(niǎo),這樣寫(xiě),代碼里還是有指明‘new SqlServerFactory()’呀,我要改的地方,依然很多。”

            “這個(gè)先不急,待會(huì)再說(shuō),問(wèn)題沒(méi)有完全解決,你的數(shù)據(jù)庫(kù)里不可能只有一個(gè)User表吧,很可能有其他表,比如增加部門(mén)表(Department),此時(shí)如何辦呢?”

            抽象工廠模式

            客戶類(lèi)和工廠類(lèi)分開(kāi)。消費(fèi)者任何時(shí)候需要某套產(chǎn)品集合時(shí),只需向抽象工廠請(qǐng)求即可。抽象工廠會(huì)再向具體的工廠生產(chǎn)出符合產(chǎn)品集規(guī)格的產(chǎn)品。

            實(shí)現(xiàn)方式(UML類(lèi)圖)


            實(shí)現(xiàn)代碼

            #include <stdio.h>

             

            class User

            {

            public:

                   int id;

                   char* name;

            };

             

            class Department

            {

            public:

                   int id;

                   char* deptname;

            };

             

            // User表接口

            class IUser

            {

            public:

                   virtual void Insert(User* user)=0;

                   virtual User* GetUser(int id)=0;

            };

             

            // Department表接口

            class IDepartment

            {

            public:

                   virtual void Insert(Department* department)=0;

                   virtual Department* GetDepartment(int id)=0;

            };

             

            class SqlserverUser : public IUser

            {

            public:

                   virtual void Insert(User* user)

                   {

                          printf("SQL Server中給User表添加一條記錄\n");

                   }

             

                   virtual User* GetUser(int id)

                   {

                          printf("SQL Server中根據(jù)ID得到User表一條記錄\n");

                          return 0;

                   }

            };

             

            class AccessUser : public IUser

            {

            public:

                   virtual void Insert(User* user)

                   {

                          printf("Access中給User表添加一條記錄\n");

                   }

             

                   virtual User* GetUser(int id)

                   {

                          printf("Access中根據(jù)ID得到User表一條記錄\n");

                          return 0;

                   }

            };

             

            class SqlserverDepartment : public IDepartment

            {

            public:

                   virtual void Insert(Department* department)

                   {

                          printf("SQL Server中給Department表增加一條記錄\n");

                   }

                  

                   virtual Department* GetDepartment(int id)

                   {

                          printf("SQL Server中根據(jù)ID得到Department表一條記錄\n");

                          return 0;

                   }

            };

             

            class AccessDepartment : public IDepartment

            {

            public:

                   virtual void Insert(Department* department)

                   {

                          printf("Access中給Department表增加一條記錄\n");

                   }

                  

                   virtual Department* GetDepartment(int id)

                   {

                          printf("Access中根據(jù)ID得到Department表一條記錄\n");

                          return 0;

                   }

            };

             

            // IFactory接口

            class IFactory

            {

            public:

                   virtual IUser* CreateUser()=0;

                   virtual IDepartment* CreateDepartment()=0;

            };

             

            class SqlServerFactory : public IFactory

            {

            public:

                   virtual IUser* CreateUser()

                   {

                          return new SqlserverUser();

                   }

                  

                   virtual IDepartment* CreateDepartment()

                   {

                          return new SqlserverDepartment();

                   }

            };

             

            class AccessFactory : public IFactory

            {

            public:

                   virtual IUser* CreateUser()

                   {

                          return new AccessUser();

                   }

                  

                   virtual IDepartment* CreateDepartment()

                   {

                          return new AccessDepartment();

                   }

            };

             

            int main()

            {

                   User* user = new User();

                   Department* dept = new Department();

                  

                   IFactory* factory = new AccessFactory();

                  

                   IUser* iu = factory->CreateUser();

                   iu->Insert(user);

                   iu->GetUser(1);

                  

                   IDepartment* id = factory->CreateDepartment();

                   id->Insert(dept);

                   id->GetDepartment(1);

                  

                   delete user;

                   delete dept;

                   delete factory;

                   delete iu;

                   delete id;

                   return 0;

            }

            運(yùn)行結(jié)果



            所有文件打包下載

            posted on 2011-06-26 22:19 lwch 閱讀(3386) 評(píng)論(2)  編輯 收藏 引用 所屬分類(lèi): 設(shè)計(jì)模式

            評(píng)論:
            # re: 抽象工廠模式 2012-11-06 17:14 | 。。。
            沒(méi)有反射啊,后面的反射沒(méi)有講  回復(fù)  更多評(píng)論
              
            # re: 抽象工廠模式 2012-11-07 14:05 | lwch
            @。。。
            C++有辦法實(shí)現(xiàn)反射嗎?  回復(fù)  更多評(píng)論
              
            久久99精品久久久久久hb无码| 国产午夜精品久久久久九九电影| 久久精品国产99久久久古代| 久久综合九色综合网站| 国产一级持黄大片99久久| 久久精品国产黑森林| 久久综合88熟人妻| 国产精品久久久久久五月尺| WWW婷婷AV久久久影片| 亚洲精品国精品久久99热| 亚洲国产精品无码久久久不卡| 久久99精品久久久久久野外| 人妻少妇久久中文字幕一区二区| 久久久久久噜噜精品免费直播| 色婷婷综合久久久久中文| 日韩AV毛片精品久久久| 婷婷久久综合九色综合98| 丁香色欲久久久久久综合网| 久久九九久精品国产| 66精品综合久久久久久久| 久久青青草原亚洲av无码app | 国产精品久久国产精品99盘| 波多野结衣久久一区二区| 51久久夜色精品国产| 99久久精品免费看国产免费| 99久久精品国内| 久久国产精品久久久| 热re99久久精品国99热| 久久中文骚妇内射| 精品久久久久久无码专区不卡| 色综合久久无码五十路人妻| 日韩精品久久久久久免费| 99久久精品国产一区二区| 思思久久99热只有频精品66| 久久人人爽人人爽人人片AV不 | 久久人人爽人人爽人人片AV东京热| 久久精品免费大片国产大片| 日日狠狠久久偷偷色综合免费| 国产精品99久久精品爆乳| 无码国内精品久久人妻麻豆按摩| 四虎影视久久久免费观看|