设计模式随笔(十):模板方法

概述

  通过一个抽象类定义一个公共骨架,生成类的步骤都通过这个骨架完成。公共的部分可以通过抽象类中的方法完成,对于不同子类需要执行的不同逻辑,子类可以实现这些抽象方法完成。

使用场景

  1.算法或操作遵循相似的逻辑;

  2.多个子类有相同方法

 

UML图

 

  抽象模板(Abstract Template)角色有如下责任:

  ■  定义了一个或多个抽象操作,以便让子类实现。这些抽象操作叫做基本操作,它们是一个顶级逻辑的组成步骤。

  ■  定义并实现了一个模板方法。这个模板方法一般是一个具体方法,它给出了一个顶级逻辑的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类实现。顶级逻辑也有可能调用一些具体方法。

  具体模板(Concrete Template)角色又如下责任:

  ■  实现父类所定义的一个或多个抽象方法,它们是一个顶级逻辑的组成步骤。

  ■  每一个抽象模板角色都可以有任意多个具体模板角色与之对应,而每一个具体模板角色都可以给出这些抽象方法(也就是顶级逻辑的组成步骤)的不同实现,从而使得顶级逻辑的实现各不相同。

 

 

抽象模板

package com.ccz.demo.design.template;

import java.math.BigDecimal;

public abstract class AbstractTemplate {

    public final BigDecimal rebatePrice(String userId, BigDecimal price, String rule) {
        BigDecimal result = BigDecimal.ZERO;
        // 1.返回用户等级
        getUserLeavel(userId);
        // 2.价格不同优惠力度不同
        result = rebateMatch(price);
        // 3.选择了不同的优惠规则
        result = ruleMatch(userId, rule, result);
        return result;
    }

    /**
     * 公共的获取用户等级
     * @param userId
     * @return
     */
    private int getUserLeavel(String userId) {
        // todo 业务处理,返回等级
        return 1;
    }

    /**
     * 匹配价格优惠
     * @param price
     * @return
     */
    protected abstract BigDecimal rebateMatch(BigDecimal price);

    /**
     * 匹配规则优惠
     * @param userId
     * @param rule
     * @return
     */
    protected abstract BigDecimal ruleMatch(String userId, String rule, BigDecimal price);

}

 

 

具体模板

package com.ccz.demo.design.template;

import java.math.BigDecimal;

/**
 * 实现子类A
 */
public class ConcreteTemplateA extends AbstractTemplate{

    @Override
    protected BigDecimal rebateMatch(BigDecimal price) {
        // 实际业务逻辑
        return price;
    }

    @Override
    protected BigDecimal ruleMatch(String userId, String rule, BigDecimal price) {
        // todo 业务逻辑
        // 不管如何减10元
        return price.subtract(BigDecimal.TEN);
    }
}

 

调用

package com.ccz.demo.design.template;

import java.math.BigDecimal;

public class TemplateClient {
    public static void main(String[] args) {
        AbstractTemplate template = new ConcreteTemplateA();
        BigDecimal actPrice = template.rebatePrice("1", BigDecimal.ZERO, "某项规则");
        System.out.println(actPrice);
    }
}

 

 

posted @ 2021-01-13 19:07  胡吃海喝的程序猿  阅读(54)  评论(0编辑  收藏  举报