博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
跟JBPM学设计模式之抽象工厂模式
阅读量:6852 次
发布时间:2019-06-26

本文共 5217 字,大约阅读时间需要 17 分钟。

JBPM学设计模式之抽象工厂模式

 

模式简介

         前面我们已经学习了简单工厂模式和工厂方法模式,今天我们来学习一下抽象工厂模式;抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。抽象工厂模式是所有的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式的基本结构图如下所示。

 

 

1. 抽象工厂结构图

 

         左边的等级结构代表工厂的等级结构,右边的等级结构代表两个不同产品的等级结构。此模式可以向客户端提供一个借口,使得客户端不用指定产品的具体类型的情况下,同时创建出多个产品对象。一般情况下我们使用工厂获取的对象是由不同产品的实体产品组成的混合体,这一点使用工厂方法模式基本上是无法实现的。

JBPM中的抽象工厂模式

       JBPM中实现的简单工厂模式和工厂方法模式,我们可以看到实际生产环境中对模式的实现与定义可能有很大的不同,这也说明设计模式只是给出一种能够使用的典型环境和实现结构,实际使用的时候要视具体的情况进行变通。JBPM对此模式的实现如下图所示

 

 

2. JBPM实现抽象工厂模式结构图

 

         从图中可以看到JBPM同样没有完全照搬此模式给出的结构定义,此代码来自JBPM中的表达式实现部分,这部分有很多的类直接来自java的实现,关联关系比较乱,很容易掩盖抽象工厂模式的使用,不过只要我们将相关的类进行角色归类,那么一切就明朗可见了。

         产品抽象类,就是FunctionMapperELResolver,他们都是来自java的表达式类库中的抽象类;

         具体产品类,其中JbpmFunctionMapper作为唯一的产品类,继承并实现FunctionMapper;实现ELResolver的具体产品类,除了java类库实现的一些类,JBPM也实现了三个JbpmConstantsElResolverJbpmEnvironmentElResolverJbpmVariableElResolver

         其中最为关键的就是JbpmELContent,其继承了java类库中的ELContent,其作为产品的持有容器,使得我们创建JbpmELContent的时候,需要同时实例化两个不同类型的产品;这就为我们使用抽象工厂模式创造了条件,具体代码如下

         public class JbpmElContext extends ELContext {

  
  ELResolver elResolver;
  FunctionMapper functionMapper;
  
  
public JbpmElContext(ELResolver elResolver, FunctionMapper functionMapper) {
    
this.elResolver = elResolver;
    
this.functionMapper = functionMapper;
  }
  
public ELResolver getELResolver() {
    
return elResolver;
  }
  
public FunctionMapper getFunctionMapper() {
    
return functionMapper;
  }
  
public VariableMapper getVariableMapper() {
    
return 
null;
  }
}

         工厂基类,JbpmElFactory作为工厂基类,并没有直接的提供创建产品functionMapperELResolver的接口,而是直接提供了创建ELContext的接口,这样就将创建具体产品的实现推迟到工厂子类里,给予工厂子类充分的自由决策权。

         public abstract class JbpmElFactory {

  
public 
static JbpmElFactory getJbpmElFactory() {
    JbpmElFactory contextFactory = EnvironmentImpl.getFromCurrent(JbpmElFactory.
class
false);
    
if (contextFactory==
null) {
      contextFactory = 
new JbpmElFactoryImpl();
    }
    
return contextFactory;
  }
  
public 
abstract ELContext createElContext();
  
public 
abstract ELContext createElContext(ScopeInstanceImpl scopeInstance);
  
public 
abstract ExpressionFactory createExpressionFactory();
}

         具体工厂类,JbpmElFactoryImpl作为工厂子类,实现了父类创建ELContext的接口,同时也提供单独的接口,来分别完成对应产品的实例化,并最终将产品进行整合,最终将ELContext的对象实例提供给客户。

         View Code

 
public 
class JbpmElFactoryImpl 
extends JbpmElFactory {
  
private 
static Log log = Log.getLog(JbpmElFactoryImpl.
class.getName());
  Class<?> functionClass = JstlFunction.
class;
  
/**
 create ElContext used during parsing time 
*/
  
public ELContext createElContext() {
    
return createCompositeResolver(
null);
  }
  
/**
 create ElContext used during evaluation time related to an execution 
*/
  
public ELContext createElContext(ScopeInstanceImpl scopeInstance) {
    
return createCompositeResolver(scopeInstance);
  }
  
protected ELContext createCompositeResolver(ScopeInstanceImpl scopeInstance) {
    CompositeELResolver compositeELResolver = 
new CompositeELResolver();
    
if (scopeInstance!=
null) {
      compositeELResolver.add(
new JbpmConstantsElResolver(scopeInstance));
      compositeELResolver.add(
new JbpmVariableElResolver(scopeInstance));
    }
    EnvironmentImpl environment = EnvironmentImpl.getCurrent();
    
if (environment!=
null) {
      compositeELResolver.add(
new JbpmEnvironmentElResolver(environment));
    }
    addCdiResolver(compositeELResolver);
    addBasicResolvers(compositeELResolver);
    FunctionMapper functionMapper = createFunctionMapper();
    
return createElContext(compositeELResolver, functionMapper);
  }
  
protected 
void addCdiResolver(CompositeELResolver compositeELResolver) {
    BeanManager beanManager = getBeanManager();
    
if (beanManager!=
null) {
      ELResolver cdiResolver = beanManager.getELResolver();
      
if (cdiResolver!=
null) {
        compositeELResolver.add(cdiResolver);
        log.debug("added cdi el resolver");
      }
    } 
else {
      log.debug("no cdi bean manager available in jndi");
    }
  }
  
protected BeanManager getBeanManager() {
    
try {
      InitialContext initialContext = 
new InitialContext();
      
return (BeanManager) initialContext.lookup("java:comp/BeanManager");
    } 
catch (NamingException e) {
      
return 
null;
    }
  }
  
public ExpressionFactory createExpressionFactory() {
    ExpressionFactory expressionFactory;
    
try {
      expressionFactory = ExpressionFactory.newInstance();
    } 
catch (NoSuchMethodError e) {
      
//
 to support previous version of el-api
      expressionFactory = (ExpressionFactory) FactoryFinder.find(ExpressionFactory.
class
        .getName(),"de.odysseus.el.ExpressionFactoryImpl", 
null, "el.properties");
    }
    BeanManager beanManager = getBeanManager();
    
if (beanManager!=
null) {
      expressionFactory = beanManager.wrapExpressionFactory(expressionFactory);
    }
    
return expressionFactory;
  }
  
protected 
void addBasicResolvers(CompositeELResolver compositeELResolver) {
    compositeELResolver.add(
new ResourceBundleELResolver());
    compositeELResolver.add(
new MapELResolver());
    compositeELResolver.add(
new ListELResolver());
    compositeELResolver.add(
new ArrayELResolver());
    compositeELResolver.add(
new BeanELResolver());
  }
  
protected FunctionMapper createFunctionMapper() {
    
return 
new JbpmFunctionMapper(functionClass);
  }
  
protected JbpmElContext createElContext(CompositeELResolver compositeELResolver, FunctionMapper functionMapper) {
    
return 
new JbpmElContext(compositeELResolver, functionMapper);
  }

        

抽象工厂模式的优劣

1.       不同的产品进行“组合”创建,客户端不必知道产品的具体类型。

2.       客户需要获取不同的产品“组合”,只需要简单的更改具体的工厂类。

3.       增加现有产品基类的子类,只需要新增相应的工厂类即可,此时很不好的遵循了开闭原则。

4.       增加新的产品系列,此时需要修改现有的工厂类,此时不能违反了开闭原则。

         

转载于:https://www.cnblogs.com/wufengtinghai/archive/2012/05/27/2520663.html

你可能感兴趣的文章
PASCAL语言子集的词法、语法分析器之实现
查看>>
四大 web 框架
查看>>
Java代码生成
查看>>
ecshop截取字符串函数
查看>>
HDU 4099 Revenge of Fibonacci(字典树)
查看>>
使用 Windows Azure 移动服务将云添加到您的应用
查看>>
代理模式(Proxy)
查看>>
ios开发之360度事件处理
查看>>
IIS6.0可支持32位和64位两种模式
查看>>
占用空间的大小
查看>>
PyConChina 2012 - 第二届中国Python开发者大会 上海.北京.西安.杭州.合肥.武汉.珠海 | 抢座网...
查看>>
模块间变量传递
查看>>
多文档多视图之间的切换过程和当文档多视图之间的切换过程
查看>>
微软说“骂吧!骂吧!我要长大!”
查看>>
C++ 函数后加const
查看>>
[BTS] 应用程序中的错误。 (Microsoft.BizTalk.ExplorerOM)
查看>>
Extjs4.1.x 框架搭建 采用Application动态按需加载MVC各模块-完美解决(二)
查看>>
Jquery控制图片最大宽度
查看>>
[philosophy]空间
查看>>
myeclipse6.0添加maven
查看>>