FK. 0 Denunciar post Postado Abril 18, 2012 Nossa, eu estava confuso, então voltei a ler os posts, e só agora fui me tocar ! O campo $dbAdapter sendo público, a qualquer momento o cara inseri uma string, o que acabaria com meu programa. Mas ele sendo privado, e tendo um método setAdapter(Db_Adapter $dbAdapter), eu garanto que essa propriedade só irá receber objetos do tipo DbAdapter especificando em seu parâmetro. Como não percebi isso? hehe. Mas isso numa linguagem com tipagem dinâmica. E quando a linguagem tem sua tipagem estática ? É disso que ainda estou com dúvida. Por exemplo no C#, ou Java: public class Pessoa { public string nome; public Pessoa(string nome) { this.nome = nome; } public string setNome(string nome) { this.nome = nome; } } Pessoa pessoa = new Pessoa('Fernando'); pessoa.nome = 'Guilherme'; pessoa.setNome('Gabriel'); // Isso não faz muito sentido, e é isso que // me deixa doido. Não faz muito sentido setar no construtor e ter um método para setar outro nome, as vezes em casos especificos pode ser necessário. Mas qual a diferença em setar o nome pelo campo, ou pelo método ? Já que, o campo é do tipo string, não haverá problemas com tipo de dado, pois já tenho seu tipo definido. Se eu tentar setar o valor 5 para o campo nome, antes de compilar já terá um erro. No seu segundo exemplo, caso eu quisesse um Square com a propriedade size com o valor 5 por exemplo, eu teria que criar outro objeto, já que, de acordo com aquela classe, eu não posso alterar o valor desse campo. :D Valeu galera. Compartilhar este post Link para o post Compartilhar em outros sites
Evandro Oliveira 331 Denunciar post Postado Abril 18, 2012 E quando o tipo é INT mas só pode receber números positivos??? Ou se, por qualquer que seja o motivo, você precise receber apenas números primos? Enfim, qualquer tipo de validação deve passar por um setter que encapsula uma propriedade. Compartilhar este post Link para o post Compartilhar em outros sites
Gabriel Heming 766 Denunciar post Postado Abril 18, 2012 Não faz muito sentido setar no construtor e ter um método para setar outro nome, as vezes em casos especificos pode ser necessário. Mas qual a diferença em setar o nome pelo campo, ou pelo método ? Nesse caso, nada além de coesão (não sei se andei confundindo as coisas). Então vejamos no caso da classe pessoa. public class Pessoa { public String nome; private String cpf; public Pessoa() {} public void setCpf( String cpf ) throws CpfInvalidoException { if( this.validaCpf( cpf ) ) { this.cpf = cpf; } else { throw new CpfInvalidoException(); } } private boolean validarCpf( String cpf ) { /** validador de cpf, retorna true em caso de válido e false em caso de inválido não explanarei formas de validação **/ } } Agora que conhecemos a classe pessoa, sabemos que ela possui dois atributos e um deles requer validação. Logo: Pessoa pessoa = new Pessoa(); pessoa.nome = "Gabriel"; pessoa.setCpf( "000.000.000-000" ); A classe faz o que ela deve fazer. Entretanto ela fere o conceito de coesão. Segundo a wiki: É a conexão, ligação, harmonía entre os elementos de um texto No nosso exemplo, temos um atributo sendo atribuídos por set e outro com acesso público. Apesar de ser algo relacionado ao português, é muito bem vindo, diga-se de passagem, na programação. Logo para manter a coesão, sua classe deveria ser tudo com set ou tudo público. Já que é obrigatório o uso de um set para a validação, por coesão, todos os outros devem utilizar set. E ainda, para não mandar a coesão para o espaço, os mesmos atributos devem possuir get's. Logo: public class Pessoa { public String nome; private String cpf; public Pessoa() {} public String getCpf() { return this.cpf; } public String getNome() { return this.nome; } public void setCpf( String cpf ) throws CpfInvalidoException { if( this.validaCpf( cpf ) ) { this.cpf = cpf; } else { throw new CpfInvalidoException(); } } public void setNome( String nome ) { this.nome = nome; } private boolean validarCpf( String cpf ) { /** validador de cpf, retorna true em caso de válido e false em caso de inválido não explanarei formas de validação **/ } } então: Pessoa pessoa = new Pessoa(); pessoa.setNome( "Gabriel" ); pessoa.setCpf( "000.000.000-000" ); --------------- Atualizado, tive de mandar correndo o post... ps: anos luz que não programava em java '-' ps2: ignorem os erros da linguagem... quase coloquei apóstrofo para demarcar uma string (LOL) Compartilhar este post Link para o post Compartilhar em outros sites
FK. 0 Denunciar post Postado Abril 18, 2012 Certo, então um campo só deveria ter um método set se ele precisasse de uma validação, caso contrário, seria redundância ? Já vi em muitos artigos, que para cada campo, ele tinha um método get e set apenas pra setar e retornar valores. Porque não fazer isso no construtor, e os que precisam de validação, ai sim método set e get ? Podemos dizer que esse tipo de código é errado ? Compartilhar este post Link para o post Compartilhar em outros sites
Gabriel Heming 766 Denunciar post Postado Abril 18, 2012 Atulizei o post acima, pois não havia completado ele. Como eu havia falado antes, é importante manter a coesão. Basicamente um padrão, a harmonia entre os elementos. Imagine: você precisa de dois métodos, um que validade uma data e outro que valide um e-mail. Quando você constrói os métodos, você coloca os seguintes nomes para cada, respectivamente: validarData(); validaEmail(); Uma mudança sútil, apenas uma letra, mas não para nosso querido português (LOL): No primeiro, validar, verbo no infinitivo. No segundo, valida, terceira pessoa do presente do indicativo ou segunda pessoa do imperativo afirmativo, dependendo da forma que for aplicado. Alguns dias depois, você precisará chamar ambos os métodos, mas qual deles é com "r" e qual deles é sem? Sem olhar o código, ou possuir uma memória fotográfica, você vai precisar olhar o código. Eu vejo isso também com os métodos de uma classe, se eu realmente preciso de um método set para um ou alguns atributos, eu utilizo para todos. Se eu necessito métodos set, eu também vou utilizar métodos get. A questão de colocá-los no construtor, eu vejo apenas como sobrecarga(overload), que em muitas situações, pra não dizer todas, é extremamente útil. Este post fala um pouco sobre o assunto de coesão e coerência. Compartilhar este post Link para o post Compartilhar em outros sites
Evandro Oliveira 331 Denunciar post Postado Abril 19, 2012 Estamos esquecendo de um conceito importante: Interfaces. Nas linguagens de programação OO mais antigas, era tido como regra que, toda propriedade seria privada e deveria ser acessada através de um método. Dá pra ir além, se desejamos ser reutilizáveis e evitar ao máximo nossas repetições, cada propriedade deveria ser acessada por uma, e apenas uma, forma. Uma flexão desse modo de pensar é um dos Zen's do Python: "Deve haver apenas uma única boa forma de se fazer algo". Obviamente, as linguagens de programação evoluíram e se tornaram mais flexíveis, diminuiram a burocracia e ampliaram a agilidade. Porém, uma coisa é fato: Se é fácil de usar, é fácil de se usar incorretamente, também. No mundo real, quando você tem um objeto em mãos, você o analisa para entender o que pode ser feito com ele. Pra quê exatamente ele serve. Entendendo que o paradigma orientado a objetos tem por objetivo ser uma abstração do mundo real dentro da programação, também devemos ter em mente que quando lidamos com objetos, devemos nos focar no que podemos fazer com eles. Percebemos aqui que, o que realmente nos interessa nos objetos, são as ações. Em muitas literaturas, as propriedades de um objeto são também chamadas de "estado". O estado varia conforme o cenário. Se você precisa mudar o estado de um objeto, deve-se analisar o que levou a essa necessidade e a melhor forma de resolvê-la. Se você apenas deseja guardar informações, independente de que tipo, sugiro que estude estruturas de dados. Conhecerá Queue, Stack, Set, List, LinkedList, HashTables, Deck, Collection e poderá avaliar a melhor forma de armazenar informações. Tudo que não for relevante a um objeto, não pertence a sua classe, houve um erro de modelagem. Em contrapartida, tudo que for pertinente ao escopo da classe está propenso a pedir uma validação de entrada e uma filtragem de saída. Compartilhar este post Link para o post Compartilhar em outros sites
Gabriel Heming 766 Denunciar post Postado Abril 19, 2012 Porém, uma coisa é fato: Se é fácil de usar, é fácil de se usar incorretamente, também. [+1] Esse é um fato muito importante, pois quando é algo flexível, tende-se a ir pelo caminho mais fácil e na grande maioria, o mais fácil não é o certo. Ainda mais falando-se em programação, o mais fácil, provavelmente, irá se tornar o mais difícil (provavelmente serão futuras gambiarras). Como na música (meu hobby. Programar também é, não vejo como trabalho), quando algo se torna repetitivo e, de certo modo, fácil demais, acaba-se perdendo a atenção nos detalhes e deixando no "automático". Assim eu vejo que acontece com os métodos triviais (set's e get's) que, na minha opinião, não são e não devem ser considerados triviais. Compartilhar este post Link para o post Compartilhar em outros sites
Prog 183 Denunciar post Postado Abril 19, 2012 Alguns dias depois, você precisará chamar ambos os métodos, mas qual deles é com "r" e qual deles é sem? Sem olhar o código, ou possuir uma memória fotográfica, você vai precisar olhar o código. Documentação necas? Use uma boa IDE! Compartilhar este post Link para o post Compartilhar em outros sites
Gabriel Heming 766 Denunciar post Postado Abril 19, 2012 Use uma boa IDE! Utilizar uma boa IDE que mostre as classes e seus métodos, para mim, é um facilitador (muito bom por sinal, utilizo o PHPDesigner e não tenho do que reclamar). Entretanto, um facilitador, tornar-se uma flexibilidade e assim como o que já foi discutido, uma probabilidade de despadronização. Não estou dizendo que não deve-se usar uma boa IDE, pelo contrário usem e abusem. Entretanto, não deve-se depender somente dela. A documentação é essencial, mas padronização é mais ainda. Compartilhar este post Link para o post Compartilhar em outros sites
FK. 0 Denunciar post Postado Abril 19, 2012 @Evandro Oliveira, Entendi, vlw! edit -- Posso afirmar que, se um objeto precisa alterar seu estado, então essa informação que o altera deve estar encapsulada na classe, de forma que eu acesso ela apenas através de uma ação ? Que por sinal, muitas das vezes necessita de uma validação de entrada ou filtragem de saída, como o Evandro Oliveira disse. Compartilhar este post Link para o post Compartilhar em outros sites
Prog 183 Denunciar post Postado Abril 19, 2012 A boa prática pede infinitivo (ação). Se você estiver programando apenas para você, beleza... pensar numa IDE como "facilitador" parece razoável. Mas envolvido numa equipe de desenvolvimento, onde você sequer participou do inicio do processo, não vejo apenas como facilitador, acho até uma IDE tão essencial quanto a documentação. Compartilhar este post Link para o post Compartilhar em outros sites
Gabriel Heming 766 Denunciar post Postado Abril 19, 2012 @Fernando Kracheski Exatamente! @Prog Você está se apegando muito a um pequeno detalhe do exemplo que eu dei anteriormente e esquecendo o foco da ideia e o motivo do exemplo. Quando eu falei: [..]Sem olhar o código[..] Eu poderia ter dito: - Sem olhar a documentação. - Sem perguntar para o desenvolvedor da classe. - Sem ir buscar na IDE. - Sem perguntar ao Akinator. Isso são apenas exemplos que se refere a uma mesma idéia. Eu especifiquei que foi ele, Fernando Kracheski, o cara que desenvolveu, e supostamente esqueceu da forma que escreveu. Sem equipes, sem IDE. Não foi mencionado nada disso pois não faz diferença para a ideia. O motivo de exemplo, foi a padronização e não o que se deve ou não usar de software. Compartilhar este post Link para o post Compartilhar em outros sites
FK. 0 Denunciar post Postado Abril 20, 2012 Olhei nos primeiros posts desse tópico, e vi que postaram sugestões de livros para design patterns. Estou procurando um também, mas não sei muito inglês, estou aprendendo isso ainda. Existe um livro em português de design patterns, mas que não seja aquele Head First? Porque esse aí, não é tão bom não, além de conter erros de tradução. Os melhores são aqueles objetivos, como o livro daqueles 4 caras dos padrões GoF, mas parece que só tem inglês, ou não ? Vlw Compartilhar este post Link para o post Compartilhar em outros sites
Gabriel Heming 766 Denunciar post Postado Abril 20, 2012 Realmente a literatura estrangeira (principalmente dos Estados Unidos) é mais completa em relação a programação. O livro Clean Code - Robert "UncleBob" Martin eu peguei em português no submarino. O livro é excelente, de leitura fácil (até onde eu li), onde não fica "pesado" o acumulo de informações. Além de estar com um ótimo preço do livro e frete. Já as traduções de livros do Martin Fowler e da GoF (Gang of Four) são um pouco mais complicados de encontrar em português. Também gostaria do livro Objetos Php, Padrões e Prática do Matt Zandstra. Entretanto, em português está na primeira edição, enquanto a original está na terceira. Compartilhar este post Link para o post Compartilhar em outros sites
FK. 0 Denunciar post Postado Abril 20, 2012 Que livro você(s) recomendariam para não só aumentar minhas habilidades em POO, mas também em Design Patterns ? Esse do clean code fala sobre padrões, ou código limpo ? Compartilhar este post Link para o post Compartilhar em outros sites
Gabriel Heming 766 Denunciar post Postado Abril 20, 2012 Bom, esse fala sobre padrões, mas sobre o código em si, realmente sobre código limpo. Os outros dele falam sobre o assunto de padrões e princípios. Agile Principles, Patterns, and Practices in C# - Robert C. Martin Agile Software Development, Principles, Patterns, and Practices - Rober C. Martiin Sobre Design Patterns, o que eu posso recomendar são os mais famosos e mais conceituados (que eu ouvi falar): Padrões de Projeto - GoF Padrões de Arquitetura de Aplicações Corporativas - Martin Fowler (Li que a tradução é péssima) Sugiro começar a ler em inglês. Compartilhar este post Link para o post Compartilhar em outros sites
FK. 0 Denunciar post Postado Abril 20, 2012 Aee Gabriel, valeu mesmo, era exatamente o que estava procurando !! --- Sugiro começar a ler em inglês. Vou fazer isso cara, as vezes já fasso. Só é um pouco chatinho que, ao invez de você se concentrar em entender o assunto, você se concentra em entender o assunto e traduzir as palavras. Compartilhar este post Link para o post Compartilhar em outros sites
Evandro Oliveira 331 Denunciar post Postado Abril 20, 2012 http://books.google.com.br/books/about/Pattern_Oriented_Software_Architecture.html?id=WVQF2PK2tlgC Compartilhar este post Link para o post Compartilhar em outros sites
Cabral Desenvolvedor 0 Denunciar post Postado Abril 25, 2012 Olá galera, Andei acompanhando o tópico e gostei do discurso. Vou aproveitar e tirar uma dúvida com vocês sobre OO. Se eu tenho uma classe e nessa classe há um método estático, toda a classe e todos os métodos devem ser estáticos? Pois sei que quando um método é abstract, toda a classe deve ser. Abraços :thumbsup: Compartilhar este post Link para o post Compartilhar em outros sites
Evandro Oliveira 331 Denunciar post Postado Abril 25, 2012 Olá galera, Andei acompanhando o tópico e gostei do discurso. Vou aproveitar e tirar uma dúvida com vocês sobre OO. Se eu tenho uma classe e nessa classe há um método estático, toda a classe e todos os métodos devem ser estáticos? Pois sei que quando um método é abstract, toda a classe deve ser. Abraços :thumbsup: Quando há pelo menos um método abstrato, a declaração da classe deve ser abstrata para impedir que a mesma seja instanciada sem uma implementação. O que não a impede de ter métodos concretos e não tem nada a ver com métodos estáticos. Pelo menos no PHP, não há uma declaração de classe estática. Não é possível fazer static class MinhaClasse { ... } O que torna inviável uma abordagem semelhante à de abstratas. Há ainda outra divergência: Uma classe com apenas métodos estáticos pode ser instanciada, a menos que tenha seu construtor obfuscado. class MinhaClasse { public static function meuMetodoEstatico() { return 'Método estático requisitado.'; } } $minhaInstancia = new MinhaClasse; echo $minhaInstancia::meuMetodoEstatico(); Veja, a diferença é que a declaração de um método abstrato inviabiliza a criação de instâncias daquele escopo. O que não é verdadeiro no caso de métodos/propriedades estáticas. Para fugir da dúvida dos estáticos, prefira a nomeação "old school" onde se denominavam os métodos estáticos de Método de Classe e os não-estáticos de Métodos de Instância. Isso já define o escopo onde algo deve ocorrer. Utilize métodos estáticos apenas quando a responsabilidade não lidar com as particularidades de cada instância. Exemplo, ao invés de class ImprovedString { public static function revert($string) { return new ImprovedString(strrev($string)); } } prefira class ImprovedString { private $contents = NULL; public function __construct($string) { if (empty($string) or !is_string($string)) { throw new InvalidArgumentException("ImprovedString expects a String as value."); } $this->contents = $string; } public function revert() { $this->contents = strrev($this->contents); } } Compartilhar este post Link para o post Compartilhar em outros sites