Pergunta

Agora estou trabalhando com o código que se parece com isso

public String getName(User user) {
     user.setSth(...);
     return user.getName();
}

Eu acho que é uma prática ruim para a mudança objetos passados ??como parâmetros. Existe uma ferramenta que detecta esse tipo de código? Olhei para findbugs, pmd e checkstyle, mas não conseguiu encontrar qualquer verificação para isso.

P.S. pena de mau exemplo.

Foi útil?

Solução

Eu acho que você já está no caminho certo: sua melhor ferramenta para detectar este tipo de código é quase certamente Findbugs . No entanto, você provavelmente terá que escrever o seu próprio detector para este padrão. Aqui está um exemplo de como você iria escrever um detector, embora isn 't exatamente o detector que você está procurando.

Aviso : Eu realmente não concordo que um getter-efetuando lado é sempre ruim estilo. No entanto, se você realmente quer encontrar esse tipo de coisa, eu recomendaria Findbugs.

Outras dicas

Você não vai encontrar nada, porque, do ponto de vista de uma ferramenta, "getName" e "setSth" são apenas chamadas de método. Os seres humanos dizem que "este é um getter" e "este é um setter" mas as ferramentas não. Na verdade, getName () não é um getter porque getters não aceita argumentos.

Assim, a ferramenta não pode ver nada incomum porque a mudança métodos objetos o tempo todo.

Se você quiser aplicar esta regra, ter um olhar para que se estendem findbugs e PMD. Ambos permitem definir restrições adicionais. O que você está procurando é provavelmente:

  • Se o nome método começa com "get"
  • E corpo do método chama o método de qualquer objeto passa como parâmetro

, em seguida, imprimir um aviso. Isso não deve demorar muito. Executar este e você vai ver como muitos "falsos positivos" você começa (advertências sobre os métodos que são realmente OK). Isso irá ajudá-lo a determinar se vale a pena prosseguir este ainda mais. Além disso, você vai ter um novo item para adicionar ao seu CV:)

Você poderia fazer User imutável (declará-la final, declarar todas as propriedades final e remota as setters. Eu sei que não, é viável em todos os lugares, mas em muitos lugares que é bom e você não terá problemas de passagem que a outras funções) .

Se tiver de "mudança" algo, você pode implementar funções como newId em que a amostra:

public final class User {
    private final String name;
    private final int id;

    User(String name, int id) {
        this.name = name;
        this.id = id;
    }

    public User newId(int newId) {
        return new User(this.name, newId);
    }

    //getters here;
}

O construído em String, Integer, ... aulas de fazer isso também.

Você pode criar uma interface chamada UserView contendo apenas "getters", fazer o usuário implementá-lo e usar a nova interface UserView como o tipo de parâmetro.

interface UserView{
 public String getName();
...

class User implements UserView...

public String getName(UserView user) {
     user.setSth(...); // Will not compile
     return user.getName();
}

Na verdade, isso é algo que em C ++ era muito fácil de fazer através do qualificador const. Você poderia definir um parâmetro como const e para esse parâmetro só poderia chamar métodos definidos como const -. Normalmente, getters

Em Java este está ausente e, francamente, eu realmente não me importo. Como mencionado há analisadores de fonte de código que pode verificar este comportamento, bem como métodos de meta-programação para fazer isso também.

Pessoalmente, acredito que se o método é chamado corretamente, não há nenhum problema de passar um objeto a ele para que é modificado.

Existem ferramentas que podem "razão" sobre o código em um nível mais elevado do que compiladores normalmente fazem. Declarativa Metaprogramação por exemplo, é uma disciplina que permite escrever programas para verificar se outro programa está em conformidade com um determinado projeto, ou, inversamente, para o meu por código de cheiros e anti-padrões.

Alguns links:

http://prog.vub.ac.be/DMP/

http://www.cs.bris.ac .uk / Publicações / pub_master.jsp? id = 1000273

e para o resto

http://www.google.com/search?num = 100 & hl = en & q = declarativa + Metaprogramação

Você está procurando algo como "const" em C ++ que irá impor tornando o valor do parâmetro como imutável como a referência que é passado no. Objetos imutáveis ??garantir que, se você pode viver com eles.

Você está argumentando que este é "ruim" porque os efeitos colaterais como este pode surpreender um usuário. Isso é válido, mas é apenas prejudicial se for um indesejado surpresa.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top