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

本文介绍了模板方法设计模式,如何通过抽象类定义固定行为和可变部分,用于解决功能部分确定和不确定的问题。通过计算代码运行时间、银行流程抽象和员工系统的示例,展示了模板方法如何在实际编程中应用。
摘要由CSDN通过智能技术生成

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


应用举例:模板方法设计模式(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());
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

该叫啥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值