2

クラスが次のように設定されている設計上の問題があります。

abstract class Advertiser        abstract class AdvertiserCampaign
      |                                    |
      |                                    |
class AdvUno extends Advertiser  class AdvUnoCampaign extends AdvertiserCampaign
class AdvDos extends Advertiser  class AdvDosCampaign extends AdvertiserCampaign
class AdvTre extends Advertiser  class AdvTreCampaign extends AdvertiserCampaign

問題は、AdvUnoAdvUnoCampaignの両方が、他の人には必要のない特別な認証方法を必要とすることです。今はこれを に配置しましたが、 (およびこのように設定された他の多くのクラス) でAdvUno必要になります。AdvUnoCampaign

  • PHP には多重継承がないため、 AdvUnoCampaignextendを作成することはできません。AdvUno
  • AdvertiserCampaignextendを作成するAdvertiserと、以下のすべての拡張クラス ( AdvUnoCampaign、など) は、それらに関係なく、各クラスAdvDosCampaignに既に実装されている一連の抽象メソッドを実装する必要があります。Advertiser

要するに、この種の状況でのベスト デザイン プラクティスは何ですか? AdvOneコードをコピーしてすべてのクラスに貼り付けるだけではだめです。ヘルプやアドバイスをいただければ幸いです。ありがとう!

4

2 に答える 2

3

並列継承階層コードの臭いと見なされ、リファクタリングする必要があります。

Martin Fowlerは、「リファクタリング」で次のように提案しています。

重複を排除するための一般的な戦略は、一方の階層のインスタンスがもう一方のインスタンスを参照していることを確認することです。MoveMethodMoveFieldを使用すると、参照クラスの階層が消えます。

しかし、私はあなたがさらに一歩進むことができると思います。各広告主とそのキャンペーンのサブクラスを作成するためにあなたの決定が何に基づいているかはわかりませんが、私はこの決定に異議を唱えます。従うべき良い習慣は、継承よりも構成を優先することです。

あなたはそのように始めることができます:

class Advertiser
{
  protected $authentication;
}

class AdvertiserCampaign
{
  protected $authentication;
}

interface AdvertiserAuthentication
{
}

class SpecialAuthenticationForAdvertiserUno implements AdvertiserAuthentication
{
}

class NoSpecialAuthenticationForOtherAdvertisers implements AdvertiserAuthentication
{
}

これで、広告主間の最初の違いは別のクラスに移されます。各広告主が異なる方法で構成されたオブジェクトになるまで、他の違いを続けますAdvertiser。同じことがキャンペーンにも当てはまります。もっと具体的に言いたいのですが、先に述べたように、そもそもなぜあなたの広告主全員が独自のクラスを持っているのかわかりません。

于 2013-03-14T22:10:16.710 に答える
0

一般に、同様の問題を解決するには、Bridge デザイン パターンがよく使用されます。

http://sourcemaking.com/design_patterns/bridge

于 2013-03-21T14:09:47.443 に答える