程序员人生 网站导航

设计模式之工厂模式

栏目:框架设计时间:2015-01-16 08:27:24

工厂模式主要是为创建对象提供了接口(接口编程)。工厂模式依照《Java与模式》中的提法分为3类:

  1. 简单工厂模式(Simple Factory) 
  2. 工厂方法模式(Factory Method) 
  3. 抽象工厂模式(Abstract Factory) 
这3种模式从上到下逐渐抽象,并且更具1般性。还有1种分类法,就是将简单工厂模式看为工厂方法模式的1种特例,两个归为1类。下面是使用工厂模式的两种情况:
  1. 在编码时不能预感需要创建哪一种类的实例。
  2. 系统不应依赖于产品类实例如何被创建、组合和表达的细节

小胖爱吃面,很喜欢那种,他可以连续1周吃面,最爱他妈做的手擀面!现在在外面实习,为了省点钱也为了解馋,每天晚上都吃面,每次吃他都在想,每次吃面还要自己做,真麻烦,等我以后有钱了,每天下馆子!每天吃面!

小胖励志成为1个IT大牛,现在实习也是时刻在学习新的知识,有1天他想“我吃面需要自己做,想吃甚么面也要自己找素材再做,好麻烦啊!”边想边写了端代码,以下:

/* * 泡面好吃,但不能每天吃哦(记得加个蛋) */ 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(); } }


这几段程序分别是泡面、拉面和凉面,最后1个吃面测试类,小胖看着程序运行的结果,心想,这样的代码看着总是有点别扭,我1个吃面的想吃各种各样的面,莫不成都要自己做啊,哪有时间学啊!代码虽然可以运行,但是之间的依赖性很高,后期不好保护啊!

小胖挠了挠脑袋,改了改代码,

/* * 他大舅他2舅都是面条 */ 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(); } }


写完,长舒1口气“我都把谢师傅请来了,这下甚么面都可以吃了,自己也不用做了,哈哈哈”

这里把充当产品的面条抽象了出来(接口),并实现这1接口,由充当工厂类的谢师傅负责生产这些产品,这样写法使代码的耦合度下降,测试类不需要知道代码里都有甚么东西,只需要1个像谢师傅这样的工厂类存在,需要甚么就传1个参数,就会得到!但是如果继续增加1个类的话,就要把工厂类打开在里面修改,对工厂类不符合开闭原则,倒是对面条(不需要修改面条的代码)符合,小胖思考了好久,继续改代码

/* * 让谢师附会分身术(抽象出来) */ 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) { //谢师傅"小胖,要吃甚么?","泡面" //"我会分身术,专门分出1个做泡面的谢师傅给你" MasterXie mx = new InstantNoodleXie(); Noodles noodle = mx.DoNoodle(); noodle.DoNooles(); } }


这里把生产者和产品均抽象了出来,让生产者与被生产者逐一对应,更加便于保护

到这里,小胖想到,即使是吃1碗面,都要使用这么复杂的程序,那末以后就要更加努力的赚钱,自己只要撒钱就好了!!!

(希望各位看客给小胖留言,小胖会逐一接受并作出修改的!!!!)







------分隔线----------------------------
------分隔线----------------------------

最新技术推荐