1:简单工厂模式
简单工厂模式我个人觉得就是为了让客户程序和类的对象分离,用户不在考虑去调用哪个方法,我只需要告诉你我的一些特征就可以调用相应的对象,以下用来自不同国籍的人来说明
a:如果现在做一个关于统计中国人,美国人,和日本人的一个功能,第一个我们考虑创建一个接口关于对人的基本操作
1publicinterfaceiperson2{3///<summary>4///添加5///</summary>6///<param name="person"></param>7///<returns></returns>8boolAdd(Person person);910///<summary>11///删除12///</summary>13///<param name="id"></param>14///<returns></returns>15boolDelete(stringid);1617///<summary>18///修改19///</summary>20///<param name="person"></param>21///<returns></returns>22boolUpdate(Person person);2324///<summary>25///获取26///</summary>27///<param name="id"></param>28///<returns></returns>29boolGet(stringid);30}
人行为的接口
b:定义一个来自不同国籍的枚举
1///<summary>2///表示国籍的枚举3///</summary>4publicenumNationality {5[Description("中国国籍")]6China =0,7[Description("美国国籍")]8America =1,9[Description("日本国籍")]10Japan =211}
定义枚举
c:实现接口类
1publicclassChinaPerson:IPerson {2PRivatereadonlystring_conn;34publicChinaPerson()5{6_conn = ConfigurationManager.ConnectionStrings["dblink"].ConnectionString;7}89publicboolAdd(Person person)10{11conststringsql ="insert into china(Id,UserName,RealName,Nationality,AddDate)values(@Id,@UserName,@RealName,@Nationality,@AddDate)";12varparameters =new[]13{14newMySQLParameter("@Id", person.Id),15newMySqlParameter("@UserName", person.UserName),16newMySqlParameter("@RealName", person.RealName),17newMySqlParameter("@Nationality",person.Nationality),18newMySqlParameter("@AddDate", person.AddDate)19};20returnMySqlHelper.ExecuteNonQuery(_conn, CommandType.Text, sql, parameters) >0;21}2223publicboolDelete(stringid)24{25conststringsql ="delete from china where Id=@id";26varparameters =new[]27{28newMySqlParameter("@Id", id)29};30returnMySqlHelper.ExecuteNonQuery(_conn, CommandType.Text, sql, parameters) >0;31}3233publicboolUpdate(Person person)34{35thrownewNotImplementedException();36}3738publicPerson Get(stringid)39{40conststringsql ="select * from china where Id=@Id";41varparameters =new[]42{43newMySqlParameter("@Id", id)44};45varmySqlHelper =newMySqlHelper(_conn);46vardateReader =mySqlHelper.ExecuteDataReader(CommandType.Text, sql, parameters);47varp=newPerson();48while(dateReader.Read())49{50p.Id = dateReader["Id"].ToString();51p.UserName = dateReader["UserName"].ToString();52p.Nationality = (Nationality)dateReader["Nationality"];53p.RealName = dateReader["RealName"].ToString();54}55returnp;56}57}
实现接口类
d:工厂根据客户端类型返回不同的实现对象
1publicclassSimpleFactory2{3publicstaticIPerson Create(Nationality nationality)4{5switch(nationality)6{7caseNationality.China:8returnnewChinaPerson();9
break;10caseNationality.America:11returnnewAmericaPerson();12
break;13caseNationality.Japan:14returnnewJapanPerson();15
break;16default:17thrownewException("参数不匹配,请验证");18
break;19}20}
工厂类
e:客户端调用
1//China2IPerson chinaPerson =SimpleFactory.Create(Nationality.China);3boolresult= chinaPerson.Add(newPerson4{5Id =Guid.NewGuid().ToString(),6UserName ="zs",7RealName ="张三",8Nationality =Nationality.China,9AddDate =DateTime.Now10});11if(result)12{13Console.WriteLine("添加成功");14}15varp = chinaPerson.Get("6a41924f-804b-4425-b5ab-19ab21311511");16Console.WriteLine(string.Format("我是{0},来自中国",p.RealName));1718//美国19IPerson americaPerson =SimpleFactory.Create(Nationality.America);20boolresult1 = americaPerson.Add(newPerson21{22Id =Guid.NewGuid().ToString(),23UserName ="ls",24RealName ="李四",25Nationality =Nationality.America,26AddDate =DateTime.Now27});28if(result1) {29Console.WriteLine("添加成功");30}31varperson = americaPerson.Get("91955e6d-c6cc-4a25-933f-243753d12b9a");32Console.WriteLine(string.Format("我是{0},来自美国", person.RealName));
客户端调用
f:查看效果
ok这整个过程就是一个简单工厂
注意事项:
1:建立简单工厂的时候我个人意见觉得参数最好是枚举或者写在配置文件中,这样的好处就是如果以后修改就改枚举或者配置文件即可。出错的概率会减小很多
优点:使用简单工厂符合低耦合的思想,让客户程序和具体实现对象分离,当修改具体实现对象的时候只需要在工厂中进行逻辑修改即可并不需要客户端去做修改。
缺点:并不符合开闭原则,因为当增加一个对象的时候就需要修改工厂,只要有修改就有可能影响现有项目的稳定性,同时如果有50个对象的时候可以switch 50 次这样就太多了。
2:工厂模式
工厂模式是在简单工厂模式的一种扩展,灵活性很强,当需要创建一个新的国籍的人的时候只需要添加并不用修改已有的代码,这样一来就会保证原先项目的稳定
先看一副简单的图
a:首先创建一个抽象的接口
1publicinterfaceIPerson2{3///<summary>4///添加5///</summary>6///<param name="person"></param>7///<returns></returns>8boolAdd(Person person);910///<summary>11///删除12///</summary>13///<param name="id"></param>14///<returns></returns>15boolDelete(stringid);1617///<summary>18///修改19///</summary>20///<param name="person"></param>21///<returns></returns>22boolUpdate(Person person);2324///<summary>25///获取26///</summary>27///<param name="id"></param>28///<returns></returns>29Person Get(stringid);30}
接口
b:然后在创建继承这个抽象接口的实体类
1///<summary>2///日本的工厂类3///</summary>4publicclassJapanFactory:IFactory {5publicIPerson Create()6{7returnnewJapanPerson();8}9}
日本工厂类
1///<summary>2///中国工厂类3///</summary>4publicclassChinaFactory:IFactory {5publicIPerson Create()6{7returnnewChinaPerson();8}9}
中国工厂类
c:在客户端调用
1//china2IFactory factory=newChinaFactory();3IPerson chinaPerson =factory.Create();4boolresult = chinaPerson.Add(newPerson {5Id =Guid.NewGuid().ToString(),6UserName ="zs",7RealName ="张三",8Nationality =Nationality.China,9AddDate =DateTime.Now10});11if(result) {12Console.WriteLine("中国 添加成功");13}1415//japan16IFactory factory1 =newChinaFactory();17IPerson japanPerson =factory.Create();18boolresult1 = japanPerson.Add(newPerson {19Id =Guid.NewGuid().ToString(),20UserName ="ls",21RealName ="李四",22Nationality =Nationality.America,23AddDate =DateTime.Now24});25if(result1) {26Console.WriteLine("日本 添加成功");27}
客户端
d:查看效果
优点:符合开闭原则,不需要修改已有的业务即可添加新的国籍的人,有很好的灵活性
缺点:需要创建更多的类(这个算不算)
上述两种模式在实际应用中可以联合使用以下关于工厂模式的一些总结
关于两种工厂模式的总结
用途:
1:工厂方法模式是一种轻量级模式,它实现了与应用特定模型的独立。客户只基于接口编程而让模式来解决其他问题
2:工厂模式有一个特殊的优点就是它能够连接起平行的类层次。
使用场景:
1:灵活性很重要
2:对象可以通过子类进行扩展
3:客户程序把职责委托给平行层次的子类