模板方法模式

1模板方法模式

模板方法模式是一种行为设计模式, 它在超类中定义了一个算法的框架, 允许子类在不修改结构的情况下重写算法的特定步骤。
在这里插入图片描述

1问题

假如你正在开发一款分析公司文档的数据挖掘程序。 用户需要向程序输入各种格式 (PDF、 DOC 或 CSV) 的文档, 程序则会试图从这些文件中抽取有意义的数据, 并以统一的格式将其返回给用户。
在这里插入图片描述
你发现这三个类中包含许多相似代码,尽管提取和解析不同文件数据的代码不同, 但数据分析的代码却几乎完全一样。 如果能在保持算法结构完整的情况下去除重复代码, 这难道不是一件很棒的事情吗?

2解决方案

模板方法模式建议将算法分解为一系列步骤, 然后将这些步骤改写为方法, 最后在 “模板方法” 中依次调用这些方法。 步骤可以是 抽象的, 也可以有一些默认的实现。 为了能够使用算法, 客户端需要自行提供子类并实现所有的抽象步骤。 如有必要还需重写一些步骤 (但这一步中不包括模板方法自身)。

让我们考虑如何在数据挖掘应用中实现上述方案。 我们可为图中的三个解析算法创建一个基类, 该类将定义调用了一系列不同文档处理步骤的模板方法。
在这里插入图片描述
首先, 我们将所有步骤声明为 抽象类型, 强制要求子类自行实现这些方法。 在我们的例子中, 子类中已有所有必要的实现, 因此我们只需调整这些方法的签名, 使之与超类的方法匹配即可。

现在, 让我们看看如何去除重复代码。 对于不同的数据格式, 打开和关闭文件以及抽取和解析数据的代码都不同, 因此无需修改这些方法。 但分析原始数据和生成报告等其他步骤的实现方式非常相似, 因此可将其提取到基类中, 以让子类共享这些代码。

正如你所看到的那样, 我们有两种类型的步骤:

抽象步骤必须由各个子类来实现
可选步骤已有一些默认实现, 但仍可在需要时进行重写。

在这里插入图片描述

3示例代码

3.1 networks/Network.java: 基础社交网络类
package com.zs.template.networks;

/**
 * @author zhaoshuai06 <zhaoshuai06@kuaishou.com>
 * Created on 2021-06-09
 */

import java.nio.charset.StandardCharsets;

/**
 * 基础社交网络类
 */
public abstract class Network {
    String userName;
    String passWord;
    Network() {}
    abstract boolean login(String userName, String passWord);
    abstract boolean sendData(byte[] data);
    abstract void logout();

    // Publish the data to whatever network
    public boolean post(String message) {

    // Authenticate before posting. Every network uses a different authentication method.
        if (login(this.userName, this.passWord)) {
            boolean result = sendData(message.getBytes(StandardCharsets.UTF_8));
            logout();
            return result;
        }
        return false;
    }
}

3.2 networks/Facebook.java: 具体社交网络
package com.zs.template.networks;

import com.zs.template.networks.Network;

/**
 * @author zhaoshuai06 <zhaoshuai06@kuaishou.com>
 * Created on 2021-06-09
 */
public class Facebook extends Network {
    public Facebook(String userName, String passWord) {
        this.userName = userName;
        this.passWord = passWord;
    }
    @Override
    boolean login(String userName, String passWord) {
        System.out.println("Facebook login...");
        return true;
    }

    @Override
    boolean sendData(byte[] data) {
        System.out.println("Facebook..." + new String(data));
        return true;
    }

    @Override
    void logout() {
        System.out.println("Facebook logout ...");
    }
}

3.3 networks/Wechat.java: 具体社交网络
package com.zs.template.networks;

/**
 * @author zhaoshuai06 <zhaoshuai06@kuaishou.com>
 * Created on 2021-06-09
 */
public class Wechat extends Network {
    public Wechat(String userName, String passWord) {
        this.userName = userName;
        this.passWord = passWord;
    }
    @Override
    boolean login(String userName, String passWord) {
        System.out.println("Wechat login...");
        return true;
    }

    @Override
    boolean sendData(byte[] data) {
        System.out.println("Wechat..." + new String(data));
        return true;
    }

    @Override
    void logout() {
        System.out.println("Wechat logout ...");
    }
}

3.4测试类
package com.zs.template.networks;

/**
 * @author zhaoshuai06 <zhaoshuai06@kuaishou.com>
 * Created on 2021-06-09
 */
public class Test {
    public static void main(String[] args) {
        Network facebook = new Facebook("facebook", "facebook");
        Network wechat = new Wechat("Wechat", "Wechat");
        facebook.post("facebook");
        wechat.post("wechat");
    }
}

在这里插入图片描述
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值