Nossas equipes estão tendo a seguinte discussão:
Digamos que temos os dois métodos a seguir:
public Response Withdraw(int clubId, int terminalId,int cardId, string invoice, decimal amount);
public Response Withdraw(Club club, Terminal terminal,Card card, string invoice, decimal amount);
o que é enviado por fio são apenas os IDs.
um lado diz que o primeiro método está correto, porque só temos os IDs de terminal e clube e deve ficar claro que não temos mais nada, essa é a minha abordagem.
o outro lado diz que o segundo método está correto porque é mais flexível.
Estamos familiarizados com a ideia de parâmetro de objeto, o outro lado também pensa que o parâmetro de objeto deve ter os objetos como propriedades.
Qual é a abordagem correta?
Talvez haja uma terceira abordagem ainda melhor?
Respostas:
A resposta depende do contexto.
Se o cliente tiver todos esses objetos disponíveis , eu usaria os parâmetros do objeto. Caso contrário, o código deles parecerá mais complicado do que precisa. (Por exemplo, eles terão chamadas como
club.getId()
, por exemplo.)Se o cliente tiver apenas os IDs disponíveis com facilidade, talvez a segunda abordagem seja melhor, pois talvez você não queira que o cliente tenha que montar / carregar todos esses objetos se realmente precisar apenas dos IDs.
Uma opção é fornecer os dois métodos , para que o cliente possa escolher qual deles usar (já que isso não atrapalha sua API)
Em geral, os parâmetros do objeto são mais extensíveis, pois se no futuro você precisar de outro dado para fazer o trabalho, não precisará introduzir outro método que utilize essas informações extras.
Por fim, as assinaturas do seu método não devem ser ditadas pelas especificidades do que o método faz (no seu caso, o que exatamente ocorre por fio). A API deve fazer sentido abstratamente, portanto, se a implementação mudar, você não está ferrado.
fonte
A primeira abordagem é indicativa de obsessão primitiva . Como você está passando ints e strings, é muito fácil para o programador cometer um erro (por exemplo, passando um clubId para o parâmetro terminalId). Isso resultará em erros difíceis de encontrar.
No segundo exemplo, é impossível aprovar um clube quando um terminal é esperado - isso geraria um erro de tempo de compilação.
Mesmo assim, eu ainda olharia
string invoice
. Uma fatura é realmente uma string? O queamount
significa isso ? É mais provável que seja um valor monetário.Você mencionou na sua pergunta "o que é enviado por fio são apenas os IDs". Isso está correto, mas não deixe esse requisito enlamear seu domínio.
A melhor explicação que vi a favor dessa abordagem foi na regra 3 da Object Calisthenics :
fonte
Não há resposta certa para este. Qualquer uma das opções pode estar certa para o trabalho. Bem, de qualquer maneira, o argumento da fatura levantou um sulco na minha testa, eu não tenho idéia do que é isso ao ler o código.
Se você enviar um ID, os dois sistemas precisarão ser fortemente acoplados ao que isso representa. O ClubID é a chave na tabela de clubes. Mais especificamente, o chamador e o destinatário precisam concordar como a tabela Clubs é chamada e em qual banco de dados está. Se você não deseja ou não pode impor essa restrição, passaria o objeto usando alguma descrição comum, nativo, serializado, xml, nome = valor qualquer que seja, um arquivo ini :)
Isso, como você identificou, custará "over the wire". Evitar isso, basta enviar o identificador para você em outro lugar. Então, qual deles te machuca menos agora (ou pode ser mais tarde ...) é o indicador de bom versus ruim.
fonte