Esta não é uma lista exaustiva, mas considere alguns dos seguintes fatores ao decidir se um objeto deve ser passado para um método como argumento:
O objeto é imutável? A função é 'pura'?
Os efeitos colaterais são uma consideração importante para a manutenção do seu código. Quando você vê código com muitos objetos com estado mutáveis sendo passados por todo o lugar, esse código geralmente é menos intuitivo (da mesma maneira que variáveis de estado globais podem ser menos intuitivas), e a depuração se torna mais difícil e com o tempo. consumindo.
Como regra geral, procure garantir, tanto quanto razoavelmente possível, que todos os objetos que você passar para um método sejam claramente imutáveis.
Evite (novamente, na medida do possível) qualquer projeto em que se espere que o estado de um argumento seja alterado como resultado de uma chamada de função - um dos argumentos mais fortes para essa abordagem é o Princípio da menor surpresa ; ou seja, alguém lendo seu código e vendo um argumento passado para uma função tem "menos probabilidade" de esperar que seu estado mude após o retorno da função.
Quantos argumentos o método já possui?
Métodos com listas de argumentos excessivamente longas (mesmo que a maioria desses argumentos tenham valores "padrão") começam a parecer um cheiro de código. Às vezes, essas funções são necessárias, no entanto, e você pode considerar criar uma classe cujo único objetivo é agir como um Objeto de Parâmetro .
Essa abordagem pode envolver uma pequena quantidade de mapeamento de código padrão adicional do seu objeto 'fonte' para o seu objeto de parâmetro, mas esse é um custo bastante baixo em termos de desempenho e complexidade, no entanto, e existem vários benefícios em termos de dissociação e imutabilidade de objetos.
O objeto transmitido pertence exclusivamente a uma "camada" dentro do seu aplicativo (por exemplo, um ViewModel ou uma entidade ORM?)
Pense em Separação de Preocupações (SoC) . Às vezes, perguntar-se se o objeto "pertence" à mesma camada ou módulo em que seu método existe (por exemplo, uma biblioteca de wrapper de API rolada manualmente ou sua camada lógica de negócios principal etc.) pode informar se esse objeto realmente deve ser passado para aquele método.
O SoC é uma boa base para escrever código modular limpo, com pouco acoplamento. por exemplo, um objeto de entidade ORM (mapeamento entre o código e o esquema do banco de dados) idealmente não deve ser transmitido na sua camada de negócios ou pior na sua camada de apresentação / interface do usuário.
No caso de passar dados entre 'camadas', ter parâmetros de dados simples passados para um método é geralmente preferível à passagem de um objeto da camada 'errada' em um objeto. Embora seja provavelmente uma boa idéia ter modelos separados, que existem na camada 'certa', na qual você pode mapear.
A função em si é muito grande e / ou complexa?
Quando uma função precisa de muitos itens de dados, pode valer a pena considerar se essa função está assumindo muitas responsabilidades; procure oportunidades em potencial para refatorar usando objetos menores e funções mais curtas e simples.
A função deve ser um objeto de comando / consulta?
Em alguns casos, o relacionamento entre os dados e a função pode estar próximo; nesses casos, considere se um objeto de comando ou um objeto de consulta seria apropriado.
Adicionar um parâmetro de objeto a um método força a classe que contém a adotar novas dependências?
Às vezes, o argumento mais forte para os argumentos "Dados antigos simples" é simplesmente que a classe de recebimento já é autocontida e a adição de um parâmetro de objeto a um de seus métodos poluiria a classe (ou, se a classe já estiver poluída, ela será piorar a entropia existente)
Você realmente precisa passar por um objeto completo ou precisa apenas de uma pequena parte da interface desse objeto?
Considere o Princípio de Segregação de Interface com relação às suas funções - ou seja, ao passar um objeto, ele deve depender apenas de partes da interface desse argumento que ele (a função) realmente precisa.