工厂模式

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值