设计模式-工厂模式
2018-06-17 21:02:44来源:未知 阅读 ()
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 = 2 11 }
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.Now 10 }); 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 Person 21 { 22 Id = Guid.NewGuid().ToString(), 23 UserName = "ls", 24 RealName = "李四", 25 Nationality = Nationality.America, 26 AddDate = DateTime.Now 27 }); 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.Now 10 }); 11 if (result) { 12 Console.WriteLine("中国 添加成功"); 13 } 14 15 //japan 16 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.Now 24 }); 25 if (result1) { 26 Console.WriteLine("日本 添加成功"); 27 }
d:查看效果
优点:符合开闭原则,不需要修改已有的业务即可添加新的国籍的人,有很好的灵活性
缺点:需要创建更多的类(这个算不算)
上述两种模式在实际应用中可以联合使用以下关于工厂模式的一些总结
关于两种工厂模式的总结
用途:
1:工厂方法模式是一种轻量级模式,它实现了与应用特定模型的独立。客户只基于接口编程而让模式来解决其他问题
2:工厂模式有一个特殊的优点就是它能够连接起平行的类层次。
使用场景:
1:灵活性很重要
2:对象可以通过子类进行扩展
3:客户程序把职责委托给平行层次的子类
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:java之log4j的配置
下一篇:.NET笔记(一)
- PHP常用的五种设计模式及应用场景,来了解下 2019-08-23
- PHP设计模式学习下 2019-08-09
- MySQL的sql_mode模式说明及设置 2019-07-24
- php - tcp 粘包/拆包实例 2019-07-24
- Nginx+PHP+FastCGI加速模式 2019-06-14
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash