模板方法模式,从网站登陆开始提及

如今的互联网上,想必每一个网站都有登陆功能,拿咱们技术人员常逛的技术网站CSDN掘金博客园等为例,它们都有登陆功能,并且它们的登陆流程都差很少,若是咱们把这些网站的登陆流程用代码模拟出来,该怎么弄呢?java

在模拟流程以前,先来分析这个登陆流程,其实无论哪一个网站,登陆流程都是如下四步:算法

  • 一、跳转到登陆页面
  • 二、输入用户名和密码
  • 三、点击登陆按钮
  • 四、跳转到首页

咱们就照着这个流程来用代码来模拟网站登陆的过程,咱们以 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类的具体设计以下:ide

/** * 模板方法模式-抽象类 */
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,测试类的具体代码以下:spa

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()方法,而后子类作具体实现就好,保证了这个流程不会出错。
  • 子类只须要专一于实现就好,子类不须要管执行流程

从咱们的网站登陆案例中,能够看出模板方法模式确实给咱们带来了很多的好处,一块儿来总结一下模板方法模式的优缺点吧。3d

模板方法模式的优势

  • 封装不可变部分,扩展可变部分
  • 提取公共代码,便于维护
  • 行为由父类控制,子类实现

模板方法模式的缺点

  • 对每一个不一样的实现都须要定义一个子类,这会致使类的个数增长,系统更加庞大,设计也更加抽象
  • 父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这致使一种反向的控制结构,它提升了代码阅读的难度

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

最后

打个小广告,欢迎扫码关注微信公众号:「平头哥的技术博文」,一块儿进步吧。

平头哥的技术博文
相关文章
相关标签/搜索