模板方法模式
意图:定义一个操作中算法的骨架,将一些步骤推迟到子类中实现。可以改变该算法的结构而重新定义该算法的步骤。
适用场景:Template method模式适用于存在几个互不相同但概念上相似的过程。每个过程的变化是相互耦合的,因为它们都与某个过程相关。
问题:要完成在某一细节层次一致的一个过程或一系列的一些步骤,但其个别步骤要在更详细的层次上的实现可能不同。
解决方案:允许定义可变的子步骤,同时保持基本过程一致。
参与者与协作者:Template Method由一个抽象类组成,这个抽象类定义了需要覆盖的基本template方法。每个从这个抽象类派生的具体类将为此模板实现新方法。
效果:模板提供了一个很好的代码复用平台。它还有助于确保所需步骤的实现。它将每个concrete类的覆盖步骤绑定起来,因此只有在这些变化总是并且只能在一起发生时,才应该使用Template method模式。
实现:创建一个抽象类,用抽象方法实现一个过程。这些抽象方法必须在子类中实现,以执行过程的每个步骤。如果这些步骤是独立变化的,那么每个步骤都可以用strategy模式来实现。
模板方法模式通用结构图:
(1)模板方法模式的引入
主要操作对象有用户和图书。用户有增删查改的操作,图书也有增删查改的操作。这两者在进行增删查改时基本上只有sql语句是不同的,那么我们可以先定义一个通用类然后让用户和图书的实现类继承这个通用类,这样在子类实现的时候就可以直接使用父类中的方法,然后选择子类自己需要的sql语句。
(2)模板方法模式的实现
先定义一个通用接口IBaseDao
package xaut.wjh.dao;
import java.io.Serializable;
import java.util.List;
import xaut.wjh.entity.PageBean;
public interface IBaseDao <T extends Serializable,ID extends Serializable>{
//数据插入,例如用户注册,新增图书
public T save(T entity);
//通过页数进行查询
public List<T> queryByHql(String sql,PageBean<T> page,Object...values);
//通过ID进行查询,返回查询到的当前类的实体对象
public T load(ID id);
//修改
public void revise(String sql,Object...values);
//删除
public void del(String sql,Object...values);
}
然后创建一个具体类去实现这个通用接口中的方法
package xaut.wjh.dao;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import org.hibernate.Session;
import xaut.wjh.entity.PageBean;
import xaut.wjh.util.HibernateSessionFactory;
import xaut.wjh.util.MySqlUtil;
public class BaseDaoImpl<T extends Serializable,ID extends Serializable> implements IBaseDao<T,ID>{
//获取T的Class对象是关键,看构造方法
private Class<T> persistClass = null;
/**
* 当子类继承时就会加载BaseDaoTmpl的构造方法,就能得到子类实例化之后的泛型具体类
*/
public BaseDaoImpl() {
//为了得到T的Class,采用如下方法
//1得到该泛型类的子类对象的Class对象
Class clz = this.getClass();
//2得到子类对象的泛型父类类型(也就是BaseDaoImpl<T>)
//例如:type: xaut.wjh.dao.BaseDaoImpl<xaut.wjh.entity.TUsers>
ParameterizedType type = (ParameterizedType) clz.getGenericSuperclass();
// System.out.println("type"+type);
Type[] types = type.getActualTypeArguments();
//例如:persistClass.getSimpleName()=TUsers
persistClass = (Class<T>) types[0];
// System.out.println("clsSimpleName"+persistClass.getSimpleName());
}
@Override
public Serializable save(Serializable entity) {
Session session=HibernateSessionFactory.getSessionFactory().getCurrentSession();
session.save(entity);
return entity;
}
@Override
public T load(ID id) {
Session session=HibernateSessionFactory.getSessionFactory().getCurrentSession();
T entity=session.load(persistClass,id);
return entity;
}
@Override
public List<T> queryByHql(String sql, PageBean<T> page,Object... values) {
if(page!=null&&page.getPageSize()>0) {
// if(page.getTotalPages()<1) {
int totalRecords=MySqlUtil.myQuerytForList(sql, values).size();//获得查询出的总记录数
System.out.println("totalRecords"+totalRecords);
if(totalRecords<1) {//无记录
return null;
}
//根据记录数计算总页数
int totalPages=(totalRecords+page.getPageSize()-1)/5;//例如(21+4)/5=5,(24+4)/5=5;(20+4)/5=4,(25+4)/5=5
page.setTotalPages(totalPages);
page.setTotalRecords(totalRecords);
// }
if(page.getCurrentPage()>page.getTotalPages()) {//容错处理
page.setCurrentPage(page.getTotalPages());
}
int begin=(page.getCurrentPage()-1)*page.getPageSize();
List<T> list=MySqlUtil.queryForPage(sql, values, begin,page.getPageSize());
return list;
}
//若Page为null则不进行分页处理
return MySqlUtil.myQuerytForList(sql, values);
}
@Override
public void revise(String sql,Object...values) {
MySqlUtil.update(sql, values);
}
@Override
public void del(String sql, Object... values) {
MySqlUtil.update(sql, values);
}
}
然后定义子类的接口和具体实现
用户操作接口继承通用接口
package xaut.wjh.dao;
import xaut.wjh.entity.TUsers;
public interface IUserDao extends IBaseDao<TUsers,Integer>{
public boolean login(TUsers user);
public boolean regist(TUsers user);
public boolean existsName(String username);
public String getPhotoPath(TUsers user);
public TUsers queryUser(TUsers user);
public TUsers reviseBasic(TUsers user);
public void delUser(TUsers user);
}
用户类具体类实现继承通用实现类
package xaut.wjh.dao;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import xaut.wjh.entity.TUsers;
import xaut.wjh.util.MyMD5Util;
import xaut.wjh.util.MySqlUtil;
public class UserDaoImpl extends BaseDaoImpl<TUsers,Integer> implements IUserDao{
@Override
public boolean login(TUsers user) {
String sql="from TUsers u where u.username=? and u.TRoles.id=?";
Object[] values= new Object[]{user.getUsername(),user.getTRoles().getId()};
//如果有输入的用户名和角色对应的用户则证明此用户存在
List<TUsers> list=this.queryByHql(sql, null,values);
//然后再验证密码是否正确
if(list.size()>0) {
String passwordInDb=list.get(0).getPassword();
try {
if(MyMD5Util.validPassword(user.getPassword(), passwordInDb)) {
return true;
}
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return false;
}
@Override
public boolean regist(TUsers user) {
String encryptedPwd="";
try {
//将密码使用MD5加密后再存入数据库
encryptedPwd = MyMD5Util.getEncryptedPwd(user.getPassword());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
user.setPassword(encryptedPwd);
System.out.println("user"+user);
this.save(user);
return true;
}
@Override
public boolean existsName(String username) {
String sql="from TUsers u where u.username=?";
List<TUsers> list=this.queryByHql(sql,null,username);
if(list!=null&&list.size()>0) {
return true;
}
return false;
}
@Override
public String getPhotoPath(TUsers user) {
String hql="select photoName from TUsers u where u.username=?";
List<String> list=MySqlUtil.myQuery(hql,user.getUsername());
String photoPath=null;
if(list!=null&&list.size()>0) {
photoPath="/"+list.get(0);
}
System.out.println("photoPath"+photoPath);
return photoPath;
}
//查询用户信息
@Override
public TUsers queryUser(TUsers user) {
String hql="from TUsers u where u.username=?";
List<TUsers> list=MySqlUtil.myQuery(hql,user.getUsername());
if(list!=null&&list.size()>0) {
return list.get(0);
}
return null;
}
@Override
public TUsers reviseBasic(TUsers user) {
String sql="update TUsers u set u.age=?,u.sex=?,u.photoName=? where u.id=?";
Object[] values= {user.getAge(),user.getSex(),user.getPhotoName(),user.getId()};
this.revise(sql, values);
//返回更新后的值
return this.queryUser(user);
}
@Override
public void delUser(TUsers user) {
String sql="delete from TUsers u where u.id=?";
this.del(sql, user.getId());
}
}
图书的操作与用户类似都是继承父类接口或实现类。
图书操作接口
package xaut.wjh.dao;
import java.util.List;
import xaut.wjh.entity.PageBean;
import xaut.wjh.entity.TBooks;
public interface IBookDao extends IBaseDao<TBooks,Integer>{
//新增图书
//展示图书列表,根据分类,根据关键字模糊查询
public List<TBooks> queryBook(TBooks book,PageBean page);
public TBooks bookDetail(Integer id);
}
图书操作的具体实现类
package xaut.wjh.dao;
import java.util.List;
import xaut.wjh.entity.PageBean;
import xaut.wjh.entity.TBooks;
import xaut.wjh.util.MySqlUtil;
public class BookDaoImpl extends BaseDaoImpl<TBooks,Integer> implements IBookDao{
//根据书名或者作者名进行模糊查询
public List<TBooks> queryBook(TBooks book,PageBean page){
String sql="from TBooks b where b.name=? or b.auth=?";
System.out.println("queryBook中的book"+book);
Object[] values= new Object[]{book.getName(),book.getName()};
List<TBooks> list=this.queryByHql(sql,page, values);
return list;
}
//图书详情展示
@Override
public TBooks bookDetail(Integer id) {
return this.load(id);
}
}
设计模式课程设计中的部分内容,很多东西没做完吧,之前的练习。