行为型模式--模版方法模式(图文详解)

模板方法模式在采摘机器人中的应用
文章介绍了如何使用模板方法模式解决采摘机器人在苹果和桃子采摘过程中的代码重复问题。通过定义一个抽象类,规定了采摘流程的模板,子类只需实现具体的识别和成熟度判断算法,提高了代码的复用性和可扩展性,同时也遵循了开闭原则。

采摘机器人-场景体验

今天看抖音上外国开始使用采摘苹果的机器人,我们模仿一下的他的大体流程:

  1. 主体采摘车进入苹果园
  2. 进入苹果指定采摘地点(路线)
  3. 采摘无人机起飞
  4. 识别苹果
  5. 识别苹果是否成熟
  6. 采摘并运送至采摘车储物空间
  7. 储物空间满时退出苹果园
  8. 到苹果储存地点卸载苹果

转化成代码:

public static void main(String[] args) {
        String apple = "苹果";
        String appleOrchard = "苹果园";
        String mainBody = "主体采摘车";
        String pickingDrone = "采摘无人机";
        System.out.println("1:"+mainBody+"进入"+appleOrchard+"。");
        System.out.println("2:"+mainBody+"进入"+apple+"指定采摘路径。");
        System.out.println("3:"+pickingDrone+"起飞。");
        System.out.println("4:"+pickingDrone+"通过"+apple+"识别算法,识别"+apple);
        System.out.println("5:"+pickingDrone+"通过"+apple+"成熟度识别算法,识别成熟"+apple);
        System.out.println("6:"+pickingDrone+"采摘成熟"+apple+"并送至"+mainBody+"储物空间。");
        System.out.println("7:"+mainBody+"储物空间满时退出"+appleOrchard+"。");
        System.out.println("8:"+mainBody+"到达"+apple+"储存仓库卸载"+apple);
    }

执行结果:
在这里插入图片描述

  农场主使用了上述机器人之后发现非常不错,所以选择桃子和🍐的采摘也要使用机器人进行。
于是桃子采摘的代码如下:

public static void main(String[] args) {
        String peach = "桃子";
        String peachOrchard = "桃子园";
        String mainBody = "主体采摘车";
        String pickingDrone = "采摘无人机";
        System.out.println("1:"+mainBody+"进入"+peachOrchard+"。");
        System.out.println("2:"+mainBody+"进入"+peach+"指定采摘路径。");
        System.out.println("3:"+pickingDrone+"起飞。");
        System.out.println("4:"+pickingDrone+"通过"+peach+"识别算法,识别"+peach);
        System.out.println("5:"+pickingDrone+"通过"+peach+"成熟度识别算法,识别成熟"+peach);
        System.out.println("6:"+pickingDrone+"采摘成熟"+peach+"并送至"+mainBody+"储物空间。");
        System.out.println("7:"+mainBody+"储物空间满时退出"+peachOrchard+"。");
        System.out.println("8:"+mainBody+"到达"+peach+"储存仓库卸载"+peach);
    }

  此时我们对比苹果和桃子采摘的代码会发现重复了是很高的。他们的处理过程基本相同。世间水果如此多,如果为每一种水果都按照这种方式写一个采摘机器人,那繁琐程度、无聊程度以及出现错误的概率是非常高的。
  归纳一下上面代码的特点:有统一的处理流程,区别只是流程中某些步的具体实现可能不同。

模版方法模式-解决问题

  为了解决上述问题,大佬们总结出了“模版方法模式”,也就是有一个方法它规定了某个事情的处理流程模版(规定某个地方要干什么事,具体怎么干不管),某些步骤的具体处理逻辑由子类去自己实现。

使用模版方法的思想改造我们的代码:
定义一个模版方法:

public abstract class FruitPick {
	//用final修饰防止被子类重写
    public final void pickWork(){
        String mainBody = "主体采摘车";
        String pickingDrone = "采摘无人机";
        System.out.println("1:"+mainBody+"进入"+getOrchardName()+"。");
        System.out.println("2:"+mainBody+"进入"+getFruitName()+"指定采摘路径。");
        System.out.println("3:"+pickingDrone+"起飞。");
        System.out.println("4:"+pickingDrone+"通过"+runIdentify(getFruitName()));
        System.out.println("5:"+pickingDrone+"通过"+runMaturityIdentify(getFruitName()));
        System.out.println("6:"+pickingDrone+"采摘成熟"+getFruitName()+"并送至"+mainBody+"储物空间。");
        System.out.println("7:"+mainBody+"储物空间满时退出"+getOrchardName()+"。");
        System.out.println("8:"+mainBody+"到达"+getFruitName()+"储存仓库卸载"+getFruitName());
    }

    /**
     * 获取水果名称
     * @return
     */
    public abstract String getFruitName();

    /**
     * 获取水果园名称
     * @return
     */
    public abstract String getOrchardName();

    /**
     * 水果识别算法
     * @param fruitName 水果名称
     * @return
     */
    public abstract String runIdentify(String fruitName);

    /**
     * 水果成熟度识别算法
     * @param fruitName 水果名称
     * @return
     */
    public abstract String runMaturityIdentify(String fruitName);

}

模版方法中的苹果采摘类实现:

public class ApplePickMain extends FruitPick{
    public static void main(String[] args) {
        ApplePickMain applePickMain = new ApplePickMain();
        applePickMain.pickWork();
    }
    @Override
    public String getFruitName() {
        return "苹果";
    }

    @Override
    public String getOrchardName() {
        return "苹果园";
    }

    @Override
    public String runIdentify(String fruitName) {
        //一系列苹果识别逻辑
        if ("苹果".equals(fruitName)){
            return "苹果识别算法识别完成,结果:是苹果";
        }
        return "苹果识别算法识别完成,结果:不是苹果";
    }

    @Override
    public String runMaturityIdentify(String fruitName) {
        //一系列苹果成熟度判断逻辑
        return "苹果程度度识别算法识别完成,结果:已成熟。";
    }
}

其他水果采摘类的实现方式同苹果类。
  通过上述优化。重复的代码都被提升到了超类中,每一种水果对应的类只需要去完成自己独特的业务逻辑即可,而且公共的处理流程也被规范化。减少了出现问题的可能性。

模版方法模式-定义

  模板方法模式(Template Method Pattern),又叫模板模式(Template Pattern),在一个抽象类公开定义了执行它的方法的模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行
  简单说,模板方法模式,定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构,就可以重定义该算法的某些特定步骤,这种类型的设计模式属于行为型模式。

上述定义引自:模版方法模式

优缺点

优点

  1. 共同处理逻辑放在了父类,可以提高复用性。
  2. 个性化逻辑由子类自己去实现,提高代码的扩展性。
  3. 去除了子类的重复代码,符合开闭原则。

缺点

  1. 每中事物都要有一个子类实现,增加了类的数量。
  2. 如果父类增加新的抽象方法,所有子类都要修改。
  3. 间接增加了系统复杂性。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值