代码变形记之模板方法模式
创始人
2025-07-04 21:01:11
0

背景

有5类数据A、B、C、D、E,需要分别进行处理。

优化前

通过ParamBuilder来分别构造各自参数,然后在Runner中分别调用,分别判断。

package TemplateMethodPattern.before;

public class Runner {
    public static void main(String[] args) {
        Param param = new Param();
        ParamBuilder paramBuilder = new ParamBuilder();
        // 处理数据A
        boolean result = paramBuilder.buildA(param);
        if (!result) {
            return;
        }
        boolean inserted = doIt(param);
        if (!inserted) {
            return;
        }
        // 处理数据B
        result = paramBuilder.buildB(param);
        if (!result) {
            return;
        }
        inserted = doIt(param);
        if (!inserted) {
            return;
        }
        // 处理数据C
        result = paramBuilder.buildC(param);
        if (!result) {
            return;
        }
        inserted = doIt(param);
        if (!inserted) {
            return;
        }
        // 处理数据D
        result = paramBuilder.buildD(param);
        if (!result) {
            return;
        }
        inserted = doIt(param);
        if (!inserted) {
            return;
        }
        // 处理数据E
        result = paramBuilder.buildE(param);
        if (!result) {
            return;
        }
        inserted = doIt(param);
        if (!inserted) {
            return;
        }
    }

    public static boolean doIt(Param param) {
        return param.flag;
    }
}
package TemplateMethodPattern.before;

import lombok.Data;

@Data
public class Param {
    public boolean flag;
}
package TemplateMethodPattern.before;

public class ParamBuilder {
    public boolean buildA(Param param) {
        return true;
    }
    public boolean buildB(Param param) {
        return false;
    }
    public boolean buildC(Param param) {
        return true;
    }
    public boolean buildD(Param param) {
        return false;
    }
    public boolean buildE(Param param) {
        return true;
    }
}

存在问题

Runner中存在较多重复代码。

优化方法

模板方法模式,Template Method Pattern。将重复代码抽象为一个抽象类,定义多个子类继承并实现各自代码。

优化后

AbstractHandler抽象了重复方法,子类继承后实现build()方法。Runner中调用process()方法来遍历子类对象进行处理。

package TemplateMethodPattern.after;

import TemplateMethodPattern.after.handler.*;
import TemplateMethodPattern.before.Param;

import java.util.Arrays;
import java.util.List;

public class Runner {
    public static void main(String[] args) {
        Param param = new Param();
        List handlers = Arrays.asList(
                new AHandler(),
                new BHandler(),
                new CHandler(),
                new DHandler(),
                new EHandler()
        );
        for (AbstractHandler handler : handlers) {
            if (!handler.process(param, Runner::doIt)) {
                return;
            }
        }
    }

    public static boolean doIt(Param param) {
        return param.flag;
    }
}
package TemplateMethodPattern.after.handler;

import TemplateMethodPattern.before.Param;

import java.util.function.Function;

public abstract class AbstractHandler {
    protected abstract boolean build(Param param);

    public boolean process(Param param, Function doIt) {
        boolean result = build(param);
        if (!result) {
            return false;
        }
        return doIt.apply(param);
    }
}
package TemplateMethodPattern.after.handler;

import TemplateMethodPattern.before.Param;

public class AHandler extends AbstractHandler{
    @Override
    protected boolean build(Param param) {
        return true;
    }
}
package TemplateMethodPattern.after.handler;

import TemplateMethodPattern.before.Param;

public class BHandler extends AbstractHandler{
    @Override
    protected boolean build(Param param) {
        return false;
    }
}
package TemplateMethodPattern.after.handler;

import TemplateMethodPattern.before.Param;

public class CHandler extends AbstractHandler{
    @Override
    protected boolean build(Param param) {
        return true;
    }
}
package TemplateMethodPattern.after.handler;

import TemplateMethodPattern.before.Param;

public class DHandler extends AbstractHandler{
    @Override
    protected boolean build(Param param) {
        return false;
    }
}
package TemplateMethodPattern.after.handler;

import TemplateMethodPattern.before.Param;

public class EHandler extends AbstractHandler{
    @Override
    protected boolean build(Param param) {
        return true;
    }
}

个人感想,因为我是从Python转到Java,在使用设计模式解决这个问题后,我也思考了如果使用Python该怎么处理?Python是动态语言,有鸭子类型,对于重复代码通过定义一个公共函数,动态绑定类型就能解决,感兴趣的同学可以试试。不同的语言都各自的优势,也有各自的限制。也有各自的解决方法。

相关内容

热门资讯

如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
施耐德电气数据中心整体解决方案... 近日,全球能效管理专家施耐德电气正式启动大型体验活动“能效中国行——2012卡车巡展”,作为该活动的...
20个非常棒的扁平设计免费资源 Apple设备的平面图标PSD免费平板UI 平板UI套件24平图标Freen平板UI套件PSD径向平...
德国电信门户网站可实时显示全球... 德国电信周三推出一个门户网站,直观地实时提供其安装在全球各地的传感器网络检测到的网络攻击状况。该网站...
为啥国人偏爱 Mybatis,... 关于 SQL 和 ORM 的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行...
《非诚勿扰》红人闫凤娇被曝厕所... 【51CTO.com 综合消息360安全专家提醒说,“闫凤娇”、“非诚勿扰”已经被黑客盯上成为了“木...
2012年第四季度互联网状况报... [[71653]]  北京时间4月25日消息,据国外媒体报道,全球知名的云平台公司Akamai Te...