2010-11-19 11 views
0

J'essaie de comprendre comment concevoir la hiérarchie des classes pour une classe Carrier que j'implémente. J'ai actuellement une classe de base abstraite Carrier.Conception d'une hiérarchie de classes sans héritage multiple en Java

J'ai une autre classe abstraite TimedCarrier (TC) qui étend Carrier avec des informations temporelles et liées au domaine. Les classes de béton s'étendent de Carrier et TimedCarrier. L'utilisateur a besoin d'un moniteur de progression, donc je crée une classe abstraite MonitoredCarrier (MC) qui s'étend de Carrier. Les classes de béton s'étendent de Monitored Carrier.

Cela fonctionne bien pendant un certain temps jusqu'à ce que les besoins des utilisateurs changent. Maintenant, j'ai besoin d'un MonitoredTimedCarrier. Je ne peux évidemment pas sous-classer TC et MC. Je pense à la mise en œuvre MC comme interface:

class TimedCarrier implements IMonitored 
class Carrier implements IMonitored 

(depuis plus de sens pour moi dans le cadre de ce domaine, je devrais être en mesure de surveiller Carriers si oui ou non ils sont chronométrés), mais MC est une classe richement implémentée, et je vais devoir copier-coller toutes les méthodes dans des classes qui s'étendaient depuis MC. Je ne veux pas dupliquer le code.

Comment puis-je résoudre ce problème? Merci.

[Modifier]

TimedCarrier étend porteuse avec un groupe de variables membres et les méthodes de lecture/définition. MonitoredCarrier étend Carrier avec des variables membres, des méthodes getter/setter et un tas de méthodes qui fonctionnent avec le moniteur.

class TimedCarrier extends Carrier { 
    int var1.. 
    int var2.. 

    public void setVar1(int var1) {...} 
    public int getVar1() {...} 
    .... 
} 

class MonitoredCarrier extends Carrier { 
    int var1.. 
    int var2.. 

    public void setVar1(int var1) {...} 
    public int getVar1() {...} 
    .... 
    public void monitorSomething() {...} 
    public void monitorOtherSomething() {...} 
} 

Répondre

3

Il me semble que vous devriez envisager d'utiliser la délégation. Par exemple, au lieu d'une classe s'étendantTimedCarrier, il étendrait simplement Carrier - mais serait ensuite passé au constructeur de TimedCarrier en tant qu'instance déléguée. TimedCarrier déléguerait alors les opérations, mais garderait aussi la trace du temps.

Idem MonitoredCarrier. Bien sûr, sans connaître les détails de ce qui se passe, il est difficile de dire exactement si c'est approprié, mais c'est le genre d'approche que j'ai utilisé plusieurs fois avec succès. (Avez-vous besoin de Carrier pour être une classe abstraite plutôt qu'une interface, d'ailleurs? Serait-il logique d'avoir une interface puis une classe abstraite implémentant l'interface pour les opérations communes?)

+0

Je suis d'accord. Dans de nombreux cas, la composition l'emporte sur l'héritage. – gpampara

2

Je voudrais l'approcher comme ce,

interface Timeable {....} 
interface Monitorable {....} 
interface Carrier {....} 

Et puis aller avec cela.

class TimedCarrier implements Carrier, Timeable {....} 
class MonitoredCarrier implements Carrier, Monitorable {....} 
class MonitoredTimedCarrier implements Carrier, Timeable, Monitorable {....} 

Ce n'est pas une idée tirée par les cheveux. C'est partout dans l'API Java. Regardez Runnable, et similaire.

0

Je disposerais de Carrier, Timer et Monitor en tant qu'interfaces pour que les classes puissent les implémenter selon leurs besoins.En ce qui concerne le mixage de la fonctionnalité, vous pouvez faire en sorte que MonitoredTimedCarrier étende MonitoredCarrier et implémente Timer, puis transfère toutes les méthodes Timer à une classe interne qui étend votre classe abstraite avec les fonctionnalités dont vous avez besoin.

Ceci est juste un moyen potentiel, il existe plusieurs modèles de conception qui pourraient vous aider ici. Bonne chance!