2010年9月16日
摘要: 一、分布式实现原理
如上图所示,主要通过Apache-Server作为中转服务器,实现多个tomcat服务器之间的分布式处理,用户直接请求Apache-Server,然后Apache-Server会将请求分发到具体的tomcat-server,之...
阅读全文
posted @
2011-06-22 16:09 obpm 阅读(8196) |
评论 (4) |
编辑 收藏
从设计理念层面看abstract class和interface
上面主要从语法定义和编程的角度论述了abstract class和interface的区别,这些层面的区别是比较低层次的、非本质的。本小节将从另一个层面:abstract class和interface所反映出的设计理念,来分析一下二者的区别。作者认为,从这个层面进行分析才能理解二者概念的本质所在。
前面已经提到过,abstarct class在Java语言中体现了一种继承关系,要想使得继承关系合理,父类和派生类之间必须存在"is a"关系,即父类和派生类在概念本质上应该是相同的(参考文献〔3〕中有关于"is a"关系的大篇幅深入的论述,有兴趣的读者可以参考)。对于interface 来说则不然,并不要求interface的实现者和interface定义在概念本质上是一致的,仅仅是实现了interface定义的契约而已。为了使论述便于理解,下面将通过一个简单的实例进行说明。
考虑这样一个例子,假设在我们的问题领域中有一个关于Door的抽象概念,该Door具有执行两个动作open和close,此时我们可以通过abstract class或者interface来定义一个表示该抽象概念的类型,定义方式分别如下所示:
使用abstract class方式定义Door:
abstract class Door {
abstract void open();
abstract void close();
}
使用interface方式定义Door:
interface Door {
void open();
void close();
}
其他具体的Door类型可以extends使用abstract class方式定义的Door或者implements使用interface方式定义的Door。看起来好像使用abstract class和interface没有大的区别。
如果现在要求Door还要具有报警的功能。我们该如何设计针对该例子的类结构呢(在本例中,主要是为了展示abstract class和interface反映在设计理念上的区别,其他方面无关的问题都做了简化或者忽略)?下面将罗列出可能的解决方案,并从设计理念层面对这些不同的方案进行分析。
解决方案一:
简单的在Door的定义中增加一个alarm方法,如下:
abstract class Door {
abstract void open();
abstract void close();
abstract void alarm();
}
或者
interface Door {
void open();
void close();
void alarm();
}
那么具有报警功能的AlarmDoor的定义方式如下:
class AlarmDoor extends Door {
void open() { … }
void close() { … }
void alarm() { … }
}
或者
class AlarmDoor implements Door {
void open() { … }
void close() { … }
void alarm() { … }
}
这种方法违反了面向对象设计中的一个核心原则ISP(Interface Segregation Priciple),在Door的定义中把Door概念本身固有的行为方法和另外一个概念"报警器"的行为方法混在了一起。这样引起的一个问题是那些仅仅依赖于Door这个概念的模块会因为"报警器"这个概念的改变(比如:修改alarm方法的参数)而改变,反之依然。
解决方案二:
既然open、close和alarm属于两个不同的概念,根据ISP原则应该把它们分别定义在代表这两个概念的抽象类中。定义方式有:这两个概念都使用abstract class方式定义;两个概念都使用interface方式定义;一个概念使用abstract class方式定义,另一个概念使用interface方式定义。
显然,由于Java语言不支持多重继承,所以两个概念都使用abstract class方式定义是不可行的。后面两种方式都是可行的,但是对于它们的选择却反映出对于问题领域中的概念本质的理解、对于设计意图的反映是否正确、合理。我们一一来分析、说明。
如果两个概念都使用interface方式来定义,那么就反映出两个问题:1、我们可能没有理解清楚问题领域,AlarmDoor在概念本质上到底是Door还是报警器?2、如果我们对于问题领域的理解没有问题,比如:我们通过对于问题领域的分析发现AlarmDoor在概念本质上和Door是一致的,那么我们在实现时就没有能够正确的揭示我们的设计意图,因为在这两个概念的定义上(均使用interface方式定义)反映不出上述含义。
如果我们对于问题领域的理解是:AlarmDoor在概念本质上是Door,同时它有具有报警的功能。我们该如何来设计、实现来明确的反映出我们的意思呢?前面已经说过,abstract class在Java语言中表示一种继承关系,而继承关系在本质上是"is a"关系。所以对于Door这个概念,我们应该使用abstarct class方式来定义。另外,AlarmDoor又具有报警功能,说明它又能够完成报警概念中定义的行为,所以报警概念可以通过interface方式定义。如下所示:
abstract class Door {
abstract void open();
abstract void close();
}
interface Alarm {
void alarm();
}
class AlarmDoor extends Door implements Alarm {
void open() { … }
void close() { … }
void alarm() { … }
}
这种实现方式基本上能够明确的反映出我们对于问题领域的理解,正确的揭示我们的设计意图。其实abstract class表示的是"is a"关系,interface表示的是"like a"关系,大家在选择时可以作为一个依据,当然这是建立在对问题领域的理解上的,比如:如果我们认为AlarmDoor在概念本质上是报警器,同时又具有Door的功能,那么上述的定义方式就要反过来了。
转载人员-Nicholas
posted @
2010-11-07 13:57 obpm 阅读(552) |
评论 (4) |
编辑 收藏
可关闭的TabbedPane结构:
测试代码:
package cn.demo.test;
import java.awt.Component;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.UIManager;
/**
* Test
* @author Tom
*
*/
public class TestDemo {
public static void main(String[] args) {
try {
String feel = UIManager.getSystemLookAndFeelClassName();
UIManager.setLookAndFeel(feel);
} catch (Exception e) {
e.printStackTrace();
}
JFrame frame = new JFrame();
frame.setTitle("可关闭Tab测试");
frame.setSize(300, 400);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
TabbedPane tabbedPane = new TabbedPane();
tabbedPane.setCloseButtonEnabled(true);
tabbedPane.addTab("测试一", null, new JLabel("测试一"));
tabbedPane.addTab("测试二", null, new JLabel("测试二"));
tabbedPane.addTab("测试三", null, new JLabel("测试三"));
tabbedPane.addTab("测试四", null, new JLabel("测试四"));
tabbedPane.addTabbedPaneListener(new TabbedPaneListener(){
@Override
public void allTabsRemoved() {
// TODO Auto-generated method stub
}
@Override
public boolean canTabClose(Tab tab, Component component) {
// TODO Auto-generated method stub
return false;
}
@Override
public void tabAdded(Tab tab, Component component, int index) {
// TODO Auto-generated method stub
}
@Override
public void tabRemoved(Tab tab, Component component, int index) {
// TODO Auto-generated method stub
System.out.println("close");
}
@Override
public void tabSelected(Tab tab, Component component, int index) {
// TODO Auto-generated method stub
}
});
frame.add(tabbedPane);
frame.setVisible(true);
}
}
测试效果:
源码下载:TabbedPane.rar
发表人: Tom
posted @
2010-10-24 16:44 obpm 阅读(6113) |
评论 (2) |
编辑 收藏
在数据库层使用SQL分页可以很大程度增加平台系统程序运行速度与效率。本人只是初入手半数据库半程序的开发,所以对数据库研究不深。于是要收集下列代码以作参考,同时也Post出来可以让需要的人参考一下,高手就请见笑了。说转载说不上,说原创也... 国庆期间在家家里的机子跑DB比较困难,做不了过多测试。不过语句或函数方面本人都仔细看过抄回来的SQL的网页里示例,感觉基本上大同小异,如果有错误查下做相应的修改或百度Google一下应该没什么大问题,也请多多包涵。当然,有机会就会对下列SQL做测试,然后会进行修正。至于每个数据库分页在这就不进行深究,只是列出个可用的方法。
##########
# MySQL#
##########
select * from tlk_buginfo limit startPos, pageSize
startPos: 定义当前页起始位置(不包括startPos)
pageSize: 每页显示数据的条数
##########
# MSSQL#(2005的row_number,暂无2000)
##########
1、
--返回第20-40行数据
select top 20 * from (select row_number() over (order by EmployeeID) as RowNumber, * from HumanResources.Employee) TableNickname where RowNumber>=20
2、
--返回第20-40行数据
select * from (select row_number() over (order by EmployeeID) as RowNumber, * from HumanResources.Employee) TableNickname where RowNumber between 20 and 40
3、
--返回第20-40行数据
with OrderedResults as
(select *, ROW_NUMBER() OVER (order by EmployeeID) as RowNumber FROM HumanResources.Employee)
select * from OrderedResults where RowNumber between 20 and 40
##########
# Oracle#
##########
①采用rownum关键字(三层嵌套)
--返回第5-15行数据
select * from (select row_.*, rownum num from (select * from tlk_buginfo) row_ where rownum<=15) where num>=5
②采用row_number解析函数进行分页(效率更高)
--返回第5-15行数据
select tab.* from (select t.*, row_number() over (order by lastmodified) as num from tlk_buginfo t) tab where num between 5 and 15
##########
# DB2#
##########
select * from (select *, rownumber() over(order by 排序字段 asc ) as rowid from 表名 )as a where a.rowid >= startPage AND a.rowid <endPage
##########
# Hsqldb#
##########
select LIMIT 0 10 表名
收集资料:(allen)
posted @
2010-10-10 21:32 obpm 阅读(383) |
评论 (1) |
编辑 收藏
(denny)
posted @
2010-10-08 00:11 obpm 阅读(1457) |
评论 (1) |
编辑 收藏
HTML5 是近十年来 Web 标准最巨大的飞跃。和以前的版本不同,HTML 5 并非仅仅用来表示 Web 内容,它的使命是将 Web
带入一个成熟的应用平台,在这个平台上,视频,音频,图象,动画,以及同电脑的交互都被标准化。尽管 HTML 5 的实现还有很长的路要走,但 HTML 5 正在改变
Web。
HTML 最近的一次升级是1999年12月发布的 HTML
4.01。自那以后,发生了很多事。最初的浏览器战争已经结束,Netscape 灰飞烟灭,IE5 作为赢家后来又发展到 IE6, IE7到IE8。Mozilla
Firefox 从 Netscape 的死灰中诞生,并跃居第二位。苹果和 Google 各自推出自己的浏览器,而小家碧玉的 Opera
仍然嘤嘤嗡嗡地活着,并以推动 Web 标准为己命。我们甚至在手机和游戏机上有了真正的 Web 体验,感谢 Opera,iPhone 以及 Google
已经推出的 Android。
然而这一切,仅仅让 Web 标准运动变得更加混乱,HTML 5 和其它标准被束之高阁,结果,HTML 5
一直以来都是以草案的面目示人。
于是,一些公司联合起来,成立了一个叫做 Web Hypertext Application
Technology Working Group (Web 超文本应用技术工作组 - WHATWG) 的组织,他们将重新拣起 HTML 5。这个组织独立于
W3C,成员来自 Mozilla, KHTML/Webkit 项目组,Google,Apple,Opera 以及微软。尽管 HTML 5
草案不会在短期内获得认可,但 HTML 5 总算得以延续。
HTML 5 将带来什么?以下是 HTML 5 草案中最激动人心的部分:
全新的,更合理的 Tag,多媒体对象将不再全部绑定在 object 或 embed Tag
中,而是视频有视频的 Tag,音频有音频的 Tag。本地数据库。这个功能将内嵌一个本地的 SQL 数据库,以加速交互式搜索,缓存以及索引功能。同时,那些离线
Web 程序也将因此获益匪浅。不需要插件的富动画。Canvas 对象将给浏览器带来直接在上面绘制矢量图的能力,这意味着我们可以脱离 Flash 和
Silverlight,直接在浏览器中显示图形或动画。一些最新的浏览器,除了 IE,已经开始支持 Canvas。浏览器中的真正程序。将提供 API
实现浏览器内的编辑,拖放,以及各种图形用户界面的能力。内容修饰 Tag 将被剔除,而使用 CSS。理论上讲,HTML 5 是培育新 Web
标准的土壤,让各种设想在他的组织者之间分享,但 HTML 5 目前仍处于试验阶段。
Mozilla 的技术副总裁 Mike Shaver 说,HTML 5 是一个被寄予厚望的概念,它既是
WHATWG 组织的实验田,又是 W3C 的标准之路。
Shaver 认为,Mozilla 的兴趣和 WHATWG 实验相吻合,Mozilla 在 HTML 5
工作组中非常活跃,我们对一些早期的细则进行实验并将成熟的结果提交 W3C。
在过去的几年,Mozilla 随着各种出现的新标准,推出多个富有前瞻性的项目,包括
Prism,一个用于离线运行 Web 程序的系统,以及 Weave,一个数据存储框架。
Shaver 说,HTML 5 运动肇始于对 W3C 的不耐烦,Web 标准中的很多进展都因 W3C
将重点从 HTML 转移到 XML 而停滞不前。
很多基于 XML 架构的新技术被设计出来替代 HTML,Shaver
说,这不是一条正确的道路,人们不应象黑瞎子掰玉米把样一边掰一边丢。
HTML 5 的新实验在 Firefox 以及 基于 Webkit 的 Safari 和 Chrome
浏览器中逐渐得到强化,但仍有不少问题。
Chrome 的开发者 Darin Fisher 说,Chrome
仍在襁褓中时,就不得不面临几个问题,尽管使用的是最新的 Webkit,HTML 5 的本地数据库功能在 Chrome 的初期版本中并没有实现。因为 Chrome
的沙箱机制和 Webkit 的数据库功能有冲突。
而由于 Chrome 属于秘密开发,Chrome 的开发人员也不便参与 Webkit 的开发。
我们要想保守 Chrome 的秘密,就无法参与 Webkit 社区。Fisher
说,我们很希望可以在某些方面给 Webkit 以帮助,我们拥有众多经验丰富的开发者,我们很想知道人们目前遇到的挑战并乐意提供帮助。
随着 Chrome 的发布,Fisher 说他的团队成员有时会和 Webkit
的人一起吃饭,有些人私下里还成了好朋友。Fisher 称,他们迫切地想同其他 Webkit 开发组一起工作解决离线数据库的问题。
Chrome 里面还包含Google 的开源 Gears 技术,用来实现与 HTML 5 类似的离线功能。
Gears 可以看作已有 API 的替代品,Fisher 说,HTML 5
对新浏览器来说是非常好的东西,但绝大多数用户还使用旧浏览器。Gears 可以让那些旧浏览器也获得这样的 API,我们正在为 HTML 5 版 API 提供兼容。
Gears 兼容性非常好,它正成为将 HTML 5 带向人们桌面的另外一条途径。
目前,绝大多数工作由 Apple,Mozilla, Opera, Google 以及 Trolltech
展开。微软在干什么?IE 因其对 Web 标准的迟钝而闻名,更不要说 HTML 5。但 IE8 可能会做出改变。
微软 IE 平台与 WHAT 工作组主席 Chris Wilson
在邮件中称,我们希望我们现在开始的工作可以在 HTML 工作组创建一套测试系统。Wilson 说,IE 开发组仍然对 HTML 5
的一些提议感到担忧。我觉得工作组的所有成员都会承认我们还有很多事要做。
目前处于 Beta 版的 IE9,已经包含 HTML 5
的诸多新功能。它拥有一个跨文档消息系统,本地存储,以及一些离线事件来检测网络的中断。但还有些功能还未提上议程,如 Canvas。
HTML 5
非常庞大,仍处在开发阶段,我认为浏览器厂商应当尽快达成一致,而每个浏览器的具体实现时间可以自己选择。Web 开发者和浏览器厂商会同意 Wilson
的下面这句话,这确切无疑是一个激动人心的时刻,我们希望看到 Web 成为新的应用平台。
HTML5写的例子(IE9或google浏览器才有效果):
HTML5学习资料:
http://www.chinabyte.com/bang/html5/
收集资料:(denny)
posted @
2010-10-07 21:46 obpm 阅读(2101) |
评论 (1) |
编辑 收藏
首先,在jbpm4中,流程定义相关的部署信息就存在
JBPM4_DEPLOYMENT、
JBPM4_DEPLOYPROP及
JBPM4_LOB (存放当发布一个png和xml文件后的流程定义后的记录)。中。
JBPM4_HIST_PROCINST、
JBPM4_HIST_ACTINST两张表中,分别存放的是process Instance、Activity Instance的历史记录,Activity Instance是指流程定义中各个步骤:task descition等存放Process Instance、Activity Instance历史记录的表有了,那他们的当前记录存在什么地方呢?这就需要弄清楚jBPM的另外几个概念。一般而言,在jBPM中,“a process instance is the root of a tree of executions”。因此,当一个流程实例Split出两个并行步骤的时候,在
JBPM4_EXECUTION表中将有三笔相关记录,一笔是代表流程实例的Root Execution,另外两笔是关于上述两个并行步骤的Child Execution。
此外,在jbpm中,Activity的种类是很丰富的,可以是Control Flow Activities,如sub-process,decision等,也可以是Automatic Activity,如java、script、sql等,其中需要人来参与完成的Activity被称为Task,待办任务放在
JBPM4_TASK表中,而历史任务放在
JBPM4_HIST_TASK表中。
对一个Task而言,它可能会有多个Participation(swim lane 同样会有多个Participation),Participation的种类有Candidate、client、owner、Replaced Assignee和viewer,而具体的Participation既可以是单一用户,也可以是用户组,Participation的信息存放在
JBPM4_PARTICIPATION中。
Swim Lane是一种Runtime Process Role,通过Swim Lane,多个Task可以一次分配到同一Actor身上,存放这些信息是表
JBPM4_PARTICIPATION。
JBPM4_ID_GROUP、
JBPM4_ID_MEMBERSHIP、
JBPM4_ID_USER这是基本的权限控制,建议关于用户认证方面还是自己开发一套,这个功能太简单了,难以满足需求。
JBPM4_JOB存放的是Timer的定义。
JBPM4_PROPERTY这是jbpm引擎参数表。
JBPM4_VAR表存放流程临时变量,当流程实例结束后,表中内容清除。
JBPM4_HIST_VAR表存放历史临时变量,但是jbpm4好像还没有对这张表进行利用。
JBPM4_HIST_DETAIL表保存变量变更记录。
了解jbpm4.3以上这18张表后,我们应该在流程运行中,详细观察jbpm是如何对这些表进行操作,以及进行什么样的操作的。
发布一个流程定义后:
JBPM4_DEPLOYMENT新增一条记录
JBPM4_DEPLOYPROP新增三条记录
JBPM4_LOB新增两条记录
开始一个流程startProcessInstanceByKey后:
JBPM4_EXECUTION新增一条记录
JBPM4_TASK新增一条记录
JBPM4_HIST_PROCINST、
JBPM4_HIST_ACTINST分别新增一条记录
JBPM4_HIST_TASK新增一条记录
当执行taskService.setVariables(task.getId(), map);时,
JBPM4_VARIABLES中添加变量记录
转载人员:Nicholas
posted @
2010-09-16 19:51 obpm 阅读(1240) |
评论 (0) |
编辑 收藏