Reputation: 10030
I have a design problem where my classes are set up in such a way:
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
The problem is that AdvUno
and AdvUnoCampaign
both need a special authentication method that's not necessary for the others. Right now I've placed it in AdvUno
, but again, it'll be needed by AdvUnoCampaign
(and a bunch of other classes that are set up in this way).
AdvUnoCampaign
extend AdvUno
since there's no multiple inheritance in PHP, but also because it's just generally not a good, clean design practice.AdvertiserCampaign
extend Advertiser
, then all of the extending classes below (AdvUnoCampaign
, AdvDosCampaign
, etc) must implement a bunch of abstract methods that are of no concern to them, and which are already implemented in each of the Advertiser
classes.In short, what's the best design practice in this sort of situation? I'd rather not just copy and paste the code into all of the AdvOne
classes. Any help or advice would be appreciated. Thanks!
Upvotes: 2
Views: 253
Reputation: 706
In general, to resolve problems similar to yours the Bridge design pattern is commonly used.
http://sourcemaking.com/design_patterns/bridge
Upvotes: 0
Reputation: 24576
Parallel Inheritance Hierarchies are considered a code smell, something that should be refactored.
Martin Fowler suggests in "Refactoring":
The general strategy for eliminating the duplication is to make sure that instances of one hierarchy refer to instances of the other. If you use Move Method and Move Field, the hierarchy on the referring class disappears.
But I think you can go one step further. I don't know, what your decision was based on to make sub classes for each advertiser and their campaigns, but I would challenge this decision. A good practise to follow is to Favor Composition over Inheritance.
You could start like that:
class Advertiser
{
protected $authentication;
}
class AdvertiserCampaign
{
protected $authentication;
}
interface AdvertiserAuthentication
{
}
class SpecialAuthenticationForAdvertiserUno implements AdvertiserAuthentication
{
}
class NoSpecialAuthenticationForOtherAdvertisers implements AdvertiserAuthentication
{
}
Now the first difference between the advertisers is moved into another class. Go on with other differences until each advertiser is just an object of Advertiser
composed in a different way. The same goes for the campaigns. I would like to be more concrete but as stated before, I have no idea why your advertisers all have their own classes in the first place.
Upvotes: 3