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

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

JBPM学设计模式之建造者模式

模式简介

         建造者模式,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

         一个产品常常会有不同的组成成分作为零部件,这些零件可能是对象,也可能不是对象,他们通常由叫做产品的内部表象。不同的产品可以有不同的内部表象,也就是不同的零部件。使用建造者模式可以使客户端不需要知道所生成的产品对象有哪些零部件,每个产品的相应零部件有什么不同,是怎么建造出来的,以及是怎样组成产品的。建造者模式的简图如下

 

1. 建造者模式结构图

 

         在这个示意图中,最终产品是由两部分组成的,所以相应的建造方法也有两个。这个模式涉及到一下四个角色。

         抽象建造者角色:给出一个接口,规范产品对象的各个组成部分的建造。一般而言此接口独立于应用程序的商业逻辑。模式中直接创建产品的具体建造者,必须实现这个接口所要求的两种方法,一种是建造方法,比如图中BuildPart1()和BuildPart2;另外一种是结果返回方法,即图中的GetProduct()。一般来说产品所包含的零部件数目与建造方法的数目相符。

         具体建造者角色:担任这个角色的是与应用程序紧密相关的一些类,他们在应用程序调用下创建产品的实例。其需要完成任务包括:

         实现抽象建造者builder所声明的接口,给出一步一步创建产品实例的操作。

         建造过程完成后,提供产品的实例。

         导演者角色:其调用具体的建造者角色以创建产品对象。应当指出的是,导演者角色并没有产品类的具体知识,真正具有与产品类具体知识的是具体的建造者角色。

         产品角色:产品就是模式中要建造的复杂对象。

         导演者角色是与客户端打交道的角色。导演者角色将客户端创建产品的请求划分为对各个零件的建造请求,再将这些请求委派给具体建造者角色。具体建造者角色是做具体建造工作的,但是却不为客户端所知。

         一般而言,每有一个产品类,就有一个相应的具体建造者类。这些产品应当有一定数目的零件,而每有一个两件就相应的在所有建造者橘色里有一个建造方法。

JBPM中的建造者模式

         对于这个模式,虽然JBPM中提供了几个亿builder结尾的类,但是这些类并没有在代码中使用,同时也不是很适合建造者模式应用的场景。最终选择的JBPM中获取缓存对象部分的代码实现,虽然从代码的意图符合建造者模式,但是并不完美还是有一些差距的。如果您觉得看不懂或者不正确,可以参考其他设计模式给出的实例代码。

 

2. JBPM中的建造者模式

 

         我们知道JBPM自己实现了一套IOC,这套IOC为延迟加载全局对象、缓存全局对象、获取全局对象提供了便捷的方式。下面我们以HibernateConfiguration为例,来说明这个模式的实现。

         导演者角色ContextEnvironmentProcessEngine三者都提供了获取产品的接口,我们可以通过产品对象的类型或者名称来获取。

         public interface Context {

  Object get(String key);
  <T> T get(Class<T> type);
}

  

public 
interface Environment {
  
/**
   * searches a named object in all the contexts in the default search order. 
   * 
@return
 the object if it exists in the environment, <code>null</code> if there is no object with the given name in the environment.
   
*/
  
public 
abstract Object get(String name);
  
/**
 searches an object based on type.  The search doesn take superclasses of the context elements 
   * into account.
   * 
@return
 the first object of the given type or null in case no such element was found.  
   
*/
  
public 
abstract <T> T get(Class<T> type);

}

 

public 
interface ProcessEngine {  
  
/**
 retrieve and object defined in the process engine by type 
*/
  <T> T get(Class<T> type);
  
/**
 retrieve and object defined in the process engine by name 
*/
  Object get(String name);  

     抽象建造者角色DescriptorAbstractDescriptor作为抽象建造者,分别提供了构造产品对象和相应成员的方法constructinitialize

        public interface Descriptor extends Observable, Serializable {

  
/**
   * constructs the object.
   * 
@param
 wireContext {
@link
 WireContext} in which the object is created. This is also the {
@link
 WireContext} 
   * where the object will search for other object that may be needed during the initialization phase.
   * 
@return
 the constructed object.
   
*/
  Object construct(WireContext wireContext); 
  
/**
   * called by the WireContext to initialize the specified object.
   * For more information about initialization, see {
@link
 WireContext} section lifecycle.
   * 
@param
 object object to initialize.
   * 
@param
 wireContext the context in which the object will be initialized.
   
*/
  
void initialize(Object object, WireContext wireContext);
}

          

public 
abstract 
class AbstractDescriptor 
extends DefaultObservable 
implements Serializable, Descriptor {
  
private 
static 
final 
long serialVersionUID = 1L;
  
protected 
long dbid;
  
protected 
int dbversion;
  
protected 
int version;
  
protected String name = 
null;
  
/**
 lazy creation and delayed initialization 
*/
  
public 
static 
final 
char INIT_LAZY='L';
  
  
/**
 eager creation and delayed initialization 
*/
  
public 
static 
final 
char INIT_EAGER='E';
  
  
/**
 lazy creation and immediate initialization 
*/
  
public 
static 
final 
char INIT_REQUIRED='R';
  
  
/**
 eager creation and immediate initialization 
*/
  
public 
static 
final 
char INIT_IMMEDIATE='I';
  
protected 
char init = INIT_LAZY;
  
public AbstractDescriptor() {
  }
  
public AbstractDescriptor(String name) {
    
this.name = name;
  }
  
  
public Class<?> getType(WireDefinition wireDefinition) {
    
return 
null;
  }
  
  
public 
boolean isEagerInit() {
    
return (init == INIT_EAGER || init == INIT_IMMEDIATE);
  }
  
public 
boolean isDelayable() {
    
return (init == INIT_EAGER || init == INIT_LAZY);
  }
  
  
public 
void initialize(Object object, WireContext wireContext) {
  }
  
/**
 the db primary key. 
*/
  
public Long getDbid() {
    
return dbid;
  }
  
public String getName() {
    
return name;
  }
  
public 
void setName(String name) {
    
this.name = name;
  }
  
/**
 see section 'Initialization' of {
@link
 WireContext} 
*/
  
public 
void setInit(
char init) {
    
this.init = init;
  }

      具体建造者角色:具体的建造者角色就是建造对象的Descriptor类,这个例子中就是HibernateConfigurationDescriptor

        public class HibernateConfigurationDescriptor extends AbstractDescriptor {

  
private 
static 
final 
long serialVersionUID = 1L;
  
private 
static 
final Log log = Log.getLog(HibernateConfigurationDescriptor.
class.getName());
  String className;
  String namingStrategyClassName;
  List<Operation> cfgOperations = 
new ArrayList<Operation>();
  List<Operation> cfgCacheOperations = 
new ArrayList<Operation>();
  PropertiesDescriptor propertiesDescriptor = 
null;
  
public Object construct(WireContext wireContext) {
    
//
 instantiation of the configuration
    Configuration configuration = 
null;
    
if (className!=
null) {
      
try {
        log.trace("instantiating hibernate configuration class "+className);
        Class<?> configurationClass = ReflectUtil.classForName(className);
        configuration = (Configuration) ReflectUtil.newInstance(configurationClass);
      } 
catch (Exception e) {
        
throw 
new JbpmException("couldn't instantiate hibernate configuration class "+className, e);
      }
    } 
else {
      log.trace("instantiating default hibernate configuration");
      configuration = 
new Configuration();
    }
    
return configuration;
  }
  
public 
void initialize(Object object, WireContext wireContext) {
    Configuration configuration = (Configuration) object;
    apply(cfgOperations, configuration, wireContext);
    apply(cfgCacheOperations, configuration, wireContext);
    
if (propertiesDescriptor!=
null) {
      Properties properties = (Properties) wireContext.create(propertiesDescriptor, 
false);
      
if (log.isDebugEnabled()) log.debug("adding properties to hibernate configuration: "+properties);
      configuration.addProperties(properties);
    }
  }
  
private 
void apply(List<Operation> operations, Configuration configuration, WireContext wireContext) {
    
if (operations!=
null) {
      
for (Operation operation: operations) {
        log.trace(operation.toString());
        operation.apply(configuration, wireContext);
      }
    }
  }
  
public Class<?> getType(WireDefinition wireDefinition) {
    
if (className!=
null) {
      
try {
        
return ReflectUtil.classForName(className);
      } 
catch (Exception e) {
        
throw 
new WireException("couldn't create hibernate configuration '"+className+"': "+e.getMessage(), e.getCause());
      }
    }
    
return Configuration.
class;
  } 

}  

    建造者模式的特点

1.       分离对象表示和对象的创建过程。由于建造者隐藏了产品具体组建过程,所以如果需要改变产品的内部表示,只需要中心定义一个具体的建造者就可以了。

2.       需要生成的产品对象的属性互相依赖。建造者模式可以强制实行一种分步骤的建造过程。因此,可以强制产品的一个属性必须在另一个属性之前赋值。

3.       在对象的创建过程中需要使用到系统中的其他一些对象,但是其在产品的创建过程中不容易得到。

转载于:https://www.cnblogs.com/wufengtinghai/archive/2012/06/05/2535531.html

你可能感兴趣的文章
代码描述10313 - Pay the Price
查看>>
jQuery最佳实践
查看>>
centos64i386下apache 403没有权限访问。
查看>>
下划线的学习5
查看>>
Spring Data JPA教程, 第六部分: Sorting(未翻译)
查看>>
重建二叉树
查看>>
企业管理软件开发之九 以数据绑定为基础的控件只读,创建时可写,必须大写,必须小写的原理与实现...
查看>>
批处理清理VS工程目录(递归删除Debug, Release, ipch目录及*.sdf文件)
查看>>
在Windows中监视IO性能
查看>>
thrift之TTransport层的缓存传输类TBufferedTransport和缓冲基类TBufferBase
查看>>
Oracle数据库日期范围查询的两种实现方式
查看>>
PHP魔术变量和魔术方法
查看>>
张子强_百度百科
查看>>
Windows下命令行下启动ORACLE服务
查看>>
从网络得到数据--Arduino+以太网
查看>>
删除重复记录(Mysql,SqlServer,Sqlite)
查看>>
vb sendmessage 详解1
查看>>
aaalogo写入中文出错的解决方法
查看>>
常用的一些SQL语句整理,也许有你想要的。
查看>>
JAVA帮助文档全系列 JDK1.5 JDK1.6 JDK1.7 官方中英完整版下载
查看>>