创建一个工厂类,里面写方法负责创建对象。提供创建实例的功能,而无需关心具体实现。锅是由调用者和工厂一起负责的。
由于如果创建一个对象,不单是工厂类内部的问题,调用者往里面传入信息了,所以一旦出现问题是双方的问题。他解耦的结果是虽然锅没彻底甩出去,但是找了一个一起背锅的。
类关系图如下:
产品接口:
packagecreate.simplefactory;publicinterfaceFood{publicvoidcook();}具体产品1:
packagecreate.simplefactory;publicclassJiucaijidanimplementsFood{publicvoidcook(){System.out.println("韭菜鸡蛋做好了");}}具体产品2:
packagecreate.simplefactory;publicclassXihongshijidanimplementsFood{publicvoidcook(){System.out.println("西红柿鸡蛋做好了");}}工厂类:
packagecreate.simplefactory;publicclassFoodFactory{publicFoodcreateByName(Stringname){if("Jiucaijidan".equals(name)){returnnewJiucaijidan();}elseif("Xihongshijidan".equals(name)){returnnewXihongshijidan();}returnnull;}publicFoodcreateByClassname(Stringname){try{if(name!=null&&!"".equals(name)){return(Food)Class.forName(name).newInstance();}}catch(Exceptione){e.printStackTrace();}returnnull;}publicFoodcreateByClass(Class
packagecreate.simplefactory;publicclassTest{publicstaticvoidmain(String[]args){Foodf1=newFoodFactory().createByName("Jiucaijidan");f1.cook();Foodf2=newFoodFactory().createByClassname("create.simplefactory.Xihongshijidan");f2.cook();Foodf3=newFoodFactory().createByClass(Xihongshijidan.class);f3.cook();}}
二、工厂模式
关系图如下:
packagecreate.factory;publicinterfaceFood{publicvoidcook();}具体产品1:
packagecreate.factory;publicclassJiucaijidanimplementsFood{publicvoidcook(){System.out.println("韭菜鸡蛋做好了");}}具体产品2:
packagecreate.factory;publicclassXihongshijidanimplementsFood{publicvoidcook(){System.out.println("西红柿鸡蛋做好了");}}工厂接口:
packagecreate.factory;publicinterfaceFoodFactory{publicFoodcreate();}具体工厂1:
packagecreate.factory;publicclassJiucaiFactoryimplementsFoodFactory{publicFoodcreate(){returnnewJiucaijidan();}}具体工厂2:
packagecreate.factory;publicclassXihongshiFactoryimplementsFoodFactory{publicFoodcreate(){returnnewXihongshijidan();}}测试类:
packagecreate.factory;publicclassTest{publicstaticvoidmain(String[]args){FoodFactoryff1=newXihongshiFactory();FoodFactoryff2=newJiucaiFactory();Foodf1=ff1.create();Foodf2=ff2.create();f1.cook();f2.cook();}}
三、抽象工厂模式
考虑工厂的出现,将里面的简单工厂用工厂替换,就是抽象工厂。而且可以出现多级抽象工厂。
如果工厂进行背锅,里面有一些质量好的工厂就会有意见,所以内部分裂了,内部进行甩锅,就是抽象工厂。工厂总接口越稳定、内部背锅规则越详细,那么甩锅的设计就更完善、这个抽象工厂越成功。
关系图如下(只是其中一种展现方式):
具体产品1:
packagecreate.abstractfactory;publicclassXiangyouJiucaijidanimplementsCondiment,Food{@Overridepublicvoidadd(){System.out.println("添加香油的");}@Overridepublicvoidcook(){System.out.println("韭菜鸡蛋做好了");}}具体产品2:
packagecreate.abstractfactory;publicclassXiangyouXihongshijidanimplementsCondiment,Food{@Overridepublicvoidadd(){System.out.println("添加香油的");}@Overridepublicvoidcook(){System.out.println("西红柿鸡蛋。");}}具体产品3:
packagecreate.abstractfactory;publicclassJijingJiucaijidanimplementsFood,Condiment{publicvoidcook(){System.out.println("韭菜鸡蛋做好了");}@Overridepublicvoidadd(){System.out.println("添加鸡精。");}}具体产品4:
packagecreate.abstractfactory;publicclassJijingXihongshijidanimplementsFood,Condiment{publicvoidcook(){System.out.println("西红柿鸡蛋做好了");}@Overridepublicvoidadd(){System.out.println("添加鸡精。");}}产品分类1:
packagecreate.abstractfactory;publicinterfaceCondiment{voidadd();}产品分类2:
packagecreate.abstractfactory;publicinterfaceFood{publicvoidcook();}总产品接口:
packagecreate.abstractfactory;publicinterfaceCookFactory{publicFoodcreateXihongshijidan();publicFoodcreateJiucaijidan();}分类产品工厂1:
packagecreate.abstractfactory;publicclassJijingFactoryimplementsCookFactory{publicFoodcreateXihongshijidan(){returnnewJijingXihongshijidan();}publicFoodcreateJiucaijidan(){returnnewJijingJiucaijidan();}}分类产品工厂2:
packagecreate.abstractfactory;publicclassXiangyouFactoryimplementsCookFactory{publicFoodcreateXihongshijidan(){returnnewXiangyouXihongshijidan();}publicFoodcreateJiucaijidan(){returnnewXiangyouJiucaijidan();}}测试类:
packagecreate.abstractfactory;publicclassTest{publicstaticvoidmain(String[]args){CookFactoryff1=newJijingFactory();CookFactoryff2=newXiangyouFactory();Foodf1=ff1.createXihongshijidan();Foodf2=ff2.createXihongshijidan();f1.cook();f2.cook();}}
四、多级抽象工厂模式
考虑工厂模式,将简单工厂用抽象工厂替换。
如果工厂接口层级较高,需要考虑如果尽量少的改动上方接口进行接口分层,胡乱分层会出问题。层级越靠上的改动频率应该越低。
对于工厂之上的抽象系列,也可能是单纯的工厂里面进行产品分类形成的,可能是多个工厂合道一起也可能是一个工厂拆分。如果是拆分就看拆分的详细程度,决定了抽象程度。不管是合并还是拆分,其实都需要重构。想要一开始就设计完美是不可能的.
五、抽象工厂的实现步骤(以上面的抽象工厂为例)
1、分析具体的产品特性,找出2中不同类别的特征。
比如:香油的韭菜鸡蛋、鸡精的韭菜鸡蛋、香油的西红柿鸡蛋、鸡精的西红柿鸡蛋。
那么一个菜可以有主料和调两部分。
2、考虑2类特性那一个变化的几率比较低。
我个人认为调料新品种的出现会频率更高,那么就认为主料的变化相对固定。
3、根据变化频率低的创建总接口
接口:菜肴
里面两个方法:做一个西红柿鸡蛋
做一个韭菜鸡蛋
如果认为是调料稳定,那么这里应该是两外的两个方法:添加香油的食物、添加鸡精的食物。
4、根据总接口和具体菜肴,创建不同的工厂类
第一个工厂往里面添加香油
第二个工厂往里面添加鸡精
5、这时候考虑变化,我们认为调料是变化的,就会出现新的调料,比如生抽。
那么我们的变化是总接口不变化!!,然后添加一个新的工厂类。
如果总接口先变化,那么说明设计错误。
ps:项目地址svn://47.105.188.20/kitty/2%E3%80%81code/pattern用户名密码:reader/reader