[JAVA] [Reading Memo] Refactoring-Typecode replacement (for typecodes that affect behavior)-2

What? State pattern?

https://qiita.com/takutotacos/items/654e204d618d2059de7f The point is to do something similar to this.

I want to do ↑, but I use this pattern when the type code changes during the life of the object. It is a subclassed that can accommodate changes in the type code.

How? How do you do it?

Change before.java


class Employee {
    static final int ENGINEER = 0;
    static final int SALESMAN = 1;
    static final int MANAGER = 2;

    private int type;

    public Employee(int type) {
        this.type = type;
    }

    int payAmount() {
        switch (type) {
            case ENGINEER: return monthlySalary;
            case SALESMAN: return monthlySalary + commission;
            case MANAGER : return monthlySalary + bonus;

        }
    }
}

I want to get rid of the above switch statement. For that purpose, implement as follows.

After change.java


class Employee {
    private EmployeeType type;

    int getType() {
        return type.getType();
    }

    void setType(int type) {
        this.type = EmployeeType.newType(type);
    }
}

abstract class EmployeeType {
    public static final int ENGINEER = 0;
    public static final int SALESMAN = 1;
    public static final int MANAGER = 2;

    static EmployeeType newType(int code) {
        switch (code) {
            case EmployeeType.ENGINEER: return new Engineer();
            case EmployeeType.SALESMAN: return new Salesman();
            case EmployeeType.MANAGER : return new Manager();
            default: throw new IllegalArgumentException("Illegal employee code");
        }
    }

    abstract int getType();
}

public class Engineer extends EmployeeType {
    @Override
    int getType() {
        return EmployeeType.ENGINEER;
    }
}

class Salesman extends EmployeeType {
    @Override
    int getType() {
        return EmployeeType.SALESMAN;
    }
}

class Manager extends EmployeeType {
    @Override
    int getType() {
        return EmployeeType.MANAGER;
    }
}

After this, if the payroll logic is implemented in each subclass, there will be no conditional branching from the client class except for object creation. In this case, it seems that you will not forget to implement the logic even if you increase the types of subclasses. Even if you forget to add a subclass to the switch statement when creating an object, it will throw an error and end, so it is easy to recognize that you forgot to implement it, making it an easy-to-debug program.

Recommended Posts

[Reading Memo] Refactoring-Typecode replacement (for typecodes that affect behavior)-2
[Reading Memo] Refactoring-Typecode replacement (for typecodes that affect behavior)-1
A memo for myself that object-oriented is something