2016-12-30 2 views
1

학습 '솔리드'원칙 클래스에 더 많은 확장을 추가해야하는 경우 생성자를 수정하는 것이 좋습니다. 비즈니스 로직.생성자가있는 열린 닫힌 원칙

나는 '열린 닫힘'원칙을 위반하는 생성자를 수정하는 것처럼 보였지만, 어떤 논리를 수행하기 위해 다른 클래스를 주입해야한다면 어떨까요? 어떻게하면 생성자 수정없이이 작업을 수행 할 수 있습니까? 일반적으로 생성자 수정이 '열린 닫힘'원칙을 위반합니까?

예를 들어 보겠습니다.

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

} 

그래서 꽤 간단합니다 인터페이스를

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

을 있어요 그리고 하나의 구현이있다 (그리고 누군가가 종속성으로 내 라이브러리를 추가하고자하는 경우 아마도 다른 사람이있을 수 있습니다). CountableDefaultShopFactoryShopFactory을 구현하며 두 메서드를 재정의하며 각 메서드가 몇 번 호출되었는지 계산하기 위해 일부 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를 추가하여 내 생성자를 수정했다. 나는 CountercouponsCounter이라고 부르며 ShopFactory이라는 계산 가능한 값을 하나 더 추가해야합니다. 하지만 CouponDAO을 추가하는 것은 나에게 좋지 않습니다.

더 나은 해결책이있는 방법이 궁금합니다.

+0

이 '팩토리'는 무엇이됩니까? – weston

답변

3

네, 이제 수업을 변경해야 할 이유가 여러 개 부여되었으므로 CLP를 위반 한 것입니다.

새로운 요구 사항이 발생했습니다. 코드가 변경되지 않고 단일 메서드에서만 사용 된 모든 새 종속성을 추가하지 않고도 코드를 확장 할 수있었습니다. (괜찮 으면 공장 포스트 픽스를 삭제할 것입니다.) :

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

답변 해 주셔서 감사합니다. SRP가 왜 휘발성이되는지 설명해 주시겠습니까? – user3127896

+0

내가 말했듯이 이제 수업을 변경해야하는 이유 한 두 개 이상을 부여했습니다. – weston

+0

다른 이유는 하나만 있습니다. – user3127896