<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>tminglei's blog</title>
    <description></description>
    <link>http://tminglei.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>一个大型网站系统的架构建议及构想</title>
        <author>tminglei</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://tminglei.javaeye.com">tminglei</a>&nbsp;
          链接：<a href="http://tminglei.javaeye.com/blog/193954" style="color:red;">http://tminglei.javaeye.com/blog/193954</a>&nbsp;
          发表时间: 2008年05月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          改行了，不再做软件开发了，之前工作中做过的一些有价值的东西陆续发布在这，希望对其他人有用。<br /><br />------------------------------------------------------<br />这是我在上一家做网络交友的公司工作时提出的架构草案的所有相关文档。不过没有被采纳，甚至我本人还因为表达了想法而惹了麻烦。^^<br /><br />打包附件的文档结构：<br />--一个网站架构的建议及构想.doc：方案最初的思路和构想<br />--Web Site System Architecture.ppt：用于展示并得到加深和扩展的方案构想<br />--WS_Client_API_Design.doc：方案中一重要特性的展开<br />--\Frameworks_UML\：架构中主要框架（Spring、Struts2、OpenJPA等）的原理及架构要点图<br /><br />（注：.jude文件可用JUDE软件打开）<br /><br />----------------------------------------------------<br />方案文档节选：<br />序言：灵活、简单和标准化是第一位的。灵活，就给以后的功能扩展、性能调优等留下了极大的回旋余地。简单，实现简单和理解简单，就更少负担，更容易沟通和协作。标准化，就给超出部门企业范围的有效信任和协作埋下了种子。复杂系统的构建，需要能有效整合多方有益的资源。动态系统的成长，需要能支持不断的调整和重构。<br /><br />一、基本需求及目标<br />按照主站+合作网络、不断增加多种应用及访问接入方式的发展模式，系统应有足够灵活的架构，以支持多种表现层/客户端，集成多种服务形式，拓展新功能，同时保持良好的性能。系统共享一个数据库，数据一致性和安全相当重要。<br /><br />应该提供给应用开发者一个容易理解和使用的开发环境，能快速实现和不断完善各种应用；应该提供给界面设计者一个界面元素丰富的开发环境，能灵活的表现设计意图并支持重用；应该提供给产品设计者一个简单清晰的思维框架，能够容易的设计和把握产品的要点和细节。（架构本身只是一个骨架，它的血肉要靠各位设计开发人员来填充。但架构提供的平台应能很好的把各类设计开发人员黏合在一起，提供一个很好的起点。）<br /><br />系统应能巧妙收集各类用户信息，不断改进用户体验带来更多用户价值。（网站的各种产品应该成为企业和用户之间沟通互动的主要渠道。）<br /><br />......
          <br/>
          <span style="color:red;">
            <a href="http://tminglei.javaeye.com/blog/193954#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 17 May 2008 20:33:06 +0800</pubDate>
        <link>http://tminglei.javaeye.com/blog/193954</link>
        <guid>http://tminglei.javaeye.com/blog/193954</guid>
      </item>
      <item>
        <title>一些扩展或新实现的Swing控件</title>
        <author>tminglei</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://tminglei.javaeye.com">tminglei</a>&nbsp;
          链接：<a href="http://tminglei.javaeye.com/blog/193952" style="color:red;">http://tminglei.javaeye.com/blog/193952</a>&nbsp;
          发表时间: 2008年05月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          改行了，不再做软件开发了，之前工作中做过的一些有价值的东西陆续发布在这，希望对其他人有用。<br /><br />附件是这些控件的源码及Rose设计文档，相关说明如下：<br />1、com.ctic.core.pub.ui.CExtComboBox.java，以及com.ctic.core.pub.ui.support.NVConvertor. java（其中NVConvertor是几乎所有名值解决方案的核心接口）；<br />2、com.ctic.core.pub.ui.CExtList.java。相关的，助手类com.ctic.core.pub.ui.support. CompoundListListenerHelper.java用于实现组合列表；<br />3、com.ctic.core.pub.ui.CExtTable.java和com.ctic.core.pub.ui.support.CExtTableModel.java，以及com.ctic.core.pub.ui.support.SorterTableModel.java和com.ctic.core.pub.ui.support.table下的文件；<br />4、com.ctic.core.pub.ui.CExtTree.java和com.ctic.core.pub.ui.TreeChooser.java；<br />5、com.ctic.core.pub.ui.DateChooser.java<br />6、com.ctic.core.pub.ui.SimplePivotTable.java<br />7、com.ctic.core.pub.ui.PagingComponent.java（分页方案的界面类）<br /><br />并且，1）com.ctic.core.pub.ui.test包下是相关控件的一些测试或示例类；2）Rose文档“Logical view -> UIComponents”是相关控件的一些设计图。
          <br/>
          <span style="color:red;">
            <a href="http://tminglei.javaeye.com/blog/193952#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 17 May 2008 20:13:22 +0800</pubDate>
        <link>http://tminglei.javaeye.com/blog/193952</link>
        <guid>http://tminglei.javaeye.com/blog/193952</guid>
      </item>
      <item>
        <title>可以给Javabean添加动态属性特性的工具类</title>
        <author>tminglei</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://tminglei.javaeye.com">tminglei</a>&nbsp;
          链接：<a href="http://tminglei.javaeye.com/blog/193949" style="color:red;">http://tminglei.javaeye.com/blog/193949</a>&nbsp;
          发表时间: 2008年05月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          改行了，不再做软件开发了，之前工作中做过的一些有价值的东西陆续发布在这，希望对其他人有用。<br /><br />相关说明：<br />1）可以通过两种方式让其他普通Javabean获得动态属性的特性<br />  a）继承DynamicBeanImpl类就自动获得动态属性特性；<br />  b）目标Javabean声明实现DynamicBean或Map接口，而有关接口方法的具体实现，则委托给DynamicBeanImpl<br /><br />示例代码如下：<br />1）	改造方式1的示例代码如下：<br />1）		/**<br />2）		 * 通过继承机制直接获得动态属性特性的扩展类<br />3）		 * @author Tu_Minglei<br />4）		 */<br />5）		public class MyTestBean extends DynamicBeanImpl {<br />6）			private Long id;<br />7）			private String name;<br />8）			private Object value;<br />9）	<br />10）	public Long getId() {<br />11）		return id;<br />12）	}<br />13）	public void setId(Long id) {<br />14）		this.id = id;<br />15）	}<br />16）	public String getName() {<br />17）		return name;<br />18）	}<br />19）	public void setName(String name) {<br />20）		this.name = name;<br />21）	}<br />22）	public Object getValue() {<br />23）		return value;<br />24）	}<br />25）	public void setValue(Object value) {<br />26）		this.value = value;<br />27）	}<br />}<br />2）	改造方式2的示例代码如下：<br />1）		/**<br />2）		 * 通过接口+聚合机制获得动态属性特性的扩展类<br />3）		 * @author Tu_Minglei<br />4）		 */<br />5）		public class MyTestBean2 implements DynamicBean,Map {<br />6）			private Long id;<br />7）			private String name;<br />8）			private Object value;<br />9）	<br />10）	public Long getId() {<br />11）		return id;<br />12）	}<br />13）	public void setId(Long id) {<br />14）		this.id = id;<br />15）	}<br />16）	public String getName() {<br />17）		return name;<br />18）	}<br />19）	public void setName(String name) {<br />20）		this.name = name;<br />21）	}<br />22）	public Object getValue() {<br />23）		return value;<br />24）	}<br />25）	public void setValue(Object value) {<br />26）		this.value = value;<br />27）	}<br />28）	<br />29）	@Override<br />30）	public String toString(){<br />31）		return "[id:"+id+",name:"+name+",value:"+value+"]";<br />32）	}<br />33）	<br />34）	/**++++++++++++++++++++++++++++++++++++++++++++++++++++++<br />35）	* 			说明：以下代码可以原封不动的拷入目标类中<br />36）	**++++++++++++++++++++++++++++++++++++++++++++++++++++++*/<br />37）	DynamicBeanImpl _dynamicStub = new DynamicBeanImpl(this);<br />38）	public Object get(String propName) {<br />39）		return _dynamicStub.get(propName);<br />40）	}<br />41）	public void set(String propName, Object value) {<br />42）		_dynamicStub.set(propName, value);<br />43）	}<br />44）	public void declare(String propName, Class propType) {<br />45）		_dynamicStub.declare(propName, propType);<br />46）	}<br />47）	/**---- 注：如果不需要实现Map接口，下列代码可以不拷入目标类中 ----*/<br />48）	/**--------------- for Map Implementation ---------------*/<br />49）	public Object get(Object key) {<br />50）		return _dynamicStub.get(key);<br />51）	}<br />52）	public Object put(Object key, Object value) {<br />53）		return _dynamicStub.put(key, value);<br />54）	}<br />55）	public void putAll(Map t) {<br />56）		_dynamicStub.putAll(t);<br />57）	}<br />58）	public Object remove(Object key) {<br />59）		return _dynamicStub.remove(key);<br />60）	}<br />61）	public void clear() {<br />62）		_dynamicStub.clear();<br />63）	}<br />64）	public boolean containsKey(Object key) {<br />65）		return _dynamicStub.containsKey(key);<br />66）	}<br />67）	public boolean containsValue(Object value) {<br />68）		return _dynamicStub.containsValue(value);<br />69）	}<br />70）	public Set keySet() {<br />71）		return _dynamicStub.keySet();<br />72）	}<br />73）	public Collection values() {<br />74）		return _dynamicStub.values();<br />75）	}<br />76）	public Set entrySet() {<br />77）		return _dynamicStub.entrySet();<br />78）	}<br />79）	public boolean isEmpty() {<br />80）		return _dynamicStub.isEmpty();<br />81）	}<br />82）	public int size() {<br />83）		return _dynamicStub.size();<br />84）	}<br />}<br /><br />注：DynamicBeanImpl同时实现了DynamicBean和Map接口。
          <br/>
          <span style="color:red;">
            <a href="http://tminglei.javaeye.com/blog/193949#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 17 May 2008 20:03:46 +0800</pubDate>
        <link>http://tminglei.javaeye.com/blog/193949</link>
        <guid>http://tminglei.javaeye.com/blog/193949</guid>
      </item>
      <item>
        <title>管理记录增删改状态以达到批量提交的工具类</title>
        <author>tminglei</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://tminglei.javaeye.com">tminglei</a>&nbsp;
          链接：<a href="http://tminglei.javaeye.com/blog/193948" style="color:red;">http://tminglei.javaeye.com/blog/193948</a>&nbsp;
          发表时间: 2008年05月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          改行了，不再做软件开发了，之前工作中做过的一些有价值的东西陆续发布在这，希望对其他人有用。 <br /><br />--------------------------------------------------------<br /> * 缓存记录更新（增、删、改）请求，以达到批量提交&lt;br><br /> * &lt;p>典型使用方式如下：&lt;code>&lt;pre><br /> * ICURDRequestCache curdCache = CURDRequestCacheImpl.newInstance();<br /> * ...<br /> * curdCache.addCURDRequest(bean1, ICURDRequestCache.DEL_RECORD);<br /> * curdCache.addCURDRequest(bean3, ICURDRequestCache.UPD_RECORD);<br /> * ...<br /> * Map&lt;Object,String> batchCRUDs = curdCache.getAllCURDRequests(false);<br /> * ...<br /> * &lt;/code>&lt;/pre><br /><br /><br />细节之处请查看附件源代码。
          <br/>
          <span style="color:red;">
            <a href="http://tminglei.javaeye.com/blog/193948#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 17 May 2008 19:51:35 +0800</pubDate>
        <link>http://tminglei.javaeye.com/blog/193948</link>
        <guid>http://tminglei.javaeye.com/blog/193948</guid>
      </item>
      <item>
        <title>通用差异比较和报告工具类</title>
        <author>tminglei</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://tminglei.javaeye.com">tminglei</a>&nbsp;
          链接：<a href="http://tminglei.javaeye.com/blog/193947" style="color:red;">http://tminglei.javaeye.com/blog/193947</a>&nbsp;
          发表时间: 2008年05月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          改行了，不再做软件开发了，之前工作中做过的一些有价值的东西陆续发布在这，希望对其他人有用。 <br /><br />-------------------------------------------------------<br />该工具类的使用说明如下：<br />随便传入两个对象，该工具类能告诉你：<br />1）两个对象是否有差异，更进一步，还可以告诉你<br />2）指定的分支路径有多少差异项，以及<br />3）指定的分支路径有多少特定类型的差异项<br /><br />细节之处请查看附件源代码。
          <br/>
          <span style="color:red;">
            <a href="http://tminglei.javaeye.com/blog/193947#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 17 May 2008 19:41:19 +0800</pubDate>
        <link>http://tminglei.javaeye.com/blog/193947</link>
        <guid>http://tminglei.javaeye.com/blog/193947</guid>
      </item>
      <item>
        <title>规则框架方案（草案）</title>
        <author>tminglei</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://tminglei.javaeye.com">tminglei</a>&nbsp;
          链接：<a href="http://tminglei.javaeye.com/blog/193944" style="color:red;">http://tminglei.javaeye.com/blog/193944</a>&nbsp;
          发表时间: 2008年05月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          改行了，不再做软件开发了，之前工作中做过的一些有价值的东西陆续发布在这，希望对其他人有用。<br /><br />（图片看不到的话，请下载打包了文档和代码的附件^^）<br />------------------------------------------------------------ <br /><div style="text-align: center"><span style="font-size: large"><span style="color: darkred">规则方案说明</span></span></div><br />方案简介：<br />规则方案的目标是对外提供规则（校验、计算等）服务。它提供了这样一套机制：1）针对特定对象类型，用户预先关联一些规则；2）运行时，用户传入对象实例，规则服务将找到并执行相应的规则，把结果返回给用户。<br />据此，对本方案的了解将着重于两方面：1）规则的实现及管理；2）使用运行时情况。<br /><br />实现说明：<br />一、规则的实现<br />规则封装的是一小段逻辑过程，它所处理的数据或对象一般被称为事实。在编码实现具体规则之前，开发者应该大概的考虑一下以下几点问题：<br />1）	事实对象如何获得，处理结果如何收集并传递给用户？<br />2）	规则本身的执行如果依赖其他的资源（如：其他服务、数据等）或规则，如何处理？<br />3）	规则是否应可以配置，可以嵌套组合以形成更复杂的规则？如何配置和组合？<br /><br />规则框架提供了一整套机制来回答上述问题，其大致情形可如下图所示：<br /> <br />RuleContext（环境对象）提供了规则执行时所需的一切：<br />a) 通过existFactObject(int factType, String conditions)、getFactObject(int factType, String conditions)和getFactObjects(int factType, String conditions)方法，规则可以判断执行时所需要的事实对象的存在与否，并获取之；<br />b) 通过addResult(String name, Object resultValue)和addError(String occurPlace, String errorCode, String errorContent)方法，规则可以提交执行结果或错误；<br />c) 通过getServComponent(int servType)方法，规则可以获得执行时所需的其他资源对象。<br />规则接口只有一个方法：execute(RuleContext ctx)。<br /><br />为了便于扩展和重用，规则实现类可以（可选的）实现Configurable接口。所声明的参数的具体值将在规则管理时指定，并且该规则类实例投入运行前由框架设置好。<br />为了实现规则的嵌套组合（把一系列规则组合成一个针对特定目的运行的整体），结构中引入了RuleSet接口，它和Rule接口构成了一个组合模式。用户可以在规则管理时给实现了RuleSet接口的实现类加入一系列其他规则来实现规则的嵌套。<br /><br />PS：当用户可以方便的获得RuleContext实现时，规则开发中的测试将非常简单，只需在实例化相应的规则实现类后给execute()方法传入RuleContext实现对象即可，执行结果可以直接从RuleContext实现对象的相应方法获得。<br /><br />二、规则的管理<br />规则管理的主接口是：RuleInfoService，它的实现类负责规则实现类的登记/注册、元规则描述的分门别类和预配置、实际规则描述与特定对象类型的关联和存取等。相应的过程如下图所示：<br /> <br />注：运行时，规则服务将会根据（实际）规则描述的信息实例化相应的规则实现类，并用规则描述中的配置信息去配置它。这样配置好的规则就处于可执行状态下了。<br /><br />三、运行时情况<br />RuleService接口是本框架/方案运行时的主接口，它的实现类负责根据传入的带校验对象查找相应的规则，创建RuleContext实例，运行规则，并抽取结果信息返回给用户。实际实现中的相应过程如下图所示：<br /> <br />1）	用户要求校验目标对象；<br />2）	规则服务先根据目标对象以及其他资源服务对象创建了RuleContext实例；<br />3）	规则服务接着问规则信息服务索要和目标对象相关的规则描述信息；<br />4）	针对每一条规则描述信息：<br />i)	获得相应的规则实例；<br />ii)	用规则描述中的配置信息配置它。<br />5）	从根规则开始，传入创建好的RuleContext实例嵌套的执行所有规则；<br />6）	从RuleContext实例中提取出错信息返回给用户<br /><br />最后值得提及的是，该方案支持规则的跨网络传输，可以运行在客户端构建的同样环境下。这样用户对象可以在客户端即时校验，获得更好的速度体验。并且，可以实现规则的服务器端集中部署，用户使用时动态加载和更新。<br />实现的要点是，规则开发者首先应通过接口方式获得和调用资源对象的方法，而由框架在创建RuleContext实例时根据客户端和服务器端程序运行环境的不同给它设置这些资源服务接口的不同实现。<br /><br />使用要点：<br />规则方案实际上定义了三个相关的角色：<br />规则开发者——开发在特定事实环境下运行，可以做出相应判断或得出相应结果的规则实现类；<br />规则管理者——规则的注册、分门别类、配置、关联等；<br />规则服务用户——使用规则服务校验相应对象或计算相应结果。<br /><br />三种角色的人员通力合作，才能达到规则的统一管理、扩展和重用、使用简单等方案所追求的目标。文件“com.ctic.core.prod.common.rule.RuleServiceTest.java”展示了一个简单而完整的例子，可以看看。
          <br/>
          <span style="color:red;">
            <a href="http://tminglei.javaeye.com/blog/193944#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 17 May 2008 19:25:56 +0800</pubDate>
        <link>http://tminglei.javaeye.com/blog/193944</link>
        <guid>http://tminglei.javaeye.com/blog/193944</guid>
      </item>
      <item>
        <title>分页方案</title>
        <author>tminglei</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://tminglei.javaeye.com">tminglei</a>&nbsp;
          链接：<a href="http://tminglei.javaeye.com/blog/193943" style="color:red;">http://tminglei.javaeye.com/blog/193943</a>&nbsp;
          发表时间: 2008年05月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          改行了，不再做软件开发了，之前工作中做过的一些有价值的东西陆续发布在这，希望对其他人有用。<br /><br />（这个方案是应用于Swing环境下的。需要调整到Web环境的话，前端控件要重新开发，并且要解决和Web框架的集成，但核心机制是不变的。）<br />（图片看不到的话，请下载打包了文档和代码的附件^^）<br />------------------------------------------------------------ <br /><div style="text-align: center"><span style="font-size: large"><span style="color: darkred">分页方案说明</span></span></div><br />方案简介：<br />分页方案为客户端开发用户提供这样一套机制：它托管用户的所有待浏览记录或查询记录相关的参数信息，而后根据用户的分页请求提供相应的记录。<br /><br />实现说明：<br />一、核心结构<br />分页方案围绕着由分页控件建立的机制展开，相关的结构如下：<br /> <br />&lt;图片><br /><br />分页控件是用于进行翻页的可视化控件，该控件建立了这样一种机制：根据用户的翻页请求，从IPagingWorker中取得相应的记录，并显示到IPagingViewer中。而通过PagingHelper，用户可以简单方便的创建实用的IPagingViewer和IPagingWorker。<br />典型的使用方式如下：<br />	PagingComponent pagiComp = new PagingComponent();<br />	pagiComp.setPageSize(12);<br />	pagiComp.setPagingViewer(PagingHelper.createPagingViewerFor(mTable));<br />	pagiComp.setPagingWorker(PagingHelper.createPagingWorkerFor(client.query(params)));	//(或<br />	pagiComp.setPagingWorker(PagingHelper.createPagingWorkerFor(ModuleIDs.MODULE_PROD, "productService", "queryProductList", new Class[] {Product.class}, new Object[] {paraObj}));<br />	//...<br /><br />二、助手类<br />PagingHelper，是为方便分页控件使用的助手类，当前主要用于（根据用户参数信息）创建IPagingViewer和IPagingWorker。默认实现的IPagingViewer，可以自动识别常见的界面控件及其Model，像CExtTable/CExtTableModel、CExtList/ DefaultListModel等，通过调用相应的方法而给其设置新值/记录集。<br />默认实现了两个IPagingWorker，一个简单的托管用户传入的待浏览记录集；一个托管用户查询记录所需的服务及方法名、参数等信息，通过服务器端的相应支持，可以自主获取所需范围的记录。<br /><br />三、后台支持<br />IPagingWorker的第二种默认实现的相关结构如下：<br /> <br />&lt;图片2><br /><br />MethodPagingWorkerImpl托管了用户查询记录所需的服务及方法名、参数等信息，使用这些信息，通过PagingService可以获得总记录数等相关信息，通过UserService（用户的服务）可以获得指定范围的记录。<br />注意，指定范围的记录是通过UserService获得的，而原本的UserService以及相关的UserDAO是不能获取指定范围的记录的。这是怎么回事呢？<br />分页所需的额外信息是通过用户参数对象携带的（这要求改造用户参数对象，使之能存放除正常用户数据之外的信息；一般可通过DynamicBean及其实现类DynamicBeanImpl来完成），由MethodPagingWorkerImpl在客户端存入，并由UserDAO在服务器端取出并使用。用户可以通过PagingUtils来从用户参数对象中存取这些信息，该类封装了相关的实现细节。相关的示例代码如下：<br />return getSqlMapClientTemplate().queryForList("T_PRODUCT. selectByProdObj", paraObj, PagingUtils. getSkipResults (paraObj), PagingUtils. getMaxResults(paraObj));<br /><br />（注：更多的设计及实现细节，请参阅相关的Rose设计及源码。）<br /><br />使用要点：<br />在使用分页方案的过程中，用户需要做的工作如下：<br />1、在UserPanel中，创建PagingComponent，设置每页记录数，并调用PagingHelper的相应方法创建PagingViewer和PagingWorker来配置它；（如果创建的是PagingWorker的MethodPagingWorkerImpl实现，继续）<br />2、服务器端，在DAO实现中，把原来调用SqlMapClientTemplate的queryForList (statementName, parameterObject)方法的地方，改为调用queryForList (statementName, parameterObject, skipResults, maxResults)方法。而skipResults、maxResults的值，可通过PagingUtils的相应方法获得；（可选）<br />3、用DynamicBean/DynamicBeanImpl改造相应的参数对象。（可选）<br /><br />注：a）上述2、3步的任何一步缺失，均不会造成程序运行异常，但会使方案达不到真正的分批获取并缓存记录的效果，而是一次性全部获取并缓存在客户端；<br />b）另外，即使使用的是PagingWorker的SimplePagingWorkerImpl实现，也可以在所有相关的DAO及参数Model的代码中做上述2、3步的调整，不会造成程序运行异常。
          <br/>
          <span style="color:red;">
            <a href="http://tminglei.javaeye.com/blog/193943#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 17 May 2008 19:18:06 +0800</pubDate>
        <link>http://tminglei.javaeye.com/blog/193943</link>
        <guid>http://tminglei.javaeye.com/blog/193943</guid>
      </item>
      <item>
        <title>动态属性方案</title>
        <author>tminglei</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://tminglei.javaeye.com">tminglei</a>&nbsp;
          链接：<a href="http://tminglei.javaeye.com/blog/193940" style="color:red;">http://tminglei.javaeye.com/blog/193940</a>&nbsp;
          发表时间: 2008年05月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          改行了，不再做软件开发了，之前工作中做过的一些有价值的东西陆续发布在这，希望对其他人有用。<br /><br />（图片看不到的话，请下载打包了文档和代码的附件^^）<br />------------------------------------------------------------<br /><div style="text-align: center"><span style="font-size: large"><span style="color: darkred">动态属性方案说明</span></span></div><br />方案简介：<br />一般情况下，最终用户可操作存取的数据范围受限于预先定义或编码的数据库表字段及Java Model类的属性声明。动态属性方案让用户得以突破这些限制，可以动态增删属性或字段，对之编辑并存取。<br />方案可以分为两部分，一部分是使普通JavaBean具有动态属性的特性；一部分是提供对这些动态属性的界面编辑及持久化的支持。<br /><br />实现说明：<br />一、使普通JavaBean具有动态属性特性<br />改造普通JavaBean，使之具有动态属性特性的职责，由接口DynamicBean及其实现类DynamicBeanImpl承担。只需轻微调整普通JavaBean的代码，即可使其获得动态属性的特性，同时保持原有特性不变。<br />DynamicBean和DynamicBeanImpl提供如下两种改造方式：<br /><br /> &lt;图片1><br /><br />1）改造方式1的示例代码如下：<br />1）/**<br />2） * 通过继承机制直接获得动态属性特性的扩展类<br />3） * @author Tu_Minglei<br />4） */<br />5）public class MyTestBean extends DynamicBeanImpl {<br />6）	private Long id;<br />7）	private String name;<br />8）	private Object value;<br />9）	<br />10）	public Long getId() {<br />11）		return id;<br />12）	}<br />13）	public void setId(Long id) {<br />14）		this.id = id;<br />15）	}<br />16）	public String getName() {<br />17）		return name;<br />18）	}<br />19）	public void setName(String name) {<br />20）		this.name = name;<br />21）	}<br />22）	public Object getValue() {<br />23）		return value;<br />24）	}<br />25）	public void setValue(Object value) {<br />26）		this.value = value;<br />27）	}<br />}<br />2）改造方式2的示例代码如下：<br />1）/**<br />2） * 通过接口+聚合机制获得动态属性特性的扩展类<br />3） * @author Tu_Minglei<br />4） */<br />5）public class MyTestBean2 implements DynamicBean,Map {<br />6）	private Long id;<br />7）	private String name;<br />8）	private Object value;<br />9）	<br />10）	public Long getId() {<br />11）		return id;<br />12）	}<br />13）	public void setId(Long id) {<br />14）		this.id = id;<br />15）	}<br />16）	public String getName() {<br />17）		return name;<br />18）	}<br />19）	public void setName(String name) {<br />20）		this.name = name;<br />21）	}<br />22）	public Object getValue() {<br />23）		return value;<br />24）	}<br />25）	public void setValue(Object value) {<br />26）		this.value = value;<br />27）	}<br />28）	<br />29）	@Override<br />30）	public String toString(){<br />31）		return "[id:"+id+",name:"+name+",value:"+value+"]";<br />32）	}<br />33）	<br />34）	/**++++++++++++++++++++++++++++++++++++++++++++++++++++++<br />35）	* 			说明：以下代码可以原封不动的拷入目标类中<br />36）	**++++++++++++++++++++++++++++++++++++++++++++++++++++++*/<br />37）	DynamicBeanImpl _dynamicStub = new DynamicBeanImpl(this);<br />38）	public Object get(String propName) {<br />39）		return _dynamicStub.get(propName);<br />40）	}<br />41）	public void set(String propName, Object value) {<br />42）		_dynamicStub.set(propName, value);<br />43）	}<br />44）	public void declare(String propName, Class propType) {<br />45）		_dynamicStub.declare(propName, propType);<br />46）	}<br />47）	/**---- 注：如果不需要实现Map接口，下列代码可以不拷入目标类中 ----*/<br />48）	/**--------------- for Map Implementation ---------------*/<br />49）	public Object get(Object key) {<br />50）		return _dynamicStub.get(key);<br />51）	}<br />52）	public Object put(Object key, Object value) {<br />53）		return _dynamicStub.put(key, value);<br />54）	}<br />55）	public void putAll(Map t) {<br />56）		_dynamicStub.putAll(t);<br />57）	}<br />58）	public Object remove(Object key) {<br />59）		return _dynamicStub.remove(key);<br />60）	}<br />61）	public void clear() {<br />62）		_dynamicStub.clear();<br />63）	}<br />64）	public boolean containsKey(Object key) {<br />65）		return _dynamicStub.containsKey(key);<br />66）	}<br />67）	public boolean containsValue(Object value) {<br />68）		return _dynamicStub.containsValue(value);<br />69）	}<br />70）	public Set keySet() {<br />71）		return _dynamicStub.keySet();<br />72）	}<br />73）	public Collection values() {<br />74）		return _dynamicStub.values();<br />75）	}<br />76）	public Set entrySet() {<br />77）		return _dynamicStub.entrySet();<br />78）	}<br />79）	public boolean isEmpty() {<br />80）		return _dynamicStub.isEmpty();<br />81）	}<br />82）	public int size() {<br />83）		return _dynamicStub.size();<br />84）	}<br />}<br /><br />注：DynamicBeanImpl同时实现了DynamicBean和Map接口。<br /><br />有关这两种改造方式的完整样例代码及其测试用例，请查看com.ctic.core.prod.common.extproperty. DynamicBeanImplTest.java。<br /><br />二、对这些动态属性的界面编辑及持久化的支持<br />对动态属性的定义信息及数据信息的存取，以及编辑界面的生成的职责，由扩展属性框架承担。<br />扩展属性框架（以下简称为：框架）提供如下存取机制：<br />1）首先，用户通过框架预先为指定对象关联一些属性定义信息；<br />2）以后，当用户传入指定对象（已实现DynamicBean接口）要求保存时，框架将按照预先定义的信息提取相应的属性数据保存下来；<br />3）接着，当用户传入指定对象要求装填相关属性数据时，框架将能够把原先保存的数据按照属性说明的要求填入该对象中。<br />当用户传入指定对象，要求获得相应的编辑面板时，框架可以根据用户预先关联的属性定义信息，生成编辑面板。<br />框架的基本结构及对外接口如下图所示：<br /><br /> &lt;图片2><br /><br />相关说明：<br />1）用户将通过DynamicPropertyService服务接口存取属性定义信息并和目标对象关联；<br />2）用户将通过DynamicPropertyService服务接口或者相应的PropertyDataBO存取和目标对象关联的属性数据信息；<br />3）用户将通过DynamicPanelManager服务类获得相应的编辑面板。<br /><br />关于框架在：1）属性定义信息和目标对象关联；2）对目标对象的动态属性数据存取；3）动态属性编辑面板的生成，等方面的实现细节，请参阅相关的Rose设计文档及源代码，在此不作累述。<br /><br />注1：框架内部根据目标对象的特征信息，来保持和所托管信息的匹配。不同对象类型有不同的特征信息，而方案只预置了对一部分目标对象的支持。<br />注2：相关的Rose设计文档我已上传到svn的ctic-doc\设计文档\Rose设计目录下。相关的源代码也已上传到svn上。<br /><br /><br />使用要点：<br />为了有效使用扩展属性框架，用户需要做出以下调整：<br />1）调整目标Model，以使其具有动态属性特性（注：如果框架用到的工具类KeyObjectUtils还没有对该对象类型提供支持，则还要加入相应的支持代码）；<br />2）用户预先把相应的属性定义信息和目标对象关联；<br />3）用户BO或Service在存取目标对象的过程中，加入相应的对动态属性服务的调用代码（注：为了使框架能提取到有用的特征信息，用户应保证在调用之前，Id值不为NULL）；<br />4）用户在客户端，加入调用动态面板管理器获得相应的编辑面板的代码，以及其他动态属性相关的处理代码。<br /><br />潜在应用：<br />由于DynamicBean和DynamicBeanImpl的相对独立性，使得这两个接口/类除了用于需要存储的动态属性之外，还可以存放一些不需存储的临时属性，像：和具体Model对应的VO中的属性，动态查询中临时使用的查询参数字段，标识内存中Model对象的操作状态（insert、update、delete），等等。<br /><br />注：为了使DynamicBeanImpl能充当动态查询语句中的万能参数对象的角色，该类特意实现了java.util.Map接口。用户只需把SQLMap中相应查询语句的传入参数的类型改为java.util.Map即可，其他地方可以仍旧把它当作原来的Model。
          <br/>
          <span style="color:red;">
            <a href="http://tminglei.javaeye.com/blog/193940#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 17 May 2008 19:11:48 +0800</pubDate>
        <link>http://tminglei.javaeye.com/blog/193940</link>
        <guid>http://tminglei.javaeye.com/blog/193940</guid>
      </item>
  </channel>
</rss>