设计模式---模版模式

1. 简介

模板方法模式(Template Method Pattern)是一种行为型设计模式,它在父类中定义一个算法的框架,允许子类在不改变算法结构的情况下重写算法的某些特定步骤。这种模式主要用来解决代码重复的问题,并且提供了一个算法的统一框架,使得子类可以在这个框架下去实现特定的功能。

特点

  • 代码复用:模板方法模式使得子类可以复用父类的代码,提高代码复用性。

  • 扩展性:通过覆盖父类的方法,子类可以很容易地扩展新的功能。

  • 控制反转:将一些步骤的控制权从子类反转到父类,父类控制流程,子类实现具体步骤。

结构

模板方法模式通常包含以下角色:

  • 抽象类(Abstract Class):定义了模板方法和算法的框架。模板方法一般是一个具体方法,它定义了算法的步骤,并调用基本方法来完成算法的部分步骤。

  • 基本方法(Primitive Method):在抽象类中定义的抽象方法或具体方法,是算法框架的一部分。抽象方法通常由子类实现,而具体方法则可以直接实现或由子类覆盖。

  • 钩子方法(Hook Method):在抽象类中定义的可供子类覆盖的方法,不做任何事情或包含默认实现。

  • 具体实现子类(Concrete Class):实现抽象类中定义的抽象方法,完成算法中可变的部分。

2. 具体案例

模拟爬⾍各类电商商品,⽣成营销推⼴海报场景

定义抽象类

java 复制代码
package com.xiaokai.rule;

/**
 * Author:yang
 * Date:2024-10-25 10:27
 * 模板方法模式通常包含以下几个角色:
 * <p>
 * 抽象类(Abstract Class):定义了模板方法和算法的框架。
 * 具体实现子类(Concrete Class):实现抽象类中定义的模板方法中的可变部分。
 * 钩子方法(Hook Method):在抽象类中定义,可以被子类重写,也可以不重写。
 * 模板方法(Template Method):定义算法的框架,调用基本方法和钩子方法。
 */

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;

/**
 * 基础电商推⼴服务
 * 1. ⽣成最优价商品海报
 * 2. 海报含带推⼴邀请码
 */
public abstract class AbstractNetMall {


    protected Logger logger = LoggerFactory.getLogger(AbstractNetMall.class);
    String uId; // ⽤户ID
    String uPwd; // ⽤户密码

    public AbstractNetMall(String uId, String uPwd) {
        this.uId = uId;
        this.uPwd = uPwd;
    }


    /**
     * ⽣成商品推⼴海报
     *
     * @param skuUrl 商品地址(京东、淘宝、当当)
     * @return 海报图⽚base64位信息
     */
    public String generateGoodsPoster(String skuUrl) {
        if (!login(uId, uPwd)) return null; // 1. 验证登录
        Map<String, String> reptile = reptile(skuUrl); // 2. 爬⾍商品
        return createBase64(reptile); // 3. 组装海报
    }

    // 模拟登录
    protected abstract Boolean login(String uId, String uPwd);

    // 爬⾍提取商品信息(登录后的优惠价格)
    protected abstract Map<String, String> reptile(String skuUrl);

    // ⽣成商品海报信息
    protected abstract String createBase64(Map<String, String> goodsInfo);
}

当当、京东、淘宝三种行为

java 复制代码
public class DDProduct extends AbstractNetMall {


    public DDProduct(String uId, String uPwd) {
        super(uId, uPwd);
    }

    @Override
    protected Boolean login(String uId, String uPwd) {
        // 模拟当当用户登录
        logger.debug("模拟当当用户登录, uId: {},uPwd: {}", uId, uPwd);

        return true;
    }

    @Override
    protected Map<String, String> reptile(String skuUrl) {

        // 匹配
        Map<String, String> map = new ConcurrentHashMap<String, String>();
        //Pattern p9 = Pattern.compile("(?<=title\\>).*(?=</title)");
        //Matcher m9 = p9.matcher(skuUrl);
        //if (m9.find()) {
        //    map.put("name", m9.group());
        //}
        map.put("name", "当当产品天下第一好····");
        map.put("price", "99.00");
        logger.info("模拟当当商品爬⾍解析:{} | {} 元 {}", map.get("name"),
                map.get("price"), skuUrl);
        return map;
    }

    @Override
    protected String createBase64(Map<String, String> goodsInfo) {
        Base64.Encoder encoder = Base64.getEncoder();
        logger.info("模拟⽣成当当商品base64海报");
        return encoder.encode(goodsInfo.toString().getBytes()).toString();
    }
}


public class JDProduct extends AbstractNetMall {


    public JDProduct(String uId, String uPwd) {
        super(uId, uPwd);
    }

    @Override
    protected Boolean login(String uId, String uPwd) {
        // 模拟淘宝用户登录
        logger.debug("模拟京东用户登录, uId: {},uPwd: {}", uId, uPwd);

        return true;
    }

    @Override
    protected Map<String, String> reptile(String skuUrl) {

        // 匹配
        Map<String, String> map = new ConcurrentHashMap<String, String>();
        //Pattern p9 = Pattern.compile("(?<=title\\>).*(?=</title)");
        //Matcher m9 = p9.matcher(skuUrl);
        //if (m9.find()) {
        //    map.put("name", m9.group());
        //}
        map.put("name", "京东产品天下第一好····");
        map.put("price", "4299.00");
        logger.info("模拟京东商品爬⾍解析:{} | {} 元 {}", map.get("name"),
                map.get("price"), skuUrl);
        return map;
    }

    @Override
    protected String createBase64(Map<String, String> goodsInfo) {
        Base64.Encoder encoder = Base64.getEncoder();
        logger.info("模拟⽣成京东商品base64海报");
        return encoder.encode(goodsInfo.toString().getBytes()).toString();
    }
}

public class TaoBaoProduct extends AbstractNetMall {


    public TaoBaoProduct(String uId, String uPwd) {
        super(uId, uPwd);
    }

    @Override
    protected Boolean login(String uId, String uPwd) {
        // 模拟淘宝用户登录
        logger.debug("模拟淘宝用户登录, uId: {},uPwd: {}", uId, uPwd);

        return true;
    }

    @Override
    protected Map<String, String> reptile(String skuUrl) {

        // 匹配
        Map<String, String> map = new ConcurrentHashMap<String, String>();
        //Pattern p9 = Pattern.compile("(?<=title\\>).*(?=</title)");
        //Matcher m9 = p9.matcher(skuUrl);
        //if (m9.find()) {
        //    map.put("name", m9.group());
        //}
        map.put("name", "淘宝产品天下第一好····");
        map.put("price", "4799.00");
        logger.info("模拟淘宝商品爬⾍解析:{} | {} 元 {}", map.get("name"),
                map.get("price"), skuUrl);
        return map;
    }

    @Override
    protected String createBase64(Map<String, String> goodsInfo) {
        Base64.Encoder encoder = Base64.getEncoder();
        logger.info("模拟⽣成淘宝商品base64海报");
        return encoder.encode(goodsInfo.toString().getBytes()).toString();
    }
}

测试

java 复制代码
public class MallApplication {
    public static void main(String[] args) {
        AbstractNetMall product = new TaoBaoProduct("xiaokai", "123456");
        String goodsPoster = product.generateGoodsPoster("www.taobao.com/xiaokai.caio&mfdk");
        System.out.println(goodsPoster);

    }
}


模拟淘宝用户登录, uId: xiaokai,uPwd: 123456
模拟淘宝商品爬⾍解析:淘宝产品天下第一好···· | 4799.00 元 www.taobao.com/xiaokai.caio&mfdk
模拟⽣成淘宝商品base64海报
海报生成成功:[B@7907ec20

不积跬步,无以至千里 --- xiaokai

相关推荐
四维碎片2 分钟前
【Qt】QApplication::restoreOverrideCursor():恢复鼠标光标到原始状态的用法解析
开发语言·qt·计算机外设
想进大厂的小王9 分钟前
Spring Boot⾃动配置
java·spring boot·后端
远望清一色15 分钟前
基于小波变换图像去噪MATLAB实现
开发语言·matlab
啊QQQQQ33 分钟前
linux:回车换行+进度条+git理解与使用以及如何解决免密码push问题
开发语言·javascript·ecmascript
CL_IN38 分钟前
高效集成:聚水潭奇门至金蝶云星空的数据流自动化
java·前端·自动化
Ylucius40 分钟前
14天速成前端 ------学习日志(已完结)------ 后端程序员学习了解前端
java·开发语言·前端·vue.js·学习·状态模式·1024程序员节
就叫飞六吧1 小时前
关于Java中**optional,stream,lambda**
java·开发语言
调皮的木木1 小时前
zookeeper全系列学习之分布式锁实现
java·分布式·zookeeper
零希1 小时前
正则表达式
java·数据库·mysql
lovelin+v175030409661 小时前
电商平台店铺运营:巧用 API 接口的策略之道
java·大数据·后端·python