概要:
该文章参考了《设计模式之禅》一书及一些前辈的博客文章
1.该文章阐述了工厂模式的原理及展示了工厂模式的通用模板;
2.该文章适合初学设计模式的技术人员研习;
3.该文章有许多不足之处,请各位大咖指正,喷子绕道;
正文:
1.基础工厂模式代码实现
抽象产品类
/**
* 抽象产品类
* @author Administrator
*
*/
public interface Product {
//抽象产品的公共方法1
public void method1();
//抽象产品的公共方法2
public void method2();
}
具体产品类
/**
* 具体产品类
* @author Administrator
*
*/
public class ConcreteProduct implements Product {
@Override
public void method1() {
System.out.println("抽象产品的公共方法1的具体实现");
}
@Override
public void method2() {
System.out.println("抽象产品的公共方法2的具体实现");
}
public void concreteProductMethod(){
System.out.println("具体产品类中的方法");
}
}
抽象工厂类
/**
* 抽象工厂类
* @author Administrator
*
*/
public interface Factory {
//抽象工厂生产产品的方法
public ConcreteProduct createProduct(Class<ConcreteProduct> c);
}
具体工厂类
/**
* 具体工厂类
* @author Administrator
*
*/
public class ConcreteFactory implements Factory {
@Override
public ConcreteProduct createProduct(Class<ConcreteProduct> c) {
Product product = null;
try {
product = (Product)Class.forName(c.getName()).newInstance();
} catch (Exception e) {
System.err.println("生产异常");
}
return (ConcreteProduct)product;
}
}
模拟生产-测试类
/**
* 模拟生产
* @author Administrator
*
*/
public class YieldProduct {
public static void main(String[] args) {
Factory factory = new ConcreteFactory();
ConcreteProduct product = factory.createProduct(ConcreteProduct.class);
product.method1();
product.method2();
product.concreteProductMethod();
}
}
控制台输出:
抽象产品的公共方法1的具体实现
抽象产品的公共方法2的具体实现
具体产品类中的方法
2.扩展—静态工厂模式
实现:去掉了抽象工厂类,具体工厂类中添加static关键字
优点:简化类创建过程,实用
缺点:不利于工厂的扩展
3.扩展—多工厂模式
实现及原理:每种产品对应了相应的工厂,每个工厂都独立负责创建对应的产品对象,增加工厂协调类用来封装子工厂类,避免调用者与各个子工厂交流
优点:符合单一职责原则,职责清晰明确,结构简单
缺点:降低可扩展性和可维护性
4.扩展—工厂替代单例模式
单例类:
/**
* 单例类
* @author Administrator
*
*/
public class Singleton{
//不允许通过new生成对象
private(){
}
//业务处理
public void doSomthing(){
}
}
工厂类
/**
* 工厂类
* @author Administrator
*
*/
public class SingletonFactory(){
private static Singleton singleton;
static{
try{
//反射获取类
Class c = Class.forName(Singleton.class.getName());
//获得无参构造
Constructor constructor = c.getDeclaredConstructor();
//设置无参构造是可以访问的
constructor.setAccessible(true);
//产生一个实例对象
singleton = (Singleton)constructor.newInstance();
}catch(Exception e){
System.err.println("单例生产错误");
}
}
//获取该实例对象
public static Singleton getSingleton(){
return singleton;
}
}
注:
a:使用工厂模式来产生单例对象
b:关于单例模式的反射及反序列化漏洞详请参看单例模式中的介绍
5.扩展—延迟初始化
工厂类
/**
* 工厂类
* @author Administrator
*
*/
public class ProductFactory{
//通过HashMap产生缓存,对用到的对象进行保留
private static final Map<String,Product> prMap = new HashMap();
public static synchronized Product createProduct(String type) throws Exception{
Product product = null;
//如果对象已经存在于prMap中
if(prMap.containsKey(type)){
product = prMap.get(type);
}else{
product = new ConcreteProduct();
prMap.put(type,product);
}
return product;
}
}
注:一个对象被使用完毕后,并不立刻释放,工厂类保持其初始状态,等待再次利用,通过HashMap来实现