Comecei a escrever uma nova classe e me ocorreu que eu estava adicionando muitos argumentos de método que não são estritamente necessários. Isso segue o hábito de evitar ter estado em classes específico para alguma chamada de método, em vez de ser configuração geral ou dependências da classe.
Fazer isso significa que muitos métodos que não poderiam ter argumentos acabam com um, dois ou três.
Gostaria de ouvir suas opiniões sobre o que você acha dessa troca e como decide sobre qual abordagem adotar em que situação?
Como o código geralmente é mais fácil de entender do que o inglês ao descrevê-lo, criei uma pequena essência com as duas variantes: https://gist.github.com/JeroenDeDauw/6525656
class-design
complexity
methods
parameters
cohesion
Jeroen De Dauw
fonte
fonte
Respostas:
Como o único método visível externamente do seu exemplo é
updateTable
, acho que é bom usar campos em vez de parâmetros de método.Se isso faz parte de uma classe mais genérica (por exemplo
TableTools
), eu moveria os métodos auxiliares que precisam do estado para uma classe interna oculta.Exemplo de pseudo-código:
Dessa forma, você evita campos que são usados por apenas um método público. Além disso, o código é seguro para threads no sentido de que toda chamada para updateTable usa sua própria cópia do TableUpdater e, portanto, das variáveis de instância do TableUpdater.
fonte
O uso de campos coopta a capacidade de ter multithreading disponível para os métodos que usam esses campos.
Usar campos como esse é apenas um pouco melhor do que usar globais do ponto de vista de reutilização e manutenção, o ponto principal aqui é que configurações complexas precisam de documentação cuidadosa e atualizada sobre quais métodos usam e / ou eliminam quais campos; algo que você não precisa fazer ao usar argumentos.
fonte
Nas palavras dos leigos:
Novamente, na minha humilde opinião, os métodos não coesos pertencem a uma classe de utilidade e não a uma classe com um nome de domínio.
fonte
Não use campos no caso atual! Dois "threads" usando o objeto ao mesmo tempo confundirão seriamente. Eles não precisam ser reais, separar tópicos também (daí as aspas). Se você configurar o objeto para uma tabela, chame um método que o use para outra tabela e tente usar a configuração original, você terá um problema. Atenha-se aos parâmetros no momento.
O que você deseja fazer aqui é criar uma nova classe de atualizador usada em apenas um caso. A classe original pode ter um método para criar uma instância sempre que necessário. A nova classe teria campos. Você tem o melhor dos dois mundos. Às vezes, é mais simples seguir os parâmetros, mas no seu exemplo você já está chegando onde uma classe separada seria melhor.
fonte
Eu acho que a escolha deve estar de acordo com a situação real, como você vê. Se um item pertence a uma instância, ele deve ser visto como seu campo. Se o item for externo à instância, ele deve ser passado como um parâmetro de método.
Nesse caso, devemos ser guiados não pela efetividade (de qualquer maneira, a diferença é insignificante) ou (Deus salve!) Facilidade de digitação, mas pela compreensibilidade e naturalidade do código.
fonte
Na minha opinião, se você estiver escrevendo código que faz algo em algo , deve-se usar parâmetros que definam para quais coisas eles devem ser feitos e seu nome deve definir, tanto quanto possível, o que ele faz com ele.
Se você está escrevendo um código que empacota uma ação a ser executada em algo , você deve agrupar as coisas em que ele deve ser executado em um objeto e passá-las para o que faz alguma coisa .
Essa ação se torna um tipo de meta-descrição das chamadas para os métodos da primeira, que você pode executar posteriormente, enfileirando-a ou até mesmo decidir não fazê-lo por algum motivo.
Então, a sua pergunta traduz em que é uma ação ou de uma função ? Uma Ação pode ser adiada ou cancelada e, portanto, deve resumir aquilo em que atua. Uma Função acontece imediatamente, portanto não é necessário preservar seus parâmetros.
Você pode desfazer e Ação, mas não uma Função .
fonte