应用举例:模板方法设计模式(抽象类)

2024-01-10 12:44:38

模板方法设计模式(抽象类)


应用举例:模板方法设计模式(TemplateMethod)

抽象类体现的就是一种模板模式,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展、改造,但子类总体上会保留抽象类的行为方式。

解决的问题:

  • 当功能内部一部分实现是确定的,另一部分实现是不确定的。这时可以把不确定的部分暴露出去,让子类去实现。
  • 换句话说,在软件开发中实现一个算法时,整体步骤很固定、通用,这些步骤已经在父类中写好了。但是某些部分易变,易变部分可以抽象出来,供不同子类实现。这就是一种模板模式。

案例1:计算代码运行时间

  1. 创建一个Template模板类,其中代码(code)方法是不确定的,抽象出来,计算时间(spendTime)方法是确定的。
  2. 输出星号类(PrintStar)继承模板类,重写父类的code方法。
public class TemplateTest {

    public static void main(String[] args) {
        PrintStar ps = new PrintStar();
        ps.spendTime();
    }
}

abstract class Template {

    public void spendTime() {
        long start = System.currentTimeMillis();
        code();
        long end = System.currentTimeMillis();
        System.out.println("花费的时间为:" + (end - start));
    }

    public abstract void code();

}

class PrintStar extends Template {

    @Override
    public void code() {
        System.out.println("*");
        System.out.println("**");
        System.out.println("***");
        System.out.println("****");
        System.out.println("*****");
    }
}

案例2:银行流程抽象

  1. 创建一个银行模板抽象类BankTemplateMethod,该类中排队取号(takeNumber)、反馈评分(evaluate)方法是确定的,办理业务方法(transact)是不确定的,需要抽象出去由子类实现具体的业务。模板方法(process)调用流程是固定的。
  2. 取款类(DramMoney)继承银行模板类,重写父类的transact方法。
  3. 理财类(ManageMoney)继承银行模板类,重写父类的transact方法。
public class TemplateMethodTest {

    public static void main(String[] args) {
        BankTemplateMethod btm = new DramMoney();
        btm.process();

        BankTemplateMethod btm2 = new ManageMoney();
        btm.process();
    }
}

abstract class BankTemplateMethod {

    public void takeNumber() {
        System.out.println("排队取号");
    }

    //办理具体的业务
    public abstract void transact();

    public void evaluate() {
        System.out.println("反馈评分");
    }

    //模板方法
    public final void process() {
        takeNumber();
        transact();
        evaluate();
    }

}

class DramMoney extends BankTemplateMethod {

    @Override
    public void transact() {
        System.out.println("我要取款!!!");
    }
}

class ManageMoney extends BankTemplateMethod {

    @Override
    public void transact() {
        System.out.println("我要理财!!!我这里有200W");
    }
}

案例三:抽象员工系统,分全职工和小时工,输出他们的工资(生日当月工资加二百)

  1. 创建员工抽象类(Employee),工资计算(calculateSalary)方法不确定需要抽象,是否为生日当月(isBirthday)方法、总工资计算(earnings)方法是确定的。
  2. 创建全职工类(SalariedEmployee)继承员工抽象类,重写工资计算(calculateSalary)方法。
  3. 创建小时工类(HourlyEmployee)继承员工抽象类,重写工资计算(calculateSalary)方法。

员工抽象类 Employee.java:

@Data
@AllArgsConstructor
@NoArgsConstructor
public abstract class Employee {

    private String name;
    private Integer number;
    private MyDate birthday;

    public abstract double calculateSalary();

    public String toString() {
        return "name = " + name + ",number = " + number + ", birthday = " + birthday.toDateString();
    }

    //模板方法:返回工资
    public final double earnings() {
        return calculateSalary() + isBirthday();
    }

    public double isBirthday() {
        Calendar now = Calendar.getInstance();
        return birthday.getMonth() - 1 == now.get(Calendar.MONTH) ? 200 : 0;
    }
}

@Data
@AllArgsConstructor
@NoArgsConstructor
class MyDate {
    private Integer year;
    private Integer month;
    private Integer day;


    public String toDateString() {
        return year + "年" + month + "月" + day + "日";
    }
}

全职工类 SalariedEmployee.java

@Data
@NoArgsConstructor
public class SalariedEmployee extends Employee {

    private double monthlySalary;

    public SalariedEmployee(String name, Integer number, MyDate birthday, double monthlySalary) {
        super(name, number, birthday);
        this.monthlySalary = monthlySalary;
    }

    @Override
    public double calculateSalary() {
        return monthlySalary;
    }

    public String toString() {
        return "SalariedEmployee[" + super.toString() + "]";
    }
}

小时工类 HourlyEmployee.java

@Data
@NoArgsConstructor
public class HourlyEmployee extends Employee {

    private double wage;//小时工资
    private int hour;//月工作小时

    @Override
    public double calculateSalary() {
        return wage * hour;
    }

    public HourlyEmployee(String name, Integer number, MyDate birthday, double wage, int hour) {
        super(name, number, birthday);
        this.wage = wage;
        this.hour = hour;
    }

    public String toString() {
        return "HourlyEmployee[" + super.toString() + "]";
    }
}

测试类 PayrollSystem.java

public class PayrollSystem {

    public static void main(String[] args) {
        Employee[] emps = new Employee[2];
        emps[0] = new SalariedEmployee("张小亮", 1001, new MyDate(1992, 1, 21), 18000);
        emps[1] = new HourlyEmployee("刘大地", 1002, new MyDate(1998, 4, 10), 21, 18);

        for (Employee emp : emps) {
            System.out.println(emp.toString());
            System.out.println("工资为:" + emp.earnings());
        }
    }
}

文章来源:https://blog.csdn.net/qq_42236791/article/details/135500287
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。