【问题标题】:Java - Possible use of Strategy Design Pattern?Java - 可能使用策略设计模式?
【发布时间】:2023-07-11 09:16:01
【问题描述】:
public class ClassA_V01 {
    private String name;
    private int age;

    // getter and setter
}

public class ClassA_V02 {
    private String name;
    private int age;
    private int gender;

    // getter and setter
}   

public static void main(String[] args) {
    SomeClass classA = new ClassA_V01();
    classA.setName("myName);
    classA.setAge(99);
    performLogic(classA);

    // OR
    SomeClass classA = new ClassA_V02();
    classA.setName("myName);
    classA.setAge(99);
    classA.setAge(1);
    performLogic(classA);
}

public void performLogic(SomeClass classA) {
    // do something
}

要使策略模式起作用,两个类必须实现接口中定义的相同方法。但是如果类需要有不同的字段和方法呢?

在我的例子中,ClassA_V01 和 ClassA_V02 是同一个类,只是多了一个属性“gender”

如何实现上述,使 classA 可以等于 ClassA_V01() 或 ClassA_V02?

【问题讨论】:

    标签: java design-patterns strategy-pattern


    【解决方案1】:

    ...为了使策略模式起作用,两个类必须实现接口中定义的相同方法。但是如果这些类需要具有不同的字段和方法怎么办?...”真的这不是策略模式的标准。

    策略模式的目的是识别和使算法系列可互换。如果您仔细阅读该模式的文档,则可以在许多相关类仅在行为上有所不同时使用策略。

    适当的分解是更好(可扩展)设计的关键。 Employee 分配的典型(但原始)解决方案,子类 tempEmp 和 PermanentEmp 类型将给我们带来麻烦,并且不允许 temp 员工在其生命周期内成为永久的(这实际上没有任何意义条款)。发生这种情况是因为我们错过了一个重要的观点 - 每个员工的员工素质并没有什么不同,他们都是具有不同薪酬政策的同一类型的员工。 (同样的逻辑可以扩展到休假政策等)

    如果所有类型的员工都有基于相同组件(相同状态)的薪水计算,这将变得很简单。但是您的问题是,如果 TempEmployee 仅获得 basicPay 而 PermanentEmployee 获得 basicPay 以及 travelAllowance(TempEmp 不存在的附加属性),该怎么办。这可以通过简单的继承层次结构以及依赖于员工(又名上下文)属性(年龄)的计算算法的策略组合来建模

    public class Employee {
        //name and id
        private PayPackage payPackage;
        private int age;
        PayPackage strategy;
        public double computeSalary() {
            return payPackage.computePay(age);
        }
        //get/setPayPackage(...)
    }
    public abstract class PayPackage {
        private double basicPay;
        abstract public double computePay(int age);
        protected double getBasicPay(){
            return basicPay;
        }
    }
    public class TempPayPackage extends PayPackage{
        @Override
        public double computePay(int age) {
            double veteranAllowance = 0;
            if (age > 40) {
                veteranAllowance = 2000.00;
            }
            return getBasicPay() + veteranAllowance;
        }
    }
    public class PermanentPayPackage extends PayPackage{
        private double travelAllowance;
        @Override
        public double computePay(int age) {
            double veteranAllowance = 0;
            if (age > 40) {
                veteranAllowance = 5000.00;
            }
            return getBasicPay() + travelAllowance + veteranAllowance;
        }
    }
    

    要记住的重要一点是设计模式永远不会单独工作或作为替代模式,它们与面向对象的代码和其他模式一起工作。

    【讨论】: