java - 构造函数的开闭原则

标签 java solid-principles open-closed-principle

学习“SOLID”原则我想知道如果我需要向类添加更多扩展,例如可以修改构造函数吗?商业逻辑。

据我所知,修改构造函数似乎违反了“开放-封闭”原则,但是如果我需要注入(inject)另一个类来执行某些逻辑怎么办?如何在不修改构造函数的情况下做到这一点?一般来说,构造函数修改是否违反“开放-封闭”原则?

让我们考虑一个例子。

有一个界面

public interface ShopFactory {
    List<Discount> getDiscounts();
    List<Sale> getSales();
}

并且有一个实现(如果有人想将我的库添加为依赖项,可能还有其他实现)

public class CountableDefaultShopFactory implements ShopFactory {

    Counter discountsCounter;
    Counter salesCounter;

    public DefaultShopFactory(Counter discountsCounter, Counter salesCounter) {
        this.discountsCounter = discountsCounter;
        this.salesCounter = salesCounter;
    }

    @Override
    List<Discount> getDiscounts() {
        discountsCounter.count();
        return Discount.defaultDiscounts();
    }

    @Override
    List<Sale> getSales() {
        salesCounter.count();
        return Sale.defaultSales();
    }

}

所以这非常简单。 CountableDefaultShopFactory 实现 ShopFactory,重写两个方法并依赖于一些 Counter 对象来计算每个方法被调用的次数。每个方法都使用静态方法返回一些数据。

现在假设我被要求添加一种方法,这次我需要从某些存储中获取数据,并且有一项服务可以从该存储中提供一些数据。在这种情况下,我需要在我的类中注入(inject)此服务才能执行操作。

它看起来像这样:

public class CountableDefaultShopFactory implements ShopFactory {

    Counter discountsCounter;
    Counter salesCounter;
    Counter couponsCounter;
    CouponDAO couponDAO;

    public DefaultShopFactory(Counter discountsCounter, Counter salesCounter, Counter couponsCounter, CouponDAO couponDAO) {
        this.discountsCounter = discountsCounter;
        this.salesCounter = salesCounter;
        this.couponsCounter = couponsCounter;
        this.couponDAO = couponDAO;
    }

    @Override
    List<Discount> getDiscounts() {
        discountsCounter.count();
        return Discount.defaultDiscounts();
    }

    @Override
    List<Sale> getSales() {
        salesCounter.count();
        return Sale.defaultSales();
    }

    @Override
    List<Coupon> getCoupons() {
        couponsCounter.count();
        return couponDAO.getDefaultCoupons();
    }

}

所以我必须通过添加一个 Counter 类来修改我的构造函数
CouponDAO。我可以再添加一个名为 couponsCounterCounter,因为这是 ShopFactory 的可数实现。但添加 CouponDAO 对我来说看起来不太好。

我想知道是否有更好的解决方案如何做到这一点?

最佳答案

是的,它违反了开放封闭原则,而且也违反了 SRP,因为您现在已经向类(class)提供了不止一个更改理由。

出现了新的需求,您可以扩展代码,而无需更改现有内容并添加仅由单个方法使用的所有新依赖项。 (如果您不介意的话,我会删除 Factory 后缀):

public interface CouponShop extends Shop {
    List<Coupon> getCoupons();
}

public class CountableCouponShop implements CouponShop {

    public CountableCouponShop(Shop shop, Counter couponsCounter, CouponDAO couponDAO) {
        //assign to fields
    }

    @Override
    List<Discount> getDiscounts() {
        return shop.getDiscounts(); //just delegate to the old implementation of shop
    }

    @Override
    List<Sale> getSales() {
        return shop.getSales();
    }

    @Override
    List<Coupon> getCoupons() {
        couponsCounter.count();
        return couponDAO.getDefaultCoupons();
    }
}

关于java - 构造函数的开闭原则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41403053/

相关文章:

java - Android XML内部存储

java - 删除 JOptionPane 图标

java - Java中处理组件输入的最佳实践

c# - 如何使用SOLID原则构建第三方库抽象层

java - 开闭原理及Java "final"修饰符

language-agnostic - OO 设计,开放/封闭原则问题

c# - 在 C# 中加密的数据是 1 个字节太长,无法在 Java 中解密

java - 如何使用 MockHttpServletRequest 对文件上传进行单元测试?

java - 如何从 Appium JUnit 测试监控 iOS 模拟器/Android 模拟器的 HTTP 流量?

c# - 一个 child 实现接口(interface)而另一个 child 不实现接口(interface)是否违反了里氏替换原则?