工厂模式主要是为创建对象提供了接口(接口编程)。工厂模式按照《Java与模式》中的提法分为三类:
小胖爱吃面,很喜欢那种,他可以连续一周吃面,最爱他妈做的手擀面!现在在外面实习,为了省点钱也为了解馋,每天晚上都吃面,每次吃他都在想,每次吃面还要自己做,真麻烦,等我以后有钱了,天天下馆子!天天吃面!
小胖励志成为一个IT大牛,现在实习也是时刻在学习新的知识,有一天他想“我吃面需要自己做,想吃什么面也要自己找素材再做,好麻烦啊!”边想边写了端代码,如下:
/* * 泡面好吃,但不能天天吃哦(记得加个蛋) */ public class InstantNoodle { public void DoInstantNoodle(){ System.out.println("做泡面..."); } }
/* * 最爱西北拉面,好贵的说 */ public class HandPulledNoodle { public void DoHandPulledNoodle(){ System.out.println("做拉面..."); } }
/* * 夏天吃凉面,多放醋,酸爽由不得你 */ public class ColdNoodle { public void DoColdNoodle(){ System.out.println("做凉拌面..."); } }
public class EatNoodle { public static void main(String[] args) { //天天吃泡面 InstantNoodle instantNoodle = new InstantNoodle(); instantNoodle.DoInstantNoodle(); //想吃拉面了 HandPulledNoodle handPullNoodle = new HandPulledNoodle(); handPullNoodle.DoHandPulledNoodle(); } }这几段程序分别是泡面、拉面和凉面,最后一个吃面测试类,小胖看着程序运行的结果,心想,这样的代码看着总是有点别扭,我一个吃面的想吃各种各样的面,莫不成都要自己做啊,哪有时间学啊!代码虽然可以运行,但是之间的依赖性很高,后期不好维护啊!
小胖挠了挠脑袋,改了改代码,
/* * 他大舅他二舅都是面条 */ public interface Noodles { public void DoNooles(); }
public class ColdNoodel implements Noodles { @Override public void DoNooles() { System.out.println("做凉面"); } }
public class HandPulledNoodle implements Noodles { @Override public void DoNooles() { System.out.println("做拉面..."); } }
public class InstantNoodle implements Noodles { @Override public void DoNooles() { System.out.println("做泡面..."); } }
/* * 有请中华小当家中的面点王谢师傅 */ public class MasterXie { public Noodles doNoodles(String type){ if(type.equals("泡面")){ return new InstantNoodle(); }else if(type.equals("拉面")){ return new HandPulledNoodle(); }else{ return new ColdNoodel(); } } }
public class EatNoodle { public static void main(String[] args) { //谢师傅来了 MasterXie mx = new MasterXie(); //"小胖,要吃什么?" Noodles noodle = null; //"谢师傅!我要吃泡面!!!" noodle = mx.doNoodles("泡面"); //"好的" noodle.DoNooles(); //"谢师傅,我想吃凉面!" noodle = mx.doNoodles("凉面"); //"好的" noodle.DoNooles(); } }写完,长舒一口气“我都把谢师傅请来了,这下什么面都可以吃了,自己也不用做了,哈哈哈”
这里把充当产品的面条抽象了出来(接口),并实现这一接口,由充当工厂类的谢师傅负责生产这些产品,这样写法使代码的耦合度降低,测试类不需要知道代码里都有什么东西,只需要一个像谢师傅这样的工厂类存在,需要什么就传一个参数,就会得到!但是如果继续增加一个类的话,就要把工厂类打开在里面修改,对工厂类不符合开闭原则,倒是对面条(不需要修改面条的代码)符合,小胖思考了许久,继续改代码
/* * 让谢师傅会分身术(抽象出来) */ public interface MasterXie { public Noodles DoNoodle(); }
/* * 凉面谢师傅 */ public class ColdNoodleXie implements MasterXie { @Override public Noodles DoNoodle() { // TODO Auto-generated method stub return new ColdNoodle(); } }依次有泡面谢师傅和拉面谢师傅
public class EatNoodle { public static void main(String[] args) { //谢师傅"小胖,要吃什么?","泡面" //"我会分身术,专门分出一个做泡面的谢师傅给你" MasterXie mx = new InstantNoodleXie(); Noodles noodle = mx.DoNoodle(); noodle.DoNooles(); } }
到这里,小胖想到,即便是吃一碗面,都要使用这么复杂的程序,那么以后就要更加努力的赚钱,自己只要撒钱就行了!!!
(希望各位看客给小胖留言,小胖会一一接受并作出修改的!!!!)