开放式原理与构造函数

时间:2016-12-30 21:45:26

标签: java solid-principles open-closed-principle

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

从我所学到的内容看起来,修改构造函数我违反了“开放式关闭”。原则,但如果我需要注入另一个类来执行某些逻辑呢?如何在没有构造函数修改的情况下执行此操作,并且通常,构造函数修改违反了“open-closed”#39;原理?

让我们考虑一个例子。

有一个界面

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个对象,以计算每个方法被调用的次数。每个方法都使用静态方法返回一些数据。

现在让我们说我已经被要求再添加一个方法,这次我需要从某个存储中获取数据,并且有一个服务从该存储中提供一些数据。在这种情况下,我需要在我的类中注入此服务才能执行操作。

它看起来像这样:

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。我还需要再添加一个名为Counter的{​​{1}},因为这是couponsCounter的可数实现。但添加ShopFactory对我来说并不好看。

我想知道有更好的解决方法吗?

1 个答案:

答案 0 :(得分:3)

是的,它违反了Open Closed,但也违反了SRP,因为你现在给了这个课程不止一个改变的理由。

出现了一个新的要求,您可以扩展代码而不更改其中的内容并添加仅由单个方法使用的所有新依赖项。 (如果你不介意,我会放弃工厂后缀):

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();
    }
}