Come evitare ... Helper o ... Classi di manager

8

Ho parecchie classi Helper nel mio progetto. Ho letto che questa è una brutta cosa, ma sospetto che "Helper" sia il suffisso sbagliato per loro. Darò un esempio.

Per prima cosa, ho una classe User . Ho bisogno di un metodo GetSuggestedFriends() per un utente. Voglio mantenere la logica per determinare l'elenco di amici suggeriti dalla classe User , quindi non si gonfia. Al momento, ho un FriendshipHelper che riceve un User nel suo costruttore. Contiene la logica per ottenere amici suggeriti e ora posso chiamare myUser.FriendshipHelper.GetSuggestedFriends() .

Originariamente FriendshipHelper aveva solo metodi statici e un oggetto User è stato passato in ognuno di essi. Se stavo scrivendo la lezione da zero ora, forse la chiamerei FriendshipManager - fa anche cose come aggiungere e rimuovere gli amici.

Ho letto anche che le classi ...Manager sono cattive, comunque. Come dovrei chiamare questa classe? O è questo "codice cattivo"? Dove dovrebbe essere la logica per ottenere amici suggeriti, amici attuali e aggiungere e rimuovere gli amici dal vivo? Sicuramente non tutti in una gigantesca classe User ?

    
posta user1002973 26.06.2015 - 15:20
fonte

2 risposte

10

How to avoid …Helper or …Manager classes«

In generale: per buon design

First, I have a User class. I need a method GetSuggestedFriends() for a user.

Sì. Un user ha una relazione con l'altro users . E la relazione potrebbe essere espressa come un metodo su user , ad es. %codice%. Questa è la responsabilità di user.isFriend(user2) -object. Inoltre, chiedi a un altro oggetto per di trovare altri amici . Delega la responsabilità per trovare amici su un altro oggetto e questo è abbastanza fine .

Right now, I have a FriendshipHelper which receives a User in its constructor. It contains the logic for getting suggested friends, and I can now call myUser.FriendshipHelper.GetSuggestedFriends()

Questo non è per sé cattivo, ma ha uno svantaggio: l'inizializzazione di "Helper" con un user limita le possibilità a quell'uno user .

Ciò di cui hai bisogno è un oggetto , che aiuta a trovare amici per qualsiasi utente. Quindi un metodo generico avrebbe senso: user che in return fornisce una collezione di possibili amici ( userMatcher.findFriendsFor(user) ).

If I was writing the class from scratch now, maybe I'd call it FriendshipManager

Il tuo problema non è scrivere "classi helper", è trovare i nomi giusti . ;)

it also does things like adding and removing friends.

Questo è un disegno errato . Prenditi ad esempio: La tua mamma aggiunge amici alla tua vita o li aggiungi da solo?

Naturalmente la collezione di amici è una proprietà di user stessa e quindi è il metodo user o user.addFriend(user)

What should I call this class?

Come detto prima: hai solo un problema di denominazione e i tuoi "aiutanti" sono ok . Ma devi riflettere più attentamente sulle responsabilità di ciascun oggetto.

Where should the logic for getting suggested friends, current friends, and adding and removing friends live? Surely not all in a giant User class

No. Questi sono due lavori per i quali hai bisogno di un oggetto separato , come nella vita reale dove hai persone e una agenzia di appuntamenti .

    
risposta data 26.06.2015 - 18:36
fonte
3

Suggerirei di avere una classe FriendshipService con un metodo (non statico) GetSuggestedFriends(User) . Evita metodi statici poiché non puoi implementare un'interfaccia che rende più difficile il test. Evita di aggiungere l'oggetto utente al costruttore, poiché potresti voler estendere il tuo FriendshipService con metodi non specificamente correlati a un singolo utente. (Ad esempio, potresti suggerire amici a un gruppo di utenti o suggerire amici in base a qualcos'altro)

Molto probabilmente un utente non dovrebbe conoscere FriendshipService (a causa del pattern di singola responsabilità)

    
risposta data 26.06.2015 - 16:27
fonte

Leggi altre domande sui tag