我遇到了一个设计问题,我的课程以这样的方式设置:
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
问题是AdvUno
和AdvUnoCampaign
都需要一种特殊的身份验证方法,而其他方法则不需要。现在我已将它放在AdvUno
中,但同样需要AdvUnoCampaign
(以及以这种方式设置的一堆其他类)。
AdvUnoCampaign
扩展AdvUno
,因为PHP中没有多重继承,但也因为它通常不是一个好的,干净的设计实践。AdvertiserCampaign
扩展Advertiser
,那么下面的所有扩展类(AdvUnoCampaign
,AdvDosCampaign
等)必须实现一堆抽象方法不关心它们,并且已经在每个Advertiser
类中实现了它们。简而言之,在这种情况下,最好的设计实践是什么?我宁愿不只是将代码复制并粘贴到所有AdvOne
类中。任何帮助或建议将不胜感激。谢谢!
答案 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设计模式。