一 模板方法模式简介(Template Method Pattern Introduction)
模板方法模式主要用于对算法或者行为逻辑进行封装,如果多个类中存在某些相似的算法逻辑或者行为逻辑,可以通过将这些相似的逻辑提取到模板方法类中实现,然后让相应的子类根据需要实现某些自定义的逻辑。
二 ZK的原理
1)ZK是一个页面对应着一个类,而每个页面,基本上都有很多的相似操作.例如:增加,删除,修改,查询等等.因此我们很容易想到如何把相同的逻辑抽去出来呢?模板方法模式为我们提供了良好的解决方案.下我给出所有的代码.
下面的解决方案只代表特殊,不代表普遍,具体的模板还需要根据项目中的应用具体设计.^-^
模板类可以被多个页面继承,而不需要重新编写,如果个位读者实在没有明白,我在近几日内更新文章,写出一个具体的例子与大家分享.
2)结构说明,下面的图是我这个例子中用到的项目情况
index.zul和index2.zul,对应着数据库中的2个表.他们的后台代码IndexUI.java和IndexUI2.java中,却没有增加按钮的事件,而是写到了父类中,public final void onClick$btnInsert() ;这样所有的增加操作就可以共享一个代码了.删除,修改等原理也是如此.略
mysql数据库表结构
IndexUI.java 书籍后台管理类
index2.zul 光盘管理
Book.java 书籍实体类
Disk.java 光盘实体类
Template.java
persistence.xml JPA配制文件
模板方法模式主要用于对算法或者行为逻辑进行封装,如果多个类中存在某些相似的算法逻辑或者行为逻辑,可以通过将这些相似的逻辑提取到模板方法类中实现,然后让相应的子类根据需要实现某些自定义的逻辑。
二 ZK的原理
1)ZK是一个页面对应着一个类,而每个页面,基本上都有很多的相似操作.例如:增加,删除,修改,查询等等.因此我们很容易想到如何把相同的逻辑抽去出来呢?模板方法模式为我们提供了良好的解决方案.下我给出所有的代码.
下面的解决方案只代表特殊,不代表普遍,具体的模板还需要根据项目中的应用具体设计.^-^
模板类可以被多个页面继承,而不需要重新编写,如果个位读者实在没有明白,我在近几日内更新文章,写出一个具体的例子与大家分享.
2)结构说明,下面的图是我这个例子中用到的项目情况
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; @Entity public class Book { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="Id") private int id; @Basic private String name; @Basic private 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; @Entity public class Disk { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="Id") private int id; @Basic private String name; @Basic private 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. /HDPYWeb protected 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>