工厂方法模式及其扩展

设计模式之禅学习——工厂方法模式

 

工厂方法模式——定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。

 

一、工厂方法模式的通用代码:

首先要定义产品族,也就是一个产品的接口

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

 运行结果如下:



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值