设计模式之工厂方法模式

设计模式之工厂方法模式

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

通用类图:


    其中,抽象产品类负责定义产品的共性,实现对事物最抽象的定义;Creator为抽象创建类,也就是抽象工厂,具体如何创建产品类是由具体实现工厂ConcreateCreator完成的。

通用源码

抽象产品类

public abstract class Product {
	//产品类的公用方法
	public void method1(){
	}
	
	//抽象方法
	public abstract void method2();
}

具体产品类1

public class ConcreteProduct1 extends Product{
	public void method2(){
	}
}

具体产品类2

public class ConcreteProduct2 extends Product{
	public void method2(){
	}
}

抽象工厂类

public abstract class Creator {
	//创建一个产品对象
	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) {
		// TODO Auto-generated method stub
		Creator creator=new ConcreteCreator();
		Product product=creator.createProduct(ConcreteProduct1.class);
	}
}

例子:女娲造人

人类总称

public interface Human {
	public void getColor();
	public void talk();
}

黑人

public class BlackHunman implements Human{
	public void getColor(){
		System.out.println("黑色");
	}
	public void talk(){
		System.out.println("黑人说黑话");
	}
}

黄人

public class YellowHuman implements Human{
	public void getColor(){
		System.out.println("黄色");
	}
	public void talk(){
		System.out.println("黄人说汉语");
	}
}

白人

public class WhiteHuman implements Human{
	public void getColor(){
		System.out.println("白色");
	}
	public void talk(){
		System.out.println("白人说英语");
	}
}

抽象工厂

public abstract class AbstractHumanFactory {
	public abstract <T extends Human> T createHuman(Class<T> c);
}

具体工厂

public class HumanFactory extends AbstractHumanFactory{
	public <T extends Human> T createHuman(Class<T> c){
		Human human=null;
		try{
			human=(T)Class.forName(c.getName()).newInstance();
		}catch(Exception e){
			System.out.println("人种错误");
		}
		return (T)human;
	}
}

女娲类

public class NvWa {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		AbstractHumanFactory yinyanglu=new HumanFactory();
		System.out.println("第一批人是白人");
		Human whiteHuman=yinyanglu.createHuman(WhiteHuman.class);
		whiteHuman.getColor();
		whiteHuman.talk();
		System.out.println("第二批人是黑人");
		Human blackHuman=yinyanglu.createHuman(BlackHunman.class);
		blackHuman.getColor();
		blackHuman.talk();
		System.out.println("第三批人是黄人");
		Human yellowHuman=yinyanglu.createHuman(YellowHuman.class);
		yellowHuman.getColor();
		yellowHuman.talk();
	}
}

工厂方法模式的优点:

1.良好的封装性,代码结构清晰,如调用者需要创建一个具体的产品对象,只要知道产品的类名即可,不需要知道创建具体过程,降低模块间耦合;

2.工厂方法扩展性非常优秀,在增加产品的情况下,只要适当的修改具体类的工厂类或者扩展一个工厂类即可;

3.屏蔽产品类,产品如何变花,调用者不需要关心,他只需要关心产品的接口,只要接口不变,系统的上层模块就不需要变化,因为产品的实例化工作是由工厂类负责的;

4.工厂方法模式是非常典型的及饿哦欧框架,高层模块只需要知道产品的抽象类,不用关心其它的实现类。

使用场景

1.工厂方法模型是new一个对象的替代品,在需要生成对象的地方都可以使用,但是需要慎重的考虑是否增加一个工厂类进行管理,增加代码的复杂度;

2.需要灵活地、可扩展的框架时,可以考虑采用工厂方法模型;

3.工厂方法模式可以使用在异构项目中;

4.可以使用在测试驱动开发的框架下。

工厂方法模型的扩展

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;
	}
}
场景类

public class NvWa {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//AbstractHumanFactory yinyanglu=new HumanFactory();
		System.out.println("第一批人是白人");
		//Human whiteHuman=yinyanglu.createHuman(WhiteHuman.class);
		Human whiteHuman=HumanFactory.createHuman(WhiteHuman.class);
		whiteHuman.getColor();
		whiteHuman.talk();
		System.out.println("第二批人是黑人");
		//Human blackHuman=yinyanglu.createHuman(BlackHunman.class);
		Human blackHuman=HumanFactory.createHuman(BlackHunman.class);
		blackHuman.getColor();
		blackHuman.talk();
		System.out.println("第三批人是黄人");
		//Human yellowHuman=yinyanglu.createHuman(YellowHuman.class);
		Human yellowHuman=HumanFactory.createHuman(YellowHuman.class);
		yellowHuman.getColor();
		yellowHuman.talk();
	}
}


2.升级为多个工厂类

多工厂模式抽象工厂类

public abstract class AbstractHumanFactory {
	public abstract Human createHuman();
}
黑人工厂类

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

黄人工厂类

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

白人工厂类

public class WhiteHumanFactory {
	public Human createHuman(){
		return new WhiteHuman();
	}
}
女娲类

public class NvWa {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//AbstractHumanFactory yinyanglu=new HumanFactory();
		System.out.println("第一批人是白人");
		//Human whiteHuman=yinyanglu.createHuman(WhiteHuman.class);
		//Human whiteHuman=HumanFactory.createHuman(WhiteHuman.class);
		Human whiteHuman=(new WhiteHumanFactory()).createHuman();
		whiteHuman.getColor();
		whiteHuman.talk();
		System.out.println("第二批人是黑人");
		//Human blackHuman=yinyanglu.createHuman(BlackHunman.class);
		//Human blackHuman=HumanFactory.createHuman(BlackHunman.class);
		Human blackHuman=(new BlackHumanFactory()).createHuman();
		blackHuman.getColor();
		blackHuman.talk();
		System.out.println("第三批人是黄人");
		//Human yellowHuman=yinyanglu.createHuman(YellowHuman.class);
		//Human yellowHuman=HumanFactory.createHuman(YellowHuman.class);
		Human yellowHuman=(new YellowHumanFactory()).createHuman();
		yellowHuman.getColor();
		yellowHuman.talk();
	}
}

    如果要扩展一个产品类,就需要建立一个相应的工厂类,这样就增加了扩展的难度。因为工厂类和产品类的数量相同,维护时需要考虑两个对象之间的关系。

3.替代单例模式


单例类

public class Singleton {
	private Singleton(){
	}
	public void doSomething(){
	}
}
单例工厂

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;
	}
}

4.延迟初始化

延迟初始化:一个对象被消费完毕后,并不立刻释放,工厂类保持其初始状态,等待被再次使用。


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

public class ProductFactor {
	private static final Map<String,Product> prMap=new HashMap();
	public static synchronized Product createProduct(String type)throw Exception{
		Product product=null;
		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;
	}
}















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值