vc está destruindo a encapsulação da sua classe… dessa maneira vc não tem controle algum de o que/quem está acessando esse atributo e o que esta fazendo com ele… fora outras inúmeras coisas que, com certeza, o pessoal aqui vai citar
Veja só, o método:
faz muito mais sentido do que o método :
que usa um atributo da classe para executar a consulta
mas, é claro, que isso depende muito da sua classe. Mas assim, só de ver esse método, essa é a opinião que eu tenho.
Uma regra básica da Orientacao a Objetos é o encapsulamento. Salvo raras excessoes, faça todos os seus atributos private e faça metodos get/set para acessa-los.
Fora isso, seu código tem o problema de q o metodo chamado só funciona se o cara passar um valor antes pro atributo. Isso nao é bom, vc nao pode confiar no usuario de sua classe dessa maneira.
E, faça o metodo text() como getText(), em Java eh mais aceito assim.
Esta sintaxe é de liguagens que implementam “propriedades” onde text não seria um método e sim uma propriedade. Você digita ojbeto.text, mas na verdade está acessando objeto.getText. Da mesma forma poderia ser objeto.text = “texto”, na verdade seria objeto.setText(“texto”), nestes casos os gets e sets são privados e o acesso é feito pelo nome da propriedade. O java não implementa este tipo de propriedade como é feito no Delphi (acho que o C# tb tem). O comum realmente é criar getText e setText públicos e text privado.
Aliás gostaria de saber o porquê desta ausência de propriedades…
Pq um dos propositos da linguagem eh manter o menor numero de keywords possivel, e confiar mais em idiomas e boas praticas, pelo menos de acordo com o tio Gosling. Mas parece que o pessoal se tocou de que isso eh uma bomba esperando pra explodir, e ta dando uma ajustada em algumas coisas (vide novas features da 1.5).
Pq propriedades são resultado de uma diarreia cerebral que começou com o Niklaus Wirth e não parou mais.
Existem 3 motivos principais para não querer propriedades:
1)É um estupro sintático da linguagem. Uma linguagem de programação deve ser o mais intuitiva e clara possivel. Se uma construção da linguagem pode representar 2 coisas completamente diferentes ou a mesma coisa possui 2 contruções diferentes, o negocio vira 1 zona. A burrada mestre foi com o pascal e a criação de 2 sintaxes para chamar 1 função:
i := funcaoSemParametros;
i := funcaoComParametros(1);
Moral da historia, o código perde clareza. Com properties a coisa fica beeem mais feia, porque voce passa a ter 2 sintaxes para fazer exatamente a mesma coisa:
int i = this.prop;
int j = this.getProp();
Sem falar que isso causa 1 mal ainda pior! Passamos a ter a mesma sintaxe para fazer duas coisas completamente diferentes!
int i = this.field;
int j = this.property;
Ou seja, você passa a programar no reino na incerteza, “isso é um field ou uma property?”
Elas são redundantes. Uma linguagem tem que ser enxuta ao máximo na sintaxe e rica na semantica que esta proporciona. Properties adicionam nenhuma coisa alem de problemas.
3)Properties estimulam programação burra. Parece que todo programador mediocre é atraido a usar toneladas de properties, não estou dizendo que quem usa é, apenas que os mediocres adoram. Já vi as coisas mais estupidas do mundo sendo feitas com properties, como por exemplo: (pseudo java)
public class Cagada {
int pk;
public Cagada(int pk) { this.pk =pk; }
public property int total {
get() { return "select count(*) from tabela");
}
pulbic property String fedor {
get() { return "select fedor from tabela where pk = "+pk; }
set() { "update tabela set fedor="+fedor+" where pk="+pk;}
}
se a pergunta era sobre como buscar dados na base:
sim existe um pattern, esse tipo de objeto é conhecido finder objects
e prefira usar a segunda estratégia, passando explicitamente como parâmetros os valores que vc deseja usar como critério.
Pq?
usando a estratégia de preencher atributos e e invocar um metodo find, vc terá que preparar o seu objeto para responder a todas as combinações possíveis de preenchimento de atributos e além disso terá que se preocupar com o estado do finder object.
já usando a segunda estratégia vc se concentra em apenas implementar um código que utilize os parâmetros da assinatura, não perderá tempo implementando combinações que nunca serão utilizadas e vc não precisa se preocupar mais com o estado do objeto.
Não estou defendendo nenhuma linguagem e também não sei como é feita no C#, mas o código abaixo é um erro de estrutura na classe:
Se o programador vai criar uma propriedade, os Gets e Sets passam a ser privados e o acesso a eles é unicamente pela propriedade. Levando em conta o que o cv falou sobre o número de keywords eu concordo, mas acessar um campo por uma propriedade é bem mais elegante do que usar gets e sets. è uma questão de custo benefício. O benefício do assert foi maior que o custo de mais uma palavra? :?
O código
String nome = aluno.nome;
é bem mais intuitivo que
String nome = aluno.getNome();
assim como
aluno.nome = "Fulano";
é mais intuitivo e mais elegante que
aluno.setNome("Fulano");
Ao editar uma JFrame no eclipse percebi que uma das views que abre para configuração se chama “Properties”, isto porque desta forma um propriedade faz o trabalho do Get e do Set. Quando você na lista (vê) um valor “Enable | true” o Get já foi disparado, e para alterar para False basta clicar em cime e escrever, acessando, na verdade o método Set. A propriedade em código é tão intuitiva quanto a utilização desta view. Obviamente programadores mediocres são atraídos por ela justamente porque é intuitiva, se você tem poucos recursos o modo mais fácil é o mais aconselhável. Porém, acho que a discissão é se propriedades (em java) são uma facilidade ou um desvio danoso. Sinceramente não tenho experiência para analisar todas as implicações da utilização de propriedades na tecnologia java, apenas comentei sobre o código gerado. Não estou discordando do louds, apenas acho que os exemplos que ele deu se baseiam no fato do programador ter feito besteira. Se alguém me mostrar porque uma propriedade é nociva, mesmo criando-a da forma correta (como dito acima), eu fico feliz.
Agora, “nome” é:
a) uma propriedade;
b) um atributo publico;
c) uma procedure (pascal/basic) sem parâmetro;'
d) todas elas;
e) nda;
Em Java não existe este problema. Se ocorrer um código deste tipo, você afirma com certeza de que se trata de um atributo público. Mas, e em C#, por exemplo, você conseguiria distinguir um do outro??
//C#
public class Aluno {
public string nome;
private int idade;
public int idade{
get{
return idade;
}
set{
idade = value;
}
}
}
//em algum ponto, usando a classe acima...
string nome = aluno.nome; //atributo público
int idade = aluno.idade; // propriedade
Esta questão parece a prova para tirar carteira de motorista que fiz uma vez… :lol:
Realmente, da letra c para baixo obviamente não é, porém é como disse no post anterior: vamos considerar que o programador não vai fazer besteira. Criar um atributo público??? Só pode ser a resposta a). Porém, digamos que por algum motivo eu deva criar atributos públicos. A elegância da propriedade é justamente esta!! O proramador não sabe! Se você usa uma classe desta forma:
String nome = aluno.nome;
Das duas uma: ou quem implementou a classe quer (sabe Deus porque) que você acesse o atributo diretamente ou você vai acessar pela propriedade. Tanto faz, você deve confiar na implementação e pronto.
Se for partir do princípio que o programador dor vai fazer M, ele pode criar os Gets e Sets e ainda assim colocar o atributo público.
Tem mais:
Digamos que um programador totalmente alienado a esses conceitos trabalhe na minha empresa. Quando vou verificar o trabalho dele depois de vários meses percebo que ele criou vários atributos públicos e várias outras classes já utilizam algo como aluno.nome. Se eu transformar “nome” de atributo público para uma propriedade, o código de todas as classes que o referenciaram não será trocado. Elas vão acessar aluno.nome simplesmente confiando que os devidos tratamentos deste nome serão feitos, não importa se é uma propriedade ou um método público.
Outra coisa interessante sobre propriedades é a depreciação de métodos. Se eu uso uma propriedade não me interessa se o preferredSize() está depreciado, o meu código não será alterado pois teria sido escrito na forma “jFrame.size” (propriedade) ou algo similar.
Para responder a sua pergunta, Daniel, já fazendo outra, por que deveria haver diferença entre um atributo público e uma propriedade?[/b]
Os atributos públicos não são a parte grande do problema, pq isso é uma péssima prática de OOP.
O problema começa ficar mais obvio quando temos atributos com visibilidade mais restrita que public. Para atributos protected ou ‘default’ sem dúvida teriamos problema.
Como já falei:
class Base {
protected int foo;
private int bar;
public int bar { get { return bar; } set { bar = value; } }
}
class Derived extends Base {
int x() {
return this.foo + this.bar;
}
}
O exemplo acima não fere as boas práticas de OOP, é ate aceitavel.
Mas o bicho pega quando saimos do trivial, como usando com os operadores ++, --, synchronized, etc…
Pega aquele meu exemplo onde a property acessa o banco de dados:
Cagada c = new Cagada(1);
c.fedor++; //adivinha oque acontece aqui
Perfeito. Neste ponto eu concordo com você. Em alguns momentos as especificações da linguagem não permitem uso de propriedades. Como já disse antes não conheço java o bastante para proferir se é bom ou ruim, mas é mais elegante. Veja abaixo um exemplo em Object Pascal:
tag:= tag + 1; // soma 1 a variável tag
inc(tag); // deveria fazer a mesma coisa, mas dá pau porque é uma propriedade
Existem impossibilidades como esta acima no Objact Pascal mas isso não impede a implementação. O compilador simplesmente te diz educadamente: “Por favor use Tag:= Tag + 1” ou algo assim. Não sei se o caso de c.fedor++ (pois é uma String) mas neste caso deveria dar erro mesmo.
Ainda sobre a classe Cagada, “total” obviamente não precisa ser uma propriedade, pois não há um atributo a ser encapsulado. É um método de retorno de algo processado ( c.getTotal() ).
O programador ira fazer besteira. Sempre fazem. Ao menos que voce tenha uma super equipe ou com pessoas totalmente consciente de como as cosias devem ser, uma hora ou outra ( ou quase sempre ) vai ter uns “espertos” que irao fazer burrada.
Mas ai vc vai estar quebrando os padroes da linguagem nos casos de “praticas de codificacao”… Em C#, o recomendavel eh que metodos e propriedades comecem com uma letra maiuscula… mudar simplesmente “idade” de atributo para propriedade vai deixar o teu codigo fora do padrao, ja que o correto deveria ser “Idade”.
Usando os metodos na forma “get/set” vc sabe explicitamente o que o metodo faz… Se voce tiver algo como
public int Idade {
get { return this.idade; }
}
voce tem o problema de poder nao saber que nao da para atribuir valor para a propriedade ate o compilador acusar erro ( no caso de voce nao ter o source code ou tiver preguica de ir ver ).
Ok. O exemplo do programador alienado foi ruim (não conheço C#), mas foi só para responder ao fato de que com propriedades pode haver erros como:
int i = this.prop;
int j = this.getProp(); // não devia ser público
No código acima o erro é deixar o get público. Foi isso que eu disse, não é justo avaliar uma possibilidade a partir do erro. Assim como não é justo dizer que get/set é uma furada porque, ainda assim, permite o atributo público. Tanto um como o outro são possíveis.
Na hipótese levantada pelo Rafael:
[quote=“Rafael Steil”]
public int Idade {
get { return this.idade; }
}
[/quote]
É outro exemplo de uma coisa que não deveria ser propriedade, pois se não existe o SetIdade a abstração não faz muito sentido. Aliás idade normalmente é calculada a partir de uma data de nascimento.
Mas digamos que eu queira implementar na forma acima. A propriedade Idade ou idade seria ReadOnly. Realmente não vejo problemas para ao digitar
aluno.idade = 18; // código impossível
a IDE (como faz o eclipse) me moste o erro antes de compilar. Como disse antes é uma questão de implementação na linguagem de uma abstração que não existe.
Além disso, os exemplos estão sendo mostrados na sintaxe do C# (creio). Ninguém garante que, se tiver suporte a propriedades, a 1.5 terá esta mesma sintaxe.
Eu posso nao ter o SetIdade pq simplesmente nao quero que o programador mude a idade dessa forma, mas quero que ele possa ter acesso a idade atual.
A idade pode ser calculada de qualquer forma… dizer que ela que calculada a partir da data de nascimento ja eh entrar em questoes de implementacao de determinado sistema, o que logicamente nao eh o que queremos aqui
Ao acessar o atributo diretamente, voce esta quebrando a escapsulacao.
Concordo que a IDE deveria te dizer da falha de acesso, mas nao eh isso que sempre acontece ( vide vs.net de 10 mil reais-que-nao-consegue-referenciar-direito-nem-as-suas-proprias-dlls )
Na verdade, com uma propriedade ReadOnly é exatamente isso que você tem. O programador obtém a idade com
int idade = aluno.idade; // ou aluno.Idade
mas não pode escrever o código
aluno.idade = 18; // ou aluno.Idade = 18 - não existe padrão para java
O código “aluno.idade” ou “aluno.Idade” está usando, na realidade, a propriedade e não o atributo idade. Perdoe a confusão. Mas o interessante é que isso mostra justamente uma das coisas que a propriedade deve proporcionar: a sensação de estar acessando o atributo diretamente, sem acessar de verdade.
Mas depende do uso. Eu não vou fazer nenhum programa robusto em cima do Beanshell. Eu o uso pra scripts que me auxiliam o desenvolvimento. O melhor exemplo é um script pra fazer a carga inicial do banco num projeto onde eu uso Hibernate. Se eu troco a classe, ou a implementação, ou muitas vezes a estrutura, é muuuito mais fácil eu alterar o script do que um programa em Java que faça o mesmo, ou um tedioso script em SQL.
initEMails(inbox) {
inbox.elements = new ArrayList();
// Classical SPAM mail
el = getClass("de.commworld.bpo.model.inbox.InboxElement").newInstance();
el.sender = "Love4You";
el.dateSent = new Date();
el.description = "(URGENT) enlarge your penis";
el.category = getInboxCategory("MESSAGE");
el.contentId = null;
session.save(el);
inbox.elements.add(el);
Esse script é real e mostra o aparente uso de propriedades, quando eu sei que o BS tá chamando os acessores. Tanto a classe Inbox quanto a classe InboxElement foram implementadas em Java. Se vc tá lendo um script, vc sabe o que ele vai fazer, não tem perigo. Mas o código acima em Java seria horrível.
(nota: eu construo o objeto por reflection pq eu carrego as classes dinamicamente, pra poder fazer reload. Mas um bug no bs impede que vc faça reload mais de uma vez na mesma classe).