• <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  評論-137  文章-0  trackbacks-0

            抽象工廠模式

            前序

            “這么晚才回來,都11點了。”大鳥看著剛推門而入的小菜問道。

            “嗨,沒辦法呀,工作忙。”小菜嘆氣說道。

            “怎么會這么忙,加班有點過頭了呀。”

            “都是換數據庫惹的禍唄。”

            “怎么了?”

            “我本來寫好了一個項目,是給一家企業做的電子商務網站,是用SQL Server作為數據庫的,應該說上限后除了開始有些小問題,基本都還可以。而后,公司截到另外一家公司類似需求的項目,但這家公司想省錢,租用了一個空間,只能用Access,不能用SQL Server,于是就要求我今天改造原來那個項目的代碼。”

            “哈哈,你的麻煩來了。”

            “是呀,那是相當的麻煩。但開始我覺得很簡單呀,因為地球人都知道,SQL ServerAccessADO.NET上的使用是不同的。我以為只要做一個全體替換就可以了,哪知道,替換后,錯誤百出。”

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

            “為什么?”

            “只要網站要維護,比如修改或增加一些功能,你就得改兩個項目吧,至少在數據庫中做改動,響應的程序代碼都要改,甚至和數據庫不想干的代碼也要改,你既然有兩個不同的版本,兩倍的工作量也是必然的。”

            “是呀,如果哪天要用Oracle數據庫,估計我要改動的地方更多了。”

            “那是當然,OracleSQL語法與SQL Server的差別更大。你的改動將是空前的。”

            最基本的數據訪問程序

            “你先寫一段你原來的數據庫訪問的做法給我看看。”

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

            #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中根據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;

            }

            “我最開始就是這樣寫的,非常簡單。”

            “這里之所以不能換數據庫,原因就在于SqlserverUser* su = new SqlserverUser();使得su這個對象被框死在SQL Server上了。如果這里是靈活的,專業點的說法,是多態的,那么在執行‘su->Insert(user);’和‘su->GetUser(1);’時就不用考慮是在用SQL Server還是在用Access了。”

            用工廠方法模式的數據訪問程序

            #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中根據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中根據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;

            }

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

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

            “這個先不急,待會再說,問題沒有完全解決,你的數據庫里不可能只有一個User表吧,很可能有其他表,比如增加部門表(Department),此時如何辦呢?”

            抽象工廠模式

            客戶類和工廠類分開。消費者任何時候需要某套產品集合時,只需向抽象工廠請求即可。抽象工廠會再向具體的工廠生產出符合產品集規格的產品。

            實現方式(UML類圖)


            實現代碼

            #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中根據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中根據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中根據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中根據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;

            }

            運行結果



            所有文件打包下載

            posted on 2011-06-26 22:19 lwch 閱讀(3351) 評論(2)  編輯 收藏 引用 所屬分類: 設計模式

            評論:
            # re: 抽象工廠模式 2012-11-06 17:14 | 。。。
            沒有反射啊,后面的反射沒有講  回復  更多評論
              
            # re: 抽象工廠模式 2012-11-07 14:05 | lwch
            @。。。
            C++有辦法實現反射嗎?  回復  更多評論
              
            久久国产AVJUST麻豆| 欧美粉嫩小泬久久久久久久| 亚洲精品无码专区久久同性男 | 久久噜噜电影你懂的| 国内精品九九久久久精品| 婷婷伊人久久大香线蕉AV| 久久久久久久综合日本亚洲| 狠狠色伊人久久精品综合网| 久久国产精品国语对白| 亚洲精品无码久久久久| 成人综合伊人五月婷久久| 国产精品综合久久第一页| 国产精品久久久久久久app| 99久久99久久精品免费看蜜桃| 国产精品99久久久久久猫咪| 久久笫一福利免费导航 | 91精品国产91热久久久久福利| 久久精品成人免费观看97| 久久天天躁狠狠躁夜夜avapp| 99久久99久久精品免费看蜜桃| 人妻少妇精品久久| 国产一区二区精品久久| 中文字幕乱码久久午夜| 狠狠久久综合| 久久久久久免费一区二区三区 | 精品熟女少妇aⅴ免费久久| 久久人人爽人人爽人人AV东京热| 青青青伊人色综合久久| 亚洲午夜久久久久久久久电影网| 色99久久久久高潮综合影院 | 国产精品久久久久a影院| 狠狠人妻久久久久久综合| 久久精品国产91久久综合麻豆自制| 久久亚洲AV无码西西人体| 99久久精品费精品国产 | 亚洲色欲久久久综合网东京热| 亚洲国产精品成人久久蜜臀 | 国产V亚洲V天堂无码久久久| 无码人妻久久一区二区三区免费丨| 精品人妻伦九区久久AAA片69| 激情五月综合综合久久69|