改进PHP中的类结构而不是使用多重继承

时间:2013-03-14 18:49:35

标签: php oop design-patterns inheritance

我遇到了一个设计问题,我的课程以这样的方式设置:

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(以及以这种方式设置的一堆其他类)。

  • 我无法使AdvUnoCampaign扩展AdvUno,因为PHP中没有多重继承,但也因为它通常不是一个好的,干净的设计实践。
  • 如果我AdvertiserCampaign扩展Advertiser,那么下面的所有扩展类(AdvUnoCampaignAdvDosCampaign等)必须实现一堆抽象方法不关心它们,并且已经在每个Advertiser类中实现了它们。

简而言之,在这种情况下,最好的设计实践是什么?我宁愿不只是将代码复制并粘贴到所有AdvOne类中。任何帮助或建议将不胜感激。谢谢!

2 个答案:

答案 0 :(得分:3)

Parallel Inheritance Hierarchies被视为代码气味,应该重构。

Martin Fowler在“重构”中提出建议:

  

消除重复的一般策略是确保一个实例   层次结构是指另一个的实例。如果您使用移动方法移动字段,则使用层次结构   在推荐课上消失了。

但我认为你可以更进一步。我不知道,您的决定是基于为每个广告客户及其广告系列制作子类,但我会质疑此决定。遵循的一个好习惯是Favor Composition over Inheritance

你可以这样开始:

class Advertiser
{
  protected $authentication;
}

class AdvertiserCampaign
{
  protected $authentication;
}

interface AdvertiserAuthentication
{
}

class SpecialAuthenticationForAdvertiserUno implements AdvertiserAuthentication
{
}

class NoSpecialAuthenticationForOtherAdvertisers implements AdvertiserAuthentication
{
}

现在,广告客户之间的第一个区别被转移到另一个班级。继续其他差异,直到每个广告客户只是Advertiser以不同方式组成的对象。这些活动也是如此。我想更具体,但如前所述,我不知道为什么你的广告客户都有自己的课程。

答案 1 :(得分:0)

通常,要解决与您类似的问题,通常会使用Bridge设计模式。

http://sourcemaking.com/design_patterns/bridge