1. 设计模式之模板方法模式:抽取通用代码逻辑到父类

1.1. 介绍

在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。这种类型的设计模式属于行为型模式。

解决在多个子类中重复实现相同的方法的问题,通过将通用方法抽象到父类中来避免代码重复

优缺点及建议

优点 
1.封装不变部分:算法的不变部分被封装在父类中。
2.扩展可变部分:子类可以扩展或修改算法的可变部分。
3.提取公共代码:减少代码重复,便于维护。

缺点
1.类数目增加:每个不同的实现都需要一个子类,可能导致系统庞大。

使用建议
1.当有多个子类共有的方法且逻辑相同时,考虑使用模板方法模式。
2.对于重要或复杂的方法,可以考虑作为模板方法定义在父类中。

注意事项
1.为了防止恶意修改,模板方法通常使用final关键字修饰,避免被子类重写。

1.2. 实现及相关代码

假设有一个业务,开发优惠券逻辑,优惠券种类有很多,都会有一段通用逻辑,然后每种优惠券都有自己特殊的逻辑。

1.2.1. 没使用设计模式方式

接口及数据对象

public static class DiscountCalculator1 {
    public void calculate() {
        System.out.println("通用的计算逻辑");
        System.out.println("优惠计算器1的特殊计算逻辑");
    }
}

public static class DiscountCalculator2 {
    public void calculate() {
        System.out.println("通用的计算逻辑");
        System.out.println("优惠计算器2的特殊计算逻辑");
    }
}

public static class DiscountCalculator3 {
    public void calculate() {
        System.out.println("通用的计算逻辑");
        System.out.println("优惠计算器3的特殊计算逻辑");
    }
}

调用方法

public static void main(String[] args) {
    DiscountCalculator1 calculator1 = new DiscountCalculator1();
    calculator1.calculate();

    DiscountCalculator2 calculator2 = new DiscountCalculator2();
    calculator2.calculate();

    DiscountCalculator3 calculator3 = new DiscountCalculator3();
    calculator3.calculate();
}

可能会遇到的问题

各种优惠券都有通用的逻辑,如果通用逻辑要调整,需要改各类优惠券的代码,当种类很多的时候,很容易有遗漏。修改遗漏会引发很严重的问题,导致价格计算错误,会有严重的损失。扩展性、维护性很差。

1.2.2. 使用设计模式方式

使用模版方法设计模式,可以把通用逻辑抽象出来,各类优惠券可以公用复用,当要调整逻辑时,只修改一个地方,所有优惠券都会生效,不会有遗漏。

接口及数据对象

public interface DiscountCalculator {
    void calculate();
}

/** 模板方法实现的精华所在 */
public static abstract class AbstractDiscountCalculator implements DiscountCalculator {
    public void calculate() {
        // 完成通用的计算逻辑
        commonCalculate();
        // 完成特殊的计算逻辑
        specificCalculate();
    }

    private void commonCalculate() {
        System.out.println("通用的计算逻辑");
    }

    protected abstract void specificCalculate();
}

public static class DiscountCalculator1 extends AbstractDiscountCalculator {
    public void specificCalculate() {
        System.out.println("优惠计算器1的特殊计算逻辑");
    }
}

public static class DiscountCalculator2 extends AbstractDiscountCalculator {
    public void specificCalculate() {
        System.out.println("优惠计算器2的特殊计算逻辑");
    }
}

public static class DiscountCalculator3 extends AbstractDiscountCalculator {
    public void specificCalculate() {
        System.out.println("优惠计算器3的特殊计算逻辑");
    }
}

调用方法

public static void main(String[] args) {
    DiscountCalculator calculator1 = new DiscountCalculator1();
    calculator1.calculate();

    DiscountCalculator calculator2 = new DiscountCalculator2();
    calculator2.calculate();

    DiscountCalculator calculator3 = new DiscountCalculator3();
    calculator3.calculate();
}

results matching ""

    No results matching ""