java - 如何在没有instanceof或类型转换的情况下以OOP方式防止继承破坏所有依赖关系?

标签 java oop inheritance design-patterns

我们正在对飞机上的所有座位进行计费。最初我们每个座位都有折扣。 假设我们有一个类 Discount,并且 seat-billingaudit 代码依赖于它。

class Discount {

    private int discountId; // unique key stored in database

    public int getDiscountId() {
        return discountId;
    }

    public List<Seat> getListOfSeatsWithDiscount() {

    }

    public int getDiscountPercentPerSeat() { return 10; }

}

class SeatBill {
    public void billPerSeat() {
        for (each seat object) {
            // fetch discountObject from database.
            Discount d;
            // get list of seats with discounts, and for each of such seats
            seatObject.totalCost = seatObject.totalCost * (100 - d.getDiscountPercentPerSeat())/100;
        }
    }
}

然后我们有一个审核类,它关心折扣座位。

class Audit {

    public void audit(Discount id) {
        // fetch discount object from database given discount id.
        for (seat in d.getListOfSeatsWithDiscount()) {
            // log all the seats.
        }
    }
}

现在,飞机管理层决定增加另一个折扣 -> 假日季节的每月折扣。 因此,我们创建了一个抽象类 Discount 并创建了 DiscountPerSeatDiscountPerMonth

abstract class Discount {
    private int discountId; // unique key stored in database

    public int getDiscountId() {
        return discountId;
    }
}

class DiscountPerSeat extends Discount {


    public List<Seat> getListOfSeatsWithDiscount() {

    }

    // returns 10% discount on each seat reserved.
    public int getDiscountPercentPerSeat() { return 10; }

}

class DiscountPerMonth extends Discount {

    public boolean checkIfMonthIsValid(int month) {
        return month == 12;
    }

    // returns 10% discount on monthly bill
    public int getDiscountPercentPerMonth() { return 10; } 
}

每月账单代码现在将更改。

class MonthlyBill {

    public int monthlyBillPerPersonOrCompany(int id) {
        int totalCostPerEntity = gettotalCost(id);
        // fetch discount object from database
        // apply discount if 'current month' is december'
        totalCostPerEntity = totalCostPerEntity * (100 - (disCountPerMonth.getDiscountPercentPerMonth()))/100
    }
}

现在我的问题是:

  1. Audit 类已损坏,因为 getListOfSeatsWithDiscount 已移至其抽象方法折扣的子类中。如何在没有 typecaseting/instanceof 的情况下修复它?

  2. SeatBill 类已损坏,因为抽象类 Discount 不支持 getDiscountPercentPerSeat。如何在不进行类型转换/instanceof的情况下解决这个问题?

  3. MonthlyBill 将从数据库中获取折扣对象。再次,如何以 OOP 方式解决这个问题,而不依赖于 的实例?

基本上,代码库中的大量依赖关系都被破坏了,因为代码依赖于子类的特定方法,例如 getListOfSeatsgetValidMonth 等,这些方法无法抽象到基类.

请让我知道此类重构的通用解决方案/设计模式。

最佳答案

要解决问题1,需要声明public abstract List<Seat> getListOfSeatsWithDiscount();在折扣中。然后你需要定义getListOfSeatsWithDiscount()也有每月折扣。如果 Audit 仅适用于 DiscountPerSeat,则只需在 Audit 中使用 DiscountPerSeat(而不是 Discount)即可。

要解决问题2,您需要声明public abstract int getDiscount();将 Discount 中的 DiscountPerSeat 和 DiscountPerMonth 中的方法重命名为 getDiscount()。

问题3应该通过问题2的解决方案来解决。

关于java - 如何在没有instanceof或类型转换的情况下以OOP方式防止继承破坏所有依赖关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41399979/

相关文章:

java - 转换 0xFF 给我 -1 -> 有符号与无符号?

java - 如何检测用户是否只是在 SearchView.setOnQueryTextListener 中按下退格(删除)键?

javascript - 基于原型(prototype)的变量范围,JavaScript 中的 `new` 运算符

java - 如何在 Android 10 中以编程方式设置自定义主题属性

java - 如何使用hibernate和可选参数进行查询?

c# - 当不能选择多重继承时如何重用代码?

java - 为什么在泛型类(Java)的构造函数中提供类型参数是错误的?

Java继承之谜

c++ - 如何使用派生类中的函数而不将它们添加到基类中

python - 如何在 PyQT 中分离 ui 和实现?