Rendere la sottoclasse più specifica del tipo con gli accessor

1

Ho una super classe: TriggerManager con una sottoclasse TimedTriggerManager . NOTA: sto lavorando in java

TimedTriggerManager riguarda solo TimedTrigger s, una sottoclasse di Trigger . TriggerManager fa riferimento a tutti gli oggetti Trigger . Per modificare la sottoclasse ( TimedTriggerManager ) per accettare solo TimedTriggers nei suoi accessori e mutatori (getter e setter) ho le seguenti domande:

1) Ho in TriggerManager il seguente public void addTrigger(Trigger t) . In TimedTriggerManager dovrei semplicemente sovrascrivere il metodo per generare un errore se l'argomento ( t ) non è un TimedTrigger . In tal caso, quale errore devo gettare? In caso contrario, cosa dovrei fare?

2) Dovrei aggiungere un altro metodo getTimedTrigger per lavorare con la getTrigger della classe supper in modo che non debba mantenere il casting dei tipi? (Poiché quest'ultimo restituirebbe un oggetto Trigger )

3) C'è qualcos'altro che sto dimenticando, o qualche pratica comune che non sto facendo?

    
posta sinθ 08.06.2013 - 22:26
fonte

2 risposte

4

La tua situazione puzza della classica gerarchia di forme in cui un quadrato eredita dal rettangolo (e aggiunge il vincolo che entrambe le dimensioni siano le stesse). Questo è generalmente considerato come un fallimento del Principio di sostituzione di Liskov (LSP) , perché il vincolo aggiunto fa sì che le operazioni di classe base siano non sempre appropriato per la classe derivata.

Se il metodo getTrigger è inteso solo per l'uso all'interno della gerarchia, è possibile convertire l'ereditarietà tra TriggerManager e TimedTriggerManager attorno (rendendo TimedTriggerManager la classe base), in quanto una classe derivata potrebbe indebolire il requisiti inseriti sui parametri del metodo ma non li rafforzano.

Se getTrigger è anche inteso per uso esterno, quindi TriggerManager e TimedTriggerManager non possono avere una relazione di ereditarietà senza violare l'LSP. In tal caso, potrebbe essere meglio creare TriggerManager e TimedTriggerManager classi fratelli che entrambi ereditano da AbstractTriggerManager . Il AbstractTriggerManager fornisce tutte le funzionalità comuni, ma nessun metodo pubblico in cui TriggerManager e TimedTriggerManager pongono requisiti diversi sui parametri (come addTrigger ).

    
risposta data 09.06.2013 - 13:38
fonte
1

1) Sì. A meno che tu non abbia un'interfaccia comune per Trigger e TimedTrigger , il che significa che TimedTriggerManager non richiede alcuna funzionalità speciale da TimedTrigger , dovresti controllare il tipo del Trigger ricevuto e assicurarti che sia un TimedTrigger .

2) Non mi sembra una buona idea. La classe base di solito non dovrebbe sapere nulla delle classi derivate. Quindi penso che il casting non sia un grosso problema qui. A mio avviso, il design risulta più pulito.

3) In effetti usi direttamente una classe concreta TriggerManager ? Si pensi che si potrebbe voler considerare l'utilizzo di un'interfaccia invece di un oggetto di base per i gestori specializzati.

    
risposta data 08.06.2013 - 23:41
fonte

Leggi altre domande sui tag