Pergunta

Recentemente, começou a trabalhar em Java e foi introduzido ao mundo selvagem e louca de getters e setters para tudo. Eu odiava no início, mas rapidamente me acostumei com isso. Muito usado para isso.

Eu tenho passado muito tempo ultimamente a pensar mais sobre design de classe. Uma das coisas que eu estou tentando fazer é evitar a armadilha de fazer getters e setters para tudo. No entanto, grande parte do trabalho que eu faço é com entidades que são principalmente os recipientes de dados e eu não estou certo de que getters e setters são realmente inapropriado nesses casos.

Aqui está um exemplo simples usando propriedades públicas.

class Space {
    public String name;
    public String description;
    Space(final String name, final String description) {
        this.name = name;
        this.description = description;
    }
}

Aqui está um exemplo simples usando propriedades privadas e usando getters e setters.

class Space {
    private String name;
    private String description;
    Space(final String name, final String description) {
        this.name = name;
        this.description = description;
    }
    public String getName() {
        return this.name;
    }
    public void setName(final String name) {
        this.name = name;
    }
    public String getDescription() {
        return this.description;
    }
    public void setDescription(final String description) {
        this.description = description;
    }
}

Nestes exemplos, tanto o name e os campos description deve ser capaz de ser alterado.

Eu me sinto como o exemplo getter / setter é mais clara e esconde os detalhes de implementação do que name e description são. Também permitiria que para validação no set mais tarde, se necessário.

Eu li várias discussões sobre getters e setters sendo maus e / ou um anti-padrão, mas ele realmente se sente como aqueles podem não se aplicar a esta situação.

Talvez existam algumas opções que eu ainda não ter considerado. Estou aberto para sugestões!

Foi útil?

Solução

Para colocá-lo simples:

  • Você precisa getters para todos os campos que devem ser lidos a partir do exterior.
  • Você precisa setters para todos os campos que devem ser escritos a partir do exterior.

Esta pode ser 100%, mas na maioria das vezes é menos.

Outras dicas

A primeira versão (propriedades públicas) não é uma boa idéia. O segundo é melhor. Como Josh Bloch diria, "imutabilidade favor" :

public class Space {
    private final String name;
    private final String description;

    public Space(final String name, final String description) {
        this.name = name;
        this.description = description;
    }

    public String getName() {
        return name;
    }

    public String getDescription() {
        return description;
    }
}

Dito isto, getters e setters tendem a ser usado em demasia .

Você já ouviu o muitas vezes simplista "get / setters são maus". Ninguém (espero) realmente significa que há algo errado com ele para objetos de dados. Acho que a idéia real é:

"getters / setters são maus, exceto para objetos de armazenamento de dados simples", que em si é apenas um evangelismo de "dizer não pergunte".

O ideal seria se uma classe tem getters e setters, isso é todas que deveria ter.

Essa é a de qualquer maneira argumento. Eu não sei se concordo com ele.

Enquanto o padrão acessor ajuda a esconder os detalhes de implementação de uma classe (por exemplo, usando uma tabela hash a Atributos loja para economizar memória em classes de baixa densidade usados), pode ser muito detalhado para implementar (o seu exemplo tem 12 linhas mais com os assessores). É por isso que C # tem uma sintaxe propriedade especial, que permite especificar de forma concisa acessores padrão:

class Space {
    public String Name { get; set; }
    public String Description { get; set; }
    Space(final String name, final String description) {
        this.Name = name;
        this.Description = description;
    }
}

formas alternativas podem adicionar especificadores e / ou código de acesso:

private String _name;
public String Name {
    get { if (_name == null) FetchName(); return _name; }
    private set { _name = value; }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top