Mike Cialowicz
Mike Cialowicz

Reputation: 10030

Improving class structure in PHP instead of using multiple inheritance

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).

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

Answers (2)

gphilip
gphilip

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

Fabian Schmengler
Fabian Schmengler

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

Related Questions