工厂方法模式及其扩展
设计模式之禅学习——工厂方法模式
工厂方法模式——定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。
一、工厂方法模式的通用代码:
首先要定义产品族,也就是一个产品的接口
package com.wang.factoryPattern.method; /** * 产品类接口 * @author HeJW * */ public interface Product { public void method1(); public String method2(String args); }
然后,让我们定义两个实现该接口的类,也就是具体的产品:
第一个产品:
package com.wang.factoryPattern.method; /** * 具体产品类1 * @author HeJW * */ public class ConcreteProduct1 implements Product { public ConcreteProduct1(){ System.out.println("ConcreteProduct1 被创建"); } @Override public void method1() { System.out.println("xx"); } @Override public String method2(String args) { return args; } }
第二个产品,代码与第一个产品基本相同:
package com.wang.factoryPattern.method; /** * 具体产品类2 * @author HeJW * */ public class ConcreteProduct2 implements Product { public ConcreteProduct2(){ System.out.println("ConcreteProduct2 被创建"); } @Override public void method1() { System.out.println("yy"); } @Override public String method2(String args) { return args; } }
现在该定义工厂方法的工厂接口了:
package com.wang.factoryPattern.method; /** * 工厂方法的接口 * @author HeJW * */ public interface Factory { /* * 创建一个产品对象,其输入参数类型可以自行设置 * 通常为String、Enum、Class等,当然也可以为空 */ //输入类型为Class public <T extends Product> T productFactory1(Class<T> c); //输入类型为String public Product productFactory2(String product); }
之后,实现该工厂接口:
package com.wang.factoryPattern.method; /** * 具体工厂类 * @author HeJW * */ public class ConcreteFactory implements Factory { @Override public <T extends Product> T productFactory1(Class<T> c) { Product product1 = null; try { product1 = (Product)Class.forName(c.getName()).newInstance(); } catch (Exception e) { //异常处理 } return (T)product1; } @Override public Product productFactory2(String product) { Product product2 = null; if( product.equals("ConcreteProduct1") ){ product2 = new ConcreteProduct1(); } else { product2 = new ConcreteProduct2(); } return product2; } }
现在工厂方法模式已经实现了,下面编写一个测试类,看看工厂方法模式的使用:
package com.wang.factoryPattern.method; /** * 测试类 * @author HeJW * */ public class App { public static void main(String[] args) { Factory factory = new ConcreteFactory(); ConcreteProduct1 product1 = factory.productFactory1(ConcreteProduct1.class); product1.method1(); ConcreteProduct2 product2 = (ConcreteProduct2) factory.productFactory2("ConcreteProduct2"); product2.method1(); } }
运行结果如下:
二、工厂方法模式的扩展
1、工厂方法模式向下缩小为简单工厂模式,
简单工厂模式的工厂类代码如下:
package com.wang.factoryPattern.simple; import com.wang.factoryPattern.method.Product; /** * 简单工厂类 * 就是加了个static * @author HeJW * */ public class SimpleFactory { public static <T extends Product> T productFactory( Class<T> c ){ Product product = null; try { product = (Product)Class.forName(c.getName()).newInstance(); } catch (Exception e) { e.printStackTrace(); } return (T)product; } }
非常简单,下面编写一个测试类,看看简单工厂模式的使用:
package com.wang.factoryPattern.simple; import com.wang.factoryPattern.method.ConcreteProduct1; /** * 简单工厂测试类 * @author HeJW * */ public class App { public static void main(String[] args) { ConcreteProduct1 product1 = SimpleFactory.productFactory(ConcreteProduct1.class); product1.method1(); } }
2、工厂方法模式向上扩展为多工厂模式,所谓多工厂模式,就是为具体的每一个产品类,都有专门的工厂方法,该工厂方法,只能生产指定的某一产品。
多工厂模式的工厂接口:
package com.wang.factoryPattern.many; import com.wang.factoryPattern.method.Product; /** * 多工厂模型的工厂接口 * @author HeJW * */ public interface ProductFacory { public Product productFactory(); }
产品1的工厂方法:
package com.wang.factoryPattern.many; import com.wang.factoryPattern.method.ConcreteProduct1; import com.wang.factoryPattern.method.Product; /** * ConcreteProduct1工厂的实现类 * @author HeJW * */ public class ConcreteProduct1Factory implements ProductFacory { @Override public Product productFactory() { return new ConcreteProduct1(); } }
产品2的工厂方法:
package com.wang.factoryPattern.many; import com.wang.factoryPattern.method.ConcreteProduct2; import com.wang.factoryPattern.method.Product; /** * ConcreteProduct2工厂的实现类 * @author HeJW * */ public class ConcreteProduct2Factory implements ProductFacory { @Override public Product productFactory() { return new ConcreteProduct2(); } }
现在已经为产品1和产品2定制了专门的工厂,现在我们看看多工厂模式的使用:
package com.wang.factoryPattern.many; import com.wang.factoryPattern.method.ConcreteProduct1; public class App { public static void main(String[] args) { ProductFacory factory = new ConcreteProduct1Factory(); ConcreteProduct1 product1 = (ConcreteProduct1) factory.productFactory(); product1.method1(); } }
3、使用工厂方法模式替代单例模式,使用的是一些反射的知识。
首先先建立一个符合单例模式的单例类:
package com.wang.factoryPattern.singleton; /** * 单例类 * @author HeJW * */ public class Singleton { private Singleton(){ //不允许通过New,产生一个对象 System.out.println("singleton 创建"); }; public void method(){ System.out.println("singleton 输出"); } }
然后为这个单例类创建它的工厂方法:
package com.wang.factoryPattern.singleton; import java.lang.reflect.Constructor; /** * 替代单例模式的工厂类 * @author HeJW * */ public class SingletonFactory { private static Singleton singleton; static{ try{ Class c1 = Class.forName(Singleton.class.getName()); //获得无参构造函数 Constructor constructor = c1.getDeclaredConstructor(); //设置无参构造函数是可访问的 constructor.setAccessible(true); //产生一个实例对象 singleton = (Singleton) constructor.newInstance(); } catch( Exception e ){ //异常处理 } } public static Singleton getSingleton(){ return singleton; } }
编写一个测试类,来看看单例类是不是只被创建的一次:
package com.wang.factoryPattern.singleton; public class App { public static void main(String[] args) { Singleton singleton1 = SingletonFactory.getSingleton(); singleton1.method(); Singleton singleton2 = SingletonFactory.getSingleton(); singleton2.method(); } }
运行结果如下:
4、使用工厂方法模式实现类的延时初始化
意思就是如果这个产品没有被创建或者已经被销毁,那么就创建一个;如果在程序运行中,已经有了实例对象,那么就直接用这个实例对象,代码如下:
package com.wang.factoryPattern.lazy; import java.util.HashMap; import java.util.Map; import com.wang.factoryPattern.method.ConcreteProduct1; import com.wang.factoryPattern.method.ConcreteProduct2; import com.wang.factoryPattern.method.Product; /** * 延时初始化的工厂类 * @author HeJW * */ public class LazyProductFactory { private static final Map<String, Product> prMap = new HashMap<String, Product>(); public static synchronized Product ProductFactory(String type){ Product product = null; //如果Map中已经有这个对象 if ( prMap.containsKey(type) ) { product = prMap.get(type); } else { if( type.equals("ConcreteProduct1") ){ product = new ConcreteProduct1(); } else if (type.equals("ConcreteProduct2")) { product = new ConcreteProduct2(); } //同时把对象放到缓存容器中 prMap.put(type, product); } return product; } }
测试类代码如下:
package com.wang.factoryPattern.lazy; import com.wang.factoryPattern.method.ConcreteProduct1; public class App { public static void main(String[] args) { ConcreteProduct1 product1 = (ConcreteProduct1) LazyProductFactory.ProductFactory("ConcreteProduct1"); product1.method1(); //当此次创建ConcreteProduct1时,是从map中取出的。 ConcreteProduct1 product2 = (ConcreteProduct1) LazyProductFactory.ProductFactory("ConcreteProduct1"); product2.method1(); } }
运行结果如下:
上一篇: jquery插件开发之实现jquery手风琴功能分享
下一篇: 古代笑话与现代经典