模板方法模式
模板模式
本质
固定算法骨架
定义
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
用模板模式解决问题的思路
重复或者相似代码太多、扩展不方便,出现这些问题的原因在相似模块之间的实现是完全分开的、相互独立的,没有从整体上进行控制。若是把它们合起来看,就会发现,那些重复或者相似的代码应该被抽离出来。而不重复的就应该做成扩展方法,放到子类去实现。
登陆控制的示例:
- 根据登陆人员的编号去获取相应数据。(必有)
- 获取对登陆人员填写的密码数据进行加密后的数据,如果不需要加密,那就直接返回登陆人员填写的数据。
- 判断登陆人员填写的数据是否与数据库的数据匹配。(必有)
代码:
定义一个登陆的模板,把公共的代码定义成方法在父类中实现,不同的定义成抽象方法,放到子类去实现
/** * 登陆控制模板的抽象类 **/ public abstract class LoginTemplate { /** * 判断登陆数据是否正确 * @param封装登陆数据的Model * @return boolean **/ public final boolean login(LoginModel lm){ //登陆实现 } /** * 根据登陆编号查找和获取储存中相应的数据 * @param 登陆编号 * @return 登陆编号储存中相应的数据 **/ public abstract LoginMedel findLoginUser(String loginId); /** * 对密码数据进行加密 * @param 密码数据 * @return 加密后的密码数据 **/ public String encryptPwd(String pwd){ return pwd } /** * 判断用户填写的登陆数据和储存中对应的数据是否匹配 * @param 用户填写登陆数据 * @param 在储存中对应的数据 * @return boolean **/ public boolean match(LoginModel lm, LoginModel dbLm){ //匹配实现。。。。 } }
封装进行登陆控制所需要的数据类,可以把他们的数据合并在一个类里面,不同的可以在子类中扩展。
/** * 登陆控制的数据类 **/ public class LoginModel { private String loginId; private String pwd; //省略get,set }
实现普通用户的登陆逻辑
/** * 普通用户登陆逻辑 **/ public class NormalLogin extends LoginTemplate { public LoginModel findLoginUser(String loginId){ //省略具体实现 } }
实现工作人员登陆控制的登陆逻辑
/** * 工作人员登陆逻辑 **/ public class WorkerLogin extends LoginTemplate { public LoginModel findLoginUser(String loginId){ //省略具体实现 } public String encryptPwd(String pwd){
// 覆盖父类的方法,提供正在的加密实现 // 省略具体实现 } }
以上就是一个完整的模板方法模式案例,模板模式在实际应用中非常广泛,尤其是设计框架级功能的时候非常有用。
模板方法模式还有一个额外的好处,就是可以控制子类的扩展。因为在父类中定义好了算法的步骤,只是在某几个固定的点才会调用到被子类实现的方法,因此也只允许这几个点来扩展功能。