
2007年6月5日
摘要: 为什么要做用户系统
几乎每个应用都会用到用户系统。如果能够进行通用化,自然是一种很快意的事了。然而到目前为止我还没有找到一个让我满意的类似的东西。不是说它们不够好,而在于它们不能满足管理和部署上的可伸缩性、灵活性及与现有应用的可集成性上,所以只好自己做了一个。
阅读全文
posted @
2008-04-21 10:19 李学斌 阅读(3445) |
评论 (25) |
编辑
摘要: 在”项目à产品à平台我的编程人生“中大体说明了一下我在一个什么样的需求环境下要搭建一个平台,及要建成一个什么样的平台之后,本文将着重讲一下这个平台的体系结构,及设计要点。有下面的内容:
l 设计要点
Ø 应用与Web Service(简称WS)分离。
Ø 数据库与WS分离
Ø 应用集成
l 结构说明
Ø 简化的应用调用接口
Ø 重点模块说明
Ø 心血的结晶
l 接下来的文章
阅读全文
posted @
2008-03-24 09:12 李学斌 阅读(8154) |
评论 (17) |
编辑
对于dudu
的”
博客园博客程序架构设计图初稿”我有一些想法,之所以不跟在该文章后面评论,主要是因为我感觉十分重要,还望dudu
体谅。有下面几方面的内容:
用户体验及内容服务是最重要的,
做为博客园的用户,最想知道和最关心的是改版后与改版前有什么使用上的不同,增加了那些新内容。如果这次改版对用户来讲没有什么新的体验,只是就目前的架构进行一下重新整理,我还是建议不要这么做。在决定改版之前发一正式的文以征集一下用户对使用博客园的一些想法,这可以为新版本注入新的思路。
设计的可对比性
新版本的`草图是看到了,然而有想茫然,因为不知道老版本的架构是什么样的,没有对比性,所以不知道哪些是改进的,那些是已经有的;现在哪些地方是不合理的,以及要改成什么样的。
博客园这么大一个滩子,工作量是巨大的,我想一次改成是非常困难的事情,需要有一个迭代的计划才行。哪些先改,哪些后改,根据用户的需要来一个优先级排列。
新旧版本的衔接性
有几个方面的衔接:
l 用户体验上的衔接。
l 原有架构和新架构的衔接性。
l 在新版本未出来之前,新功能的添加是否和新架构同步进行?
这些都是要认真考虑的问题.
看dudu的想法大有推倒重来的意思。这种气度令人佩服。既然公布设计草图旨在听取大家的意见,最好再把上面提到的问题让大家一起来讨论一下。说心理话我可不想在等了好久之后看到一个很“陌生”的新版博客园。
祝博客园走好!
posted @
2008-03-21 11:08 李学斌 阅读(3161) |
评论 (21) |
编辑
摘要: 如果您认为这篇文章主要讲“我”的人生经历,那就错了,我很少写感慨之类的文章。没有哗众取宠的意思,只是想说我是如何走上架构这条路的,以及架构的心得,并讲述我目前正在结构的内容。也为以后的文章做一个铺垫。
主要讲下面的几件事情:
项目à产品à平台的经过
架构心得
现在的架构内容
架构的完美性
阅读全文
posted @
2008-03-18 09:47 李学斌 阅读(8076) |
评论 (30) |
编辑
自定义审核活动
前面已经讲了许多有关自定义活动在设计上需要注意的一些事项,但对于自定义审核活动来讲,我们的设计还要有许多工作要进行。
为了简化用户的流程上的设计将流程的一些算法封装到自定义活动中可以大大增加自定义活动的使用的方便性。其直接的效果是从数十个活动减少到三四个,当然这只是针对电台文稿审核来讲的。而且基本上从根本上杜绝了IFELSE、WHILE等活动的使用,这可将用户条件编辑的复杂度降为0!这种设计所带来的另一个好处就是外界应用和工作流交互的灵活性。
可能看过本系列文章中的第一篇的都还有些印象,那里面描述了新闻文稿审核的一些用户需求,如果不太清楚,大家不妨回头看一下,这里不多讲。
审核活动的两种计算模式:
l 人员数量要求。某一条件必须要有一定人员数量的参与要求。
l 权重值和要求。当某一条件的参与人员的权重值之和要达到某一数值。
两种模式中只能在一个活动实例中选择一种模式进行使用,
每种计算模式又都有下面三种类型的载体。
l 角色:可指定多个角色, 且如果在权重值和模式下角色中的每个人的权重值应来源于角色的权重值。或在人员数量要求模式下可以指定总的人员数量要求及每个角色的人员数量要求。
l 人员:可指定参与的人员列表,可有人员数量要求或权重值要求。
l 用户组:和角色的要求类似
每种计算模式中只能使用一种载体,
在现实情况下这些已经足够了。其它许多复杂的情况都可以分解为多个简单的活动实例来处理;这样在程序逻辑和业务管理上都是相对简单和高效的。
自定义审核活动有三个条件:
l 通过条件:满足该条件后,活动便可顺利执行完成。
l 回退条件:满足该条件后,该过程处理起来有一点复杂,下面会讲。
l 不通过条件:满足该条件后,则立即结束WF实例的运行,并从数据库中进行清除。
有人担心这三个条件会在运行时,同时满足。情况有可能是这样的,这主要是因为处理过程中没有锁定和保持状态的一致性所引起的。这个锁定不是简单的WF实例加载时的锁定,而是用于活动处理的数据收集同WF实例的联合锁定及状态持久化。
关于用户数据的收集同实例的运行进行分离并放在同一事务中保持状态的一致性及运用锁定机制和尽量减少锁定时间等话题请参阅前面的文章。
但是还是会有糟糕的事情发生,那就是所有的条件都不可能满足!这不是程序逻辑的功能所引起的问题,而是业务逻辑的问题。这种问题是程序无法去控制的。举个例子:如在设计时要求的人员数量大于实际的人员数量就会发生这种问题。
有关用户系统中的数据
首先我不喜欢这里所谈的问题,它涉及到自定义审核活动的通用性。自定义审核活动在设计时需要指定上面所讲的一系列属性。对于计算模式和三个条件设置来讲是比较简单的,问题出在载体上。“用户、用户组、角色”这些数据的存储与提取会因具体应用而有所不同;包括运行时审核数据的提取都是一个紧耦合的问题。如果要进行松耦合,这里必须要进行相应的映射和转换处理才可以。这会对部署和二次开发带来额外的要求!
但这是值得的,为此我们需要强制定义数据的形态(:)类型)以接收标准的数据(相对于自定义审核活动来讲)。而由应用来做数据的提取与转换。需要说明的是,仅“用户、用户组、角色”的定义还是不够的,在运行时我们还需要把用户的审核信息也必须加以定义才可以。
对实例进行监视及警告
我们不能要求用户所设计的业务逻辑是没有问题的,我们也无法去阻止这种错误的发生,但我们应该有一个监视机制来提醒用户那些WF实例已经好久没有处理了。可以用WF自带的Track&Trace来实现记录WF实例运行的细节。但个人认为那样会产生很多的无用数据,而且要进行清理维护操作。其实有一种更简捷的方法来找出这些停滞了的WF实例:用户审核数据。这些数据包括用户信息,用户的审核意见及所对应的WF设计ID和自定义审核活动ID(需要单独的表来维系WF设计ID和自定义审核活动ID与审核数据的关系)。利用这些数据做一个查询窗口就可以找到“死掉”的WF实例。并给用户提供一个真正杀死WF实例的机会。
Level变量
这是自定义审核活动的一个公共变量,这个变量具有重要意义,它是实现回退处理、再提交、跨审的关键点。如何利用Level变量去实现这些功能先放一下。为了便于后面的理解,先讲一下Level的规则。
每一个自定义审核活动都有一个Level变量。且在设计时,进行指定。Level的值必须是一个整数值。后一个活动实例的Level值必须是前一个活动Level值与1的和。我们必须在WF设计时进行这种Level值的验证,否则上一段所提到的要实现的功能将无法正常工作!
在自定义审核活动之外我们还需要维系一个关系表,这个表包含下面的主要信息:
l WF实例ID
l 下一个自定义审核活动的Level值,会将该值传递给WF实例中的CurrentLevel变量。
l 工件ID
记住,WF设计图里面没有IFELSE、WHILE和其它非自定义审核活动。有了这张表会方便提取针对某一用户所需要运行的WF实例列表。
回退处理与再提交
WF自定义审核活动实例在运行过程中如果发现满足了回退条件,则活动会创建一个新的WF实例并将Level的值减1赋给新的WF实例并结束清除当前WF实例。不过这里有一个前提条件:只有所在的活动位于第二层或以上,才可以有回退的功能。这样处理后,前一级已经审核处理过的人员就又可以再次进行审核操作了。
这里有以下几个设计要点:
l 回退会创建新的WF实例。这可能是大家都没有想到的事情,其实这就是利用Level属性来简化这种WF设计时的工作精髓所在。从而使设计者不去关心如何在设计界面上“画出”各层之间的复杂的流转关系;而只是关心有几层,并在每层上设计相关的属性便可以了。
l 用户的审核数据必须区分不同WF实例,而不是用稿件进行区分。
l 一个稿件可以有多个WF实例与之关联
有人可能存在疑虑,一个WF实例被分成多次运行会造成数据的切割现象,其实这个问题可以这样来理解。我们用WF的目的是用它的流程“控制”而不是去注重“数据的连续”,数据的连续性其实已经由用户审核数据实现了,所以可以不必关心跨多个WF实例的问题。
跨审的实现
跨审的实现也是借助于Level属性值来工作的。只要所对应的Level值高的用户就可以提调比当前自定义审核活动Level值低的WF实例来运行。只是在运行时将其Level的值设置成该用户所对应的活动的Level值便可以了。
自定义审核活动有这么一个逻辑处理:如果当前WF实例的Level值大于当前活动的Level值则该活动直接运行完毕,以过渡到下一个活动中去;直到Level值相等时再进行审核的业务操作。
自定义审核活动与外界数据的交换
Level是如何被改变的,这可能是大家关心的问题。在这里我们有多种方案可进行选择。
l 静态成员的访问:我们可以把要交换的数据放到一个静态成员变量中。
l AddService:WFRunTime(对不起,我简写了)和Host是运行在两个不同的线程中的。但WFRunTime有一个AddService的函数可以把Host中的任何东西加入到WF所在环境中去。这样WF实例可以通过GetService来得到该对象。
l 创建实例时指定参数:这个方法只能在创建时进行参数的传递,但对于多次加载的WF实例是无法重新指定这些参数的。
l communication services interfaces:这是WF SDK里面的东西。主要用于事件和方法,所以最好不要用。
对于Level来讲回退里可用指定的Level来创建新的WF实例;对于跨审和其它情况来讲,则在实例运行前利用第一、二两点的任何一种方法对其实例的Level进行赋值,然后再运行。
其它问题
就现在的情况来看,用户在设计时不需要复杂的设计就可以定制一个“复杂”的审核处理流程。包括逐级递审,回退、跨审等。但这都是人为干预的审核,对于自动审核来讲还是不完善的。自动审核(不是智能审核稿件内容)是指在一定时间内如果没有人为给出审核意见,则自动递交到下一个审核层次上去。这样我们就会相中Delay活动。
如果用Delay就会用到Listen。这会带来一个新的问题!我们的自定义活动必须要有接受外界触发的能力才可以将Delay和我们的审核活动放到Listen中去。如何做?真是两难的选择!我们如果扩展了IActivityEventListener接口,那么我们的审核活动的使用模式便会进行改变!!我不做结论,但很想听一下读者的意见。
写到这里,该结束了。回头看看不觉有些惭愧,平台的东西太少,模板的东西太多。本来还想写一下WF与工件的维护框架,WF设计管理框架。现在看来相对简单,就不写了。如果有什么问题,只要不是基础性的问题,我还是很愿意和大家一起讨论的。
完……。
posted @
2007-06-25 10:14 李学斌 阅读(3176) |
评论 (14) |
编辑
摘要: 自定义活动(五)
中止活动的运行
无论用停止、放弃、中止或中断等之类的这些词都不能很直接地表达我这里所表达的意思!这是目前为止我遇到的封装业务逻辑到自定义活动的最大障碍;因为就自定义审核活动来讲,用户所设计的工作流中每一个活动可能被多次执行。例如需要多个人参与同一个层次的审核,当条件不满足是便“停止”运行,然后等待下一个用户来输入用于计算的基础数据,并重新执行该逻辑,直到条件满足该活动执行完毕并过渡到下一个活动为止。需要特别说明一下,这里的自定义活动的逻辑包含了基础数据的读取,条件的判断及是否往下执行、原地等待还是回退的处理,而不是用一大堆WF预置的活动来支持,全部功能都封装于一个活动之内;另外这里不对回退进行说明,有关回退的内容请看后续的文章。
在WF的SDK中有一个很关键的术语“persistence point”,它决定了下次加载时WF实例开始运行的点。我将用这个词语来解释一些问题,让我们来看一下它在我们“中断”工作流中所产生的影响!
……
至此同一个活动可重复执行的问题得到了解决。至此自定义活动的话题也将结束。下面将针
阅读全文
posted @
2007-06-11 09:17 李学斌 阅读(2656) |
评论 (15) |
编辑
自定义活动(四)
保持状态的一致性及完整性
上一节讲过,要完成一个审核活动所要处理的数据有下面的内容
l工件进行编辑并进行保存
l记录工件的审核情况
l运行完后保存WF实例的状态
通过上面我们可以看到在工作流活动运行之外我们还进行了一些数据的操作,就自定义审核活动来讲,在WWF的一些技术细节与应用体会(二)中我提到过活动执行的完整性及一些实现方法,在这里是用不上的,因为我们的部分数据在工作流之外进行了处理。我们必须在工作流运行环境之外提供一个将数据的收集、工件的编辑及活动运行后WF实例的持久化放在同一事务中。
另在开发自定义审核活动时我们需要指定PersistOnClose属性。否则这个状态将不会被记录。这个属性非常关键!我们只希望在活动运行完成时自动进行持久化以便使工作流过渡到下一个活动中去。但将条件不满足时,放弃运行(不是中止!)。这对数据的状态一致性也非常重要。
待续……
posted @
2007-06-05 08:59 李学斌 阅读(2454) |
评论 (10) |
编辑