模拟场景:女娲造人,第一次经验不足造出白人,第二次时间太紧,造出黑人,第三次才造出黄种人。
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
原文:http://www.cnblogs.com/littleQin/p/3675702.html