java - 里氏替换和 SRP 原则违反 - 如何最好地构建这个场景?

标签 java c# oop design-patterns object-oriented-analysis

在学习 SRP 和 LSP 时,我正在尝试改进代码的设计,以最好地遵守这两个原则。我有一个雇员类,上面有一个calculatePay 方法。首先,我相信遵循 OOP SOLID 原则,calculatePay() 方法不应该是员工对象的责任。员工的共同职责是执行Duties()、takeLunchBreak()、clockIn() 和clockOut() 等。我这样想对吗?这就是为什么我觉得calculatePay()应该属于其他类。好吧,这就是我的 SRP 不安全感。

来到LSP:

我有会计师、推销员和董事等子类。这些都是拿薪水的员工。我如何改变这个设计以更好地支持志愿者?志愿者没有报酬。

public class Employee {

    private String name;
    private int salary;
    private boolean topPerformer;
    private int bonusAmount;


    public Employee(String name, int salary, boolean topPerformer, int bonusAmount) {
       // set fields etc..
    }

    // This method doesn't seem to belong here.
    public int calculatePay(){
        if(topPerformer)
            return salary+bonusAmount;
         else{
            return salary;
         }
    }
}

最佳答案

您实际上在这里处理许多不同的实体。

第一个实体是员工——您已经拥有了。

第二个实体是支付结构。正如您所看到的,最初的代码似乎很简单,直到您添加了一名志愿者。

第三是报酬计算——受薪员工根据表现获得不同的报酬,而志愿者则没有钱。

当您考虑到不同的员工可能与雇主有不同的契约(Contract)关系时,生活会变得更加有趣,这意味着他们具有相同的“付款结构”,但最终付款不同。其次,一名员工可以同时属于多个类别 - 受薪员工也可以做志愿者工作 - 这是您需要将“付款结构”和“付款计算”分成不同类别的另一个原因。

实现这些概念 -

首先,通过添加“paymentstruct ”类将支付结构移动到它自己的类中,如下所示:

public PaymentStructure(salary, 
                        boolean topPerformer, 
                        int bonusAmount) {       
    // set properties for a salaried employee etc..
}

public PaymentStructure() {// default constructor = volunteer employee 
                           // set salary, bonusamount to 0, topPerformer to false, etc..
}

这样做还可以添加其他类型的付款计算输入 - 例如工作完成时的一次性付款等。

接下来,如果您只允许与员工建立单一付款关系,则需要更改员工构造函数以接受付款结构:

public Employee(String name, PaymentStructure PayStructureParm)
   // Save PayStructureParm to a class property 
}

然后编写一个类来实现支付计算逻辑:

public DeterminePayment(){
   public float calculatePayment(PaymentStructure PayStructureParm) { 
            // logic to turn the payment structure into a final payment 
     return finalPayment; }
}

这会将员工、付款结构和付款计算拆分为各自的类,然后所有这些类都可以根据需要进行扩展。

为了获得更大的灵 active ,每个类都可以针对接口(interface)进行编码,并且特定类型的支付结构和计算类针对其各自的接口(interface)进行编码。

关于java - 里氏替换和 SRP 原则违反 - 如何最好地构建这个场景?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25712458/

相关文章:

java - JUnit 4 - 期望某个类的异常,但不是子类

java - 在模拟器/手机中运行应用程序时出现 NoClassDefFoundError

java - Cometd 发布输入数据 Map 而不是等待服务器的输出

oop - 在装饰器模式中添加状态

java - 为了验证而重写变异方法

c++ - 动态分配对象

java - JPA中表之间关系的问题

c# - 如何使用 C# 从 Windows 10 日历中检索 UWP 中的约会

c# - 是否有支持 Windows 7 的 SetProcessDPIAware 的反函数?或者如何回到原来的状态?

c# - 双缓冲 C#