Como evitar as classes… Auxiliar ou… Gerente

9

Eu tenho algumas aulas de auxiliar no meu projeto. Eu li que isso é uma coisa ruim, mas suspeito que "Helper" seja o sufixo errado para eles. Eu vou dar um exemplo.

Primeiro, eu tenho uma Useraula. Eu preciso de um método GetSuggestedFriends()para um usuário. Quero manter a lógica para determinar a lista de amigos sugeridos fora da Userclasse, para que não fique inchado. Agora, eu tenho um FriendshipHelperque recebe um Userem seu construtor. Ele contém a lógica para receber amigos sugeridos e agora posso ligar myUser.FriendshipHelper.GetSuggestedFriends().

Originalmente, FriendshipHelpertinha apenas métodos estáticos e um Userobjeto foi passado para cada um. Se eu estivesse escrevendo a turma do zero agora, talvez eu chamasse FriendshipManager- também faz coisas como adicionar e remover amigos.

Eu também li que as ...Manageraulas são ruins, no entanto. Como devo chamar essa classe? Ou, é esse "código incorreto"? Onde deve estar a lógica para obter amigos sugeridos, amigos atuais e adicionar e remover amigos? Certamente nem todos em uma Userclasse gigante ?

user1002973
fonte
Onde esse código mora? É um serviço? Ele acessa um armazenamento de dados? É a interface do usuário para fazer essas coisas amigáveis?
Telastyn
3
Uma vez que você se livrou de todos os métodos estáticos e encontrou um lar real no seu design de POO, essas classes não são realmente classes auxiliares, portanto, fique à vontade para renomear. Não há nada de errado com um FriendshipManager se você precisar gerenciar amizades em seu projeto.
Jeffo
O que há de errado Facebook?
toniedzwiedz

Respostas:

10

Como evitar ... Auxiliar ou ... Classes de gerente «

Em geral: por um bom design

Primeiro, eu tenho uma classe de usuário. Eu preciso de um método GetSuggestedFriends () para um usuário.

Sim. A user tem um relacionamento com outro users. E o relacionamento pode ser expresso como um método user, por exemplo user.isFriend(user2). Essa é a responsabilidade do userobjeto-. Além disso, você pede a outro objeto ajuda para encontrar outros amigos . Você delega a responsabilidade de encontrar amigos para outro objeto, e isso é ótimo .

No momento, tenho um FriendshipHelper que recebe um usuário em seu construtor. Ele contém a lógica para obter amigos sugeridos e agora posso chamar myUser.FriendshipHelper.GetSuggestedFriends ()

Isso não é, por si só , ruim, mas tem uma desvantagem: inicializar o "Auxiliar" com um userlimita as possibilidades a ele user.

O que você precisa é de um objeto , o que ajuda a encontrar amigos para qualquer usuário. Assim, um método genérico faria sentido: userMatcher.findFriendsFor(user)que em troca oferece uma coleção de possíveis amigos ( user).

Se eu estivesse escrevendo a turma do zero agora, talvez eu chamasse de FriendshipManager

Seu problema não é escrever "classes auxiliares", é encontrar os nomes certos . ;)

Ele também faz coisas como adicionar e remover amigos.

Esse é um design errado . Por exemplo: sua mãe adiciona amigos à sua vida ou você os adiciona sozinho?

É claro que a coleção de amigos é uma propriedade em usersi e também o método user.addFriend(user)ouuser.removeFriend(user)

Como devo chamar essa classe?

Como dito anteriormente: você só tem um problema de nomeação e seus "ajudantes" estão bem . Mas você precisa pensar com mais cuidado sobre as responsabilidades de cada objeto.

Onde deve estar a lógica para obter amigos sugeridos, amigos atuais e adicionar e remover amigos? Certamente nem todos em uma classe de usuário gigante

Não. São dois trabalhos para os quais você precisa de um objeto separado , como na vida real, onde você tem pessoas e uma agência de namoro .

Thomas Junk
fonte
3
Ótima explicação, mas você claramente nunca conheceu minha mãe. : '(
Matt
1
@ HEATH3N Espero que isso não influencie seus recursos de modelagem de software.
Thomas Junk
3

Eu sugiro que você tenha uma FriendshipServiceclasse que possui um GetSuggestedFriends(User)método (não estático) . Evite métodos estáticos, pois você não pode implementar uma interface que torne mais difícil o teste. Evite adicionar o objeto de usuário ao construtor, pois você pode estender seu FriendshipService com métodos não especificamente relacionados a um único usuário. (Por exemplo, você pode sugerir amigos para um conjunto de usuários ou sugerir amigos com base em outra coisa)

Um usuário provavelmente não deve estar ciente do FriendshipService(devido ao Padrão de responsabilidade única)

Bjorn
fonte
7
Alterar o sufixo de "Helper" para "Service" não facilita a ideia da responsabilidade da classe pelo nome, que eu acho que é o cerne da questão.
Mike Partridge
Bem, o nome em si pode não dizer muito, mas eu diria que usar o sufixo "Service" é uma maneira mais padronizada de comunicar que a classe executa algum tipo de lógica avançada. As classes "auxiliares" são (pelo menos para minha experiência) geralmente mais relacionadas a tarefas muito simples, como formatação simples e métodos estáticos pequenos. Eu esperaria que você pudesse substituir uma interface de "Serviço" por diferentes implementações. Além disso, há muitas perguntas aqui, não apenas os nomes.
Bjorn
Acordado. Todos os três "Auxiliar", "Gerente" e "Serviço" são maneiras de agrupar métodos para evitar toneladas de classes superespecíficas com um único método, mas "Serviço" tem um pouco mais de significado, como você descreveu. Eu acrescentaria que isso implica que a classe faz parte da interface da camada de serviço, ajudando a simplificar o acesso à lógica de negócios (que pode ser composta de muitas classes mais específicas) para uma determinada classe de domínio. Se a lógica da sugestão deve estar em uma classe separada da lógica adicionar / remover depende de quão complexa é a implementação da lógica da sugestão.
Mike Partridge
Quando nomeamos as classes ThingManager ou ThingService, abrimos a porta para a criação de classes que crescem fora de controle. Como o nome não indica claramente nada específico que pertence à classe, também não exclui nada. Eu preciso de um novo método que lide com a coisa. Onde isso vai? Idk, coloque-o no ThingManager com todos os outros métodos.
Scott Hannen