85977328 发表于 2013-1-29 11:52:42

ZK经典用法---模板方法模式(更新)

一 模板方法模式简介(Template Method Pattern Introduction)
    模板方法模式主要用于对算法或者行为逻辑进行封装,如果多个类中存在某些相似的算法逻辑或者行为逻辑,可以通过将这些相似的逻辑提取到模板方法类中实现,然后让相应的子类根据需要实现某些自定义的逻辑。

二 ZK的原理
1)ZK是一个页面对应着一个类,而每个页面,基本上都有很多的相似操作.例如:增加,删除,修改,查询等等.因此我们很容易想到如何把相同的逻辑抽去出来呢?模板方法模式为我们提供了良好的解决方案.下我给出所有的代码.
    下面的解决方案只代表特殊,不代表普遍,具体的模板还需要根据项目中的应用具体设计.^-^
    模板类可以被多个页面继承,而不需要重新编写,如果个位读者实在没有明白,我在近几日内更新文章,写出一个具体的例子与大家分享.
2)结构说明,下面的图是我这个例子中用到的项目情况
http://dl.iteye.com/upload/attachment/291880/93279f58-ae6f-3e9d-9c34-08bc99b35a15.jpg
index.zul和index2.zul,对应着数据库中的2个表.他们的后台代码IndexUI.java和IndexUI2.java中,却没有增加按钮的事件,而是写到了父类中,public final void onClick$btnInsert() ;这样所有的增加操作就可以共享一个代码了.删除,修改等原理也是如此.略
mysql数据库表结构
CREATE TABLE `book` (`Id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(255) DEFAULT NULL,`title` varchar(255) DEFAULT NULL,PRIMARY KEY (`Id`)) CREATE TABLE `disk` (`Id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(255) DEFAULT NULL,`MB` varchar(255) DEFAULT NULL,PRIMARY KEY (`Id`)) index.zul 图书管理
<?page title="Auto Generated index.zul"?><window title="书籍信息" border="normal" width="200px"apply="com.huaxin.ui.IndexUI"><hbox><label value="作者" /><textbox id="name" /></hbox><hbox><label value="标题" /><textbox id="title" /></hbox><button id="btnInsert" label="增加" /><button id="btnReset" label="重置" /><button id="btnUpdate" label="修改" /><button id="btnDelete" label="删除" /></window>
IndexUI.java 书籍后台管理类
package com.huaxin.ui;import org.zkoss.zk.ui.Component;import org.zkoss.zul.Textbox;import com.huaxin.entity.Book;import com.huaxin.template.Template;public class IndexUI extends Template {Textbox name;Textbox title;public IndexUI() {super();}public void doAfterCompose(Component comp) throws Exception {super.doAfterCompose(comp);comp.setVariable(comp.getId() + "Ctrl", this, true);// 测试打印,访问父类初始化的属性System.out.println(super.webappPath);}public Book getInstance() {Book book = new Book();book.setName(name.getValue());book.setTitle(title.getValue());return book;}public <Book> void setInstance(Book obj) {}}
index2.zul 光盘管理
<?page title="Auto Generated index.zul"?><window title="光盘信息" border="normal" width="200px"apply="com.huaxin.ui.IndexUI2"><hbox><label value="名称" /><textbox id="name" /></hbox><hbox><label value="容量" /><textbox id="MB" /></hbox><button id="btnInsert" label="增加" /><button id="btnReset" label="重置" /><button id="btnUpdate" label="修改" /><button id="btnDelete" label="删除" /></window>
IndexUI2.java 光盘后台管理类package com.huaxin.ui;import org.zkoss.zk.ui.Component;import org.zkoss.zul.Textbox;import com.huaxin.entity.Disk;import com.huaxin.template.Template;public class IndexUI2 extends Template {Textbox name;Textbox MB;public IndexUI2() {super();}public void doAfterCompose(Component comp) throws Exception {super.doAfterCompose(comp);comp.setVariable(comp.getId() + "Ctrl", this, true);// 测试打印,访问父类初始化的属性System.out.println(super.webappPath);}public Disk getInstance() {Disk disk = new Disk();disk.setName(name.getValue());disk.setMB(MB.getValue());return disk;}public <Disk> void setInstance(Disk obj) {}}
Book.java 书籍实体类
package com.huaxin.entity;import javax.persistence.Basic;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.Table;@Entitypublic class Book {@Id@GeneratedValue(strategy=GenerationType.IDENTITY)@Column(name="Id")private int id;@Basicprivate String name;@Basicprivate String title;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}}
Disk.java光盘实体类
package com.huaxin.entity;import javax.persistence.Basic;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;@Entitypublic class Disk {@Id@GeneratedValue(strategy=GenerationType.IDENTITY)@Column(name="Id")private int id;@Basicprivate String name;@Basicprivate String MB;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getMB() {return MB;}public void setMB(String mB) {MB = mB;}}
Template.java
package com.huaxin.template;import java.util.List;import javax.persistence.EntityManager;import javax.persistence.EntityManagerFactory;import javax.persistence.EntityTransaction;import javax.persistence.Persistence;import javax.persistence.Query;import org.zkoss.zk.ui.Execution;import org.zkoss.zk.ui.Executions;import org.zkoss.zk.ui.util.GenericForwardComposer;import org.zkoss.zkplus.databind.AnnotateDataBinder;import org.zkoss.zul.Button;import com.huaxin.entity.Book;public abstract class Template extends GenericForwardComposer {/* * private 私有 public 公有 friendly 默认的,同包内访问 protected 具有friendly权限,同时子类可以访问 */// e.g. /HDPYWebprotected String webappPath = "";// e.g. http://localhost:80/HDPYWeb/protected String basePath = "";// 取得request对象protected Execution request = Executions.getCurrent();// 刷新protected AnnotateDataBinder binder;protected Button btnReset; // 重置protected Button btnInsert;// 增加protected Button btnUpdate;// 更新protected Button btnDelete;// 删除protected Class<?> clazz;public Template() {webappPath = request.getContextPath();basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + webappPath + "/";}// 方法必须为public,否则无法调用(反射)// 增加public final void onClick$btnInsert() {EntityManagerFactory factory = Persistence.createEntityManagerFactory("mysql");EntityManager em = factory.createEntityManager();EntityTransaction tx = em.getTransaction();tx.begin();em.persist(getInstance());tx.commit();}// 删除----方法没有用public修饰,所以不起作用protected final void onClick$btnDelete() {{// 真正使用的时候,此处要添加数据库操作代码alert("delete");}}// 修改public final void onClick$btnUpdate() {{// 真正使用的时候,此处要添加数据库操作代码alert("update");}}// 重置public final void onClick$btnReset() {{// 真正使用的时候,此处要添加数据库操作代码alert("reset");}}// 取得页面输入数据,泛型方法,子类继承以后,返回的类型可以自定义public abstract <T> T getInstance();// 取得页面输入数据public abstract <T> void setInstance(T obj);}
persistence.xml   JPA配制文件
<?xml version="1.0" encoding="UTF-8"?><persistence xmlns="http://java.sun.com/xml/ns/persistence"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0"><!--persistence-unit的name属性提供了创建EntityManagerFacotry时的 关键字transaction-type则指定了使用的事务管理类型这里使 用'RESOURCE_LOCAL'参数表示使用本地事务 --><persistence-unit name="mysql" transaction-type="RESOURCE_LOCAL"><!--JPA的提供类,OpenJPA的设置如下如果使用其它的JPA实现,这里 的内容需要修改成相应的提供类 --><provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider><!-- OpenJPA容器中管理的实体类列表 --><class>com.huaxin.entity.Book</class><class>com.huaxin.entity.Disk</class><!--OpenJPA容器访问数据库的参数 --><properties><property name="openjpa.ConnectionURL" value="jdbc:mysql://127.0.0.1/test" /><property name="openjpa.ConnectionDriverName" value="com.mysql.jdbc.Driver" /><property name="openjpa.ConnectionUserName" value="root" /><property name="openjpa.ConnectionPassword" value="root" /></properties></persistence-unit></persistence>
页: [1]
查看完整版本: ZK经典用法---模板方法模式(更新)