惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
The GitHub Blog
The GitHub Blog
J
Java Code Geeks
Engineering at Meta
Engineering at Meta
N
Netflix TechBlog - Medium
A
About on SuperTechFans
博客园 - 三生石上(FineUI控件)
罗磊的独立博客
MongoDB | Blog
MongoDB | Blog
B
Blog RSS Feed
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
有赞技术团队
有赞技术团队
T
Tailwind CSS Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
Vercel News
Vercel News
腾讯CDC
博客园 - 聂微东
The Cloudflare Blog
F
Fortinet All Blogs
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
Visual Studio Blog
Last Week in AI
Last Week in AI
B
Blog

博客园 - 镜涛

Spark环境搭建遇到的问题 This installation has not been configured properly for Software Updates The Activator X for bundle Y is invalid, caused by ClassNotFoundException: X SAP全球技术大会参会随笔 工作流系统概述 需要掌握的flex知识点 ORA-01460: 转换请求无法实现或不合理 【转载】Tomcat内存溢出的原因及调试 做产品开发的感想 基于SAML的单点登录.NET代理端实现方案 Cursor identified in Fetch statement is not open Java下载中文乱码问题解决方法 - 镜涛 - 博客园 获取矩形中心点与矩形外某点连线和矩形交点的算法 Could not find the main class. Program will exit. - 镜涛 Unrecognized attribute 'targetFramework'.错误解决 [译]Razor内幕之模板 - 镜涛 - 博客园 [译]Razor内幕之表达式 - 镜涛 - 博客园 [译]Razor内幕之解析 [译]Razor内幕之介绍
去除对象中的类型集合
镜涛 · 2011-04-28 · via 博客园 - 镜涛

一般来说,当某一个对象有多个集合类型的子元素时,我们都会给每个子元素创建一个集合对象来承载子元素,类似于:

public class Process
{
public var isExecutable:Boolean;
public var refLaneSet:LaneSet;
public var startEventList:ArrayList;
public var endEventList:ArrayList;
public var taskList:ArrayList;
public var serviceTaskList:ArrayList;
public var sendTaskList:ArrayList;
public var receiveTaskList:ArrayList;
public var userTaskList:ArrayList;
}

一般来说,这是没什么问题的。但是某些情况下,例如在图形化与结构化文档之间进行转化时,这样做有很多弊端。如图:

 

图中:

Participant1,展现类型为PoolDiagram,对应模型为之前的Process对象;

Task1,展现类型为UserTaskDiagram,对应模型为UserTask

Task2,展现类型为ManualTaskDiagram,对应模型为ManualTask

我们每向Participant1中增加一个UserTaskDiagram或者ManualTaskDiagram时,都需要向对应的Process中增加UserTask或者ManualTask对象;删除时也是如此。这时候就需要通过判断图形的类型来向相关的模型列表中增加模型对象,删除也需要判断。在类型比较少的时候,这样做比较简单,但是如果类型比较多的时候,特别是类型数量是一个变化点的时候,这种处理方式局限性就很大了,每次变动,都会对既有的代码造成影响。具体的代码可能类似于:

增加:

If(diagram is UserTaskDiagram) Process.UserTaskList.add(userTask)

Else if(diagram is ManualTaskDiagram)Process.ManualTaskDiagram.addmanualTask

......

......

删除:

If(diagram is UserTaskDiagram) Process.UserTaskList.remove(userTask)

Else if(diagram is ManualTaskDiagram)Process.ManualTaskDiagram.removemanualTask

......

......

即使我们将这段代码封装到一个地方,这个地方在新类型增加时也需要改变,有没有一种方法可以在类型增加时不改变既有代码呢?答案是肯定的。

具体方案如下:

public class ContainerElement
{
private var _typeListDic:Dictionary=new Dictionary();public function addChildElement(element:BPMNElement):void
{
if(!_typeListDic[element.type])
_typeListDic[element.type]
=new ArrayCollection();
_typeListDic[element.type].addItem(element);
}
public function removeChildElement(element:BPMNElement):void
{
if(_typeListDic[element.type])
{
var index:
int=_typeListDic[element.type].getItemIndex(element);
if(index!=-1)
{
_typeListDic[element.type].removeItemAt(index);
}
}
}
public function getChildElements(classInfo:Class):ArrayCollection
{
if(!_typeListDic[classInfo])
_typeListDic[classInfo]
=new ArrayCollection();
return _typeListDic[classInfo];
}
}
public class Process extends ContainerElement
{
public var isExecutable:Boolean;
public var laneSet:LaneSet;public function Process(){}public function get type():Class
{
return Process;
}
}

上面的代码将所有的类型列表相关的操作封装在ContainerElement中,该类维护一个类型和对象集合的映射关系,从而将相关的判断逻辑从代码中去除。再增加或者去除新类型时我们的process类是保持不变的,相关的增加删除逻辑也会保存相对固定。

经过以上实现,之前的增加删除逻辑变为:

Process.addChildElement(userTask);

Process.removeChildElement(manualTask);