Un oggetto dipendente dall'implementazione di più oggetti, metodi inutili in certi casi?

1

Voglio progettare un sistema in cui le persone usano una casa.

Le persone in una casa possono camminare, sedersi su sedie, mangiare cibo, guardare la TV, cucinare, pulire, cacca ecc.

Quindi volevo iniziare con la stanza più piccola della casa. I servizi igienici.

Questo è quello che ho fatto.

Quindi non sembra così male adesso, ma ho paura di aggiungere un'altra stanza all'equazione.

Ad esempio, l'utente non dovrebbe essere autorizzato a usare la cacca () all'interno della cucina. Né può lavare () il soggiorno.

Quindi, quando entrerà in cucina o nel salotto, avrà già uno o più metodi che non servono a niente e semplicemente bug, che non sembra davvero efficiente.

Ho ragione con questo design? Come posso migliorarlo?

    
posta Steve Chamaillard 05.05.2017 - 10:11
fonte

4 risposte

3

The user shouldn't be allowed to poo() inside the kitchen for example. Nor can he flush() the living room.

Quindi è un buon indicatore che quei metodi non appartengono all'utente, ma piuttosto alla stanza.

Tuttavia non è chiaro in che modo gli oggetti interagiranno nel tuo programma. Evitare qualsiasi downcasting (da Room to Toilet) per accedere ad azioni specifiche della stanza. In questa situazione penso che tu abbia bisogno di una classe di azione. The Room dovrebbe esporre un metodo per fornire un elenco di possibili azioni.

    
risposta data 05.05.2017 - 10:48
fonte
2

I metodi di azione dovrebbero essere negli oggetti a cui si riferiscono. Quindi il metodo poo e flush dovrebbe essere nella classe ToiletBowl .

Con questo approccio finisci con oggetti che contengono alcune azioni (TV, Sedia, ToiletBowl ecc.), stanze che contengono quegli oggetti e la casa che contiene stanze.

L'utente sarà in grado di entrare in diverse stanze, avere accesso agli oggetti ed eseguire le loro azioni.

La stanza può contenere diversi oggetti, puoi facilmente mettere la TV nella toilette e può essere usata come utente.

Ad esempio, la classe ToiletBowl avrà due metodi

Input(SomeStuff staff) {}
Flush() {}
    
risposta data 07.05.2017 - 21:46
fonte
0

Includere metodi in una classe base che non possono essere implementati utilmente in una sottoclasse viola il Principio di sostituibilità di Liskov, che è uno dei principi più fondamentali della progettazione orientata agli oggetti. L'LSP afferma essenzialmente che se il codice che utilizza un oggetto di un tipo funziona correttamente, dovrebbe funzionare anche con qualsiasi sottotipo. In questo caso, tuttavia, è possibile scrivere codice che funzioni con alcuni tipi di stanza ma non con altri.

Come precedentemente commentato, potresti inserire i metodi nei sottotipi per i quali sono appropriati, ma poi dovresti downcast per accedervi, che è generalmente considerato una cattiva idea perché rende difficile aggiungere nuovi comportamenti che usa le funzionalità dei nuovi tipi.

Una soluzione a questo è usare il pattern Visitor, che fornisce un modo utile per accedere ai vari sottotipi in un modo che ti permette di essere sicuro di aver aggiornato in modo appropriato tutte le operazioni che dipendono da questo tipo.

Un approccio meno implicato potrebbe essere quello di esporre Room in una lista di oggetti Command che possono essere applicati alla stanza. Questo potrebbe essere un approccio utile da parte tua per fornire un'interfaccia utente che si adatti alle azioni disponibili. Ma non fornisce un modo semplice per adattarsi agli algoritmi automatici che si basano su tali azioni.

    
risposta data 07.05.2017 - 20:40
fonte
0

Penso che sia necessario riprogettare i metodi dell'interfaccia per renderli meno impegnativi e più istruttivi. Invece di dire alla stanza a flush , informalo che stai solo quando cacca. Il bagno rispondeva arrossendo, la camera da letto rispondeva puzzolente. Forse la metafora della tua stanza in realtà non è il giusto confronto con il tuo reale spazio problematico.

La chiave qui è smettere di pensare agli oggetti come a cose inanimate a cui fai qualcosa e iniziare a dare loro il libero arbitrio. Le interfacce ideali avranno nomi come didLoad , willAppear o onClick .

Quindi, se ho visto una classe Room per esempio nel contesto che stai presentando, mi aspetterei che avesse dei metodi su di esso, come didEnter , willExit , itemDeposited(item) . La stanza farà la cosa giusta quando chiamo questi metodi senza che io debba sapere cosa fa con loro.

    
risposta data 08.05.2017 - 03:06
fonte

Leggi altre domande sui tag