模板模式1

16.1  场景问题

16.1.1  登录控制

       几乎所有的应用系统,都需要系统登录控制的功能,有些系统甚至有多个登录控制的功能,比如:普通用户可以登录前台,进行相应的业务操作;而工作人员可以登录后台,进行相应的系统管理或业务处理。

现在有这么一个基于Web的企业级应用系统,需要实现这两种登录控制,直接使用不同的登录页面来区分它们,把基本的功能需求分别描述如下:

先看看普通用户登录前台的登录控制的功能:

  • 前台页面:用户能输入用户名和密码;提交登录请求,让系统去进行登录控制
  • 后台:从数据库获取登录人员的信息
  • 后台:判断从前台传递过来的登录数据,和数据库中已有的数据是否匹配
  • 前台Action:如果匹配就转向首页,如果不匹配就返回到登录页面,并显示错误提示信息

再来看看工作人员登录后台的登录控制功能:

  • 前台页面:用户能输入用户名和密码;提交登录请求,让系统去进行登录控制
  • 后台:从数据库获取登录人员的信息
  • 后台:把从前台传递过来的密码数据,使用相应的加密算法进行加密运算,得到加密后的密码数据
  • 后台:判断从前台传递过来的用户名和加密后的密码数据,和数据库中已有的数据是否匹配
  • 前台Action:如果匹配就转向首页,如果不匹配就返回到登录页面,并显示错误提示信息

说明:普通用户和工作人员在数据库里面是存储在不同表里面的;当然也是不同的模块来维护普通用户的数据和工作人员的数据;另外工作人员的密码是加密存放的。

16.1.2  不用模式的解决方案

       由于普通用户登录和工作人员登录是不同的模块,有不同的页面,不同的逻辑处理,不同的数据存储,因此,在实现上完全当成两个独立的小模块去完成了。这里把它们的逻辑处理部分分别实现出来。

(1)先看普通用户登录的逻辑处理部分,示例代码如下:

/**

 * 普通用户登录控制的逻辑处理

 */

public class NormalLogin {

    /**

     * 判断登录数据是否正确,也就是是否能登录成功

     * @param lm 封装登录数据的Model

     * @return true表示登录成功,false表示登录失败

     */

    public boolean login(LoginModel lm) {

       //1:从数据库获取登录人员的信息,就是根据用户编号去获取人员的数据

       UserModel um = this.findUserByUserId(lm.getUserId());

       //2:判断从前台传递过来的登录数据,和数据库中已有的数据是否匹配

       //先判断用户是否存在,如果um为null,说明用户肯定不存在

       //但是不为null,用户不一定存在,因为数据层可能返回new UserModel();

       //因此还需要做进一步的判断

       if (um != null) {

           //如果用户存在,检查用户编号和密码是否匹配

           if (um.getUserId().equals(lm.getUserId())

                  && um.getPwd().equals(lm.getPwd())) {

              return true;

           }

       }

       return false;

    }

    /**

     * 根据用户编号获取用户的详细信息

     * @param userId 用户编号

     * @return 对应的用户的详细信息

     */

    private UserModel findUserByUserId(String userId) {

       // 这里省略具体的处理,仅做示意,返回一个有默认数据的对象

       UserModel um = new UserModel();

       um.setUserId(userId);

       um.setName("test");

       um.setPwd("test");

       um.setUuid("User0001");

       return um;

    }

}

       对应的LoginModel,示例代码如下:

/**

 * 描述登录人员登录时填写的信息的数据模型

 */

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;

    }

}

对应的UserModel,示例代码如下:

/**

 * 描述用户信息的数据模型

 */

public class UserModel {

    private String uuid,userId,pwd,name;

    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;

    }

}  

(2)再看看工作人员登录的逻辑处理部分,示例代码如下:

/**

 * 工作人员登录控制的逻辑处理

 */

public class WorkerLogin {

    /**

     * 判断登录数据是否正确,也就是是否能登录成功

     * @param lm 封装登录数据的Model

     * @return true表示登录成功,false表示登录失败

     */

    public boolean login(LoginModel lm) {

        //1:根据工作人员编号去获取工作人员的数据

       WorkerModel wm = findWorkerByWorkerId(lm.getWorkerId());

       //2:判断从前台传递过来的用户名和加密后的密码数据,

//和数据库中已有的数据是否匹配

       //先判断工作人员是否存在,如果wm为null,说明工作人员肯定不存在

       //但是不为null,工作人员不一定存在,

       //因为数据层可能返回new WorkerModel();因此还需要做进一步的判断

       if (wm != null) {

           //3:把从前台传来的密码数据,使用相应的加密算法进行加密运算

           String encryptPwd = this.encryptPwd(lm.getPwd());

           //如果工作人员存在,检查工作人员编号和密码是否匹配

           if (wm.getWorkerId().equals(lm.getWorkerId())

                  && wm.getPwd().equals(encryptPwd)) {

              return true;

           }

       }

       return false;

    }

    /**

     * 对密码数据进行加密

     * @param pwd 密码数据

     * @return 加密后的密码数据

     */

    private String encryptPwd(String pwd){

       //这里对密码进行加密,省略了

       return pwd;

    }

    /**

     * 根据工作人员编号获取工作人员的详细信息

     * @param workerId 工作人员编号

     * @return 对应的工作人员的详细信息

     */

    private WorkerModel findWorkerByWorkerId(String workerId) {

       // 这里省略具体的处理,仅做示意,返回一个有默认数据的对象

       WorkerModel wm = new WorkerModel();

       wm.setWorkerId(workerId);

       wm.setName("Worker1");

       wm.setPwd("worker1");

       wm.setUuid("Worker0001");

       return wm;

    }

}

对应的LoginModel,示例代码如下:

/**

 * 描述登录人员登录时填写的信息的数据模型

 */

public class LoginModel{

    private String workerId,pwd;

    public String getWorkerId() {

       return workerId;

    }

    public void setWorkerId(String workerId) {

       this.workerId = workerId;

    }

    public String getPwd() {

       return pwd;

    }

    public void setPwd(String pwd) {

       this.pwd = pwd;

    }

}

对应的WorkerModel,示例代码如下:

/**

 * 描述工作人员信息的数据模型

 */

public class WorkerModel {

    private String uuid,workerId,pwd,name;

    public String getUuid() {

       return uuid;

    }

    public void setUuid(String uuid) {

       this.uuid = uuid;

    }

    public String getWorkerId() {

       return workerId;

    }

    public void setWorkerId(String workerId) {

       this.workerId = workerId;

    }

    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;

    }

}

16.1.3  有何问题

       看了上面的实现示例,是不是很简单。但是,仔细看看,总会觉得有点问题,两种登录的实现太相似了,现在是完全分开,当作两个独立的模块来实现的,如果今后要扩展功能,比如要添加“控制同一个编号同时只能登录一次”的功能,那么两个模块都需要修改,是很麻烦的。而且,现在的实现中,也有很多相似的地方,显得很重复。另外,具体的实现和判断的步骤混合在一起,不利于今后变换功能,比如要变换加密算法等。

       总之,上面的实现,有两个很明显的问题:一是重复或相似代码太多;二是扩展起来很不方便。

       那么该怎么解决呢?该如何实现才能让系统既灵活又能简洁的实现需求功能呢?

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值