一、模式描述
?我的程序中有需要一系列的對象,比如我們要吃一碗米飯(Rice),要喝一杯咖啡(Coffee)......,要想利用他們,我們就必須在程序中根據用戶要求,然后一個個調用 new 操作符來生成他們,這樣客戶程序就要知道相應的類的信息,生成的代碼顯然不夠靈活。那么我們可以在代碼中不利用具體的類,而只是說明我們需要什么,然后就能夠得到我們想要的對象呢?
這當然是可以的,根據GOF在《設計模式》一書里介紹,要創建對象這樣的工作應該是屬于創建型模式完成的。熟悉各種設計模式意圖的朋友就會很快得出結 論:“提供一個創建一系列相關或相互依賴對象的接口,而無需指定它們具體的類”,至少“無需指定它們具體的類”符合我們的要求。OK,這就是抽象工廠模式 的意圖。
二、模式意圖
提供一個創建一系列相關或相互依賴對象的接口,而不需指定他們具體的類。
三、模式UML圖:
四、模式參與者
抽象工廠(Abstract Factory)角色:擔任這個角色的是工廠方法模式的核心,它是與應用系統商業邏輯無關的。
具體工廠(Concrete Factory)角色:這個角色直接在客戶端的調用下創建產品的實例。這個角色含有選擇合適的產品對象的邏輯,而這個邏輯是與應用系統的商業邏輯緊密相關的。
抽象產品(Abstract Product)角色:擔任這個角色的類是工廠方法模式所創建的對象的父類,或它們共同擁有的接口。
具體產品(Concrete Product)角色:抽象工廠模式所創建的任何產品對象都是某一個具體產品類的實例。這是客戶端最終需要的東西,其內部一定充滿了應用系統的商業邏輯。
五、模式與反射
?利用設計模式可以使我們的代碼更靈活,更容易擴展,更容易維護。各種面向對象的程序設計語言都提供了基本相同的機制:比如類、繼承、派生、多態等等。但是又有各自的特色,C# 中的反射機制便是一個很重要的工具,好好地利用就可以在實際中發揮很大的作用。
?反射是.NET Framework中的一個非常重要的特性。相信絕大多數的朋友都對其有所了解或是已經熟練的應用這項技術。 我們需要根據需求去動態的創建一對象的實例,在程序設計中,通常我們會為了解耦合,把接口的實現對象寫入配置文件,讓工廠自己去一個特定的地方(配置文 件)找他應該要實例化的對象(接口的實現對象),通過這樣來實現“依賴注入(Dependency Injection)”。
本來“依賴注入”需要專門的IOC容器提供,比如Spring.net,Castle這類似的框架產品。而在抽象工廠模式的應用中顯然沒有這么麻煩,通常的實現就是使用.NET技術‘反射’就可以了。下面是反射的兩種常見應用:
應用一:
Activator.CreateInstance("類型");
應用二:
Assembly.Load("程序集名稱").CreateInstance("命名空間.類名稱");
六、抽象工廠的簡單實現
Entity Code
1namespace DesignPattern.AbstractFactory
2{
3 public class User
4 {
5 private int _id;
6 public int Id
7 {
8 get { return _id; }
9 set { _id = value; }
10 }
11
12 private string _name;
13 public string Name
14 {
15 get { return _name; }
16 set { _name = value; }
17 }
18
19 private string _age;
20 public string Age
21 {
22 get { return _age; }
23 set { _age = value; }
24 }
25
26 public User()
27 { }
28
29 public User(int id, string name, string age)
30 {
31 _id = id;
32 _name = name;
33 _age = age;
34 }
35 }
36}
37----------------------------------------------------------------------
38namespace DesignPattern.AbstractFactory
39{
40 public class News
41 {
42 private int _id;
43 public int Id
44 {
45 get { return _id; }
46 set { _id = value; }
47 }
48
49 private string _title;
50 public string Title
51 {
52 get { return _title; }
53 set { _title = value; }
54 }
55
56 private string _context;
57 public string Context
58 {
59 get { return _context; }
60 set { _context = value; }
61 }
62
63 private string _author;
64 public string Author
65 {
66 get { return _author; }
67 set { _author = value; }
68 }
69
70 public News()
71 { }
72
73 public News(int id, string title, string context, string author)
74 {
75 _id = id;
76 _title = title;
77 _context = context;
78 _author = author;
79 }
80 }
81}
82
1namespace DesignPattern.AbstractFactory
2{
3 /**//// <summary>
4 /// 抽象產品角色
5 /// </summary>
6 public interface INews
7 {
8 void Insert(News news);
9 News QueryById(int newsId);
10 }
11
12 /**//// <summary>
13 /// 具體產品角色
14 /// </summary>
15 public class NewsSql:INews
16 {
17 public void Insert(News news)
18 {
19 Console.WriteLine("插入新聞到SQL數據庫");
20 }
21
22 public News QueryById(int newsId)
23 {
24 return new News(1, "Hello", " Hello C#!", "beniao");
25 }
26 }
27
28 /**//// <summary>
29 /// 具體產品角色
30 /// </summary>
31 public class NewsAccess : INews
32 {
33 public void Insert(News news)
34 {
35 Console.WriteLine("插入新聞到Access數據庫");
36 }
37
38 public News QueryById(int newsId)
39 {
40 return new News(1, "Hello", " Hello C#!", "beniao");
41 }
42 }
43}
1namespace DesignPattern.AbstractFactory
2{
3 /**//// <summary>
4 /// 抽象產品角色
5 /// </summary>
6 public interface IUser
7 {
8 void Insert(User user);
9 User QueryById(int userId);
10 }
11
12 /**//// <summary>
13 /// 具體產品角色
14 /// </summary>
15 public class UserSql:IUser
16 {
17 public void Insert(User user)
18 {
19 Console.WriteLine("Insert SQL OK!");
20 }
21
22 public User QueryById(int userId)
23 {
24 return new User(1, "beniao", "22");
25 }
26 }
27
28 /**//// <summary>
29 /// 具體產品角色
30 /// </summary>
31 public class UserAccess : IUser
32 {
33 public void Insert(User user)
34 {
35 Console.WriteLine("Insert Access OK!");
36 }
37
38 public User QueryById(int userId)
39 {
40 return new User(2, "beniao", "23");
41 }
42 }
43}
1namespace DesignPattern.AbstractFactory
2{
3 /**//// <summary>
4 /// 工廠角色(根據配置文件來確定創建何種對象)
5 /// </summary>
6 public class DataAccess
7 {
8 public static IUser CreateUser()
9 {
10 string obj = ConfigurationManager.AppSettings["usersql"];
11 return (IUser)Assembly.Load("DesignPattern.AbstractFactory").CreateInstance(obj);
12 }
13
14 public static INews CreateNews()
15 {
16 string obj = ConfigurationManager.AppSettings["newssql"];
17 return (INews)Assembly.Load("DesignPattern.AbstractFactory").CreateInstance(obj);
18 }
19 }
20***********************************************************************************
21 /**//// <summary>
22 /// 如果根據GOF的定義及UML圖,此為抽象工廠角色
23 /// </summary>
24 public class Factory
25 {
26 public virtual IUser CreateUser()
27 {
28 return null;
29 }
30
31 public virtual INews CreateNews()
32 {
33 return null;
34 }
35 }
36
37 /**//// <summary>
38 /// 具體的工廠角色
39 /// </summary>
40 public class SqlFactory:Factory
41 {
42 public override IUser CreateUser()
43 {
44 string obj = ConfigurationManager.AppSettings["usersql"];
45 return (IUser)Assembly.Load("DesignPattern.AbstractFactory").CreateInstance(obj);
46 }
47
48 public override INews CreateNews()
49 {
50 string obj = ConfigurationManager.AppSettings["newssql"];
51 return (INews)Assembly.Load("DesignPattern.AbstractFactory").CreateInstance(obj);
52 }
53 }
54
55 /**//// <summary>
56 /// 具體的工廠角色
57 /// </summary>
58 public class AccessFactory : Factory
59 {
60 public override IUser CreateUser()
61 {
62 string obj = ConfigurationManager.AppSettings["useracc"];
63 return (IUser)Assembly.Load("DesignPattern.AbstractFactory").CreateInstance(obj);
64 }
65
66 public override INews CreateNews()
67 {
68 string obj = ConfigurationManager.AppSettings["newsacc"];
69 return (INews)Assembly.Load("DesignPattern.AbstractFactory").CreateInstance(obj);
70 }
71 }
72}
1namespace DesignPattern.AbstractFactory
2{
3 class Program
4 {
5 static void Main(string[] args)
6 {
7 IUser user = DataAccess.CreateUser();
8 user.Insert(null);
9
10 INews news = DataAccess.CreateNews();
11 news.Insert(null);
12
13 //******************GOF************************
14
15 Factory factory = new SqlFactory();
16 factory.CreateNews().Insert(null);
17 factory.CreateUser().Insert(null);
18
19 factory = new AccessFactory();
20 factory.CreateNews().Insert(null);
21 factory.CreateUser().Insert(null);
22 }
23 }
24}
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
