首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >模板方法模式,从网站登录开始说起

模板方法模式,从网站登录开始说起

作者头像
Bug开发工程师
发布2019-10-11 11:24:56
1.3K0
发布2019-10-11 11:24:56
举报
文章被收录于专栏:码农沉思录码农沉思录

现在的互联网上,想必每个网站都有登录功能,拿我们技术人员常逛的技术网站 CSDN掘金博客园等为例,它们都有登录功能,而且它们的登录流程都差不多,如果我们把这些网站的登录流程用代码模拟出来,该怎么弄呢?

在模拟流程之前,先来分析这个登录流程,其实不管哪个网站,登录流程都是以下四步:

  • 1、跳转到登录页面
  • 2、输入用户名和密码
  • 3、点击登录按钮
  • 4、跳转到首页

我们就照着这个流程来用代码来模拟网站登录的过程,我们以 CSDN掘金为例。

模拟 CSDN 登录
/**
 * 模拟csdn登录
 */
public class CsdnLogin {
    // 第一步:获取登录页面
    public void getLoginPage(){
        System.out.println("跳转到csdn登录页面...");
    }
    // 第二步:设置用户名密码
    public void setUserAndPass(){
        System.out.println("设置好了csdn的用户名和密码...");
    }
    // 第三步:点击登录
    public void clickLogin(){
        System.out.println("点击了csdn的登录按钮...");
    }
    // 进入主页
    public void home(){
        System.out.println("欢迎来到CSDN社区...");
    }
}
模拟掘金登录
/**
 * 模拟掘金登录
 */
public class JuejinLogin {
    // 第一步:获取登录页面
    public void getLoginPage(){
        System.out.println("跳转到掘金登录页面...");
    }
    // 第二步:设置用户名密码
    public void setUserAndPass(){
        System.out.println("设置好了掘金的用户名和密码...");
    }
    // 第三步:点击登录
    public void clickLogin(){
        System.out.println("点击了掘金的登录按钮...");
    }
    // 进入主页
    public void home(){
        System.out.println("欢迎来到掘金社区...");
    }
}
测试类
public class Test {
    public static void main(String[] args) {
        System.out.println("--------模拟登录到csdn--------");
        System.out.println("");
        CsdnLogin csdn = new CsdnLogin();
        csdn.getLoginPage();
        csdn.setUserAndPass();
        csdn.clickLogin();
        csdn.home();
        System.out.println("");

        System.out.println("--------模拟登录到掘金--------");
        System.out.println("");
        JuejinLogin juejin = new JuejinLogin();
        juejin.getLoginPage();
        juejin.setUserAndPass();
        juejin.clickLogin();
        juejin.home();
    }
}
测试结果

从测试结果来看,我们的设计和实现都没有一点问题,在这里 CSDN掘金都有自己的控制流程,那如果我一不小心把 juejin.clickLogin();写到了 juejin.setUserAndPass();的前面,那我的登录岂不是失败了?仔细想想, CSDN掘金登录流程都是一样的,那我们能不能把这个流程固定到一个方法中,让它变成一个不可变的标准流程呢?也许这是可行的,我们使用一种新的设计模式,叫做模板方法模式。先一起来简单了解一下模板方法模式。

模板方法模式的定义

在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中,模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。

模板方法模式的通用类图

模板方法模式相对其他模式来说比较简单,模板方法模式就涉及到两个角色:

  • AbstractClass:抽象类
  • ConcreteClass:具体的实现类

我们用模板方法模式来重新设计我们的模拟登录过程, 我们按照 AbstractClass的规则来实现模拟登录的模板抽象类 LoginTemplateLoginTemplate类的具体设计如下:

/**
 * 模板方法模式-抽象类
 */
public abstract class LoginTemplate {

     abstract void getLoginPage();

     abstract void setUserAndPass();

     abstract void clickLogin();

     abstract void home();

    /**
     * 在模板中定义了一个登录方法
     * 这个方法是我们登录的一个流程模板
     */
    public final void login(){
        getLoginPage();
        setUserAndPass();
        clickLogin();
        home();
        System.out.println("");
    }
}

我们将登录涉及到的四个方法抽到到这个中,并且定义了一个模板方法 login(),模板方法中的定义好了执行的顺序,需要特别注意的地方是模板方法使用了 final修饰,这样做的目的是防止子类重写改变执行的顺序。

ConcreteClass类是具体的实现,我们需要定义两个 ConcreteClass类, CsdnJueJin类是我们的具体实现,这两个类的具体实现跟我们最开始设计的差不多,具体的登录细节移步到这里。 CsdnJueJin类的具体实现如下:

public class Csdn extends LoginTemplate {
    @Override
    public void getLoginPage() {
        System.out.println("跳转到csdn登录页面...");
    }

    @Override
    public void setUserAndPass() {
        System.out.println("设置好了csdn的用户名和密码...");
    }

    @Override
    public void clickLogin() {
        System.out.println("点击了csdn的登录按钮...");
    }

    @Override
    public void home() {
        System.out.println("欢迎来到CSDN社区...");
    }
}
public class JueJin extends LoginTemplate {
    @Override
    public void getLoginPage() {
        System.out.println("跳转到掘金登录页面...");
    }

    @Override
    public void setUserAndPass() {
        System.out.println("设置好了掘金的用户名和密码...");
    }

    @Override
    public void clickLogin() {
        System.out.println("点击了掘金的登录按钮...");
    }

    @Override
    public void home() {
        System.out.println("欢迎来到掘金社区...");
    }
}

重新编写我们的测试类 App,测试类的具体代码如下:

public class App {
    public static void main(String[] args) {
        // 模拟csdn登录
        LoginTemplate csdn = new Csdn();
        // 调用模板方法
        csdn.login();

        // 模拟掘金登录
        LoginTemplate juejin = new JueJin();
        juejin.login();
    }
}

测试结果:

使用模板方法模式之后,给我们模拟登录带来了哪些好处?我总结了一下,使用模板方法模式带来了如下好处:

  • LoginTemplate类主导一切,它有一个保护 login()方法控制着整个登录流程
  • 控制顺序方法只存在一个地方,如果需要修改的话,比较方便,避免了我们需要在具体实现类中,由于操作失误导致的顺序问题。如果需要添加在登录前进行机器人验证,我们只需要在 clickLogin()添加一个 verify()方法,然后子类做具体实现就好,保证了这个流程不会出错。
  • 子类只需要专注于实现就好,子类不需要管执行流程

从我们的网站登录案例中,可以看出模板方法模式确实给我们带来了不少的好处,一起来总结一下模板方法模式的优缺点吧。

模板方法模式的优点
  • 封装不可变部分,扩展可变部分
  • 提取公共代码,便于维护
  • 行为由父类控制,子类实现
模板方法模式的缺点
  • 对每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象
  • 父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这导致一种反向的控制结构,它提高了代码阅读的难度

最后多少一句,JDK 中的 Collections.sort()方法就是用模板方法来排序的,有兴趣的可以去深入了解一下。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-10-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码农沉思录 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 模拟 CSDN 登录
  • 模拟掘金登录
  • 测试类
  • 测试结果
  • ?
  • 模板方法模式的定义
  • 模板方法模式的通用类图
  • ?
  • 模板方法模式的优点
  • 模板方法模式的缺点
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档