2016-12-30 17 views
1

「SOLID」の原則を学ぶ私はクラスにいくつかの拡張を追加する必要がある場合は、コンストラクタを変更することは大丈夫ですか?ビジネスの論理。コンストラクタのオープンクローズドの原理

私が学んだことは、コンストラクタを変更するように見えますが、私は 'オープンクローズ'の原則に違反しますが、ロジックを実行するために別のクラスを注入する必要がある場合はどうすればいいですか?どのようにしてコンストラクタの変更なしでこれを行うことができますか?一般に、コンストラクタの変更は 'オープンクローズ'の原則に違反しますか?

例を考えてみましょう。

だから、それは非常に簡単だ

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

} 

CountableDefaultShopFactoryShopFactoryを実装し、2つのメソッドをオーバーライドし、各メソッドが何回呼び出されたかをカウントするために、いくつかのCounterオブジェクトに依存します。各メソッドは、静的メソッドを使用していくつかのデータを返します。

もう1つの方法を追加するよう依頼されましたが、今回は一部のストレージからデータを取得する必要があり、そのストレージからデータを提供するサービスがあります。この場合、操作を実行するためにこのサービスをクラスに注入する必要があります。

そしてこのようなルックスになるだろう:

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

} 

だから、私は1つの以上Counterクラスを追加し、
CouponDAOで私のコンストラクタを変更する必要がありました。私はCountercouponsCounterと呼びます。これは、ShopFactoryのカウント可能な実装なので、もう1つ追加する必要があります。しかし、CouponDAOを追加しても私にとってはうまく見えません。

もっと良い解決方法があるのですか?

+0

これらの「ファクトリー」は何になりますか? – weston

答えて

3

はい、これはOpen Closedにも違反していますが、SRPにも違反しています。クラスを変更する理由が複数あるためです。

新しい要件があり、そこにある内容を変更せずに、コードを拡張して、単一のメソッドでのみ使用された新しい依存関係をすべて追加することができました。 (私が気にしないなら、Factory postfixを削除します):

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

私は1つの理由、つまりもう1つのメソッドを追加するだけです。 – user3127896

関連する問題