1:簡單工廠模式
簡單工廠模式我個人覺得就是為了讓客戶程序和類的對象分離,用戶不在考慮去調用哪個方法,我只需要告訴你我的一些特征就可以調用相應的對象,以下用來自不同國籍的人來說明
a:如果現在做一個關于統計中國人,美國人,和日本人的一個功能,第一個我們考慮創建一個接口關于對人的基本操作
1 public interface iperson 2 { 3 /// <summary> 4 /// 添加 5 /// </summary> 6 /// <param name="person"></param> 7 /// <returns></returns> 8 bool Add(Person person); 9 10 /// <summary>11 /// 刪除12 /// </summary>13 /// <param name="id"></param>14 /// <returns></returns>15 bool Delete(string id);16 17 /// <summary>18 /// 修改19 /// </summary>20 /// <param name="person"></param>21 /// <returns></returns>22 bool Update(Person person);23 24 /// <summary>25 /// 獲取26 /// </summary>27 /// <param name="id"></param>28 /// <returns></returns>29 bool Get(string id);30 }
b:定義一個來自不同國籍的枚舉
1 /// <summary> 2 /// 表示國籍的枚舉 3 /// </summary> 4 public enum Nationality { 5 [Description("中國國籍")] 6 China = 0, 7 [Description("美國國籍")] 8 America = 1, 9 [Description("日本國籍")]10 Japan = 211 }
c:實現接口類
1 public class ChinaPerson:IPerson { 2 PRivate readonly string _conn; 3 4 public ChinaPerson() 5 { 6 _conn = ConfigurationManager.ConnectionStrings["dblink"].ConnectionString; 7 } 8 9 public bool Add(Person person)10 {11 const string sql = "insert into china(Id,UserName,RealName,Nationality,AddDate)values(@Id,@UserName,@RealName,@Nationality,@AddDate)";12 var parameters = new[]13 {14 new MySQLParameter("@Id", person.Id),15 new MySqlParameter("@UserName", person.UserName),16 new MySqlParameter("@RealName", person.RealName),17 new MySqlParameter("@Nationality",person.Nationality), 18 new MySqlParameter("@AddDate", person.AddDate)19 };20 return MySqlHelper.ExecuteNonQuery(_conn, CommandType.Text, sql, parameters) > 0;21 }22 23 public bool Delete(string id)24 {25 const string sql = "delete from china where Id=@id";26 var parameters = new[]27 {28 new MySqlParameter("@Id", id)29 };30 return MySqlHelper.ExecuteNonQuery(_conn, CommandType.Text, sql, parameters) > 0;31 }32 33 public bool Update(Person person)34 {35 throw new NotImplementedException();36 }37 38 public Person Get(string id)39 {40 const string sql = "select * from china where Id=@Id";41 var parameters = new[]42 {43 new MySqlParameter("@Id", id)44 };45 var mySqlHelper = new MySqlHelper(_conn);46 var dateReader = mySqlHelper.ExecuteDataReader(CommandType.Text, sql, parameters);47 var p=new Person();48 while (dateReader.Read())49 {50 p.Id = dateReader["Id"].ToString();51 p.UserName = dateReader["UserName"].ToString();52 p.Nationality = (Nationality)dateReader["Nationality"];53 p.RealName = dateReader["RealName"].ToString();54 }55 return p;56 }57 }
d:工廠根據客戶端類型返回不同的實現對象
1 public class SimpleFactory 2 { 3 public static IPerson Create(Nationality nationality) 4 { 5 switch (nationality) 6 { 7 case Nationality.China: 8 return new ChinaPerson(); 9 break;10 case Nationality.America:11 return new AmericaPerson();12 break;13 case Nationality.Japan:14 return new JapanPerson();15 break;16 default:17 throw new Exception("參數不匹配,請驗證");18 break;19 }20 }
e:客戶端調用
1 //China 2 IPerson chinaPerson = SimpleFactory.Create(Nationality.China); 3 bool result= chinaPerson.Add(new Person 4 { 5 Id = Guid.NewGuid().ToString(), 6 UserName = "zs", 7 RealName = "張三", 8 Nationality = Nationality.China, 9 AddDate = DateTime.Now10 }); 11 if (result)12 {13 Console.WriteLine("添加成功");14 }15 var p = chinaPerson.Get("6a41924f-804b-4425-b5ab-19ab21311511");16 Console.WriteLine(string.Format("我是{0},來自中國",p.RealName));17 18 //美國19 IPerson americaPerson = SimpleFactory.Create(Nationality.America);20 bool result1 = americaPerson.Add(new Person21 {22 Id = Guid.NewGuid().ToString(),23 UserName = "ls",24 RealName = "李四",25 Nationality = Nationality.America,26 AddDate = DateTime.Now27 });28 if (result1) {29 Console.WriteLine("添加成功");30 }31 var person = americaPerson.Get("91955e6d-c6cc-4a25-933f-243753d12b9a");32 Console.WriteLine(string.Format("我是{0},來自美國", person.RealName));
f:查看效果
ok這整個過程就是一個簡單工廠
注意事項:
1:建立簡單工廠的時候我個人意見覺得參數最好是枚舉或者寫在配置文件中,這樣的好處就是如果以后修改就改枚舉或者配置文件即可。出錯的概率會減小很多
優點:使用簡單工廠符合低耦合的思想,讓客戶程序和具體實現對象分離,當修改具體實現對象的時候只需要在工廠中進行邏輯修改即可并不需要客戶端去做修改。
缺點:并不符合開閉原則,因為當增加一個對象的時候就需要修改工廠,只要有修改就有可能影響現有項目的穩定性,同時如果有50個對象的時候可以switch 50 次這樣就太多了。
2:工廠模式
工廠模式是在簡單工廠模式的一種擴展,靈活性很強,當需要創建一個新的國籍的人的時候只需要添加并不用修改已有的代碼,這樣一來就會保證原先項目的穩定
先看一副簡單的圖
a:首先創建一個抽象的接口
1 public interface IPerson 2 { 3 /// <summary> 4 /// 添加 5 /// </summary> 6 /// <param name="person"></param> 7 /// <returns></returns> 8 bool Add(Person person); 9 10 /// <summary>11 /// 刪除12 /// </summary>13 /// <param name="id"></param>14 /// <returns></returns>15 bool Delete(string id);16 17 /// <summary>18 /// 修改19 /// </summary>20 /// <param name="person"></param>21 /// <returns></returns>22 bool Update(Person person);23 24 /// <summary>25 /// 獲取26 /// </summary>27 /// <param name="id"></param>28 /// <returns></returns>29 Person Get(string id);30 }
b:然后在創建繼承這個抽象接口的實體類
1 /// <summary>2 /// 日本的工廠類3 /// </summary>4 public class JapanFactory:IFactory {5 public IPerson Create()6 {7 return new JapanPerson();8 }9 }
1 /// <summary>2 /// 中國工廠類3 /// </summary>4 public class ChinaFactory:IFactory {5 public IPerson Create()6 {7 return new ChinaPerson();8 }9 }
c:在客戶端調用
1 //china 2 IFactory factory=new ChinaFactory(); 3 IPerson chinaPerson = factory.Create(); 4 bool result = chinaPerson.Add(new Person { 5 Id = Guid.NewGuid().ToString(), 6 UserName = "zs", 7 RealName = "張三", 8 Nationality = Nationality.China, 9 AddDate = DateTime.Now10 });11 if (result) {12 Console.WriteLine("中國 添加成功");13 }14 15 //japan16 IFactory factory1 = new ChinaFactory();17 IPerson japanPerson = factory.Create();18 bool result1 = japanPerson.Add(new Person {19 Id = Guid.NewGuid().ToString(),20 UserName = "ls",21 RealName = "李四",22 Nationality = Nationality.America,23 AddDate = DateTime.Now24 });25 if (result1) {26 Console.WriteLine("日本 添加成功");27 }
d:查看效果
優點:符合開閉原則,不需要修改已有的業務即可添加新的國籍的人,有很好的靈活性
缺點:需要創建更多的類(這個算不算)
上述兩種模式在實際應用中可以聯合使用以下關于工廠模式的一些總結
關于兩種工廠模式的總結
用途:
1:工廠方法模式是一種輕量級模式,它實現了與應用特定模型的獨立。客戶只基于接口編程而讓模式來解決其他問題
2:工廠模式有一個特殊的優點就是它能夠連接起平行的類層次。
使用場景:
1:靈活性很重要
2:對象可以通過子類進行擴展
3:客戶程序把職責委托給平行層次的子類
新聞熱點
疑難解答