工厂模式

来源:互联网 发布:java多线程编程技术 编辑:程序博客网 时间:2024/05/20 13:18

what

Define an interface for creating an object,but let subclasses decide which class to
instantiate.Factory Method lets a class defer instantiation to subclasses.(定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。 )


why

产品类的实现如何变化,调用者都不需要关心,它只需要关心产品的接口,只要接口保持不变,系统中的上层模块就不要发生变化,降低模块间的耦合,利于代码的扩展。

工厂方法模式是典型的解耦框架。 高层模块值需要知道产品的抽象类, 其他的实现类都不用关心。

how

抽象产品类

public abstract class Product {  // 产品类的公共方法 public void method1() {   // 业务逻辑处理 }  // 抽象方法 public abstract void method2();}




具体产品类

public class ConcreteProduct1 extends Product {public void method2() {//业务逻辑处理}}



public class ConcreteProduct2 extends Product {public void method2() {//业务逻辑处理}}





抽象工厂

public abstract class Creator {/** 创建一个产品对象, 其输入参数类型可以自 行设置* 通常为String、 Enum、 Class等, 当然也可以为空*/public abstract <T extends Product> T createProduct(Class<T> c);}
具体工厂

public class ConcreteCreator extends Creator {public <T extends Product> T createProduct(Class<T> c) {Product product=null;try {product = (Product) Class.forName(c.getName( )).newInstance( );} catch (Exception e) {//异常处理}return (T)product;}}
场景类

public class Client {public static void main( String[] args) {Creator creator = new ConcreteCreator();Product product = creator.createProduct(ConcreteProduct1.class);/** 继续业务处理*/}}

比如创建DAO时可以在properties文件中写好对应DAO的路径(如mysql或oracle的实现)那样在更换不同的数据库时高层代码就不用修改

private DAOFactory() {prop = new Properties();try {prop.load(DAOFactory.class.getClassLoader().getResourceAsStream("manager/utils/db.properties"));} catch (IOException e) {e.printStackTrace();}}

public <T extends BaseDAO> T createDAO(Class<T> clazz) {try {String name = clazz.getName();String className = prop.getProperty("name")return (T) Class.forName(className).newInstance();} catch (Exception e) {e.printStackTrace(); throw new RuntimeException(e);}}


extension

1.缩小为简单工厂模式

public class HumanFactory {public static <T extends Human> T createHuman(Class<T> c) {//定义一个生产出的人种Human human=null;try {//产生一个人种human = (Human)Class.forName( c.getName()).newInstance();} catch (Exception e) {System.out.println( "人种生成错误! ") ;}return (T)human;}}
2.升级为多个工厂类

public abstract class AbstractHumanFactory {public abstract Human createHuman();}
public class BlackHumanFactory extends AbstractHumanFactory {public Human createHuman() {return new BlackHuman() ;}}



public class YellowHumanFactory extends AbstractHumanFactory {public Human createHuman() {return new YellowHuman();}}

public class whiteHumanFactory extends AbstractHumanFactory {public Human createHuman() {return new WhiteHuman();}}

在复杂的应用中一般采用多工厂的方法, 然后再增加一个协调类, 避免调用者与各个子工厂交流, 协调类的作用是封装子工厂类, 对高层模块提供统一的访问接口

3. 替代单例模式

public class Singleton {//不允许通过new产生一个对象private Singleton() {}public void doSomething() {//业务处理}}


public class SingletonFactory {private static Singleton singleton;static{try {Class cl= Class.forName( Singleton.class.getName());//获得无参构造Constructor constructor=cl.getDeclaredConstructor();//设置无参构造是可访问的constructor.setAccessible(true) ;//产生一个实例对象singleton = (Singleton) constructor.newInstance();} catch ( Exception e) {//异常处理}}public static Singleton getSingleton() {return singleton;}}

4. 延迟初始化

public class ProductFactory {private static final Map<String, Product> prMap = new HashMap();public static synchronized Product createProduct(String type) throws Exception{Product product =null;//如果Map中已经有这个对象if(prMap.containsKey(type)) {product = prMap.get(type);} else{if( type.equals("Product1")) {product = new ConcreteProduct1();} else{product = new ConcreteProduct2();}//同时把对象放到缓存容器中prMap.put( type, product);}return product;}}

ProductFactory负责产品类对象的创建工作,并且通过prMap变量产生一个缓存,对需要再次被重用的对象保留






0 0