例子:登陆(普通用户,工作人员)
没有使用设计模式实现用户登陆
package com.tao.YanMoDesignPattern.template.notPattern;/*** @Author Mi_Tao* @Date 2023/7/22* @Description* @Version 1.0**/
public class LoginModel {private String userId,pwd;public String getUserId() {return userId;}public void setUserId(String userId) {this.userId = userId;}public String getPwd() {return pwd;}public void setPwd(String pwd) {this.pwd = pwd;}
}
package com.tao.YanMoDesignPattern.template.notPattern;/*** @Author Mi_Tao* @Date 2023/7/22* @Description 普通用户登陆控制的逻辑处理* @Version 1.0**/
public class NormalLogin {public boolean login(LoginModel lm){// 1、先从数据库获取登陆人员的信息UserModel um = this.findUserByUserId(lm.getUserId());// 2、判断从前台传递过来的登陆数据和数据库中已有的数据是否匹配// 判断用户是否存在,如果是null,说明用户肯定不存在if (um != null){if (um.getUserId().equals(lm.getUserId())&&um.getPwd().equals(lm.getPwd())){return true;}return false;}return false;}private UserModel findUserByUserId(String userId) {// 这里省略具体的处理,返回一个默认的数据对象UserModel model = new UserModel();model.setUserId(userId);model.setName("test");model.setPwd("User001");model.setUuid("1231456");return model;}
}
package com.tao.YanMoDesignPattern.template.notPattern;/*** @Author Mi_Tao* @Date 2023/7/22* @Description* @Version 1.0**/
public class UserModel {public String getUuid() {return uuid;}public void setUuid(String uuid) {this.uuid = uuid;}public String getUserId() {return userId;}public void setUserId(String userId) {this.userId = userId;}public String getPwd() {return pwd;}public void setPwd(String pwd) {this.pwd = pwd;}public String getName() {return name;}public void setName(String name) {this.name = name;}private String uuid,userId,pwd,name;
}
package com.tao.YanMoDesignPattern.template.notPattern;/*** @Author Mi_Tao* @Date 2023/7/22* @Description 普通用户登陆控制的逻辑处理* @Version 1.0**/
public class WorkerLogin {public boolean login(WorkerModel lm){// 1、先从数据库获取登陆人员的信息WorkerModel wm = findWorkerByWorkerId(lm.getWorkId());// 2、判断从前台传递过来的登陆数据和数据库中已有的数据是否匹配// 判断用户是否存在,如果是null,说明用户肯定不存在if (wm != null){if (wm.getWorkId().equals(lm.getWorkId())&&wm.getPwd().equals(enctyptPwd(lm.getPwd()))){return true;}return false;}return false;}private WorkerModel findWorkerByWorkerId(String workId) {WorkerModel workerModel = new WorkerModel();workerModel.setWorkId("work001");workerModel.setPwd("pwdWork1");workerModel.setName("workName");workerModel.setUuid("123124124");return workerModel;}private String enctyptPwd(String pwd){// 加密,省略return pwd;}}
package com.tao.YanMoDesignPattern.template.notPattern;/*** @Author Mi_Tao* @Date 2023/7/22* @Description* @Version 1.0**/
public class WorkerModel {public String getUuid() {return uuid;}public void setUuid(String uuid) {this.uuid = uuid;}public String getWorkId() {return workId;}public void setWorkId(String workId) {this.workId = workId;}public String getPwd() {return pwd;}public void setPwd(String pwd) {this.pwd = pwd;}public String getName() {return name;}public void setName(String name) {this.name = name;}private String uuid,workId,pwd,name;
}
标准的模板方法模式*
package com.tao.YanMoDesignPattern.template.pattern;/*** @Author Mi_Tao* @Date 2023/7/22* @Description 定义模板方法,源语操作等的抽象类* @Version 1.0**/
public abstract class AbstractClass {/*** 源语操作1,所谓源语操作就是抽象的操作,必须由子类提供实现*/public abstract void doPrimitiveOperation1();/*** 源语操作2,所谓源语操作就是抽象的操作,必须由子类提供实现*/public abstract void doPrimitiveOperation2();/*** 模板方法,定义算法骨架*/public final void templateMethod(){doPrimitiveOperation1();doPrimitiveOperation2();}
}
package com.tao.YanMoDesignPattern.template.pattern;/*** @Author Mi_Tao* @Date 2023/7/22* @Description* @Version 1.0**/
public class ConcreteClass extends AbstractClass{@Overridepublic void doPrimitiveOperation1() {// 具体的实现}@Overridepublic void doPrimitiveOperation2() {// 具体的实现}
}
使用模板实现以上用户登陆场景
package com.tao.YanMoDesignPattern.template.case1_extend;/*** @Author Mi_Tao* @Date 2023/7/22* @Description* @Version 1.0**/
public class NormalLoginModel extends LoginModel {private String question,answer;public String getQuestion() {return question;}public void setQuestion(String question) {this.question = question;}public String getAnswer() {return answer;}public void setAnswer(String answer) {this.answer = answer;}
}
核心方法
package com.tao.YanMoDesignPattern.template.case1_extend;/*** @Author Mi_Tao* @Date 2023/7/22* @Description* @Version 1.0**/
public abstract class LoginTemplate {/*** 判断登录数据是否正确,也就是是否能登陆成功** @param lm lm 封装登陆数据的Model* @return boolean*/public final boolean Login(LoginModel lm){// 1、根据登陆人员的编号去查找LoginModel dbLm = this.findLoginUser(lm.getLoginId());if (dbLm != null){// 加密String encrytPwd = this.encryptPwd(lm.getPwd());// 把加密后的密码设置回到登陆数据模型中lm.setPwd(encrytPwd);// 判断是否匹配return this.match(lm, dbLm);}return false;}public boolean match(LoginModel lm, LoginModel dbLm) {if (lm.getLoginId().equals(dbLm.getLoginId()) && lm.getPwd().equals(dbLm.getPwd())){return true;}return false;}/*** 加密pwd** @param pwd* @return 加密后的密码数据*/private String encryptPwd(String pwd) {return pwd;}public abstract LoginModel findLoginUser(String loginId) ;
}
package com.tao.YanMoDesignPattern.template.case1_extend;/*** @Author Mi_Tao* @Date 2023/7/22* @Description* @Version 1.0**/
public class NormalLogin extends LoginTemplate{@Overridepublic LoginModel findLoginUser(String loginId) {// 省略具体操作,返回一个默认数据对象NormalLoginModel lm = new NormalLoginModel();lm.setLoginId(loginId);lm.setPwd("workpwd");return lm;}
}
package com.tao.YanMoDesignPattern.template.case1_extend;/*** @Author Mi_Tao* @Date 2023/7/22* @Description 工作人员登录* @Version 1.0**/
public class WorkerLogin extends LoginTemplate{@Overridepublic LoginModel findLoginUser(String loginId) {// 省略具体操作,返回一个默认数据对象NormalLoginModel lm = new NormalLoginModel();lm.setLoginId(loginId);lm.setPwd("workpwd");return lm;}public String encryptPwd(String pwd){// 覆盖弗雷方法,提供真正的加密System.out.println("使用MD5 加密");return pwd;}
}
测试
package com.tao.YanMoDesignPattern.template.case1_extend;/*** @Author Mi_Tao* @Date 2023/7/22* @Description* @Version 1.0**/
public class Client {public static void main(String[] args) {// 准备登陆人信息NormalLoginModel nlm = new NormalLoginModel();nlm.setPwd("testpwd");nlm.setLoginId("testUser");nlm.setQuestion("testQuestion");nlm.setAnswer("testAnswer");// 准备用来进行判断的对象LoginTemplate lt3 = new NormalLogin2();// 登录测试boolean login = lt3.Login(nlm);System.out.println("可以进行普通人员加强版登陆="+login);}
}
Tips:
既要约束子类的行为,又要为子类提供公共功能的时候使用抽象类。
Java回调与模板方法模式
实现模板方法的两种方式
模板方法模式的优缺点
什么时候使用模板方法模式
相关模式
以上内容参考《研磨设计模式》
例子源码: https://gitee.com/zitaoyang/design-mode.git