首页 > 其他 > 详细

工厂设计模式--Factory

时间:2014-04-20 07:10:08      阅读:381      评论:0      收藏:0      [点我收藏+]

  模拟场景:女娲造人,第一次经验不足造出白人,第二次时间太紧,造出黑人,第三次才造出黄种人。

  Human接口:

 

package com.zqz.dp.factorymethod;

/**

 * @author Qin

 * human接口,因为不同色种的human会有相同的动作,只是实现不同

 */

public interface Human {

         void getColor();        //得到肤色

         void doSomething();         //一些其他动作

}

  

  创建不同肤色的human

  WhiteHuman类:

 

package com.zqz.dp.factorymethod;

/**

 * @author Qin

 * 白人,肯定是human,所以从human接口继承

 */

public class WhiteHuman implements Human {

         public void getColor() {

                   System.out.println("白人的肤色是白色的。。。");

         }

         public void doSomething() {

                   System.out.println("我是白人");

         }

}

 

  BlackHuman类:

 

package com.zqz.dp.factorymethod;

/**

 * @author Qin

 * 黑人,肯定是human,所以从human接口继承

 */

public class BlackHuman implements Human {

         public void getColor() {

                   System.out.println("黑人的肤色是黑色的。。。");

         }

         public void doSomething() {

                   System.out.println("我是黑人");

         }

}

 

  YellowHuman类:

 

package com.zqz.dp.factorymethod;

/**

 * @author Qin

 * 黄种人,肯定是human,所以从human接口继承

 */

public class YellowHuman implements Human {

         public void getColor() {

                   System.out.println("黄种人的肤色是黄色的。。。");

         }

         public void doSomething() {

                   System.out.println("我是黄种人");

         }

}

 

  AbstractHumanFactory接口:

 

package com.zqz.dp.factorymethod;

/**

 * @author Qin

 * 生产human的工厂,可以进行human的生产

 */

public interface AbstractHumanFactory {

         abstract <T extends Human> T createHuman(Class<T> c);   //根据class类型创建出指定的human

}

 

  HumanFactory类:

 

package com.zqz.dp.factorymethod;

/**

 * @author Qin human工厂的具体实现类,创建具体的human对象

 */

public class HumanFactory implements AbstractHumanFactory {

@SuppressWarnings("unchecked")

         public <T extends Human> T createHuman(Class<T> c) {

                   Human human = null; // 声明human对象,不管是什么肤色的human,肯定都是human的子类

                   try {

                            //反射创建human对象,注意human中要有一个午餐的构造器

                            human = (Human) Class.forName(c.getName()).newInstance();  

                   } catch (Exception e) {

                            e.printStackTrace();

                   }

                   return (T)human;     //返回human对象,泛型

         }

}

 

 

  NvWa

 

package com.zqz.dp.factorymethod;

/**

 * @author Qin

 * 女娲类,要用humanFactory来生成human

 */

public class NvWa {

         public static void main(String[] args) {

                   //创建一个human生成工厂

                   AbstractHumanFactory factory=new HumanFactory(); //父类实例指向子类对象

                   System.out.println("第一次经验不足生成白人=======================:");

                   Human whiteHuman=factory.createHuman(WhiteHuman.class);         //反射生成对象

                   whiteHuman.getColor();

                   whiteHuman.doSomething();

                   System.out.println("第二次烤太久生成黑人=======================:");

                   Human blackHuman=factory.createHuman(BlackHuman.class);  //反射生成对象

                   blackHuman.getColor(); 

                   blackHuman.doSomething();

                   System.out.println("第三次终于生成黄种人=======================:");

                   Human yellowHuman=factory.createHuman(YellowHuman.class);                 //反射生成对象

                   yellowHuman.getColor();        

                   yellowHuman.doSomething();}

 

  这样就完成了human的创建

  工厂方法是指定义一个创建对象的接口,让子类决定实例化哪一个类。也就是说工厂方法将子类的实例化延迟到了子类。

工厂方法的优点:

  1、  良好的封装性,代码结构清晰;有约束,规定xxxHuman要继承Human类。

  2、  可拓展性高;如上面的例子如果要再创建一个其他肤色的Otherhuman,只需要让Otherhuamn类继承Huamn类即可,工厂类不需要进行修改。

  3、  屏蔽产品类;也就是说在生成Human的时候,不需要知道Human的任何属性或者方法,只知道我要创建一个Human即可。即我可以不管Human类怎么实现,我只关心如果创建一个Human。

  4、  解耦性强。

工厂方法的使用场景

  1、  工厂方法模式是new一个对象实例化的一个替代品,所以在所有需要生成对象的地方都可以使用。但是在使用的时候要考虑清楚是否真的需要,会否添加代码的复杂度。

  2、  需要灵活的,可拓展的框架时可以考虑

  3、  异构项目中

  4、  测试驱动开发的框架下

工厂方法的拓展

  1、  缩小为简单工厂

  在上面的场景中,只需要一个工厂的存在即可,那么就可以把创建human实例的createHuman()方法定义成static的,那么就可以不需要abstractHumanFactory的存在了。

修改的代码如下:

  HumanFactory

 

package com.zqz.dp.staticfactory;

/**

 * @author Qin human工厂的具体实现类,创建具体的human对象

 */

public class HumanFactory{

         @SuppressWarnings("unchecked")

         public static <T extends Human> T createHuman(Class<T> c) {

                   Human human = null; // 声明human对象,不管是什么肤色的human,肯定都是human的子类

                   try {

                            //反射创建human对象,注意human中要有一个午餐的构造器

                            human = (Human) Class.forName(c.getName()).newInstance();  

                   } catch (Exception e) {

                            e.printStackTrace();

                   }

                   return (T)human;     //返回human对象,泛型

         }

}

 

  NvWa

 

package com.zqz.dp.staticfactory;

/**

 * @author Qin

 * 女娲类,要用humanFactory来生成human

 */

public class NvWa {

         public static void main(String[] args) {

                   //创建一个human生成工厂

                   System.out.println("第一次经验不足生成白人=======================:");

                   Human whiteHuman=HumanFactory.createHuman(WhiteHuman.class);         

//反射生成对象

                   whiteHuman.getColor();

                   whiteHuman.doSomething();

                   System.out.println("第二次烤太久生成黑人=======================:");

                   Human blackHuman=HumanFactory.createHuman(BlackHuman.class);             //反射生成对象

                   blackHuman.getColor(); 

                   blackHuman.doSomething();

                   System.out.println("第三次终于生成黄种人=======================:");

                   Human yellowHuman=HumanFactory.createHuman(YellowHuman.class);           //反射生成对象

                   yellowHuman.getColor();        

                   yellowHuman.doSomething(); }

}

 

2、  升级为多个工厂

  在上面的操作中,是否会觉得humanFactory兼顾的任务太多了呢?因为要创建白种人、黑种人和黄种人三种不同肤色的human。可能你会觉得说不会啊,这样刚好啊。但是可能在项目中,如果只用一个humanFactory(这里只是举例而已),那么要创建好几百中不同肤色的human,那这个时候你是否还会觉得说很乱呢?

所以在这里,可以升级为多个工厂,在这个场景中就是要有三个Factory,来生成不同的Human。

修改代码如下:

  AbstractHumanFactory

 

package com.zqz.dp.manyfactory;

/**

 * @author Qin

 * 生产human的工厂,可以进行human的生产

 */

public interface AbstractHumanFactory {

         abstract Human createHuman();    //生成human的工厂,具体生成什么肤色的交给具体的factory

}

 

  WhiteFactory

 

package com.zqz.dp.manyfactory;

/**

 * @author Qin

 * 创建白种人的factory

 */

public class WhiteFactory implements AbstractHumanFactory {

         public Human createHuman() {

                   return new WhiteHuman();     //返回白种人实例

         }

}

 

  BlackFactory

 

package com.zqz.dp.manyfactory;

/**

 * @author Qin

 * 创建黑种人的factory

 */

public class BlackFactory implements AbstractHumanFactory {

         public Human createHuman() {

                   return new BlackHuman();      //返回黑种人实例

         }

}

 

  YellowFactory

 

package com.zqz.dp.manyfactory;

/**

 * @author Qin

 * 创建黄种人的factory

 */

public class YellowFactory implements AbstractHumanFactory {

         public Human createHuman() {

                   return new YellowHuman();    //返回黄种人实例

         }

}

 

  NvWa

 

package com.zqz.dp.manyfactory;

/**

 * @author Qin

 * 女娲类,要用humanFactory来生成human

 */

public class NvWa {

         public static void main(String[] args) {

                   //创建一个human生成工厂

                   System.out.println("第一次经验不足生成白人=======================:");

                   Human whiteHuman=(new WhiteFactory()).createHuman();                  //指定的工厂生成指定的实例

                   whiteHuman.getColor();

                   whiteHuman.doSomething();

                   System.out.println("第二次烤太久生成黑人=======================:");

                   Human blackHuman=(new BlackFactory()).createHuman();           //指定的工厂生成指定的实例

                   blackHuman.getColor(); 

                   blackHuman.doSomething();

                   System.out.println("第三次终于生成黄种人=======================:");

                   Human yellowHuman=(new YellowFactory()).createHuman();                //指定的工厂生成指定的实例

                   yellowHuman.getColor();        

                   yellowHuman.doSomething();

         }

}

 

  在这里是反而麻烦了,只是简单举个实例而已

3、  替代单例模式

  Singleton类:

 

package com.zqz.dp.singletonfactory;

/**

 * @author Qin

 * 单例类

 */

public class Singleton {

         private Singleton(){};                  //构造方法私有化

         public void doSomething(){};    //自己的操作

}

 

  SingletonFactory

 

package com.zqz.dp.singletonfactory;

 

import java.lang.reflect.Constructor;

/**

 * @author Qin

 * 生成单例的factory

 */

public class SingletonFactory {

         private static Singleton singleton=null;

         static {      //静态代码块进行加载

                   try {

                            Class<?> c1=Class.forName(Singleton.class.getName()); //反射取得对象

                            Constructor<?> con=c1.getConstructor();               //取得singleton的构造器

                            con.setAccessible(true); //因为singleton构造器被私有化,在这里设置为可访问

                            singleton=(Singleton) con.newInstance();       //反射取得对象

                   } catch (Exception e) {

                            e.printStackTrace();

                   }       

         }

         public static Singleton getSingleton(){

                  return singleton;      //返回实例

         }

}

 

工厂设计模式--Factory,布布扣,bubuko.com

工厂设计模式--Factory

原文:http://www.cnblogs.com/littleQin/p/3675702.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!