Em uma excelente e curta entrevista, os autores falam de diversos tópicos, como a necessidade de design patterns em linguagens funcionais e dinâmicas, alguns patterns que viraram smells em grande parte dos casos (anti patterns) como o singleton, injeção de dependências como pattern e muito mais. Leitura recomendada!
Tenho para mim que o livro da gang dos 4 é um bom livro mas a pressão pelo uso de design patterns foi ruim para os programadores em geral.
Explico:
Padrões deveriam ser uma segunda ou terceira preocupação do programador. Ele deveria se concentrar em resolver o problema da forma que conseguisse. No futuro ao refatorar, caso reconhecesse algum padrão aí sim alterava o código.
Mas não foi isto que vi muitas vezes. Os caras achavam bonitinho programar por padrões.
Ora, foi neste mundo fértil de beócios que surgiu aquele terrível livro da Sun dos Core Design Patterns. Os programadores eram então incentivados a fazer do modo complexo coisas que poderiam ser mais simples.
Por algumas discussões aqui no GUJ, temo que esteja acontecendo algo semelhante com DDD. As vezes leio alguns posts tão complexos que fico com saudades do tempo em que a gente se concentrava no problema a resolver sem precisar satisfazer o colega que acha mais bonitinho assim ou assado.
Fiquem tranquilos, não estou tendo ataques de duct-tape programmer by Joel Spolsky. Apenas acho que design patterns deve ser usado por programadores experientes que reconhecem um padrão ao olhar a solução codificada ao invés de ser usado só para o programador falar difícil para o colega que usou XPTO ou KYMZ.
Seria interessante uma segunda edição baseada em outras linguagens. Mas deveria vir com um alerta: A gang dos 4 adverte, usar design patterns em excesso pode causar embruculhamento (*) do seu código.
(*) Substitua embruculhamento por uma palavra mais feia se conseguir
[]s
Luca
T
tnaires
Muito interessante a entrevista.
Será que alguém poderia indicar alguma situação onde Singleton ainda seria útil nos dias de hoje?
S
sergiotaborda
tnaires:
Muito interessante a entrevista.
Será que alguém poderia indicar alguma situação onde Singleton ainda seria útil nos dias de hoje?
Em várias situações. Mas normalmente nas que se vivem no mundo EE (liás a especificação meio que proibe isso)
Dizer que ha um problema com o singleton é não entender o que um padrão é. O problema não é com o sigleton, é com a educação OO das pessoas. A maior parte usa um singleton (porque é o padrão que aprendeu) para resolver coisas que seriam corretamente resolvidas com um outro padrão. O erro é do programador e do ensino, não do padrão ou de quem o identificou.
Padrões são para OO o que receitas são para a culinária, mas ao contrário. Quando vc começa na culinária começa seguindo receitas e só depois vc evolui para o estado em que pode simplesmente fazer. Vc entendeu as regras inerentes às receitas e vc as aplica abstractamente. Os padrões é ao contrário. VC começa por não os usar, mas vc segue os principios de OO (os que não os seguem têm problemas mais graves ). Ao usar os principios abstratamente durante um tempo vc identifica padrões.
O pulo do gato é que os padrões se podem ensinar mesmo a quem não segues os principios abstratamente e a pessoa pode programar bem usando padrões mesmo sem conhecer muito OO.
O problema não são os padrões. O problema é a fraca cultura dos programadores que não os entendem. Confundem tudo, é um caos. Coisas como dizer que pode haver mais do que uma instancia de um singleton ou que MVC é separação em camadas são exemplos da pouca e fraca cultura de padrões.
Usar padrões e programar padrões sim é uma vantagem. Quem não entende isto é porque não os usa direito ou nunca viu alguem usar direito. … ou simplesmente é preguiçoso.
Já tenho ouvido absurdos de fazer qualquer codigoa ad hoc e depois refactorar. Isso gera um custo imenso, porque a primeira coisa que o cara faz é gamb. Refactorar gamb é impossivel.
Existe até um livro “refactorando para patterns”. Se eu vou refactorar para patterns isso significa que o programa escrito com patterns é que é o melhor. portanto, se eu programar com patterns desde o inicio não preciso refactorar.
Refactorar virou pipula mágica para desculpar a asnceira, a falta de conhecimento e a gamb. Senhores, refactorar é caro! e quanto mais gamb é, mais caro fica.
Aprender a programar usando patterns é aprender a programar usando meta-OO. um nivel acima. claro, se quase ninguem sabe OO não se pode esperar que saiba patterns , mas dizer que patterns é ruim é simplesmente absurdo e um desfavor à comunidade OO (seja em que linguagem for)
Q
qmx
Até nesses casos que porventura existam, singleton não se justifica, IMHO.
Até não vejo problema em usar uma instância só pra fazer alguma coisa, a parte ruim é obrigar, como o pattern faz.
G
garcia-jj
Paulo, muito bom, obrigado por compartilhar.
tnaires, o singleton foi muito usado no passado, porém houve uma onde de “não usar” singleton… coitado dele, de um dia para o outro foi escurraçado. Ele era muito bom pelo fato de criar uma instancia unica, mas hoje em dias com os processadores mais inteligentes somados a evolução da própria vm instanciar objetos e coleta-los nem é mais tão preocupante. Vejo assim não haver uma necessidade de singleton. Lembrando que há uma proposta pro EJB 3.1 de haver uma anotação @Singleton.
Uma discução que acompanhei há algum tempo foi sobre logging… em ambientes j2ee se você usar sua classe de logger como static você não consegue trabalhar bem com os repository selectors, onde criando como instancia normal você consegue usá-los.
Luca, concordo mesmo contigo sem adicionar ou remover alguma palavra do seu post. Excelente.
Abraços
A
alots_ssa
Como foi mencionado, concordo totalmente com o Luca!!!. E a Kathy Sierra deveria escrever o novo livro, aí seria um catalogo bom de ler!!
S
sergiolopes
Sobre o singleton especificamente: o problema não é o fato de ter ou não uma instância única da minha classe. O problema é que as demais classes que usam esse meu objeto único são obrigadas a saber que aquilo é um singleton (normalmente através do famigerado getInstance estático).
A evolução do singleton hoje, na linha da separação de responsabilidades, é usar inversão de controle e injeção de dependencias. Minha classe que precisa daquela outra de instancia unica, ao inves de chamar o getInstance, recebe uma dependencias. E o container resolve se a instancia a ser injetada deve ser unica ou não.
Compare qual código deixa as duas classes mais desacopladas:
No fim, singleton hoje deixou de ser Design Pattern de código e passou a ser configuração de escopo em containers IoC.
T
tnaires
Seu exemplo mostra com toda a clareza porque é difícil escrever testes para singletons.
J
javamaniaco
De uma coisa tenho que concordar com o Luca, quando chegamos e conhecemos outras linguagens e comunidades, percebemos o quanto o Java se torna mais complexo com a tal caracteristica de adicionar Isso e Mais aquilo e Aquilo outro só para ficar, digamos, “bonitinho”. Nisso vejo que, por fora, Ruby, Python e outras vem ganhando terreno e matando o Java e sua extrema complexidade. Lamentável.
L
Luca
Olá
Você captou justamente o que eu quiz dizer. A complexidade inibe o iniciante. Vamos programar, resolver problemas, aprender o negócio, saber usar TDD. Deixem o código bonitinho para lá enquanto aprende. Com tempo a gente melhora. E aí então naturalmente usará alguns padrões.
Muito melhor do que se preocupar em escrever código baseado em padrões é se habituar a fazer revisão de código. Se você não costuma fazer as partes mais dificeis usando programação em par, pelo menos reserve alguns momentos do seu dia para sentar com outros programadores para rever os códigos deles e principalmente para que outros revejam seu código. Convença seu chefe de que isto não é perda de tempo. Vai aprender bem mais rápido e evitar levar adiante código que nem você que fez consegue explicar para o colega.
E nunca esquecer que a gente programa para resolver negócio.
[]s
Luca
A
Alessandro_Lazarotti
Concordo com o Sergio sobre usar DI invés de codificar seu Singleton,. diminuindo o acoplamento entre dependencias. Mas notem que a MOTIVAÇÃO que é algo fundamental na execução de qualquer pattern ainda existe no caso do Singleton, a diferença é que não é você que o codifica, é algum framework ou biblioteca.
Logo o Singleton, ainda hoje, pode e deve ser utilizado, a diferença é que não tem que codifica-lo em seu projeto já que o fizeram por você… apenas anote ou configure seu framework favorito
P
Paulo_Silveira
Importante no singleton é nao ficar chamando um metodo estatico getInstance como o Sergio mostrou: voce fica super acoplado e é dificilimo de testar (passar mocks). Assim como factory methods, é importante isolar esses patterns criacionais dependente de metodos estaticos, fazendo com que voce recebe a referencia no construtor: facilita bastante qualquer tipo de teste e diminui drasticamente o acoplamento.
S
sergiotaborda
Acho que devo ter acessado o guj de um universo paralelo … o que se passa com vcs ?
Desktop é uma classe singleton no JSE. Onde é que está escrito que ele é um singleton ? Cadê a assinatura souumsingleto.getsingleton ? Compare com Calendar.getInstance e Locale.getInstance que não são singleton.
Tente injetar Desktop numa classe. É muito simples com Guice, não tanto com Spring, mas e dai ? é possivel. é o que interessa.
confundir singleton dom DI ? mas que raios vcs estão pensando ? Singleton é um padrão criacional !
Vc se esquecem que DI usa factories. Alguem tem que criar os objetos para eles serem injetados !! em todos os motores de DI vc pode configurar essas factories. O ponto não é injetar, mas sim criar. Se a classe ñ é singleton várias instancias podem ser criadas mesmo com um motor de DI.
Singleton como acesso global é subsittuido por Registry.
@Singleton é a perpetuação da asneira. Não satisfeitos com a confusão do VO o povo da jcp adora meter lenha na fogueira. A culpa é do Spring que chama - erradamente - de singleton objetos que são na realidade shared object. E como o povo do Spring está na jcp… bom, já se viu.
Singletons reais são raros. Mas isso não invalida o padrão. O problema é o mau entendimento que as pessoas têm de padrões. Não só design patterns, mas de outros como Produtor-Consumir que é essencial em mensageria e concorrencia.
Castigar o singleton pelo mau uso que os programadores fazem dele é como castigar a tinta pelas palavras groseiras que se escrevem com ela. Ainda mais absurdo é culpar todos os padrões como um todo. É como se castigássemos o próprio alfabeto por permitir escrever palavras.
Vcs não estão dizendo coisa com coisa. Quem ler isso vai achar que padrões é uma porcaria. A mensagem a ser transmitida não é essa. É exatamente ao contrário. Foi depois que padrões foram introduzidos na API do java que ele ficou mais limpo. A API de collections é um otimo exemplo assim como a nova NIO2 usando Visitor para iterar arquivos. E já a NIO tinha melhorado usando uma versão de observer. E a JDBC que todo o mundo usa toda a hora é um excelente exemplo de Bridge.
O melhor e mais edgy de java é feito com aplicação de padrões!
Agora, o problema é: estudar padrões , aprender padrões, e usar padrões é dificil e complexo! Não é para qualquer um. Portanto:
padrões é otimo.
aprenda-os
aprenda-os direito!
Ha certas ocasiões em que dá tristeza ver o que se escreve de padrões … frases do tipo “Fiz um façade para encapsular a chamada”
É como ver as pessoas falarem mal ou escreverem errado. Fere os ouvidos e corta o coração quando é um profissional dizendo.
O pior não as pessoas não saberem, é alguem dizer que aprender é inutil.
Bom falar que padrões são necessários por causa da austeridade da linguagem é ainda pior asneira. São padrões de OO , de design, de arquitetura , de segurança, etc… não são padrões de linguagem !! afinal o GOF era smalltalk e C++ e ainda é válido em java, C# , qq outra linguagem OO.
Que raios deu em vocês ?
J
javamaniaco
Palavras bonitas mas como de um político. Você fala para poucos e logo poucos lhe escutam. Conheceu Rails? Viu Ruby? Quando colocamos a mão em situações como Ruby, Rails, questionamos o porque o Java ou outra louca linguagem que deseja seguir este método obscuro de desenvolvimento existe. Desde que comecei a aprender Java vi tantas palavras que posso colocar em um dicionário facilmente. Também vi quando comecei a trabalhar com isso que os projetos pequenos se tornam demorados. Seria falta de conhecimento decoreba dos padrões? Sei não, pra mim é coçar a orelha esquerda com a mão direita.
Ai vem um Rails da vida, mostra que, tudo que fiz poderia ser prático, divertido e nada confuso. Que A que programou, B entende, C entende e qualquer outras letras que colocar aqui, entende. Agora, tem projetos em Java que, graças a Deus, inventaram as IDE’s, porque é a coisa mais louca que já vi, é um padrão X que passou a ser chamado de Y, porque antes era VO, depois virou “PÓ”, rs. Ai fazem as maravilhosas packages com nomes de sei lá o que e dizem: há, isso é DDD. Putz, quantos anos levam para um iniciante aprender tudo isso? Quanto tempo terei que machucar minhas mãos para escrever “belamente”?
Eu digo uma coisa, levei nem 1 mês para entender Rails, em 2 meses estava em um projeto e até hoje já passei por 4 projetos em Rails, sendo um de porte médio. Mudei de equipe várias e várias vezes e cada linha escrita e reescrita eu compreendo. Se entrar no meio de um projeto Rails já sou produtivo. Se for em Java, só se der sorte. Sorte com a complexidade ou com metidos arrogantes que arrotam letras e padrões que nunca ouvi falar, mas que existem talvez para tornar o programador mais valioso.
Desculpe o desabafo gente, mas é que já vi tantas discussões de padrões e cada dia mais penso que sei menos. Já até falei em outro post que to quase mudando meu nick para rubymaniaco.
S
sergiolopes
Tirando as frases mais exaltadas, eu acho que no fim estamos todos falando a mesma coisa. Patterns são difíceis mas resolvem bem alguns problemas, e ótimos exemplos estão na própria API do Java SE.
E sobre o singleton em particular, é o que eu falei: o problema em geral não está em ter uma única instância (isso às vezes é útil, mas raramente como você disse). O problema é o acesso global vinculado ao Singleton (e aliás a alguns outros patterns creacionais, como a própria Factory).
Você sugeriu usar Registry para evitar o acesso global. Ok, é um jeito (embora eu não goste). Mas DI é outro jeito (que aliás substitui boa parte da necessidade do Registry). Hoje singleton acabou virando configuração dentro de container IoC, bem como boa parte das Factories, que fabricam para um container depois injetar (não chamamos mais factories em nossos códigos).
Aliás, também achei @Singleton uma má ideia
S
sergiotaborda
javamaniaco:
sergiotaborda:
Castigar o singleton pelo mau uso que os programadores fazem dele é como castigar a tinta pelas palavras groseiras que se escrevem com ela. Ainda mais absurdo é culpar todos os padrões como um todo. É como se castigássemos o próprio alfabeto por permitir escrever palavras.
Que raios deu em vocês ?
Palavras bonitas mas como de um político. Você fala para poucos e logo poucos lhe escutam.
Conheceu Rails? Viu Ruby? Quando colocamos a mão em situações como Ruby, Rails, questionamos o porque o Java ou outra louca linguagem que deseja seguir este método obscuro de desenvolvimento existe.
Isso porque vc tem pouca bagagem para entender. Qual é a base do modelo de objetos do ruby ? Em java é classe, em javascript é
prototype ( os dois são padrões ) e em ruby ? vc sabe ? eu lhe digo : meta-class.
O que é um meta-class ? é o uso do padrão MetaObject. Um MetaObject é um objeto que descreve outro. Este padrão é muito usado em XML onde um esquema define o xml, em banco de dados onde um conjunto de informações define os “metadados” (passo a expressão) do banco. Em java o tipo Class é um MetaObject porque define como um object será. Uma meta-class do ruby é um objeto que define como a class será. É um nivel acima. E é isso, apenas isso, que permite que o ruby seja mais flexivel que java. É facil entender porquê essa flexibilidade pois vc está usando um nivel de abstração mais elevado. O mesmo acontece com groovy e outras linguagens com meta-class.
Vc não viu o suficiente. tinha visto o padrão MetaObject ?
Obviamente.
Ha pessoas que dizem que furam, ha pessoa que obliteram. Cada um usa a palavra mais explicativa que conhece.
E veja só que interessante. Ele faz tudo isso apenas com um design pattern: MetaObject. Genial, não ?
Na boa, que culpa tenho eu disso ? Que culpa tenho eu ou o java ou quem quer que seja, dos seus talentos e defeitos ?
Mais uma vez : que culpa temos nós que vc não ouvi falar ? a culpa é toda sua que não estudou o suficiente!
Veja só que a ironia : vc está dizendo que ruby é uma maravilha, mas ele é feito a partir de um padrão chamado MetaObject que vc nunca ouviu falar. O cara que inventou o ruby, deve ser, portanto, pela sua logica um “metido arrogante”.
Alguns fazem, alguns ensinam e o resto lê nos livros.
E algums nem livros leêm…
Culpar padrões ou o java ou a sun ou o jcp ou seja quem for pela própria ignorância é desonesto e irresponsável.
Eu não tenho culpa de saber padrões. Ou vão me queimar na fogueira por isso ? :lol: :lol: :lol: :lol: :lol: :evil:
A
Alessandro_Lazarotti
[editado por mim mesmo - estava redundante com o que o Sergio escreveu ]
… menos a parte de @Singleton. Qual mal vc vê nesta anotação Sergio Lopes? E você Taborda, que mal você vê em uma anotação que realmente provê a criação única de um objeto em memória? Somente o nome? Se for isso o que vc sugeriria, apenas por curiosidade.
S
sergiotaborda
Sergio Lopes:
Você sugeriu usar Registry para evitar o acesso global. Ok, é um jeito (embora eu não goste). Mas DI é outro jeito (que aliás substitui boa parte da necessidade do Registry).
Pois é… então vc acha que o Spring não tem um Registry… o que vc acha que é o ApplicationContext com o seu getBean(id) ?
Pense melhor.
No guice é mais obvio o uso de regestry no objeto de bind onde vc configura o bind da interface/classe com a classe.
Não é possivel trabalhar com metadados em um Registry. A razão é simples : metadados, são, por definição, globais.
Releia o conceito de Registry e compare com o ApplicationContext. Já agora compare tb o Factory com o Provider do Guice.
Motores de injeção precisa criar objetos : logo, precisão de saber como criá-los ( registry de metadados) , criá-los (factory) e depois injetá-los (Registry de metadados de injeção lidos de annotações, xml, etc… ) se o objeto tem mecanismos especiais de criação como singleton, prototype, etc… então é preciso um factory especial, mas um factory, non the less…
S
sergiotaborda
Alessandro Lazarotti:
Olã Sergio,
Não olhei o ponto onde alguém confundiu Singleton com DI. Como você mencionou Singleton é padrão criacional e de nada tem haver com DI. O que muitos disseram aqui (e não só aqui), é que em muitos casos você pode delegar a criação do objeto fora da classe que a tem como composta ou do método que a utiliza, diminuindo a amarração da classe, o que não ocorre na maioria das vezes que é utilizado Singleton.
O que estou dizendo é muito simples : não ha como delegar a criação de um singleton a uma outra classe. Essa é a essencia do padrão. Se vc delega, é porque, obviamente não era um singleton. Singletons verdadeiros não podem ser criados sem ser pela sua propria classe.
Veja bem o conceito de singleton nasce da proibição explicita de injeção de dependencia que é um principio da OO. Portanto, não faz sentido que um motor de injeção possa criar um singleton. É como ter uma fabrica de singleton, simplesmente impossivel.
O ponto que abordei é a confusão de que um singleton possa ser criado via motor de DI. Não pode. O exemplo é a classe Desktop.
Contudo, isso não signfiica que eu não o possa injetar. Posso sim. É só configurar o motor de DI corretamente. Isto rebate o que foi dito que não usar singleton aumenta a testabilidade e a injeção. Isso é falso. Vc nunca usa singleton porque quer. VC usa porque precisa. Se ha outro jeito então aquilo não era um singleton para começo de conversa.
Pense realmente a fundo num outro jeito de implementar Runtime ou Desktop sem ser usando singleton. Não é possivel. Venham quantos DI existirem…
A
Alessandro_Lazarotti
sorry taborda, editei apagando o que vc quotou antes de ver sua resposta
S
sergiolopes
Mas é justo esse o ponto! Esses patterns hoje estão dentro dos containers IoC, a gente não escreve mais essas coisas.
Aliás, ninguém chama o getBean no Spring diretamente, certo? Senão ele seria um Registrizão esperto, apenas isso (como voce mesmo disse).
P
Paulo_Silveira
Creio que todos estamos falando o mesmo: o pessoal costuma usar singleton erroneamente, por isso precisam ter cuidado, como o proprio Erich Gamma disse: I’m in favor of dropping Singleton. Its use is almost always a design smell. Da até pra ver isso nessa sua frase:
Exatamente, mas é detalhe de nomeclatura para facilitar, todos estão falando a mesma coisa aqui. A maioria do pessoal queria um shared object, e não um singleton! (e muitas vezes é até questionável a necessidade de shared object).
Em nenhum momento dissemos que singleton esta sempre errado, ou que não se deve estudar Design Patterns, etc. Como você disse, devemos aprender a usa-los, mas direito.
S
sergiotaborda
Alessandro Lazarotti:
[editado por mim mesmo - estava redundante com o que o Sergio escreveu ]
… menos a parte de @Singleton. Qual mal vc vê nesta anotação Sergio Lopes? E você Taborda, que mal você vê em uma anotação que realmente provê a criação única de um objeto em memória? Somente o nome? Se for isso o que vc sugeriria, apenas por curiosidade.
Essa anotaçao não proves a criação unica na memoria. Se eu quiser criar outro eu posso. É só dar new. Um verdadeiro singleton vc não tem sequer como controlar a criação. Vc não pode criar outro mesmo que queira.
Um objeto que é instanciado uma vez por escolha ( para poupar memoria por exemplo) é um Shared Object, não um Singleton. são padrões diferentes que servem para coisas diferentes. Exemplo , Integer tem charedobjects para numeros no range de byte, Locale e Currency e outros usam isso tb. É um padrão bem comum para minimizar a criação redundante de objetos.
dado o argumento anterior o nome é horrivel. Deveria ser @Shared. ou @Unique ou qq outro abdejetivo. Tods menos Singleton.
S
sergiolopes
sergiotaborda:
Veja bem o conceito de singleton nasce da proibição explicita de injeção de dependencia que é um principio da OO. Portanto, não faz sentido que um motor de injeção possa criar um singleton. É como ter uma fabrica de singleton, simplesmente impossivel.
O ponto que abordei é a confusão de que um singleton possa ser criado via motor de DI. Não pode.
Agora entendi o seu ponto. Então discordamos mesmo (nestes pontos, pelo menos).
Eu consigo enxergar um singleton sendo criado fora da classe, desde que esse ser externo garanta a instância única. Claro, é uma visão diferente do GoF tradicional, e mais próxima do que se enxerga como singleton hoje no Spring e no próprio @Singleton
S
sergiotaborda
Paulo Silveira:
Creio que todos estamos falando o mesmo: o pessoal costuma usar singleton erroneamente, por isso precisam ter cuidado, como o proprio Erich Gamma disse: I’m in favor of dropping Singleton. Its use is almost always a design smell.
Não creio que estamos. A frase que cistaste é um exemplo. O que é um smell ? o singleton ?
coitado. porque ele é , e registry ou factory ou proxy não são ? Porque se livrar ( drop) do singleton. Tipo todos os autores vão nunca mais escrever sobre ele, logo ele nunca mais será usado. Entendem ? isso não faz sentido.
O que ele deveria dizer era : precisamos explicar melhor, com mais exemplos para que as pessoas não achem que estão usando o padrão.
Um padrão tem um escopo onde pode ser usado. A maioria usa singleton no escopo errado. A implementação tecnica pode até ser perfeita, mas se o escopo é errado, é um smell. O escopo do uso, não o padrão e não o coitado do singleton.
Para os que não sabem porque eu estou falando o que estou falando releiam o topico todo ( e os n-trocentos do mesmo assunto).
S
sergiotaborda
Sergio Lopes:
sergiotaborda:
Veja bem o conceito de singleton nasce da proibição explicita de injeção de dependencia que é um principio da OO. Portanto, não faz sentido que um motor de injeção possa criar um singleton. É como ter uma fabrica de singleton, simplesmente impossivel.
O ponto que abordei é a confusão de que um singleton possa ser criado via motor de DI. Não pode.
Agora entendi o seu ponto. Então discordamos mesmo (nestes pontos, pelo menos).
Eu consigo enxergar um singleton sendo criado fora da classe, desde que esse ser externo garanta a instância única. Claro, é uma visão diferente do GoF tradicional, e mais próxima do que se enxerga como singleton hoje no Spring e no próprio @Singleton
Dê um exemplo. Crie um mecanismo para criar o objeto de forma que ele seja um singleton sem que a classe crie o objeto. ( teste com runtime e desktop para ver se funciona. lembre-se que runtime é um recurso realmente único. )
P
Paulo_Silveira
Tem razao. Tirar do livro é exagero. Melhor seria ter esse tipo de discussão lá e mostrar exatamente o smell, mostrando que não é legal usar como variável global, difícil de testar se invocado o método estático em todos os lugares, etc, mas que da pra usar bem se tomar cuidado E tiver a real necessidade (que é dificil aparecer).
P
Paulo_Silveira
sergiotaborda:
Dê um exemplo. Crie um mecanismo para criar o objeto de forma que ele seja um singleton sem que a classe crie o objeto. ( teste com runtime e desktop para ver se funciona. lembre-se que runtime é um recurso realmente único. )
Crie uma interface publica que se chama Runtime e uma implementacao package-protected que se chama DefaultRuntime. Registre essa configuracao no seu container de DI, de que deve ter so um DefaultRuntime a ser injetado. O container usando um pouco de magica consegue dar new na classe paclage-protected. Pronto! Podia ate ter na System um getRuntime que devolvesse o DefaultRuntime unicamente instanciado. Codigo limpo, testavel (diferente de como é atualmente, impossivel de se testar unitariamente quem depende diretamente de Runtime sem magia negra), e é uma forma de implementar singleton. A unica forma de burlar isso seria por reflection+magia, e da pra fazer a mesma coisa com o singleton tradicional, entao estamos igualmente protegidos. Alias, essa tecnica é pra la de conhecida e muita gente usa de outras formas.
A falta de uma interface para Runtime, e qualquer outro singleton, é certamente um pequeno pecado.
Essa visao do Sergio Lopes, como ele disse, é diferente da tradicional, mas tem o mesmo efeito.
F
fredferrao
sergiotaborda:
Paulo Silveira:
Creio que todos estamos falando o mesmo: o pessoal costuma usar singleton erroneamente, por isso precisam ter cuidado, como o proprio Erich Gamma disse: I’m in favor of dropping Singleton. Its use is almost always a design smell.
Não creio que estamos. A frase que cistaste é um exemplo. O que é um smell ? o singleton ?
coitado. porque ele é , e registry ou factory ou proxy não são ? Porque se livrar ( drop) do singleton. Tipo todos os autores vão nunca mais escrever sobre ele, logo ele nunca mais será usado. Entendem ? isso não faz sentido.
O que ele deveria dizer era : precisamos explicar melhor, com mais exemplos para que as pessoas não achem que estão usando o padrão.
Um padrão tem um escopo onde pode ser usado. A maioria usa singleton no escopo errado. A implementação tecnica pode até ser perfeita, mas se o escopo é errado, é um smell. O escopo do uso, não o padrão e não o coitado do singleton.
Para os que não sabem porque eu estou falando o que estou falando releiam o topico todo ( e os n-trocentos do mesmo assunto).
Sinceramente nao foi o que entendi da frase do Gamma, ele disse que o USO do singleton é na maior parte um smell e nao propriamente o singleton.
P
Paulo_Silveira
fredferrao:
sergiotaborda:
O que é um smell ? o singleton ?
coitado. porque ele é , e registry ou factory ou proxy não são ?
Sinceramente nao foi o que entendi da frase do Gamma, ele disse que o USO do singleton é na maior parte um smell e nao propriamente o singleton.
verdade, bom ponto. ja estava respondido.
A
Alessandro_Lazarotti
Taborda, acredito mais na resolução das motivações descritas nos catalogos do que nos padrões conforme criados em sua essência. Ainda insisto na implicancia com anotações como @Singleton. De fato é uma factory que o cria, mas se o container que a contém é responsável pela ciclo de vida do objeto e garante que ele é único, mesmo isso não estando no objeto, ele resolve a questão Singleton de “possuir apenas uma instancia na aplicação”. A associação deste comportamento com o nome “Singleton” é muito forte, logo não vejo mal em criar uma anotação com o mesmo nome para propósito similar.
O mesmo vale para mecanismos de cluster de alguns appservers onde para garantir um “comportamento Singleton” em mais de uma maquina virtual , é habilitado um servico ativo/passivo onde o controle da instancia fica a cargo do container e não do objeto… tendo o exato comportamento Singleton do padrão (vide HA-Singleton).
J
javamaniaco
Sim, tão genial que não preciso me preocupar com isso e mais, se me preocupar, é com apenas 1.
Irinia ou não, simplicidade é genialidade e complexidade não é talento. Quero me preocupar com o negócio que o cliente deseja fazer funcionar e que me dê suporte para testar e retestar se eu alterar. Pouco importa qual pattern usou o sistema para o cliente e sinceramente, o que mais me importa é criar um software funcional, no prazo e ao mesmo tempo não seja um emaranhado de classes com nomenclaturas e padrões que mudam todas as horas.
Novamente, 1 padrão. Não mais que isso. De quantos padrões se faz um aplicativo em java? Será que levaria quanto tempo para entender tal padrão? Será que preciso saber ele para escrever bom software no Rails? A resposta é NÃO!
Agora, um framework X + Y + Z ainda preciso saber pattern A+B+C, logo, aqui estou, NA MESMA. Ai vem outro e quer adicionar mais um padrão XYZ porque é melhor que usar ABC e pronto, LÁ VAMOS NóS no barco da complexidade.
Enquanto isso, em uma linguagem bem elaborada necessita de 1 pattern, não me faça rir.
Só ler livros não lhe faz um bom programador. Só praticar também não. Precisamos dos dois e ao mesmo tempo, o $$$ é necessário para conseguirmos mais livros.
Não culpo a Sun e nem o Java. Pra ser sincero, nem sei porque tamanha complexidade é dão idolatrada e dão adotada nas empresas e porque, uma linguagem tão mais inteligente, mais fácil de escrever não teve seu lugar ao sol como o Java. Seria porque a Sun já foi bem grande? Talvez, olha o .Net, Microsoft por trás e pum, as empresas grandes adotam.
S
Ssalgado
Sergio Lopes:
…
Compare qual código deixa as duas classes mais desacopladas:
No fim, singleton hoje deixou de ser Design Pattern de código e passou a ser configuração de escopo em containers IoC.
Oi Sergio,
não estou aqui dizendo se Singleton é bom ou ruim, mas, na minha opinião, seu código mostra um problema de dependência, e não de singleton. Por exemplo:
class PrecisoDeUmCaraQueNãoSeiSeÉSingleton {
PrecisoDeUmCaraQueNãoÉSingleton() {
NaoÉSingleton n = new NãoÉSingleton();
}
}
acima temos um acoplamento maior independente do singleton em si.
class PrecisoDeUmCaraQueNãoSeiSeÉSingleton {
PrecisoDeUmCaraQueNãoÉSingleton(NãoÉSingleton n) {
// injecao de dependencia
}
}
P
Paulo_Silveira
Ola Salgado!
Voce tem razao, e o Sergio Lopes quis apontar realmente o problema da dependencia: usar o singleton sem cuidado gera um acoplamento fortissimo, dificultando tudo inclusive testes unitarios. Assim como o Erich Gamma tambem disse, o problema é nao usar o padrao direito, e nao o padrão em si.
S
Ssalgado
Paulo Silveira:
Ola Salgado!
Voce tem razao, e o Sergio Lopes quis apontar realmente o problema da dependencia: usar o singleton sem cuidado gera um acoplamento fortissimo, dificultando tudo inclusive testes unitarios. Assim como o Erich Gamma tambem disse, o problema é nao usar o padrao direito, e nao o padrão em si.
Paulo,
levando em conta as duas implementacoes 'erradas' abaixo:
o teste das 2 implementações fica difícil independente do singleton (como dito antes).
Quando não é singleton nada pode ser feito, quando é singleton, alguns gatos são possíveis:
public void testGatoParaTestarAlgumaCoisa {
SouUmSingleton aInstanciaParaTeste = SouUmSingleton.getInstance();
/*
Via reflection o estado interno do singleton.
*/
// Chama método de PrecisoDeUmCaraSingleton. Que vai utilizar o singleton modificado.
}
Código mau feito é difícil de testar. Mas nesse caso específico, com singleton ainda é possível tentar fazer um gato.
F
Foxlol
Acredito que este artigo da InfoQ vem bem a calhar nesta discussão:
Como o Luca disse, sobre se preocupar com o problema primeiro e refatorar depois, tenho a dizer que isso só é válido se vc sabe dos juros que serão cobrados sobre isso.
A refatoração deve acontecer a todo momento [Martin Fowler], vc se preocupa inicialmente somente com o problema e aí vai refatorando, refatorando até ter um código “decente”.
A aplicação de Patterns, além de mostrar soluções para problemas conhecidos, também favorece uma comunicação universal entre os desenvolvedores.
Como foi dito aqui, só use Patterns se vc realmente tem um problema que precise dele. Mta gente utiliza Patterns apenas por usar e sem saber o pq ele realmente existe.
Mas se tratando do problema da curva de conhecimento necessária, creio que É necessária. Se podemos evitar defeitos futuros, pq não saber como evitar?
Palavras de Mary Poppendieck:
“O maior defeito que temos agora [em desenvolvimento de software] é tolerar defeitos”
Abraços.
S
sergiotaborda
Pois é, foi isso que ele disse. E é exactamente esse o problema. Quando vc usa o singleton corretamente isso não é errado. Exemplos sao Runtime e Desktop do JSE. quando cria um objeto que não é um singleton ,mas vc implementa o codigo igual ao que usaria num singleton isso sim é errado. Mas veja, não é o padrão que está errado, é o entendimento do programador que achou que singleton serve para dar acesso global.
Ainda hoje estava repassando um artigo da javamagazine sobre jruby e o autor escrevia algo como (parafrase) :" podemos tornar o objeto jrubyqualquercoisa (não lembro de cabeça o nome e não tenho a revista aqui) um singleton para podermos ter acesso global"
Este é o exemplo típico do mau uso de singleton. Quer acesso global ? use Registry. Quer uma única instância ? use singleton.
Singleton não é para dar acesso global (senão o nome do padrão seria Globalizator )
S
sergiotaborda
Um comentário geral.
O exemplo do Paulo de como implementar singleton não é válido. Acho que vcs sempre se esquecem do essencial e continuam confundindo singleton e shared. Veja bem, o propósito do singleton não é manter um objeto unico na memória. Isso o shared tb faz. O objetivo é proibir que mais do que um objeto seja criado sob qualquer condição. Se vc usa interfaces as possibilidades do numero de objetos é ilimitada. A unica forma de proibir a instanciação é ter uma classe final e com construtor privado. Se o construtor é privado apenas a classe ela mesma ,pode criar a unica instância que existirá. Leiam o Effective Java para mais detalhes.
Os motores de injeção são feitos de vários padrões. claro. A questão é que em algum ponto os objetos que eles injetam têm que ser criados. Durante a fase de criação ela só pode ser feita por um padrão criacional.
A diferença entre um shared e um singleton é que o shared usa uma única instancia por escolha. Ele escolhe pegar um objeto qualquer e só instanciá-lo uma vez. Não importa se o objeto pode ser instanciado mais vezes, ele só o faz uma vez.
O singleton só cria uma unica instancia porque só uma é possivel. Mesmo que eu queira criar outra eu não vou conseguir. Não importa quem está usando o objecto , nem porque, o mecanismo de criação estão armadilhado para que apenas uma instancia seja possivel de ser criada.
Um objeto shared pode ser descartado, e um outro da mesma classe colocado no seu lugar. Um objeto singleton não pode ser descartado. Por tudo que vc faça sempre apenas será possivel criar apenas uma instancia.
Como já disse, não é possivel usar um motor de injeção para criar um singleton, porque o singleton é feito proibindo toda e qualquer inversão de controle relativa à criação do objeto da classe. O mecanismo de controle da criação tem que ser tal que em qualquer uso da classe apenas uma instância seja criada. Então, tem que funcionar assim, mesmo na ausência de um motor de DI.
Lembrem-se que o singleton é um padrão criacional.
@Singleton é uma aberração por estes motivos. Vc cria um session bean. Vc cria uma interface e uma implementação. A implementação não tem qualquer mecanismo que evite que mais do que um objeto seja criado. aliás, a especificação manda que tenha um construtor publico sem argumentos. Um construtor publico é a antitese do singleton.
O que @Singleton significa é : crie uma instancia desta classe e mantenha-a criada. Sempre que alguem pedir por uma instancia desta classe retorne esta que vc mantem. É uma forma de cache que só permite guardar um objeto de cada classe. (Isto é o padrão Shared Object). O @Singleton não evitará que mais um objeto seja criado. É simples pq. Se o contrutor é publico e sem argumentos nada me impede de requisitar um novo objeto dando um new.
Mais uma vez : singleton não significa “mantenha uma unica instancia” significa “não permita que mais do que uma seja criada”. Este não permita é uma condição forte. Não permita sob nenhuma condição. E é por isso que ele é um padrão criacional.
Algumas pessoas falam que reflection estraga o padrão singleton. Tente usar reflection para criar uma instancia de Runtime ou Desktop.
Algumas pessoa falam que serializable estraga o padrão singleton. Ora, se um objeto é serializavel e pode ser enviado a outra máquina ou para o disco, é obvio que este objeto está sendo partilhado por estes diversos lugares. Ele é , na realidade um shared object.Chamar-lhe singleton nao o torna singleton. Experimente usar esses truques para instanciar Runtime ou desktop.
Singletons verdadeiros são invioláveis. Caso contrário não são singletons, mesmo que sejam chamados de singletons em alguma documentação.
A taxionomia dos padrões é bem clara e acontece ao nivel abstrato e das responsabilidades , nunca da implementação. Julgar se o objeto X é singleton ou não depende de várias coisas. Se alguma delas falha, o objeto não é um singleton.
Mecanismos de DI não podem tornar uma classe singleton. Não é possivel. Simplesmente não é. Eles tornam shared facilmente,mas não singleton.
O adjetivo Singleton usado em @Singleton e na documentação de motores de DI é um erro historico. É uma má interpretação do padrão singleton (na realidade é um truque de publicidade para fazer o motor melhor do que é prometendo que ele gerencia singletons. O que é mentira) . mas o fato de ser usado assim, chamado assim , não significa que o padrão singleton está sendo usado. Não está. O @Singleton é a perpetuação do smell de mal-usar o padrão singleton. Ele é tão aberrante quanto usar singleton para fazer o acesso global.
P
peczenyj
Em que condições os singletons são interessantes?
Imagino que em ambientes com restrições de memória e uma unica instância de jvm eu posso querer usar singletons, mas por economia. Ou não?
G
garcia-jj
Muito interessante o nível da discução.
Vivendo e aprendendo. Agora o Taborda abriu uma questão interessante sobre a confusão entre shared-objects e singletons. Eu mesmo tinha essa confusão na minha mente de que singleton é apenas para ter uma instância única.
A diferença entre um shared e um singleton é que o shared usa uma única instancia por escolha. Ele escolhe pegar um objeto qualquer e só instanciá-lo uma vez. Não importa se o objeto pode ser instanciado mais vezes, ele só o faz uma vez.
O singleton só cria uma unica instancia porque só uma é possivel. Mesmo que eu queira criar outra eu não vou conseguir. Não importa quem está usando o objecto , nem porque, o mecanismo de criação estão armadilhado para que apenas uma instancia seja possivel de ser criada.
S
sergiotaborda
peczenyj:
Em que condições os singletons são interessantes?
Imagino que em ambientes com restrições de memória e uma unica instância de jvm eu posso querer usar singletons, mas por economia. Ou não?
singletons não são trade-offs. Vc não escolhe fazer uma classe singleton ou não singleton. O uso do padrão Singleton é uma necessidade, não uma escolha.
O exemplo claro é Runtime e Desktop. Quantos runtimes existem em um programa ? 1. Apenas 1. Nunca mais que 1. Portanto esse cara tem ser singleton. Não faz sentido lógico que exista mais do que um objeto runtime. É decisão abstrata de SoC. Não é uma decisao de implementação. Não é um trade-off.
Desktop. quantos desktop podem existir num OS ? 0 ou 1. Nunca mais que 1. Se o OS não suporta o conceito é zero. Dekstop.getDesktop dá exception. Se o OS suporta, o objeto é criado e devolvido.
outro exemplo : SystemTray. Quantos systemTrays podem existir. 1. apenas 1.
singletons não são “interessantes” são necessários e obrigatórios. Se para uma classe X qq vc poder implementar de outra forma que não um singleton, então essa classe não é um singleton e vc não deve usar o padrão Singleton. Tão simples assim.
P
Paulo_Silveira
Vou te ensinar um truque legal, creio entao que voce nao conheca:
Constructor<Desktop>c=ReflectionFactory.getReflectionFactory().newConstructorForSerialization(Desktop.class,Object.class.getDeclaredConstructor(newClass[0]));Desktopd1=(Desktop)c.newInstance();Desktopd2=Desktop.getDesktop();if(d1!=d2){
System.out.println("O que o Taborda disse que não da para fazer, da sim para fazer e é bem facil.");}else{
System.out.println("O que o Taborda disse que não da para fazer, realmente nao da.");}
Aprendi enquanto estudava os commits do meu irmao no XStream ha alguns anos atras. Vale a pena voce dar uma estudada tambem, da para setar campos final depois, etc etc. Fica ai a dica para voce.
Como eu já disse anteriormente, por magia negra + reflection da pra fazer (e em qualquer VM, cada uma no seu modo).
Sergio, como ficamos entao com sua implementacao de Singleton? Ela é invalida tambem? Nao existem singletons entao? Nem factories? ja que da tudo para burlar com esses truques? Seria o Desktop uma implementacao mal feita de singleton, ja que acabo de mostrar que posso instancia-lo a vontade?
C
ccaneta
O Padrão Singleton pode ser modificado para que exista “um número máximo de instâncias de uma classe”, caracterizando assim um pool de objetos, flexibilizando seu emprego nas situações em que não é necessário garantir uma instância única, mas onde deve ser limitada a quantidade total de objetos e recursos utilizados.
S
sergiotaborda
Paulo Silveira:
sergiotaborda:
Algumas pessoas falam que reflection estraga o padrão singleton. Tente usar reflection para criar uma instancia de Runtime ou Desktop.
Vou te ensinar um truque legal (…)
javadoc de sun.reflect.ReflectionFactory:
The master factory for all reflective objects, both those in java.lang.reflect (Fields, Methods, Constructors) as well as their delegates (FieldAccessors, MethodAccessors, ConstructorAccessors).
The methods in this class are extremely unsafe and can cause subversion of both the language and the verifier. For this reason, they are all instance methods, and access to the constructor of this factory is guarded by a security check, in similar style to sun.misc.Unsafe .
Isso não é reflection:
Não está no pacote java.lang nem java.lang.reflect.
Não é portável. Só funciona na jvm da sun.
Vc já deveria saber a esta hora que não se devem usar classes do pacote sun.*
Essa é uma operação nao segura.
Essa resposta é inválida. Não responde ao desafio. O desafio era usar reflection. Vc não usou reflection. Use algo no pacote java.* e voltamos ao assunto.
T
Thiago_Senna
Essas coisas do tipo, patterns, smell e tantas outras coisas são um mal danado pra essa comunidade. O pior é que acaba enjaulando alguns - se você ousa ser um pouco criativo e fazer uma alteração/experimento em alguma idéia ou pattern para ganhar produtividade já vem neguinho apontar o dedo dizendo que você não sabe OO e tem que estudar mais. Aff… isso é exagero.
Na maioria dos casos pattern só adiciona complexidade e burocracia. Faz do jeito mais prático e pronto
S
sergiotaborda
ccaneta:
O Padrão Singleton pode ser modificado para que exista “um número máximo de instâncias de uma classe”, caracterizando assim um pool de objetos,
Não. Isso é conceptualmente errado. Singleton não um master-pattern de onde derivam os outros.
Se vc quer poder escolher quantas instancias ha , isso não é um singleton. nem um shared object, é ,como vc falou , um pool. mais concretamente ObjectPool.
Não existe isso de “modificar padrões”.
C
ccaneta
Thiago Senna:
Essas coisas do tipo, patterns, smell e tantas outras coisas são um mal danado pra essa comunidade. O pior é que acaba enjaulando alguns - se você ousa ser um pouco criativo e fazer uma alteração/experimento em alguma idéia ou pattern para ganhar produtividade já vem neguinho apontar o dedo dizendo que você não sabe OO e tem que estudar mais. Aff… isso é exagero.
Na maioria dos casos pattern só adiciona complexidade e burocracia. Faz do jeito mais prático e pronto ;)
Essas coisas do tipo, patterns, smell e tantas outras coisas são um mal danado pra essa comunidade. O pior é que acaba enjaulando alguns - se você ousa ser um pouco criativo e fazer uma alteração/experimento em alguma idéia ou pattern para ganhar produtividade já vem neguinho apontar o dedo dizendo que você não sabe OO e tem que estudar mais. Aff… isso é exagero.
Na maioria dos casos pattern só adiciona complexidade e burocracia. Faz do jeito mais prático e pronto ;)
Mais prático não significa mais desleixado. Mais simples, não significa mais fácil.
Se vc não quer usar o padrão , blz. Mas o padrão é aceite universalmente. se vc tem uma ideia melhor, vc tem que defendê-la corretamente. apenas invocar criatividade não vale. A razão é que quem faz gamb tb invoca a criatividade.
Tem gente que não enxerga um palmo à frente do nariz, é verdade. Mas esses não são bons designers. SE o cara não quer que vc mude algo, ele tb tem que dar argumentos.
Pattern não adiciona burocracia. Isso é uma falácia.
O que adiciona burocracia é o mau uso dos patterns. más práticas OO, mau entendimento dos principios, etc…
não culpe os patterns pela burrice dos designers ou pseudo-designers.
X
xdraculax
Padrões são boms sim, e deviam ser até mais difundidos. Evitaria muito ré-trabalho e ré-dor-de-cabeça.
O difícil é enteldê-los na essência a ponto de utilizá-los com consistência.
Singleton é ruin depende de quem usa.
Eu peguei um projeto Mobile onde o tudo era Singleton - para diminuir o consumo de recursos (tenha paciência).
Porém em alguns locais uso singleton e não tenho problema nenhum.
Mas também não concordo no “Desenvolvimento Orientado a Padrões”, onde sem saber se é necessário, utilizar logo o padrão de cara.
Lendo o livro Refatoração Para Padrões, é possível ver que a melhor forma de aplicar um padrão é quando o problem já existe, e você usa o padrão para resolver - e não criar o problema para resolver com um padrão.
P
Paulo_Silveira
sergiotaborda:
ccaneta:
O Padrão Singleton pode ser modificado para que exista “um número máximo de instâncias de uma classe”, caracterizando assim um pool de objetos,
Não. Isso é conceptualmente errado. Singleton não um master-pattern de onde derivam os outros.
Se vc quer poder escolher quantas instancias ha , isso não é um singleton. nem um shared object, é ,como vc falou , um pool. mais concretamente ObjectPool.
Não existe isso de “modificar padrões”.
“i Permits a variable number of instances. The pattern makes it easy to change your mind and allow more than one instance of the Singleton class. Moreover, you can use the same approach to control the number of insntaces that the application uses.[/i]”
Erich Gamma at Al, Design Patterns, pagina 128. Leitura recomendada!
É bom sustentarmos nossas afirmações com referencias, para que a discussão não se torne meramente opinativa!
X
xdraculax
Porque?
Eu confio na minha capacidade e modifico se necessário.
A final de contas, padrões não são perfeitos.
Vamos virar a cabeça pros lados e enxergar possibilidades e não usar sempre os pré-moldados ein?
E padrões adicionam complexidade sim, o prório GoF diz isso.
Você pode até conhecer os padões, mas e seus programadores?
E os coitados dos estagiários? Não fazem parte da sua equipe? Ou você é uma EUquipe?
P
Paulo_Silveira
sergiotaborda:
Pattern não adiciona burocracia. Isso é uma falácia.
…
padrões não adicionam complexidade
Poxa! Outra negação do que esta no livro seminal! O xdraculax está coberto de razão:
Often they (design patterns) achieve flexibility and variability by introducing additional levels of indirection, and then can complicate a design
Design Patterns, página 31!!!
Voce teria alguma referencia sobre patterns nao adicionarem complexidade? Acho que precisamos de mais referencias para isso aqui nao virar conversa de bar, onde so ha opinioes.
S
sergiotaborda
Paulo Silveira:
“i Permits a variable number of instances. The pattern makes it easy to change your mind and allow more than one instance of the Singleton class. Moreover, you can use the same approach to control the number of insntaces that the application uses.[/i]”
Erich Gamma at Al, Design Patterns, pagina 128. Leitura recomendada!
Perai, vc está citando e recomendando o mesmo livro que este topico começa por dizer que está desatualizado ?! :shock:
É bom sustentarmos nossas afirmações com referencias, para que a discussão não se torne meramente opinativa!
Sim, mas com referencias atuais.
S
sergiotaborda
Vamos fazer assim então:
Quem acha que padrões é ruim , é coisa do demo, que programar com padrões é pior que programar ad doc, que saber padrões é desperdicio de tempo e de espaço, por favor pare de usar padrões. Esqueça que existem. Mas deixe o seu contacto no codigo para que o programador que vem a seguir poder procurar vc para explicações.
Falar que padrões é ruim é muito fácil. porque não dizer também que os principios de OO são ruins ? Afinal eles são mal usados o tempo todo. Os mesmos argumentos podem ser usados com qualquer coisa , prática ou teorica , que as massas de programador usam mal.
O ponto é muito simples : quem usa mal não pode dizer que o problema é do padrão/tecnica/prática/etc… o problema é do programador/equipe que desenhou a porcaria do código totalmente sem noção.
P
Paulo_Silveira
Um viva ao consenso
T
Thiago_Senna
sergiotaborda:
Perai, vc está citando e recomendando o mesmo livro que este topico começa por dizer que está desatualizado ?! :shock:
…
Sim, mas com referencias atuais.
Oras, mas se os conceitos dos patterns são inalteráveis, para que atualizar então?
V
ViniGodoy
Só um comentário:
Essa frase está dizendo o que é possível: The pattern makes it easy to change your mind and allow more than one instance of the Singleton class. Moreover, you can use the same approach to control the number of insntaces that the application uses."
Mas em momento nenhum ela afirma que o resultado disso ainda é um singleton. Ou afirma?
P
Paulo_Silveira
ViniGodoy:
Só um comentário:
Essa frase está dizendo o que é possível: The pattern makes it easy to change your mind and allow more than one instance of the Singleton class. Moreover, you can use the same approach to control the number of insntaces that the application uses."
Mas em momento nenhum ela afirma que o resultado disso ainda é um singleton. Ou afirma?
Tem razao!. Nao afirma, e nao é mesmo. É um shared object ou pool, dependendo. Ou ainda um factory method. Mas mostra que o pattern pode ir sofrendo alteracoes (rra essa a questao)
V
ViniGodoy
Engraçado, a definição original do pattern singleton diz: Ensure a class only has one instance, and provide a global point of access to it. [P. 127, edição de 1996 americana]
De cara, na definição, ele não fala em permitir a criação de uma única instância, embora seja um pattern criacional, mas em ter apenas uma única instância por vez. Ou seja, o singleton poderia ser destruido e recriado e, embora isso seja trabalhoso em Java, seria plenamente possível em linguagens não gerenciadas.
E notem que na definição original também cita o fato do singleton ser um “Global access point”. Entretanto, vale frisar que ser um Global access point não é o mesmo que dizer que o singleton deveria ser uma “variável global”.
Realmente, o livro deveria ser revisado porque a definição como está, leva ao erro.
V
ViniGodoy
Quanto ao uso de reflection. Vale lembrar que reflexão não é OO. É um paradigma à parte. E com reflexão, abrimos mão de segurança.
Se formos contar a reflexão, nenhum padrão é realmente seguro, já que podemos ler atributos ou invocar métodos privados, o que viola um dos princípios básicos da OO em si, o do encapsulamento.
O singleton quebra, o shared object quebra (podemos via reflection trocar o objeto shared por outro objeto), qualquer coisa quebra.
M
mochuara
Achei curioso culparem singleton por não se dar bem com testes quando o real problema com testes é a existencia de estado mutavel e acessado por diferentes threads, basicamente a idéia de um objeto que é encapsular estado mutavel. Entretanto não vejo ninguém sugerir OO como prática não-recomendada (quer dizer, Rich Rickey, criador da linguagem clojure sugeriu que this is not about message passing).
Acho que tem muito a ver com o topico ja que dizem que Clojure é segunda edição da linguagem Java.
P
Paulo_Silveira
Oi Mochuara. Nao é culpa só do estado mutavel nao (que voce tem razao, tambem dificulta):
Como voce faz unit test disso aqui sem enfiar a mao no classloader?
Como Sergio falou la atras, melhor é receber EnviadorDeEmail pelo construtor, ou melhor ainda, sua interface. Ai sim fica bem testavel.
G
gomesrod
Há algum tempo, fiz uma pergunta sobre Singleton neste tópico (aliás, o primeiro tópico que abri no fórum). Também gerou uma discussão bastante inflamada mas cheia de informações úteis.
Entre outras conclusões, cheguei a uma regrinha para decidir se o Singleton é a escolha certa para cada situação ou não:
-> O conceito deste objeto dentro do domínio exige que ele seja uma instância única? Ou seja, obrigatoriamente só existe UM no mundo que está sendo modelado? Ex. os já citados Desktop e Runtime.
-> Ou a existência de uma única instância é desejável (por praticidade de programação ou por economia de recursos da máquina), mas não intrínseca ao conceito deste objeto/classe? Ex. fábrica de conexões com BD, cache de objetos usados frequentemente dentro da aplicação.
Só se a resposta à primeira pergunta for sim, então o Singleton será a solução para este caso. Se cair no caso da segunda pergunta (algumas vezes a diferença é sutil) devemos chamar de algum outro nome, como Shared Object.
Curiosamente, não conheço casos em que algum objeto do modelo de negócio possa ser classificado como Singleton. Me parece que o padrão se aplica mais a componentes da API ou de infraestrutura.
S
sergiotaborda
Oi Mochuara. Nao é culpa só do estado mutavel nao (que voce tem razao, tambem dificulta):
Como voce faz unit test disso aqui sem enfiar a mao no classloader?
Como Sergio falou la atras, melhor é receber EnviadorDeEmail pelo construtor, ou melhor ainda, sua interface. Ai sim fica bem testavel.
Mas isso sempre foi assim. O facto de uma gambiarradores desenharem como no exemplo atesta a incompetencia deles, não de OO, de padrões ou principios. Injeção de Dependência sempre existiu e sempre foi usada. (Esse é outro assunto que daria pano para mangas : DI vs Motor de DI) Injeção de Dependência e inversão de controle são coisas básicas de OO. Se vc as seguir vc vai cair em duas coisas:
Seu codigo será mais facilmente testável.
Seu codigo começará a usar padrões (mesmo que vc não faça isso conscientemente ou sequer saiba o que são)
Testes são um segundo cliente. Eles força a desenhar o sistema para dois clientes. Isso ajuda imenso no design pq vc vê onde as coisas têm que está amarráveis não não amarradas. O verdadeiro anti-pattern aqui seria ServiceLocator não o singleton.
O serviceLocator foi abusado , como muitos outros padrões , ao ponto de criar um anti-padrão.
Agora um novo anti-padrão surge. O abuso de DI e de motores de DI. Já que é tão flexivel então não se fixe nada. Deixa tudo desamarrado. Isto causa o efeito contrário. O caos é tanto que vc identifica cadeias de injeção de 5, 7 niveis. Isso tb é um abuso.
O joshua bloch tinha uma máxima para desenhar frameworks que acho que se aplica muito bem a qq API. Vc precisa ter 3 aplicações para ela. três cenários diferentes. Só assim vc não corre o risco de incluir coisas amarradas e ajuda a ver onde está a parte fixa. O software é um destes cenários. Os testes são outros. O terceiro tem que vir de um cenário hipotético. O principio do Não faça se não precisa, é mal interpretado. Porque mesmo que vc não implemente o terceiro cenário agora, o design compativel com os 3 cenários será mais simples de evoluir. O problema acontece quando vc começa a implmentar o cenário hipotético e esquece dos testes e do software… Enfim, o ponto é que testes naturalmente tornam o codigo melhor por causa deste principio dos 3 cenários.
A mensagem que eu queria deixar clara é que : se vc programar utilizando Patterns, como sendo ferramentas , vc tb terá um codigo mais limpo e menos acoplado. Um codigo padronizado (com patterns) é naturalmente testável porque ele já segue os principios de OO que tornam isso possivel “out-of-the-box”
P
Paulo_Silveira
sergiotaborda:
Testes são um segundo cliente. Eles força a desenhar o sistema para dois clientes. Isso ajuda imenso no design pq vc vê onde as coisas têm que está amarráveis não não amarradas. O verdadeiro anti-pattern aqui seria ServiceLocator não o singleton.
O serviceLocator foi abusado , como muitos outros padrões , ao ponto de criar um anti-padrão.
Mochuara, acho que o Sergio conseguiu excplicar bem melhor. Novamente concordo 100%. Quem usa TDD nunca mais escreve esse tipo de codigo com singleton, pois de cara percebe que nao vai conseguir testar. Esse cheiro de service locator realmente é a parte prejudicial no uso do singleton.
S
sergiotaborda
gomesrod:
Há algum tempo, fiz uma pergunta sobre Singleton neste tópico (aliás, o primeiro tópico que abri no fórum). Também gerou uma discussão bastante inflamada mas cheia de informações úteis.
Entre outras conclusões, cheguei a uma regrinha para decidir se o Singleton é a escolha certa para cada situação ou não:
-> O conceito deste objeto dentro do domínio exige que ele seja uma instância única? Ou seja, obrigatoriamente só existe UM no mundo que está sendo modelado? Ex. os já citados Desktop e Runtime.
-> Ou a existência de uma única instância é desejável (por praticidade de programação ou por economia de recursos da máquina), mas não intrínseca ao conceito deste objeto/classe? Ex. fábrica de conexões com BD, cache de objetos usados frequentemente dentro da aplicação.
Só se a resposta à primeira pergunta for sim, então o Singleton será a solução para este caso. Se cair no caso da segunda pergunta (algumas vezes a diferença é sutil) devemos chamar de algum outro nome, como Shared Object.
Curiosamente, não conheço casos em que algum objeto do modelo de negócio possa ser classificado como Singleton. Me parece que o padrão se aplica mais a componentes da API ou de infraestrutura.
Parabéns!! É exactamente isso. Palmas!!
M
mochuara
Paulo Silveira:
sergiotaborda:
Testes são um segundo cliente. Eles força a desenhar o sistema para dois clientes. Isso ajuda imenso no design pq vc vê onde as coisas têm que está amarráveis não não amarradas. O verdadeiro anti-pattern aqui seria ServiceLocator não o singleton.
O serviceLocator foi abusado , como muitos outros padrões , ao ponto de criar um anti-padrão.
Mochuara, acho que o Sergio conseguiu excplicar bem melhor. Novamente concordo 100%. Quem usa TDD nunca mais escreve esse tipo de codigo com singleton, pois de cara percebe que nao vai conseguir testar. Esse cheiro de service locator realmente é a parte prejudicial no uso do singleton.
Como havia dito anteriormente, tudo se resume a estado mutavel. O conceito do Singleton em si não traz problema de testabilidade em linguagens funcionais. O problema é quem usa Java não vai conseguir mockar um singleton. E mocks são fundamentais para testabilidade em sistemas OO, ou seja, que mantem estado mutavel.
MAs mesmo em Java Singletons podem ser uteis em partes que vc não precisa testar. A classe Application do Swing por exemplo é um singleton assim como o ServiceLocator poderia ser. O fato deles não serem testaveis não deveria ser um problema ja que não pertencem ao negócio que onde fica o código critico que precisa ser testado.
C
ccaneta
sergiotaborda:
ccaneta:
O Padrão Singleton pode ser modificado para que exista “um número máximo de instâncias de uma classe”, caracterizando assim um pool de objetos,
Não. Isso é conceptualmente errado. Singleton não um master-pattern de onde derivam os outros.
Se vc quer poder escolher quantas instancias ha , isso não é um singleton. nem um shared object, é ,como vc falou , um pool. mais concretamente ObjectPool.
Não existe isso de “modificar padrões”.
Em que situação ocorrem quando vários subsistemas utilizam o mesmo arquivo de configuração ?
Em Java o que é lazy instantiation para o uso de Singleton ?, Java suporta clonagem de Objetos ?
S
sergiotaborda
ccaneta:
sergiotaborda:
ccaneta:
O Padrão Singleton pode ser modificado para que exista “um número máximo de instâncias de uma classe”, caracterizando assim um pool de objetos,
Não. Isso é conceptualmente errado. Singleton não um master-pattern de onde derivam os outros.
Se vc quer poder escolher quantas instancias ha , isso não é um singleton. nem um shared object, é ,como vc falou , um pool. mais concretamente ObjectPool.
Não existe isso de “modificar padrões”.
Em que situação ocorrem quando vários subsistemas utilizam o mesmo arquivo de configuração ?
Use Registry. Inspire-se em System.getProperties();
É uma inutilidade. A maior parte das vezes singleton não precisa ser lazy.
Até agora não encontrei um exemplo em que precise ser lazy.
sim. Veja Object.clone() e Clonable.
Esta eu não entendi a relação com o assunto.
C
ccaneta
Java suporta clonagem de Objetos ?
sim. Veja Object.clone() e Clonable.
Esta eu não entendi a relação com o assunto.
Fala Sergiãooo !!!
Como o Java suporta a clonagem de objetos, devemos declarar a classe como final, para impedir que suas subclasses possam implementar a interface Cloneable, possibilitando a duplicação de objetos pelo método “clone”, o que romperia com as obrigações deste padrão.Caso a classe Singleton seja uma subclasse de outra que suporte a clonagem, então o método “clone” deve ser sobreposto por outro que apenas lance a exceção CloneNotSupportedException, indicando a impossibilidade da realização desta operação.
[size=24]; )[/size]
G
guerios
Paulo Silveira:
sergiotaborda:
Testes são um segundo cliente. Eles força a desenhar o sistema para dois clientes. Isso ajuda imenso no design pq vc vê onde as coisas têm que está amarráveis não não amarradas. O verdadeiro anti-pattern aqui seria ServiceLocator não o singleton.
O serviceLocator foi abusado , como muitos outros padrões , ao ponto de criar um anti-padrão.
Mochuara, acho que o Sergio conseguiu excplicar bem melhor. Novamente concordo 100%. Quem usa TDD nunca mais escreve esse tipo de codigo com singleton, pois de cara percebe que nao vai conseguir testar. Esse cheiro de service locator realmente é a parte prejudicial no uso do singleton.
Eu particularmente assino embaixo de tudo que o taborda falou, porém qual é o foco do tópico ? É singleton ? DI ? não ! O foco é a revisão dos padrões
Portanto os padrões devem ser revisados? Sim ou não ? Quais devem ? Devem continuar Existindo sim ou não?
Quem falou que TDD é o correto? Desde quando TDD vale pra tudo? Entendo que TDD aqui é o Test Driven Development.
IMO, posso indicar que depois de muitos e muitos projetos de grande porte, você vai perceber que padrões são sim necessários, quais padrões? O arquiteto vai decidir por projeto e por situação junto com os requisitos do sistema.
Nunca existirá uma solução única para um problema, sempre existirão no mínimo duas, a minha solução e a outra solução possível. Por que existem vários tipos de vassoura se todas varrem o chão?
A TI tem e muito que se padronizar, seja em linguagem, em Design Patterns, em processos no que for, tudo hoje em dia é muito manual, artesanal.
Você produziria um carro do zero sempre? Ou vai usar projetos padrões? Claro que vai usar padrões? Por que?
Produzir código pra depois refatorar ? Tá então eu vou criar um motor 1.0 novo e depois de pronto eu faço ele de novo? É isso ?
Temos sim é que repensar a nossa indústria como indústria de serviços e parar de ficar discutindo se acessar um Singleton via reflection vai estourar a segurança !
Quem disse que tudo que tá na VM tá certo? Quem falou que os design patterns estão sempre certos? Alguém foi lá e amarrou a mão do cidadão?
A única coisa que sempre será constante em um projeto seja ele qual for, em qual linguagem for e pra qual cliente for, é que ele deverá ter um inicio um meio e um fim e que faça o que o cliente quer, porém isso não justifica escrever código 'porco" nem impossível de manter, o mínimo de qualidade é pedida.
O que é qualidade em desenvolvimento de software? Como medimos a qualidade de um código ? Medimos se ele usa padrão? Se implantou o padrão certinho ?
Isso sim é a questão, singleton, shared, flyweight, proxy, factory o padrão que for, não importa, o que importa é fazer um código:
Ou alguém já ouviu dizer de bilbioteca de modelagem ? Ou padrões de modelo ? O Objeto pessoa tem que ter CPF/CNPJ e nome? Não ! Cada caso é um caso.
Aonde devemos padronizar ? O que devemos padronizar? Quando padronizaremos ?
Quando teremos qualidade em SW ?
Fica ai algumas questões para os ilustres colegas da classe discutirem se desejarem
O cara não aprende java pelos padrões !!! Em linguagem nenhuma, linguagem aprende-se pela linguagem, depois você usa ela da melhor forma.
JEE Design Patterns foi a melhor forma na época encontrada por uns malucos chamados de GOF e agora com Seam e Ruby por ai com JSF 2 , Ajax e Portals e etc ?
Qual é o padrão ? :twisted: :twisted: :evil: :evil: :evil: :evil: :evil:
L
Leonardo3001
Fórum de tecnologia não tem foco, em qualquer uma que você vá. É mais interessante pela conversa que vai levando do que pelo foco.
Eu concordo com o Sérgio Taborda com relação a Singletons, que só deveria ser usado quando realmente tal objeto só existe uma única vez no domínio em questão. Tinha até o papo furado de que, com reflection, poderia-se instanciar mais de um objeto. Mas acredito que, com objetos estritamente únicos (daqueles do tipo Modem, Runtime…), uma segunda instanciação acidental postergaria erros de sincronia mais para frente. E o singleton seria uma necessidade.
No Java, existe essa confusão entre injeção de dependências e container de injeção de dependências, como se as duas coisas precisassem andar juntas. É até possível criar uma classe onde seria feita toda a instanciação de objetos, onde todo mundo obteria instâncias, deixando de lado Spring ou Guice. Eu, que estava estudando Scala, encontrei até um artigo que mostra como fazer DI usando recursos dessa linguagem. E um outro artigo que mostra o porquê de Ruby não precisar de IoC.
Deveria ser revisado. Mas acho complicado saber quais deveriam ser eliminados. Gostaria que patterns fosse algo transitório, que fosse de serventia enquanto as linguagens OO não a suportassem nativamente. Alguns patterns já existem soluções pela própria linguagem, exemplo:
Flyweight: strings em Java são assim, Integer de valores pequenos também são, Symbol em Ruby também.
Template Method: pode ser implementado via Closures em linguagens OO que a suporta
State: pode ser substituído por coroutine em Python, ou por Fibers em Ruby 1.9
Mas ainda assim não é universal e plenamente difundido, fazendo com que os patterns atuais sejam ainda a melhor opção.
TDD é bom porque ajuda a raciocinar em cima do problema antes de sair criando código a esmo. Muita gente não faz isso (e não se dá conta), preferindo olhar uma modelagem de banco e sair criando telas e objetos burros; e rezando para que o cliente olhe com bons olhos o produto final.
Qualquer outra disciplina que faça o programador pensar o problema a ser solucionado ajuda. Só não vale descartar o TDD e não ter outro pra substituir.
Minha visão de projeto de grande porte: qualquer projeto mal feito onde não houve uma alma bondosa que mantivesse a complexidade do software ao mínimo. Pra compensar o inchaço do projeto, é empurrado o engodo da disciplina militar, que faz com que nenhum movimento de progresso seja realizado.
Padrões não está na mão do arquiteto, qualquer desenvolvedor deve usar se for necessário, sem pedir benção de ninguém.
Sim, existem várias soluções. Mas discordo do “minha solução e a outra”, pois posso muito bem estar errado e não ter nada nas mãos.
Pattern = padrões que se repetem
Standard = padrões que garantem uniformidade
Brasileiro acha que padrão de projeto é que-nem norma da ABNT. Não é!
Padronização (de “standard”) é engodo. Desenvolvimento de software é artesanal, e nada vai acontecer que vá mudar isso. Cada projeto é único e tem necessidades específicas, não dá pra definir normas onde todo mundo precisa obedecer.
E se eu quisesse fazer um motor que nunca tenha existido? Tipo: um motor que seja movido a eletricidade, tenha independência de uma semana de recarga, e que vá de 0 a 100 em dois segundos. Acredite, não dá pra fazer certo da primeira vez. Precisará da construção de alguns motores antes de chegar ao ideal.
Não! Refatorar não implica processo de desenvolvimento em cascata.
L
luan03
tnaires:
Muito interessante a entrevista.
Será que alguém poderia indicar alguma situação onde Singleton ainda seria útil nos dias de hoje?
Em um projeto onde se tem o Abstract Facory, criamos uma classe Singleton para gerenciar a Connection Manager.
S
sergiotaborda
ccaneta:
Java suporta clonagem de Objetos ?
sim. Veja Object.clone() e Clonable.
Esta eu não entendi a relação com o assunto.
Fala Sergiãooo !!!
Como o Java suporta a clonagem de objetos, devemos declarar a classe como final, para impedir que suas subclasses possam implementar a interface Cloneable, possibilitando a duplicação de objetos pelo método “clone”, o que romperia com as obrigações deste padrão.Caso a classe Singleton seja uma subclasse de outra que suporte a clonagem, então o método “clone” deve ser sobreposto por outro que apenas lance a exceção CloneNotSupportedException, indicando a impossibilidade da realização desta operação.
Um singleton não deve implementar clonable da mesma forma que não deve implementar serializable ou ser extensivel.
No ambito do 'programe para herança ou proiba-a" em singleton não ha muita conversa : proiba-a.
Um singleton já tem construtor privado o que mata a herança sem precisar ser declarado final, mas mesmo assim é uma boa ideia.
Por outro lado singleton não deve herdar de ninguem (só directamente de objet, claro). Porque senão vários paradoxos podem surgir. Um singleton verdadeiro é um cara standalone, um higthlander do universo. Só pode haver um. Além de garantir isso na instanciação, é preciso matar formas artificiais de instancialização como clone , serialização e herança. Tb por essa razão não faz sentido definir um singleton através de uma interface , porque ao definir com interface estamos dizendo que várias implementações são possiveis. Portanto não garantimos que elas forcem instâncias unicas, logo, não estamos seguindo o padrão singleton.
Um singleton deve ser concreto (defindo por uma classe, não uma interface ou classe abstrata), deve ter construtor privado, ser final, não clonável e não serializável.
V
ViniGodoy
sergiotaborda:
É uma inutilidade. A maior parte das vezes singleton não precisa ser lazy.
Até agora não encontrei um exemplo em que precise ser lazy.
Concordo. Um singleton “não lazy” é mais simples e mais seguro. E na maior parte das vezes, criar uma única instância de uma classe não será problema nem de performance e nem de memória (se for um problema de memória, é melhor nem usar singleton, já que uma vez criado ele ficará lá para todo o sempre).
Depois, é bom lembrar que a VM só irá criar seu Singleton assim que for usado a primeira vez, pois será nesse momento em que a classe será carregada. Ou seja, o lazy loading já existe.
L
Luca
Olá
Engraçado, com tanto pattern por ái sendo abusado, estuprado e mal usado, só o Singleton levou pancada aqui. Gente, estão esquecendo de muitos tais como:
Facade - um dos reis do abuso. Conheci um cara que adorava facade e usava para tudo, até para escovar os dentes
Service Locator - este é dos bons. Indispensável no uso dos EJBs 1.x e 2.x. A gente usava JNDI até para ler aquele arquivinho que estava ali do lado
E sem falar dos BOLOVOs.
Quando critiquei o mau uso dos patterns juro que não pensei somente no livro motivo deste tópico. Quiz chamar a atenção que tem alguns caras por aí mais preocupados em programar por patterns para imprerssionar os colegas do que em resolver o principal problema. Ainda acho que primeiro se deve tentar resolver o problema e caso se reconheça algum pattern ou algum caso de reuso de código, uma refatoradinha básica não dói nada. A tal revisão de código é uma boa prática para reconhecer isto e ajudar programadores novos. Muito melhor do que arrotar arrogância tentando provar que sabe mais e que está sempre 100% certo.
E aí concordo com quem disse que em Ruby/Rails este mau hábito ainda não pegou.
KISS… para todos, inclusive os 100% certo…
[]s
Luca
M
mochuara
Não ha necessidade de uma segunda edicao do livro de patterns. Patterns continuam sendo um sinal que sua linguagem não possui as abstracões necessarias para resolver seu problema. Patterns como alinguagem Java não mudaram nada de la pra ca.
E
eduveks
Sinceramente eu nunca liguei para patterns, pois acho que faço um código bem estruturado, e vejo patterns um pouco como dar nome “cientifico” para as boas maneira de como os bons programadores estão resolvendo problemas.
E já aconteceu várias vezes de virem me dizer que há bacano você esta usando o pattern X, Y, Z, e eu nem imagina por completo desconhecimento do pattern, talvez até, nem o estivesse usando da maneira mais correta e nem resolvendo meu problema da maneira mais correta e prática. Penso que esta situação já deve ter acontecido com muitos, de alguém vir e dar um nome a maneira como tens o código.
Isto era o que eu pensava ante de ler muita coisa que o Sergio e o Luca disseram. Se bem que nunca pensei muito a fundo nos patterns, vou mais pelo caminho de resolver o problema da maneira mais simples e com melhor performance que consigo.
Com o que li cheguei a uma conclusão pessoal, e que espero não estar em erro.
Patterns são excelentes quando não atrapalham. Eu pelo menos tenho uma enorme pressão com tempo, tempo é dinheiro, e complicar esta fora de questão.
Agora o que resumidamente entendi do que Sergio falou, e nisto apesar do meu pouco conhecimento e tenho que concordar, é que o conhecimento dos patterns só vai ajudar, todo conhecimento é sempre bom.
Por exemplo se eu tenho um problema para resolver, e for pensar como montar as minhas classes, como vou montar a minha solução, e se houver um pattern que é indicado para esta solução e eu o conheço bem, logo se aplica-lo vou poupar imenso tempo pois conheço ele e sei como usa-lo e aplica-lo rápido e de forma eficaz.
Como já programo a muito tempo e várias linguagens, tenho talvez os meus próprios “patterns”, que para o problema X, Y, Z, vou resolver desta maneira ou daquela, que pela experiência já sei a forma prática e eficaz de resolver, e também isto pode ser chamado de vício, pois pode haver uma maneira mais fácil de resolver usando algum pattern que como desconheço vou passar a vida complicando algo que já foi simplificado.
Minha conclusão é que devo aprender mais sobre patterns para ver os meus maus vícios e como posso programar de forma mais eficaz.
Para quem esta começando, acho que isto é muita perfumaria logo de cara. Já não é fácil para muita gente começar, e levar com mais teoria sem compreender bem na prática, é impossível aprender bem.
Na prática é a conclusão que chego até aqui…
S
sergiotaborda
Luca:
Quando critiquei o mau uso dos patterns juro que não pensei somente no livro motivo deste tópico. Quiz chamar a atenção que tem alguns caras por aí mais preocupados em programar por patterns para imprerssionar os colegas do que em resolver o principal problema. Ainda acho que primeiro se deve tentar resolver o problema e caso se reconheça algum pattern ou algum caso de reuso de código, uma refatoradinha básica não dói nada.
Vc diz que não doi porque vc talvez nunca teve que lidar com isso. Refactorar para Produtor-Consumidor não é trivial se o cara fez um negocio macarrónico. Outro padrão que não é trivial é UnitOfWork. O problema nem sequer é com as classes ,aqui normalmente o problema é com deficiência de pontos de extensão onde mexer e usar os patterns.
Não ha problema algum em querer programar pattern driven , o problema é se a pessoa não sabe. É o mesmo tipo de problema de programar test driven, domain driven, etc… todos os 'driven" exigem que a pessoa saiba o que está fazendo. Só que pattern driven quando mal feito destroi todo o design do sistema tornando até o refacctoring caro , demorado ou simplesmente impossivel porque não dá nem para entender a gamb.
Resolver o problema ad hoc não é resolver o problema, é colocar um patch e adiar a solução. Ou seja, é gamb!
Se vc tem um problema vc já procura o pattern ou conjunto de patterns que irão ajudar. è por isso que os catálogos de patterns começam por explicar o problema que o padrão resolver. Espera-se que o designer saiba ligar os pontos. Se o cara não é designer a má escolha não é culpa do pattern ou do cara querer seguir patterns. É simples falta de cultura / experiencia.
O unico requisito para usar pattern é ele resolver o problema, portanto, sabendo o problema escolher o pattern é o proximo passo. O próximo passo não é inventar um codigo ad hoc que resolve. Por definição o pattern é melhor solução que algo inventado na hora.
Soluções ad doc são caras porque caem rápidamente na gamb e podem impedir o refactoring posterior.
O “simple” de KISS não significa desleixado, significa “não inventa”. Ao usar padrões vc não estará inventando nada e portanto está mantendo a coisa simples. Especialmente é simples do ponto de vista dos outros programadores que têm que ler e alterar seu codigo anos depois que vc o criou.
S
sergiotaborda
eduveks:
Sinceramente eu nunca liguei para patterns, pois acho que faço um código bem estruturado, e vejo patterns um pouco como dar nome “cientifico” para as boas maneira de como os bons programadores estão resolvendo problemas.
E já aconteceu várias vezes de virem me dizer que há bacano você esta usando o pattern X, Y, Z, e eu nem imagina por completo desconhecimento do pattern, talvez até, nem o estivesse usando da maneira mais correta e nem resolvendo meu problema da maneira mais correta e prática. Penso que esta situação já deve ter acontecido com muitos, de alguém vir e dar um nome a maneira como tens o código.
Padrões são uma linguagem. Quando o cara fala “padrão X” , duas palavras ou três, isso poupa um monte de conversa.
Exactamente! padrões poupam tempo, poupam erros, poupam refactoring (correções) e por consequencia poupam dinheiro.
Tão simples assim.
S
sergiotaborda
Esta é outra falácia comum. Padrões são agnosticos à linguagem. Padrões são usos abstratos dos principios de OO. São como cololários ou desses principios, ou regras empiricas já encontradas e testadas por muitos. Em catálogos de padrões vc tem a descrição e solução do problema do ponto de vista OO. Mas em cada linguagem vc usará os constructos dela para implementar o padrão. A implementação depende da linguagem, o padrão não.
Um exemplo simples disto é o singleton Em java é preciso desenhar a classe de um certo jeito. Em scala vc declara isso explicitamente trocando a definição de “class” por “object”. o for extendido do java é o mesmo tipo de sintax sugar mas para o padrão Iterator.
Padrões não são sinais de lacunas nas linguagens pois eles existem “antes” das linguagens.
Todo o JDBC é implementação de Bridge voltada a banco de dados.
Todo o JMS é implementação de Produtor-Consumidor
Todo o JMX é implementação de MetaObject
Todo o JNDI é implementação de Registry.
Todo a Servlet API é implementação de ChainOfResponsability (lembrar que HTTPServlet é uma especialização da API para HTTP. A API em si é mais generica)
Padrões são abstratos. Implementações são concretas e podem ser tão complexas ou simples quanto necessário.
O uso de padrões não é um defeito da linguagem.
É o uso do padrão , ou a implementação, que podem ser errados, não o padrão em si.
ServiceLocator não tem nada de errado. InicialContext do JNDI é um service locator. E containers DI usam service locator para integrar com JNDI. É o padrão natural nesta situação. Não ha outro jeito.
Mas se vc semeia acesso estático ao locator, ai sim vc está comentendo erro. E é isso que virou anti-pattern o uso de ServiceLcoator.getLocator(). se a implementação do service locator não fosse global, não haveria problema .
F
fredferrao
Eu acho que entendo o Luca quando ele diz que devemos focar no problema, na minha opnião eu gosto sim e acho bom usar padroes o problema é fazer POP programação orientada a padroes, vamos a uma suposição para melhor entendimento:
“Preciso fazer uma calculadora que some 2 numeros, bom acho que vou precisar de 2 variaveis inteiras, entao eu faço o metodo X que recebe as variaveis…” ou seja estou pensando em resolver o problema, e entao em certo ponto(conhecendo eu os padroes) “epa espera ae, aqui caberia o uso do padrao X, certo entao vou usar o padrao X para o codigo ficar mais estruturado”
Pronto, esta maneira eu considero ideal.
O outro ponto que acho que o Luca quis falar(posso estar enganado) é o seguinte.
“Preciso fazer uma calculadora, certo deixa eu consultar meu cookie book de padroes pra ver qual padrao serve pra fazer calculadora, humm X serve… nao Y…talves…” Ou seja eu NAO estou focando em resolver o probema em si, mas estou pensando apenas no padrao, ao inves de procurar resolver o problema que é somar 2 numeros eu estou ja querendo procurar um padrao, mas o cliente deseja é somar numeros.
[edit adicionando]
Ai fica a questao, devo ir resolvendo o problema e encontrando os padroes em tempo de desenvolvimento e assim estruturando o codigo, ou devo parar tudo e ja querer achar padroes sem ao menos me preocupar com o problema e como resolve-lo???
J
juliofsn
Aproveitando o tópico, alguém sabe como tá a tradução desse livro? Vale a pena, ou só a versão em inglês mesmo presta?
L
Luca
Olá
fredferrao:
O outro ponto que acho que o Luca quis falar(posso estar enganado) é o seguinte.
“Preciso fazer uma calculadora, certo deixa eu consultar meu cookie book de padroes pra ver qual padrao serve pra fazer calculadora, humm X serve… nao Y…talves…” Ou seja eu NAO estou focando em resolver o probema em si, mas estou pensando apenas no padrao, ao inves de procurar resolver o problema que é somar 2 numeros eu estou ja querendo procurar um padrao, mas o cliente deseja é somar numeros.
Isso!
E ainda acrescento diálogo o que já assisti. Ao ser apresentado ao problema um programador começa a orientar o outro:
Aqui você usa um composite mais um facade e depois junta tudo com um command. Então é só fazer os DTOs e DAOs e resolver os Service Locators
Resposta do outro programador que ainda estava pensando com a linguagem ubíqua do negócio:
Ahã??? Tem banheiro neste andar?
Pois é, infellizmente na nossa área há gente arrogante que gosta de humilhar o colega arrotando padrões e siglas. Aprenda a explicar para o colega usando a linguagem que ele entende. Se ele entende padrões, então é ótimo. Mas não imponha o uso de padrões porque há muito programador EXCELENTE que não conheçe padrões mas são do tipo Get Things Done and Working (eu conheço pelo menos 2 assim)
Os primeiros problemas a resolver são de algoritmo e de fluxo de informações. É preciso testar a solução. E com algum código para mostrar fica mais fácil parear e fazer revisão de código.
Não há que ter medo de jogar código fora. Joguem quantas linhas forem preciso. Entendam, isto não é gamb. Gamb é querer acertar a solução SEMPRE logo desde o primeiro código escrito. Será que todo mundo aqui programa igual ao Joshua Bloch? E eu duvido que o Joshua Bloch olhe para o céu e acerte o código correto logo de cara.
E usem o que tem de bom nas técnicas atuais de programar: TDD, revisão de código aos pares (não usando sempre os mesmos pares), discussão da solução na tela branca, etc.
[]s
Luca
M
mochuara
O uso de padrões não é um defeito da linguagem.
Se outra linguagem permite criar o mesmo programa sem precisar usar esses padrões JDBC, JMS, JMX, JNDI, vc tem um código menor e mais expressivo que levou metade do tempo pra fazer dando chance pra sair na frente da concorrencia que usa Java. Se é defeito ou não da linguagem fica a seu critério depois de passar por essa experiencia.
Se vc ama tanto padrões assim ok, mas ser obrigado pela linguagem a usar padrões para criar programas é um defeito da linguagem sim (na verdade, do programador por não saber escolher a ferramenta certa).
S
sergiotaborda
fredferrao:
Ai fica a questao, devo ir resolvendo o problema e encontrando os padroes em tempo de desenvolvimento e assim estruturando o codigo, ou devo parar tudo e ja querer achar padroes sem ao menos me preocupar com o problema e como resolve-lo???
Uma vez vi uma apresentação sobre como um processamento batch que consumia vários dias foi convertido para um que consumia algums minutos. A solução apresentada não referia nenhum padrão. Era uma solução empirica (i.e. encontrada por tentativa e erro e evolução sequencial ). foi explicado como o processo normal que seria feito num for é substituido por várias threads (até aqui tudo bem) mas que isso influencia no contexto de persistencia e nas dependencias entre as instancias. A solução encontrada foi utilizar 2 niveis de cache (além do cache do hibernate). No fim era proposto que o processamento poderia ser destribuido em várias máquinas usando JMS. Chegar nesta conclusão demorou alguns anos e foi necessária devido a vários problemas encontrados durante esse tempo.
Agora, se vc pensar que um processo batch é uma unidade de trabalho (um pacote) e que a performance será aumentada distribuindo o processamento em threads simplesmente consultando o catalogo de padrões vc entende que tem que usar Produtor-Consumidor e UnitOfWork. Sabendo isto, vc pode criar seu miniframework de produtor-consumidor ou vc pode usar um já pronto (JMS). A implementação de UnitOfOWork já é baseada em niveis de cache que são partilhados conforme a transação.
Vc chega nas mesma conclusões em minutos. no máximo dias. Não anos.
Pensar com padrões é um tipo de pensamento logico-matemático que leva a conclusões confiáveis. E evita perda de tempo.
A multiplicação é a soma repetida do mesmo numero. Mas ninguem faz essa soma. Um padrão melhor foi encontrado para esse tipo de soma, e hoje é uma operação fundamental.
Moral da historia: vc só vai perder tempo implementando por tentativa e erro se está fazendo algo completamente original que nunca ninguem fez. Na maioria dos casos já alguem (muitos alguens) fez isso antes e existe um padrão. Procurar nos catálogos é bem mais rápido que tentar inventar do zero.
S
sergiotaborda
O uso de padrões não é um defeito da linguagem.
Se outra linguagem permite criar o mesmo programa sem precisar usar esses padrões JDBC, JMS, JMX, JNDI,
que fique bem claro : essas coisas são tecnologias. São biblotecas. Mas elas são feitas baseadas em um padrão. ou seja, elas são assim não porque alguem estipulou assim, mas porque estão seguindo um padrão que já existia antes.
ser obrigado pela linguagem a usar padrões para criar programas é um defeito da linguagem sim (na verdade, do programador por não saber escolher a ferramenta certa).
Dê exemplos.
Ninguem é obrigado a usar padrões. Tanto isso é verdade que é possivel fazer gambs horriveis , programar procedural, etc… se java, ou qq linguagem impusesse esse tipo de regras várias coisas seriam imposisveis (smalltalk está mais perto de ter essa restrição, mas mesmo assim ela não força o uso de padrões)
Em scala , ninguem o obriga a usar “object” para definir singleton. vc pode fazer do jeito que faria em java, mas usar a feature da plataforma é melhor porque é mais garantida. Mas é uma escolha de implementação. O uso do padrão singleton vc já identificou antes de escolher a linguagem. Em java 1.4 se vc quer usar o padrão Enumeration vc precisa criar um codigo cheio de detalhes e cuidados. O padrão é excelente, mas a implementação é complexa e perigosa. Em java 1.5 a implementação é trivial porque a plataforma cuida de todos os detalhes. É o mesmo padrão, supre a mesma necessidade e resovler o mesmo problema da mesma maneira, mas são duas implementações diferentes.
Dê alguns exemplo de onde a linguagem, e não o modelo , o obrigam a usar padrões.
Mas antes de perder tempo dando exemplos pense em alguns exemplos, pense se possivel fazer sem seguir o padrão ou usando gamb. Voilá, o padrão não é mais necessário. Dê exemplo apenas daqueles que vc tem mesmo que usar um padrão.
T
tnaires
Luca, realmente pensar em padrões da forma que você e o fredferrao estão colocando - ou seja, o uso dos padrões é mais importante que a resolução do problema - é complicado. Só que esse argumento não deve ser usado pra descartar seu uso. Como o Sérgio falou, os padrões, antes de serem utilizados, devem ser estudados, para que o desenvolvedor identifique sem esforço - e sem ficar catando pelo livro - qual o padrão que melhor se adequa ao problema que ele quer resolver, ou nenhum se for o caso. Conhecê-los é útil sim, e aplicá-los também, desde que sejam aplicados nas situações que os exigem de fato.
M
mochuara
sergiotaborda:
Em java 1.4 se vc quer usar o padrão Enumeration vc precisa criar um codigo cheio de detalhes e cuidados. O padrão é excelente, mas a implementação é complexa e perigosa. Em java 1.5 a implementação é trivial porque a plataforma cuida de todos os detalhes. É o mesmo padrão, supre a mesma necessidade e resovler o mesmo problema da mesma maneira, mas são duas implementações diferentes.
Nesse ritmo quando vc acha que Java ira implementar por exemplo o MetaObject do Ruby? Java 8, 10, 12?
Tudo bem, não é defeito da linguagem Java então, ainda assim meu cliente não pode esperar pelo Java 22.4 e eu valorizo meu tempo o suficiente pra evitar sempre que possível implementaões complexas e perigosas.
L
Luca
Olá
Acho que em momento nenhum descartei usar padrões (apesar de não gostar de alguns deles incluindo o Singleton, que antes de usar recomendo cuspir no chão 3 vezes e ainda acender 3 velas a N.Sra do Software que não Escala).
Uma idéia que me incomoda faz tempo sobre a questão dos padrões no Java é a mentalidade das pessoas de primeiro tentarem descobrir serventia para os padrões antes de pensar no problema.
E o tanto que o Java ganhou de complexidade depois que acharam que software para ser bom precisa usar padrões. O cara nem leu o Effective Java e já quer tacar Business Delegate no pão no café da manhã.
Acho sempre que primeiro a gente deve tentar escrever um código que resolva nosso problema. Se o cara é bom de padrões, então use-os logo de cara (é óbvio que sem arrotar conhecimento para cima da equipe). Mas eu acho mais legal quando alguém mostra o código para outro e este diz: olha, aqui poderia ser usado o padrão tal e tal. Ou, já temos em nossa base algo parecido. Uma das melhores práticas de hoje em dia é a revisão de código em pares.
Acho errado o cara primeiro procurar se existe algum padrão em algum suposto catálogo (*) antes dele mesmo pensar na solução
(*) Imagine a catástrofe se por azar o catálogo do cara é a primeira edição do Core J2EE Patterns…
[]s
Luca
M
mochuara
Sim, isto é fundamental em programação Java pelo fato da linguagem so conter os padrões mais imbecis tornando tudo muito improdutivo. Os padrões mais úteis vc deve conseguir separado por meio de bibliotecas, ou fazer na mão vc mesmo. Apesar de haver uma cultura entre os programadores Java de que padrões é conhecimento util a verdade é, não é. O bom programador escolhe a linguagem certa para o problema, que significa a linguagem ja conter as abstrações necessárias para que apenas o código correspondente a aplicação seja necessário ser dito para o compilador.
T
tnaires
Luca, compreendo seu ponto e concordo com ele.
Lembrando que o Effective Java referencia bastante os padrões GOF. Há tópicos inclusive baseados nesses padrões.
Eu tenho esse livro :oops:
T
tnaires
Aqui discordamos. Eu substituiria a palavra útil por necessário.
T
Thiago_Senna
A comunidade java não sabe brincar! Ela adora um evangelismo… é só surgir um novo evangelista pregando X que vai todo mundo atrás. É tudo ao extremo, não sabem moderar. Não adianta dizer que a culpa é dos programadores que não entenderam direito… a comunidade java gosta de modinha (incluindo eu,rsrs). A maioria dos desenvolvedores não são estes seres super espertos que saberao escolher adequadamente os patterns. Em geral, quando aprendem os patterns, levam sempre para o lado emocional. Sempre foi assim e vai continuar…
S
sergiotaborda
Vou voltar a dizer : os padrões , os catálogos, as pessoas que usam padrões corretamente, as equipas que conversam usando padrões, nada disto tem culpa que existam desenvolvedores que não sabem. O que deveria ser defendido por todos é que os padrões devem ser aprendidos e os desenvolvedores devem aprendê-los. Quem não o fizer sempre será um desenvolvedor pior do que poderia ser.
Veja bem, principios de OO é a matemática básica e patterns é como matemática avançada. Se vc sabe o básico vc vai longe, vai a qualquer lugar, mas demorará sempre que encontrar um problema complexo. Vc pode usar o básico para criar qualquer coisa, mas o esforço não será o mesmo que alguem que sabe a matemática avançada. Para estes o problema é trivial e os problemas que eles encontram que necessitam de esforço são muito mais complexos. Sistema CRUD podem ser feitos com o básico, mas são feitos com menos esforço usando padrões.
Design não é para todos. É por isso que é preciso um designer (designer OO, não de UI). quantos mais designer a equipe tiver mais fluido será o desenvolvimento. Design não é algo para se deixar com estagiários e juniors. Eles não têm maturidade conceptual suficiente para isso. Contudo, algumas pessoas simplesmente são talentosas, portanto tb não podemos descartar à partida os que essas pessoas dizem. O ponto é que para elas comunicarem, tem que comunicar no nivel do resto da equipa e patterns dá uma boa base para isso.
M
mochuara
Vou voltar a dizer : os padrões , os catálogos, as pessoas que usam padrões corretamente, as equipas que conversam usando padrões, nada disto tem culpa que existam desenvolvedores que não sabem. O que deveria ser defendido por todos é que os padrões devem ser aprendidos e os desenvolvedores devem aprendê-los. Quem não o fizer sempre será um desenvolvedor pior do que poderia ser.
Veja bem, principios de OO é a matemática básica e patterns é como matemática avançada. Se vc sabe o básico vc vai longe, vai a qualquer lugar, mas demorará sempre que encontrar um problema complexo. Vc pode usar o básico para criar qualquer coisa, mas o esforço não será o mesmo que alguem que sabe a matemática avançada. Para estes o problema é trivial e os problemas que eles encontram que necessitam de esforço são muito mais complexos. Sistema CRUD podem ser feitos com o básico, mas são feitos com menos esforço usando padrões.
Design não é para todos. É por isso que é preciso um designer (designer OO, não de UI). quantos mais designer a equipe tiver mais fluido será o desenvolvimento. Design não é algo para se deixar com estagiários e juniors. Eles não têm maturidade conceptual suficiente para isso. Contudo, algumas pessoas simplesmente são talentosas, portanto tb não podemos descartar à partida os que essas pessoas dizem. O ponto é que para elas comunicarem, tem que comunicar no nivel do resto da equipa e patterns dá uma boa base para isso.
ZZZZZZZzzzzzzzZZZZZZZ…
Besteira, patterns não são teoremas. São ferramentas projetadas por humanos assim como pontes e sapatos. E uma ponte que desaba é ruim, um sapato que da calo é ruim, patterns que atrapalham minha produtividade tb são ruins. Esse papo de mundo parelo onde descansam eternamente os padrões bonzinhos não é relevante pra discussão atual.
S
sergiotaborda
mochuara:
Besteira, patterns não são teoremas. São ferramentas projetadas por humanos assim como pontes e sapatos. E uma ponte que desaba é ruim, um sapato que da calo é ruim, patterns que atrapalham minha produtividade tb são ruins.
Até agora vc não conseguiu produzir exemplos de como patterns atrapalham a produtividade ou de como são remendos das deficiências das linguagens. Ai fica dificil aceitar que isso é verdade.
Padrões não são ferramentas. Padrões são coisas que se repetem. Vc comparou com pontes. Padrões não são pontes, são coisas que se repetem em todas as pontes. (lembre-se que o conceito de catalogo de padrões veio exatamente da arquitetura)
C
ccaneta
mochuara:
Besteira, patterns não são teoremas. São ferramentas projetadas por humanos assim como pontes e sapatos. E uma ponte que desaba é ruim, um sapato que da calo é ruim, patterns que atrapalham minha produtividade tb são ruins. Esse papo de mundo parelo onde descansam eternamente os padrões bonzinhos não é relevante pra discussão atual.
Vamos entender o seguinte, Design Patterns é algo produzido através de observações e abstração ao projeto que atingiram maior proficiência com o uso da linguagem envolvida e isso implica em suas versões e gerações que foram tendo especificações aprimoradas e facilitadas, sendo algo que é aproximadamente testado e cientificamente aceitável, todavia a visão ao projeto que vamos recorrer depende dessa evolução que é condicionada aos padrões é a sua melhor intenção, no que cabe ao design para aquilo é propicio ao seu uso.
M
mochuara
Não precisou, vc mesmo fez, e foi destacado por mim em negrito alguns posts atras.
sergiotaborda:
Padrões não são ferramentas. Padrões são coisas que se repetem. Vc comparou com pontes. Padrões não são pontes, são coisas que se repetem em todas as pontes.
Hm… legal, mas… e ai? Padrões não são ferramentas porque mesmo?
S
sergiotaborda
mochuara:
sergiotaborda:
Até agora vc não conseguiu produzir exemplos de como patterns atrapalham a produtividade ou de como são remendos das deficiências das linguagens. Ai fica dificil aceitar que isso é verdade.
Não precisou, vc mesmo fez, e foi destacado por mim em negrito alguns posts atras.
Ah! era isso ? Então qual é o defeito da linguagem java que o padrão Enumeration resolve ?
Então qual é o defeito da linguagem java que o padrão Bridge resolve ?
Então qual é o defeito da linguagem java que o padrão Registry resolve ?
Escolha um padrão qualquer e indique qual problema da linguagem, ele resolve.
C
ccaneta
ViniGodoy:
Depois, é bom lembrar que a VM só irá criar seu Singleton assim que for usado a primeira vez, pois será nesse momento em que a classe será carregada. Ou seja, o lazy loading já existe.
Entenda que !!!
A implementação em java deste padrão deve ser utilizar um campo privado e estático do tipo da própria classe para armazenar a referencia da única instancia permitida, o qual deve ser inicializado de modo a indicar a inexistência de tal instancia.Um método estático, cujo tipo de retorno também é a própria classe, prove o ponto único de acesso a tal instancia. Se a operação de instanciação de um objeto da classe, garantimos a instancia única ao mesmo tempo que a criação, só ocorrerá quanto estritamente necessário(Lazy instantiantion)
M
mochuara
sergiotaborda:
Ah! era isso ? Então qual é o defeito da linguagem java que o padrão Enumeration resolve ?
Então qual é o defeito da linguagem java que o padrão Bridge resolve ?
Então qual é o defeito da linguagem java que o padrão Registry resolve ?
Escolha um padrão qualquer e indique qual problema da linguagem, ele resolve.
Ja foi dito que vc pode ser 2x mais produtivo numa linguagem mais alto nivel, que não precise usar patterns. O quemais vc precisa pra entender que todo o resto é balela?
C
ccaneta
mochuara:
Ja foi dito que vc pode ser 2x mais produtivo numa linguagem mais alto nivel, que não precise usar patterns. O quemais vc precisa pra entender que todo o resto é balela?
Uma coisa que eu não entendo é porque você não se situa sobre Patterns, isso pode se estender a família da linguagem como também outras implementações que venha a surgir pelo o estudo da arquitetura, estou vendo que o Sérgio, se coloca tecnicamente mas você não tem profundidade sobre um case que lhe dê melhor representação.
M
mochuara
Pelo visto não é só escrever, vc tb não saber ler! :shock:
C
ccaneta
mochuara:
ccaneta:
Uma coisa que eu não entendo é porque você não se situa sobre Patterns, isso pode se estender a família da linguagem como também outras implementações que venha a surgir pelo o estudo da arquitetura, estou vendo que o Sérgio, se coloca tecnicamente mas você não tem profundidade sobre um case que lhe dê melhor representação.
Pelo visto não é só escrever, vc tb não saber ler! :shock:
Cadê o exemplo, cadê o argumento técnico, você esta redundante o tempo inteiro não estou vendo você se colocar tecnicamente é só isso, Design Patterns já algo comprovado , a forma que se faz implementação cria abstrações que vão sofrer mudanças mas isso não foge do entendimento da arquitetura para seu proposito, o que percebi é que você quer buscar redefinição e querer quebrar esses padrões, muito bem você pode fazer isso , alias linguagem que utilizam metaprogramação são anti-patterns, ao como beanshell mas não deixam de usar decorator para manipulação de tela, por exemplo ou sendo um design patterns de comportamento.
S
sergiotaborda
mochuara:
sergiotaborda:
Ah! era isso ? Então qual é o defeito da linguagem java que o padrão Enumeration resolve ?
Então qual é o defeito da linguagem java que o padrão Bridge resolve ?
Então qual é o defeito da linguagem java que o padrão Registry resolve ?
Escolha um padrão qualquer e indique qual problema da linguagem, ele resolve.
Ja foi dito que vc pode ser 2x mais produtivo numa linguagem mais alto nivel, que não precise usar patterns.
É, foi dito, mas não provado. Nem um misero exemplo conseguem dar. Se fosse verdade choveriam exemplos.
É ridiculo dizer que Rails não é MCV, que não usa ActiveRecord ( o padrão) que ruby não usa MetaObject.
Todo o objeto JavaScript é criado por Prototype. Todos os objetos com propriedades em qualquer linguagem podem ser PropertyBag.
Mensageria , ESB usam Produtor-Consumidor. Toda a string é um Wrapper de array de characteres. Todos estes e mais são exemplos
de como os padrões formam as proprias linguagens OO, como os próprios mecanismos e definições seguem os mesmos padrões.
A razão é porque os padrão precedem as linguagens. Em todas vc pode criar um factory, um sigleton, um builder, um façade… pattern não é limitação de linguagens.
Isso é uma mentira inventada por mentcaptos e perpétuada por quem não tem condições de entender OO e se refugia na desculpa que entender OO e aplicar padrões é inutil e que é possivel programar bom codigo sem eles. Simplesmente não é.
Eu não estou tentando convencer vc. Vc é um caso perdido. Estou sou mostrando que vc não tem razão e o que afirma é falso e sem fundamento. Só para evitar que quem esteja lendo não cai na mesma asneira.
T
Thiago_Senna
Então creio que é melhor não saber OO mesmo e essa sopinha de letrinhas toda. Tem muita gente mais esperta que eu que ganhou muito dinheiro com Delphi sem essa enrolaçao toda.
J
javamaniaco
Pessoal, cada nova lida que dou nas discussões que surgiram desde a última vez que li, percebo porque Java possui tantos frameworks para: MVC, Persitência, Injeção de Dependências e por ai vai. Cada um tem uma visão do mundo, cada um com seu óculos “cor de rosa”. Logo, surgem uns que defendem o framework X porque implementa melhor os tais design patterns de que o outro não implementou direito.
A pergunta que fica é: Se querem repensar uma segunda edição, é porque muita coisa foi feita e de forma como não deveria, direito ao longo desses anos. Quem me garante que cada um dos porta-vozes que aqui falam sabem corretamente implementar tais design patterns sem erros?
Outra pergunta que fica é: Porque o criador do Rails, um framework genial por sinal, não escolheu Java ou .Net e sim Ruby? Ele poderia, mas porque não “KISS” :lol: ?
Não estou dizendo que padrões são desnecessários, mas estou dizendo que, termos diversos padrões ao mesmo tempo interagindo e, muitas vezes com efeitos refatorados, não dificultam o progresso do desenvolvimento e matam a criatividade? Um projeto Java necessita de diversos patterns mesmo ou temos casos que, ai vem a pergunta de R$ 1.000.000,00, em que os desenvolvedores repensam e refatoram os diversos patterns substituindo-os por menos?
Essas perguntas não querem sair da minha cabeça, pois vejo um tamanho tão grande de complexidade que, não me admira que um projeto besta leve 10 vezes mais para ser feito em Java com mais pessoas do que em Rails, com menos pessoas e todas entendendo seus códigos.
G
giulianocosta
Muito bom tópico!!!
Na minha visão, a falha que aparece na maioria do entendimento das pessoas (incluindo eu) é querer “coisificar” os padrões como se tivessem vida própria. Patterns nada mais são do que soluções prontas pra problemas conhecidos.
A simples pergunta que você deve fazer antes de usar um pattern é “este pattern realmente foi feito para o problema que estou tendo?”. Depois disso basta fazer testes solucionando o seu problema com o Pattern escolhido. Se ele se mostrar eficiente para você aplique-o sem medo de ser feliz…
Outro ponto rídiculo que vejo é quando chego para dar manutenção em algum sistema mais antigo e vejo desenvolvedores/analistas/arquitetos/etc tocando o pau no sistema, dizendo que foi usada tecnologia obsoleta, padrões errados, mal codificação, etc, etc, etc…
Maioria falácia! O que acontece neste ponto é que sistemas mudam, regras de negócios mudam, negócios mudam, pessoas mudam, tudo muda o tempo todo…
Então como posso culpar as pessoas ou o sistema por ele estar errando em algo que ele não foi, desde sua concepção, proposto para solucionar?
Como posso culpar um cara que modelou um carro em 1970 dizendo que o carro é “beberrão” sendo que, na época o carro não foi proposto para não o ser???
É como eu chamar intelectuais que não conheciam a teoria da Relatividade de burros… Notem que até mesmo agora que estamos entrando na era do “Nano” a própria Relatividade de Einstein já não se aplica mais…
S
sergiotaborda
Ah! , mas padrões não mudam.
Existe sim o jeito certo e o jeito errado. Pensar e aceitar que todos os jeitos são certos é que é falacioso. Se todos os jeitos fossem certos não existia o conceito de gambiarra.
Sistemas são mal projetados sim. Os desenvolvedores por pressão, ignorancia, incompetência ou desleixo introduzem o que se chama de débito tecnico. Ou seja, a melhor solução tecnica não foi usada. Não porque se escolheu não usar, mas porque não se considerou procurá-la. Só pode não usar a melhor solução tecnica, pode usar a segunda melhor. Só não pode usar a primeira coisa que lhe vem ha cabeça.
Tecnologia tem obsolescencia determinada à partida. Struts é um bom exemplo. O modelo é overbloated , complexo demais para o que precisa ser feito. Era de esperar que se torne obsoleto. E a prova é que tornou de fato. Tem alguns até defendendo que é um anti-framework. Porque ele é uma porcaria ? Porque viola vários principios de OO e boas práticas. Por exemplo, a nomenclatura é um pesadelo.
ninguem culpa o sofware por ele não solucionar um problema de negocio que não era previsto. Se culpa a equipa por não ter solucionado - ou executado da melhor forma - a solução tecnica que dá estrutrua ao software para resolver os problemas de negocio.
Soluções ruins existem sim. Infelizmente são a maioria, porque não ha investimento em arquitetos e designers , esse papel é desempenhado por amadores.
Pesquise por “débito tecnico” (tecnical debt) para mais informação de como sim é comum e errado fazer software ruim
P.S. em relação à relatividade nem vou me pronunciar porque senão ficamos aqui a vida toda. Só como exemplo o GPS funciona graças à relatividade geral.
C
clone_zealot
Sérgio, se eu entendi bem oq o mochuara quis dizer, é que ele acha inútil os desenvolvedores terem que conhecer alguns design patterns, pois eles podem muito bem serem implementados e aplicados como um sugar nas linguagens.
Você mesmo exemplificou que várias linguagens já fazem isso. Agumas através de um sugar, outras através de construções próprias, outras através da própria sintaxe da linguagem, que exige isso.
E nesse ponto eu concordo com o mochuara: existem alguns patterns que já poderiam ser nativos na linguagem, com uma construção MAIS simples ainda.
E eu reforço o MAIS simples, pq não vejo nenhum pattern como algo complexo. No máximo os seus conceitos são estranhos a programação procedural à qual a maioria esmagadora dos programadores são treinados.
Observação OFF-TOPIC: como temos filósofos no GUJ…
G
giulianocosta
Eu concordo com você…heehhehehe… O problema é que meu problema pode mudar, aliás, ele vai inevitavelmente mudar! E ninguém quer que o Pattern previamente escolhido comece a se tornar um impencilho no meu negócio.
Então por isso eu digo: Padrões não mudam até que mudem…heheheheheh… O Pattern escolhido certamente não muda, mas meu negócio, minha infra, minha mente muda…
É exatamente esse aspecto que quis abordar. Dizendo que não é culpa do Pattern quando algo que ele não foi proposto pra resolver simplesmente chega.
Por exemplo, tenho um Pattern Y pra resolver um problema X. O Pattern, obviamente, vai ditar tudo que tenho que fazer para resolver o problema X (Afinal alguem que formulou o Pattern já passou exatamente pelo problema que estou passando).
Acontece que depois de um Ano o problema X se transforma num problema Xb (Minha loja farmácia além de vender remédios começou a prestar serviços (mão de obra de sei la o quê) e preciso lançar isso no sistema). Neste ponto o Pattern não mudou, até por que ele não tinha que mudar. Afinal ele é um Padrão! O problema é que neste ponto eu tenho escolhas.
Quebro o Pattern injetando código a moda “Miguelão” para resolver minha situação .
Procuro outro Pattern e, caso exista, refatoro minha aplicação com este novo Pattern.
Tento adaptar o Pattern, que obviamente deixará de ser o Pattern outrora escolhido para se converter em outro Pattern.
etc…
Enfim, creio que eu que estamos defendendo a mesma coisa…ehheheheh
P.S. em relação à relatividade nem vou me pronunciar porque senão ficamos aqui a vida toda. Só como exemplo o GPS funciona graças à relatividade geral.
Assino embaixo! hehehhee
A
alots_ssa
Gosto do jeito que o livro “Use a cabeça! Padrões de projetos” aborda o assunto. Vai muito na linha do que o Luca falou, de ver o problema real, e aí tentar resolver, sempre tentando melhorar, talvez você caia num padrão… Particularmente, não gosto de começar a pensar em algum padrão para resolver o problema, se o mesmo nem chegou ainda… Não quero ser radical, claro que se vc quer isolar a criação do objeto vai usar algum factory e tal, mas se não for tão claro assim… eu programaria, tentaria resolver, e durante essa caminhada poderia perceber alguma coisa e “refatorar”, sim eu gosto de refatorar, prova que eu estou em melhoria continua :). De vez em quando eu vou me dar bem, de vez em quando eu vou falar: “puta merda, poderia ter usado isso antes”, acontece, faz parte do jogo :). E tambem pode acontecer com alguma escolha de padrão que vc fez… do tipo: previ que tinha de adicionar responsabilidades em tempo de execução a algum objeto, por isso usei o decorator(tomara que eu esteja certo :)), mas passou um tempo, não precisei adicionar nada e fiquei com classes a mais por uma razão que não vingou. Para mim, resumindo, programar tem muito de bom senso, e, como acho que tudo em excesso faz mal, vou pesando e decidindo o que tenho que fazer.
S
sergiotaborda
Vc está falando de um tipo diferente de padrão que não é de programação, é de modelo. Esse padrões são chamados Padrões de Aplicação ou Padrões de Analise. É um campo ainda pouco desenvolvido principalmente devido à fraca compreensão de OO entre as pessoas que conhecem os dominios. Mas temos alguns exemplos. Se vc trabalha com estoque (muitos sistemas trabalham com estoque) qual foi o padrão que vc usou para programar isso ? Nenhum ? Bom, ai já começa mal. Não foi pesquisar quais havia ? não tentou encontrar um nos N milhares de softwares que ha por ai ? Não se atentou à realidade para definir um modelo ? Estes padrões derivam diretamente da analise do negocio. O padrão para estoque é Account (conta). O mesmo que se usa em finanças e contabilidade. À partida pode não ser obvio porquê, mas é esse o padrão. O tipo de operações que se fazem nestes três ramos são semelhantes e contém regras comuns - teoricas e bem definidas e entendidas - como seja a regra de partidas dobradas.
O problema não evolui como vc explicou. O padrão não vai resolver o problema de negocio, nunca. O padrão vai resolver a tradução do modelo/dominio/regras para o software. Padrões de Analise como Account e Money têm implementação variadissima mas ninguem discute que são padrões de fato para resolver os desafios que se propõem.
Veja bem, se o problema é mutante no tempo, não ha realmente um padrão. E portanto não foi o padrão X que evoluiu para X’ e sim que o uso do padrão X foi precipitado. Não existia realmente nenhum padrão ali.
Mesmo assim, hoje em dia , é dificil que vc encontra um processo/modelo/entidade de negocio que nunca ninguém viu antes.
S
sergiotaborda
clone_zealot:
sergiotaborda:
É, foi dito, mas não provado. Nem um misero exemplo conseguem dar. Se fosse verdade choveriam exemplos.
É ridiculo dizer que Rails não é MCV, que não usa ActiveRecord ( o padrão) que ruby não usa MetaObject.
Todo o objeto JavaScript é criado por Prototype. Todos os objetos com propriedades em qualquer linguagem podem ser PropertyBag.
Mensageria , ESB usam Produtor-Consumidor. Toda a string é um Wrapper de array de characteres. Todos estes e mais são exemplos
de como os padrões formam as proprias linguagens OO, como os próprios mecanismos e definições seguem os mesmos padrões.
A razão é porque os padrão precedem as linguagens. Em todas vc pode criar um factory, um sigleton, um builder, um façade… pattern não é limitação de linguagens.
Isso é uma mentira inventada por mentcaptos e perpétuada por quem não tem condições de entender OO e se refugia na desculpa que entender OO e aplicar padrões é inutil e que é possivel programar bom codigo sem eles. Simplesmente não é.
Eu não estou tentando convencer vc. Vc é um caso perdido. Estou sou mostrando que vc não tem razão e o que afirma é falso e sem fundamento. Só para evitar que quem esteja lendo não cai na mesma asneira.
Sérgio, se eu entendi bem oq o mochuara quis dizer, é que ele acha inútil os desenvolvedores terem que conhecer alguns design patterns, pois eles podem muito bem serem implementados e aplicados como um sugar nas linguagens.
Alguns podem, mas não todos. E aqueles que são incluidos o são para facilitar. Não ha nada de errado com a linguagem que exija que se usem padrões. Padrões não são forma de remendar as limitações da linguagem. Esse é o ponto.
Se a linguagem x permite que vc implemente um padrão de forma simples ótimo, mas nem todos os padrões podem ser implementados pela linguagem. Por exemplo, java implementa o padrão Dynamic Proxy através da classe Proxy de forma simples e OO. Alguma outra faz isso ? Como vc faria um proxy dinamico usando a linguagem (não a API) ? Escolha uma onde isso é possivel e apresente. Em javascript, por exemplo, o padrão Proxy é impossivel porque não existe o conceito de contrato (interface) na linguagem nem na API. Vc não tem como fazer um objeto passar por outro de forma dinamica (tem o padrão decorator, mas é mais trabalhoso que em java).
Os pontos que quero deixar claros são :
Padrões não são forma de remendar as limitações da linguagem
A implementação, seja sugar ou normal ou via APi já pronta, não é relevante ao padrão. A implementação não faz parte do padrão.
G
giulianocosta
Sérgio, como eu escrevi na minha primeira postagem deste tópico. Que a gente tem a mania de “coisificar” padrões. Padrões são padrões dentro ou fora de uma linguagem de programação. Indiferente da granularidade que ele apareça…
Se eu citei um padrão de modelo de negócio ou um padrão de sei lá o que, isso pouco importa. O ponto aqui é que a natureza nos ensina que tudo muda o tempo todo. Portanto, o problema que meu padrão resolvia elegantemente ontem, pode não resolver elegantemente hoje, ou até mesmo nem resolver.
Em momento algum eu disse que o Pattern é mutante. O que eu disse é que o problema que ele resolve de forma padronizada é mutante. Mesmo que não pareça ser, ou até possa não parecer durante séculos, mesmo assim tenho que saber que ele é mutante. O problema é mutante e o padrão não!
Eu posso ter um Pattern que me resolve um problema muito bem na ordem granular do meu negócio, o problema aqui é que em algum momento esse padrão de ordem granular pode começar a conflitar com a necessidade do “Macro” problema. Logo, ele passará a não ser a solução mais viável pro meu “macro problema”.
Concordo plenamente, mas aqui envolve uma série de outros problemas. Nem sempre quem resolveu um problema divulga a forma como resolveu. Nem sempre se tem tempo para pesquisar, o tempo todo, soluções para problemas que estamos tendo.
E ainda, por mais que problemas sejam compartilhados aos montes, na maioria das vezes não são lisamente iguais.
Eu posso ser um arquiteto, descobrir como outros arquitetos la na Europa estam resolvendo problemas de engirecimento de cimento e adotar aqui. Mas de repente a solução dada lá não necessariamente será a melhor a ser usada aqui.
Pois aqui terei uma temperatura diferente, nivel do mar diferente, umidade do ar diferente, estações do ano diferentes… E por ai vai…
C
cawink
Mas ta loco, faz 3 ou 4 dias que vocês estão discutindo isso.
G
gomesrod
Pelo que entendi, você defende que os padrões não são uma boa coisa pois apenas estariam compensando uma deficiência na linguagem. Que as linguagens teriam por obrigação implementar os design patterns.
E se pensássemos de uma outra maneira? A linguagem que implementa de forma nativa algum padrão não está simplesmente cumprindo sua obrigação: ela foi um passo além, adicionou um recurso a mais para facilitar nossa vida.
(Ou como se gosta de dizer nas empresas, foi “pró-ativa”).
Se você é mais produtivo com a linguagem X do que Y, não considere como um defeito de Y e sim como um mérito de X; pois ela está mais em sintonia com as suas necessidades e implementou os recursos adequados para elas.
Tampouco seria correto dizer que esses recursos da linguagem X são errados em outras linguagens, apenas porque precisam ser implementados pelo desenvolvedor.
S
sergiotaborda
importa sim.
tudo menos padrões. vc mesmo concordou com isso.
Isso não é possivel. O meu ponto é que se isso acontece é porque o padrão foi mal identificado. Se ele resolver um problema ele resolve para sempre. é da sua natureza ser eterno, no sentido que não ha outra solução melhor. Mais uma vez, foi o uso do padrão que foi percepitado.
Dê exemplos. Do ponto de vista abstrato isso não faz sentido.
R
rems
E faz 3 ou 4 dias que eu estou acompanhando. Muito boa a discussão, pq na minha opnião, o sergiotaborda consegue fundamentar bem suas opniões com argumentos. Bastente construtivo esse tópico.
G
giulianocosta
Como importa? Quer dizer que padrões utilizados por engenheiros pra driblar problemas de engenharia são diferentes de padroes pra resolver problemas de negócio, modelagem, código?
De um contexto amplo, não é tudo padrão? Me explica o porquê de isso importar…
Concordo! Me expressei mal nessa frase. A situação é que o problema muda e sem um problema não existe um padrão.
Esse é o ponto que estamos divergindo Taborba. Eu compreendo teu ponto de vista à respeito de que se o problema mudou não é culpa do padrão. Na verdade, nesse aspecto, teu ponto de vista é o meu. Só discordo do ponto que tu diz que “o padrão foi mal identificado”, acho que “mal” da um significado de intenção. O fato de eu não identificar uma situação não inválida uma solução que eu tinha dado anteriormente. Apenas, neste ponto, eu tenho que me “adaptar”.
Dê exemplos. Do ponto de vista abstrato isso não faz sentido.
“Eu posso ser um arquiteto, descobrir como outros arquitetos la na Europa estam resolvendo problemas de engirecimento de cimento e adotar aqui. Mas de repente a solução dada lá não necessariamente será a melhor a ser usada aqui.
Pois aqui terei uma temperatura diferente, nivel do mar diferente, umidade do ar diferente, estações do ano diferentes… E por ai vai…”
Lógico que esse exemplo não invalidaria o padrão utilizado na Europa. Mas mesmo assim o padrão adotado na Europa não será usado de forma “lisa” aqui no Brasil.
Enfim, acho que não estamos se achando apenas no contexto que estamos dando às coisas…
S
sergiotaborda
Como importa? Quer dizer que padrões utilizados por engenheiros pra driblar problemas de engenharia são diferentes de padroes pra resolver problemas de negócio, modelagem, código?
De um contexto amplo, não é tudo padrão? Me explica o porquê de isso importar…
Padrões servem para resolver um problema da melhor forma. Para que isto funcione, o problema tem que ser identificado primeiro.
Problemas de dominio/negocio são mais facilmente mal identificados. Por causa disto os padrões não podem ser usados ou sequer se vê a opção de usar um padrão.
Por exemplo, ao trabalhar com dinheiro use Money. Ele facilita o problema de trabalhar com dinheiro em moedas diferentes. Ai, o analista (de negocio) fala que “para este sistema não ha multi-moeda”. E o money não é usado. Isto é uma falha em identificar o padrão. Todos os sistemas são multi-moeda já que se server para N serve para 1. mas se serve para 1, não serve para N.
Além destas restrições tipicas de “para este sistema” temos restrição no nivel de abstração. Por exemplo, poucos “domain experts” identificam controle de estoque com o tratamento de contas equivalente a finanças ou contabilidade. Isto porque para eles estoque é fisico (localizável no espaço-tempo) enquanto finanças e contabilidade não é. Para um software tudo sempre é meta-fisico (apenas uma ideia ou conceito). Identificar estoque com o padrão Account não é comum ou trivial para a maioria dos analistas o que os leva a modelos mais complexos/menos pradronizados.
Os padrões de analise como o nome indica advém da analise do dominio. Se essa analise não é bem feita os padrões não são identificados ou são mal-identificados.
Veja bem, os padrões são para serem aplicados ao modelo. O modelo é que resovlerá problemas do dominio, não o padrão em si.
Se o problema de dominio muda, é o modelo que muda (normalmente aumenta a abstração) se o modelo muda, é outro modelo, com outros padrões.
Só discordo do ponto que tu diz que “o padrão foi mal identificado”, acho que “mal” da um significado de intenção. O fato de eu não identificar uma situação não inválida uma solução que eu tinha dado anteriormente. Apenas, neste ponto, eu tenho que me “adaptar”.
Não. Vc tem que abandonar o modelo antigo e fazer outro. Esse outro terá outros padrões.
Vc não está reaproveitando nada. A evolução de um modelo é por descontinuidade. Se tentar fazer por continuidade, vc começará a fazer gambiarra logo,logo.
Esse exemplo não é bom. Não é de software e não caracteriza um padrão. Padrão não é uma tecnica de construção. Padrão é algo que sempre se repete. Um padrão seria, por exemplo, que a relação entre o tamanho da flor de gira-sol com as petalas se relaciona ao tamanho sem as pétalas pelo numero de ouro ( o numero de outro e um numero tal que o seu quadrado é igual a ele somado um). Isto é sempre verdade porque é um padrão da flor do gira-sol. Qualquer gira-sol em qualquer parte do mundo irá obedecer esta regra empirica.
Um padrão da arquitetura seria , por exemplo, colocar a sala sempre com as janelas viradas para a vista mais nobre. Repare como é o padrão é meio abstrato e não tem variáveis do tipo “não se pode aplicar se…”
Quando pedi exemplos, pedi de padrões de software. Exemplo em que vc escolher o padrão Y e depois , quando novo requisitos chegaram , descobrir que deveria ter sido o X.
G
giulianocosta
Ta, não sei bem o que define um gira-sol como um gira-sol. Não sei se é essa relação auréa que tu supracitou. Mas digamos que, o que define o gira-sol não é a razão auréa e sim a semente que o mesmo possui capaz de, somente ele, produzir um determinado tipo de óleo. Imaginemos que a razão auréa não se aplique a uma espécie de gira-sol achada hoje.
Como você definiria isso?
Te faço essa pergunta apenas pra mim me contextualizar com teu raciocínio. A propósito, não é uma pergunta capciosa…
Mas… Em tempo… Como disse anteriormente, acho que estamos apenas com um diferença de contexto/semântica no que estamos falando…
S
sergiotaborda
Ta, não sei bem o que define um gira-sol como um gira-sol. Não sei se é essa relação auréa que tu supracitou. Mas digamos que, o que define o gira-sol não é a razão auréa e sim a semente que o mesmo possui capaz de, somente ele, produzir um determinado tipo de óleo. Imaginemos que a razão auréa não se aplique a uma espécie de gira-sol achada hoje.
Como você definiria isso?
como disse, é uma regra empirica. O que significa que novos dados, novos requisitos podem mudar as coisas. Veja bem, este tipo de coisa não acontece com Design Patterns porque eles estão limitados ao escopo OO. A realidade não tem limites e essa que é a grande diferença dos padrões de analise.
No caso em particular, eu continuaria pelo empirismo. Vc simplesmente cataloga que existe dois tipos de flor. aqueles a que se aplica o padrão, e aqueles a que não. Estes ultimos formam uma nova classe. bom, na realidade a biologia começou bem assim …
Mas continuo achando que os exemplo não são bons já que fogem ao escopo OO e de software que é o foco aqui.
V
ViniGodoy
Acho interessante que a discussão, no final, converge para o que o Luca falou no primeiro post.
Geralmente, eu sigo os passos abaixo para desenvolver software:
Entenda do que você está fazendo;
Torne o programa eficaz (resolva o problema);
Torne o programa eficiente (resolva o problema, usando as melhores práticas).
Não dá para fugir dessa ordem.
No caso de otimização, entrariam mais dois passos:
4. Use soluções específicas para o problema;
5. Use uma arquitetura de sw/hw específica para o problema.
S
sergiotaborda
ViniGodoy:
Acho interessante que a discussão, no final, converge para o que o Luca falou no primeiro post.
Geralmente, eu sigo os passos abaixo para desenvolver software:
Entenda do que você está fazendo;
Torne o programa eficaz (resolva o problema);
Torne o programa eficiente (resolva o problema, usando as melhores práticas).
O passo 2 não deve existir. Utilizar esse passo dois gera custo, debito tecnico, gambiarra, consume tempo, deturpa o modelo, deturpa integrações com outras partes do sistema. As desvantagens são maiores que as vantagens. Básicamente : esse passo é onde está a raiz de todo o mal de um design ruim, fraco, acoplado, sem longividade.
Entenda o problema e resolva-o seguindo as melhores práticas. se não sabe quais são ,aprenda-as. Esse tempo aprendendo as boas práticas não é custo, é investimento.
L
Luca
Olá
Na verdade as idéias estão lá desde os primeiros posts mas não exatamente no primeiro.
Apesar de escrever código não fazer parte do meu dia a dia, acredito que atualmente o modo de desenvolver sistemas mudou e quem ainda não mudou, acabará em dificuldades ou isolado.
Não acho mais sentido em pensar, pensar, pensar um monte, fazer diagramas, criar as classes e só depois escrever código intocável já com toque de gênio.
Para mim o mais recomendáve é a prática de escrever código sem compromsso e ir refinando aos pouquinhos. Escrever testes bobos só para conferir algoritmos, construir classes a partir do modelo de negócio tentando dissecar o problema mas sem nenhuma preocupação com nada definitivo. O uso de BDD ajuda. E seguir sempre testando, refinando e refatorando (inclusive jogando classes fora ou criando novas, é aqui que o monte de diagramas prévios se ferram).
De tempos em tempos parar e mostrar a um colega como está resolvendo o problema. Explicar o caminho adotado e verificar se outra cabeça tem alguma idéia melhor. Pode ser que neste ponto já tenham sido incluídos alguns padrões mas se depois foram julgados pelos pares como não sendo a melhor solução, será jogado fora do mesmo jeito do que a solução ad hoc.
Vejo a revisão em par como uma das melhores práticas de desenvolvimento por vários motivos, entre eles os seguintes:
Alinha os conhecimentos da equipe em menos tempo, evita o caso de sobrar algum Sr SabeTudo 100% certo cujo conhecimento o coloque em alguma torre de marfim
Duas cabeças pensam melhor do que uma. A chance de passar erros conceituais e de entendimento do negócio é minimizada.
Aumenta a possibilidade de encontrar algum padrão adequado e principalmente algum caso de reuso de código.
Aumentam as chances do código ficar legível, de que a escolha dos nomes sejá consensual, etc.
É este o motivo porque venho enfatizando que não se deve programar por padrões e sim programar pelo problema a resolver. Padrões aparecerão naturalmente se forem necessários.
E aí alguém poderia me perguntar?
E se trabalho sozinho sem nem um colega presencial ou que possa parear via Skype?
É ruim mas acontece. Neste caso sugiro fazer do mesmo jeito e incluir no seu pomodoro paradas de tempos em tempos para rever o código e verificar se está legível, se deixa débito técnico, se está testado e é testável, se não foi feito algo parecido em outro trecho do sistema que possa ser unificado sem prejuízo e se há algum padrão que ajude na clareza do entendimento. Não use padrões só porque existem.
Como veem, o que preconizo é completamente diferente de colocar o polegar de costas para o vento e tentar advinhar logo de cara o melhor caminho a seguir.
Como antigo velejador, meu conselho é: não adianta levar o barco rápido para lado errado da raia onde podem ocorrer piores condições. É melhor correr menos riscos e ir escolhendo o vento a cada passo e mudando o rumo em cada instante que se faça necessário.
RESUMO:
Não programem por padrões.
Primeiro se concentrem na solução do problema
Não tenham medo ou vergonha de jogar código fora ou refatorar
SEMPRE que possível, e deve ser possível diariamente, mostre seu código ao colega e habitue-se a examinar o código do outro. Não pareie sempre com a mesma pessoa com quem tem mais afinidade ou já sabe o modo de pensar.
[]s
Luca
S
sergiotaborda
Vejamos às diferenças
RESUMO:
Não programem por padrões. :arrow: Modele por padrões. Padrões não são implementações!
Primeiro se concentrem na solução do problema :arrow: A solução do problema é um modelo de objetos. concentre-se em encontrar esse modelo
Não tenham medo ou vergonha de jogar código fora ou refatorar :arrow: Mas não use isso como desculpa para fazer a primeira porcaria que lhe vier à cabeça ou justificar não pensar no modelo de objeto o suficiente. Ninguem diz que precisa um modelo uml no visio, apenas precisa ter um modelo que, em toda a honestidade, é o melhor que vc consegue depois de conhecer o problema e ter visto como foi resolvido antes por outros.
SEMPRE que possível, e deve ser possível diariamente, mostre seu código ao colega e habitue-se a examinar o código do outro. Não pareie sempre com a mesma pessoa com quem tem mais afinidade ou já sabe o modo de pensar. :arrow: concerteza.
L
Luca
Olá
VIVA!!!
O Sérgio Taborda concordou com alguém! E foi comigo!
A única discordância dele comigo é esta:
Para mim o melhor meio de encontrar este modelo é iterativamente. O que recomendo é não acreditar que conseguirá encontrar este modelo logo de cara.
Seja humilde em relação ao seu código. Comece por baixo. E não tenha apego por ele. descarte-o sem dó.
Quanto a questão de modelagem
Há muito que já escrevi aqui que modelagem se faz com canetinha em quadro branco e de preferência em conjunto ou com avaliação da equipe. Para documentar basta uma máquina fotográfica digital. Então, sempre que há necessidade de fazer algum tipo de modelagem prévio, sugiro que sempre seja pareada. Se não for criada em par, que pelo menos seja discutida em par. Concordo com o Sérgio e acredito que haja boas chances de se perceber e discutir algum padrão neste momento da modelagem.
Mas sem que isto resulte em um modelo engessado que ninguém mais pode modificar. O código as vezes nos mostra algo que não conseguimos abstrair a priori.
[]s
Luca
V
ViniGodoy
Sérgio, de que adianta você ter um artilheiro que corra muito o campo, saiba passar bem, driblar bem, chegue na cara do gol, mas não marque o ponto?
O que os passos dizem, é o que o Luca disse. Primeiro você se preocupa em entender o problema. Em seguida, tenta chegar a uma solução 100% funcional. Lógico, que se você vai procurar fazer isso de uma maneira elegante. Mas a preocupação inicial deve ser o problema, e não a forma. Ninguém falou em gambi, em passo nenhum, essa inferência foi por sua conta. O passo 2 não diz “resolva o problema de forma eficaz, de qualquer jeito”, estamos falando aqui de programação profissional, não de amadorismos. COmo você mesmo citou, não se deve usar esse passo como desculpa para fazer código porco. Mas antes de sair aplicando padrões em tudo, refatorando código, procurando oportunidades de DI, tornando a arquitetura complexa, tente chegar num programa simples e funcional, sem gambiarras.
Mas, até onde eu sei, ainda não inventaram um programador imune à falhas, ou que possa prever com completa exatidão a execução de um programa antes de executa-lo. Então, se a sua solução ainda não estiver tão rápida, flexível, ou consumindo tanta memória quanto você gostaria, você pode ter que recorrer ao passo 3, e procurar formas mais eficientes, sem abrir mão da flexibilidade. Por exemplo, você pode adicionar um ou outro cenário a sua solução e ver como ela reage. Você mesmo sugeriu isso. Eu não adicionaria um cenário hipotético, antes de entender totalmente o primeiro cenário, real. Da mesma forma, não adianta ir para a revisão de código, sugerida pelo Luca, sem antes ter um código funcional.
S
sergiotaborda
Bom, então devo ser só eu… eu não vejo dessa maneira. Não sei mais o que dizer para explicar.
Eu vejo dois tipos de refactoring. Um por motivos de simples implementação, uma classe não está certa, trocar array por list, aplicar final, sychronized, , dividir método em sub-metodos, etc… coisas de codigo mesmo. E tem o refactoring de modelo. A classe não herda daquela, ou duas classes independentes deveriam ter um pai comum, um tiny type deveria ser usado em vez de um primitivo, ou invez de string. etc… coisas que , deixando como está continuaria funcionando, mas que são alteradas para que o modelo faça sentido. É este tipo de refactoring de modelo que não pode ser continuo. Acontece eventualmente, mas como exceção, Não podemos instituicionalizar o refactoring de modelo por isso é catastrófico… é o que se faz todos os dias por - ou melhor , não se faz, porque é caro p’ra caramba e as equipas afunda nesse débito tecnico infinito. É o famoso, vamos fazer assim ,porque não dá tempo de melhorar. Não estamos falando de usar o eclipse para refactorizar, estamos falando de modificar o modelo abstrato.
Refactoring é algo ruim, sua metodologia não se pode basear nisso. Refactoring é exceção é uma ferramenta de urgencia, de cirurgia, não é para fazer todos os dias. Constante refactoring significa que seu codigo e seu modelo são fracos, vc não enxergou “the big picture”. Refactoring eventual é necessário, mas para correção, se vc faz refacotoring toda a hora quer dizer que seu codigo está errado permanentemente. Refactoring não é uma ferramenta de desenvolvimento, é um ferramenta de correção. O que vcs estão defendendo é quase um refactorign driven development e isso é inaceitável.
Vejam assim: o que é melhor, um código que nunca precisou ser refactorizado ou um que é refactorizado todos os meses ?
o segundo é muito simples de alcançar. Ponha alguem sem experiencia fazendo um sistema, e é assim que ele fará. Experimentalização.
o primeiro é que é realmente dificil, complexo, e gratificante. Afinal para que foram identificados os padrões de projeto ? Porque o GOF escreveu o livro? Para que todo o planeta fique refactorando seu codigo 1000 vezes por ano ? Não me parece. Ha uma vantagem clara em modelar usando padrões. Refactoring nunca poderá competir com isso.
Só que, claro, é preciso saber fazer. Se o cara lhe diz que vai fazer um singleton a sua primeira reação deve ser: “Isso não é um singleton!” Ao que ele responderá : “mas precisamos ter acesso global” , ao que vc responde : “singleton não é para isso”. Não é facil vc explicar para alguem que a classe não é um singleton ( ou qq outro padrão) quando a pessoa tem fracas bases sobre padrões, sobre OO em geral. Eu sei, já fiz isso muito. É frustrante.
É possivel escrever bom codigo sem ser consciente da existencia de padrões : sim, concerteza. Mas é possivel escrever bom código sem que os padrões estejam lá ? Não. Portanto só ha duas alternativas: a) vc tem talento inato e colocar os padrões lá sem saber que está fazendo isso. É um dom. b) vc estuda padrões e aprende a aplicá-los.
Vcs acham que talento se aprender ? Eu não acho. Acham que por tentativa e erro a pessoa será tão boa quanto o talentoso? poderá, mas não em tempo que possa competir com a opção b. Portanto eu sigo a segunda hipotese. Não vou perder meu tempo , trabalho manual e paciencia criando algo que sei que não serã bom o suficiente.
V
ViniGodoy
Alguém já viu um código que nunca precisou de refactoring? Eu não.
Em momento nenhum eu falei que você não deveria pensar sobre o código, ou tentar faze-lo da maneira correta. Aliás, fazer um sistema simples e funcional também não é uma tarefa fácil. Envolve projeto e entender a “big picture”.
Mas não creio que sequer seja possível acertar tudo de primeira ou escapar da refatoração. Vai haver refactoring, seja você um grande mestre Yoda da programação, ou não. A diferença é só a quantidade de refatorações que serão feitas, e quando.
Também não falei em programar por experimentação. Isso, novamente, foi você que inferiu. Mas realmente acho importante as refatorações serem constantes, pois nunca vi nenhum programa ou projeto que escapou delas. Aliás, nunca vi um código que nunca precisou ser refatorado. Se você consegue programar assim, talvez deva escrever um livro dizendo como, pois para mim, isso envolve até talentos mediúnicos e sobrenaturais.
Assumir o que você diz, envolveria um projeto perfeito, um entendimento de requisitos perfeito (tanto de sua parte, quanto a de seu usuário), um controle total do ambiente e a certeza total do comportamento do sistema após implementado. E também envolve ter a noção exata de como esse sistema e o ambiente onde ele está evoluirão. Sinceramente, nunca vi ninguém dominar com precisão absoluta todos esses fatores (para não dizer, qualquer um deles).
I
Ironlynx
Taí valiosas dicas!E eu posso citar meu projeto corrente(em Swing) na qual eu nem tenho o domínio de todas as entidades do Sistema(o pessoal do SGB não é nada friendly…) e posso ter que jogar vaárias classes fora a qualquer momento.É um projeto de pesquisa, se eu me ligasse em seguir um padrão X ou Y ficaria louco.Sequer sei se eu vou gerar a base localmente ou vou pegar pedaços(é, pedaços!!!) dos diversos BD´s existentes… isso é mais comum do que muitos imaginam. Engraçado é ficar com o cliente tendo que fazer POT(Programação Orientada a Telas…) e nunca saber se essa telas resistem até a semana seguinte… :roll:
S
sergiotaborda
ViniGodoy:
Alguém já viu um código que nunca precisou de refactoring? Eu não.
Em momento nenhum eu falei que você não deveria pensar sobre o código, ou tentar faze-lo da maneira correta. Aliás, fazer um sistema simples e funcional também não é uma tarefa fácil. Envolve projeto e entender a “big picture”.
Pois, mas tb não disse o contrário…
O ponto não é que refactoring é inutil ou que se o fizer vc é mau programador. Refactoring, como já disse é uma ferramenta util. O ponto é que sempre que vc faz refactoring significa que se enganou no modelo. Mas o modelo muda, poderá dizer. Sim, mas se a mudança é constante, ha padrões para isso também. Como no exemplo do Ironlynx. Deixar que todas as classes mudem a todo o momento é non sense. É preciso ver que é constante e isolá-lo do resto. Utilizar um design que seja cooperante com a mudança e não contra ela. Bridge , Mediator e Interpreter são muito bons para isso. Sempre ha um porto seguro onde se amarrar.
Prometo que é a ultima vez que digo isto, mas preciso deixar bem claro: refactoração é utilizada quando é necessária. Sempre que usar isso representa um atrazo, um custo e um erro. Portanto, não programe à toa só porque depois poderá refactorar. Nem sempre é possivel refactorar depois. “refactor driven development” é suicídio.
Um bom modelo OO não muda quandos os requisitos mudam ele simplesmente é ajustado ( a expressão é tailored). Como uma roupa que ficou larga ela é ajustada. Mas a roupa em si é a mesma.
Quando o seu modelo muda pouco significa que vc matou a charada do melhor modelo que se adqua ao software. Quando muda muito e constantemente vc precisa abstrair mais, deixar o modelo mais flexivel,mais ajustável.
Enfim, padrões são excelentes guias. Guias não são deuses. São para ser estudados e entendidos , não reverenciados e idolatrados. É possivel matar sistemas em nome de -falsos - padrões , mas os padrões verdadeiross realmente não têm culpa. Livros de catalogos deveriam ser mais explicativos , dando exemplos reais.
Eu não aconcelho o GoF para programadores java, perfiro este aqui. Temo que uma segunda edição do GoF traria mais problemas ainda ( DI como padrão é simplesmente horrível ideia e vai causar mais problema que o MVC já causou - e o MVC nem sequer é do GoF).
C
ccaneta
Sergiãoooo !!!
Recomendei o livro de design Patterns Java WorkBook , para a Comunidade Java Livros valeu !!!
T
tivrfoa
javamaniaco:
Não culpo a Sun e nem o Java. Pra ser sincero, nem sei porque tamanha complexidade é dão idolatrada e dão adotada nas empresas e porque, uma linguagem tão mais inteligente, mais fácil de escrever não teve seu lugar ao sol como o Java. Seria porque a Sun já foi bem grande? Talvez, olha o .Net, Microsoft por trás e pum, as empresas grandes adotam.
M
mochuara
Pode ser na sua estrategia waterfall porque ela exige saber de antemao quais são todos requisitos e todos os padrões que existem pra chegar numa solução.
Mas refactoing não é suicidio pra quem planeja baseado em iterações curtas, pelo contrario, é uma pratica essencial porque permite os developers se familiarizarem com o domínio e por conta disso evitar erros na implementação (ou modelo, dá no mesmo). Se vc acha que refactoring é prejudicial deveria ler mais sobre metodologias ageis como XP, Scrum aplicado a projetos reais.
C
ccaneta
Pode ser na sua estrategia waterfall porque ela exige saber de antemao quais são todos requisitos e todos os padrões que existem pra chegar numa solução.
Mas refactoing não é suicidio pra quem planeja baseado em iterações curtas, pelo contrario, é uma pratica essencial porque permite os developers se familiarizarem com o domínio e por conta disso evitar erros na implementação (ou modelo, dá no mesmo). Se vc acha que refactoring é prejudicial deveria ler mais sobre metodologias ageis como XP, Scrum aplicado a projetos reais.
Refatoramos Código ou Requisitos, se for refatorar o requisito não poderíamos intervir na estrutura do código, se fosse para refatorar o Código que comportamentos teríamos aos requisitos, se é que isso impactaria em algo.
O que entendi na observação em ser um suicídio pode ocorrer uma quebra encadeada ao design do projeto, por motivo não intencionais devido a não se ter controle para isso ou tecnologia que faça determinado histórico de mudanças dessa natureza, naturalmente estamos falando de um projeto enorme, mas o que não vem a ser projetos pequenos que podem assumir estruturas maiores futuramente, então como mante-los.
S
sergiotaborda
Pode ser na sua estrategia waterfall porque ela exige saber de antemao quais são todos requisitos e todos os padrões que existem pra chegar numa solução.
Mas refactoing não é suicidio pra quem planeja baseado em iterações curtas, pelo contrario, é uma pratica essencial porque permite os developers se familiarizarem com o domínio e por conta disso evitar erros na implementação (ou modelo, dá no mesmo). Se vc acha que refactoring é prejudicial deveria ler mais sobre metodologias ageis como XP, Scrum aplicado a projetos reais.
Eu não disse que refactoring é prejudicial , eu disse que fazer apenas refactoring é prejudicial.
Mas já que vc é entendido em agilidade e não faz waterfall e tudo isso , explique-nos como monta o product backlog sem que acha planejamento do projeto como um todo e explique-nos o que seria o Brainstorm meatting e como se planeja os seus releases sem ser com antecedência e antes de começar o primeiro sprint. Aliás, diga-nos como calcula o numero de sprints necessários.
Depois explique como refactoring é uma tecnica de scrum e/ou onde scrum menciona tecnicas de programação/desenvolvimento.
Explique também como refactorar é totalmente inócuo ao processo do sprint e não consome qualquer tempo, custo e como não requer nenhum planejamento. Eu gostaria muito de saber como vc usa a diretiva de “re-planeja constantemente” sem ter um plano para começo de conversa.
Depois que vc explicar tudo isto , muito bem explicado, com exemplo práticos e convincentes eu respondo à sua colocação.
G
Guerr
Olá Pessoal!
Muito legal a discussão! Nos últimos 2 anos tive a oportunidade de participar e contribuir com a comunidade de padrões nos eventos SugarLoafPLoP 2008 aqui no Brasil e do PLoP nos EUA (onde Raph Johnson e outros grandes nomes estavam presentes). Esse tipo de discussão ocorre bastante nessa comunidade. Para os interessados acredito que vale a pena dar uma olhada nos artigos dessas conferências e tentar comparecer nos próimos eventos!
[]s
R
rems
Pode ser na sua estrategia waterfall porque ela exige saber de antemao quais são todos requisitos e todos os padrões que existem pra chegar numa solução.
Mas refactoing não é suicidio pra quem planeja baseado em iterações curtas, pelo contrario, é uma pratica essencial porque permite os developers se familiarizarem com o domínio e por conta disso evitar erros na implementação (ou modelo, dá no mesmo). Se vc acha que refactoring é prejudicial deveria ler mais sobre metodologias ageis como XP, Scrum aplicado a projetos reais.
Muito legal a discussão! Nos últimos 2 anos tive a oportunidade de participar e contribuir com a comunidade de padrões nos eventos SugarLoafPLoP 2008 aqui no Brasil e do PLoP nos EUA (onde Raph Johnson e outros grandes nomes estavam presentes). Esse tipo de discussão ocorre bastante nessa comunidade. Para os interessados acredito que vale a pena dar uma olhada nos artigos dessas conferências e tentar comparecer nos próimos eventos!
[]s
Bom, gostaria de saber quais seriam as suas observações já que você Guerra é um conhecedor também sobre o assunto.
; )
C
ccaneta
Recomendo sempre o Blog e o Site também Javabuilding do Sérgio Taborda, tem um ótimo conteúdo e um bom trabalho na certa.
V
ViniGodoy
Bem, acho que estamos num fórum profissional, e eu não deveria estar falando aqui que gambiarra não faz parte de um processo de desenvolvimento sério. Mas, se você acha necessário, já deixo claro, “programar orientado a gambiarra não faz parte de qualquer desenvolvimento sério”. Nesse caso, concordo com você. A técnica pode até funcionar (já que o refactoring efetivamente vai corrigir a gambi), mas certamente será um desperdício hercúleo de tempo e recursos.
Pouco tempo depois que você postou, percebi pq estamos em atrito. Na verdade, é um problema de terminologia. Tailoring, é um ajuste do modelo. A diferença é que o tailoring é um ajuste baseado numa mudança de requisito e pode, efetivamente, alterar o comportamento observável do software.
Falando no modelo, de maneira ampla, concordo parcialmente com você. Refactoring do modelo, ou mesmo o tailoring, geralmente representa mesmo um erro de modelo. Só não creio que erros de modelo possam ser evitados. Daí a importância do ciclo iterativo, onde encaramos erros como parte do processo (e, consequentemente, em muitos processos assim, deixamos de chamar os erros de erros). Parte disso, não é necessariamente falha da análise de requisitos.
O fato é que os usuários não entendem de software, e é só depois das primeiras releases que eles começam a ter uma visão melhor do que o software será, e do que eles podem ou não podem requisitar. Muitas vezes, a implementação gradual faz com que o usuário repense até mesmo o seu processo, e conceitos que ele tinha como importantes anteriormente passam a ser refeitos ou completamente abandonados, outros requisitos surgem. Já vi isso acontecer em todos os sistemas de maior porte que trabalhei.
Um exemplo disso é que já vi o modelo waterfall funcionar supreendentemente bem em sistemas de engenharia, onde o usuário tem uma noção exata do que o software será e que requisitos ele deve atender. Mesmo quando um modelo mais iterativo foi adotado, ele possuia poucas mudanças, quase nenhum retrabalho, e quase nenhuma re-analise de modelo. Não estou falando só de sistemas pequenos e específicos, mas de sistemas grandes, como os presentes em centrais telefônicas.
S
sergiotaborda
Exactamente. Erros do modelo não podem ser evitados, mas essa frase pressupõe que existe um modelo.
O meu ponto é que um modelo não nasce ad doc. Existe um ponto de partida que foi modelado antes do iniciar a implementação antes do sprint 1. Este modelo vai mudar, mas ele existe. quanto mais cuidado foi colocado na sua modelagem,menos alterações serão necessárias depois.
(P.S. eu disse “cuidado” não esforço ou detalhamento)
Básicamente, quanto melhor for a versão zero do modelo, menos ele será alterado. E como torná-lo melhor logo de inicio ? usando patterns. Esse é o meu ponto. Patterns é um catalizador para ter um modelo zero melhor. Não só isso,como para facilitar as futuras alterações que já sabemos irão existir.
C
ccaneta
Pagina 31 - Revista Mundo Java - Edição nº 33
Quando é difícil refatorar
“Existem alguns casos em que a refatoração se torna algo difícil de ser feito, e em sua grande maioria devido a um alto grau de acoplamento entre partes da aplicação.Quando a refatoração a ser feita envolve banco de dados, principalmente quando o mesmo é utilizado em mais de uma aplicação, a situação se complica.O acoplamento da aplicação com a estrutura do banco acaba sendo bem alto, e esta dependência dificulta a refatoração.”
“Pensei nisso antes ou depois do modelo, ou isso pouco importa”
L
Luca
Olá
Minha experiência com sistemas de engenharia vai desde sisteminhas pequenos até projetos de CAD de mais de 5 anos e mais de 5 milhões de dólares.
Acho que defendo o desenvolvimento por trial and error muito antes de alguém ter escrito algum livro sobre desenvolvimento iterativo.
Desenvolvendo sistemas de engenharia já passei por caso em que fiquei 1 mês, repito um mês inteiro tentando fazer funcionar e provar que funcionava uma única fórmula. Meu método de trabalho sempre incluiu desenvolver protótipos para testar o funcionamento do modelo imaginado e muitas e muitas vezes fui obrigado a alterar completamente o modelo porque justamente os testes não deram certo.
Não se esqueçam que as contas em um sistema de cálculo científico são MUITO mais complexas do que qualquer programinha de controle de estoque e faturamento que não passam de contas de somar e diminuir. Antes que algum desavisado me jogue pedras aviso que passei 6 anos da minha vida vivendo de sistemas de controle de estoque, faturamento e outras continhas de somar a mais.
Modelar um sistema na rocha e sair programando sem poder alterar o modelo me parece bem ruim. Talvez sirva para algo bem simples. Mas por exemplo para o Flickr não serviu. Como todos os sabichões daqui devem saber, os caras estavam desenvolvendo um joguinho que incluia um gerenciador de imagens. Em dado momento jogaram tudo fora e passaram a se dedicar somente ao que depois virou o Flickr.
Minha experiência com sistemas que foram modelados completamente errados e depois precisaram ser modificados não me convencem que exista algum Deus poderoso que consiga acertar sempre logo de cara. Falo isto tanto para o código como também para o modelo. E vou além. Acho raro encontrar casos em que o que o cliente pediu foi entendido 100% corretamente pelo arquiteto de software. Há sempre uma boa margem de falha.
Bom, eu realmente não esperava que o que falei valesse para todo e qualquer sistema de engenharia. Realmente, se você tem sistemas onde os cálculos terão de ser desenvolvidos no processo, fica difícil que funcione no modelo waterfall.
No caso, eu trabalhei 6 anos com sistemas de telefonia. Os padrões eram bem definidos, já havia bastante conhecimento de boa parte do processo, já que diversas centrais similares já haviam sido desenvolvidas ao longo dos anos.
Novamente, vale ressaltar que o desenvolvimento não era 100% waterfall. Acho que ninguém hoje em dia é louco de achar que vai fazer tudo num tapa. Mas era bem longe de ser considerado ágil, até porque parte do software estava em firmware, e dependia de um projeto de hardware para funcionar. E o custo para alterar isso, é altíssimo.
Isso é um conceito que hoje pode ser pouco aceitável, já existem protótipos para produzirem ambiente de aceitamento ou não, veja a ferramenta http://www.tersus.com/ e procure ver onde você faz a refatoração, a tecnologia é decisiva na hora de projetar software.
S
sergiotaborda
O ponto é bem aqui (negrito adicionado por mim).
Ninguem está degladiando experiencias. O ponto é muito simples : iterações de processos ageis não são trial and error.
Trial and error (TE) é feito repetidamente, iterações são feitas repetidamente, mas a semelhança acaba ai: na divisão temporal.
E nem sequer ai porque TE só é refeito quando se descobre erro, enquanto agilidade tem iterações pré-programadas.
O que descreveste é mais perto de TDD onde por teste o modelo é evoluido. Em TDD não ha preocupação com padrões ou sequer com OO porque - em tese- essas coisas não serão necessárias. TDD objetiva encontrar a minima solução que satisfaz os testes.
Agilidade, iteração agil, sprint, não é isso. Iteração agil é ter um conjunto de tarefas pré-defenidas e executá-las. Tão simples assim. Acontecem imprevisto, claro - chamados impedimentos - mas não são esperados. A evolução não é baseada em encontrar erros como em TE. Quando se diz que o modelo é feito iterativamente significa que ele é implementado iterativamente, mas o modelo já existe ha priori. O modelo faz parte da propria definição do projeto, do backlog e afeta diretamente as estimativas. O modelo mode ser modificado, mas isso para atender a novos/diferentes requisitos ele não é mudado sem novos requisitos apareçam. Esta é a diferença. Em Trail and erros os requisitos são fixo, e o modelo evolui até satisfazer todos. Em agilidade o modelo satisfaz todos os requisitos conhecidos de começo.
Agora vc fala que é impossivel ter uma epifania para encontrar esse modelo primogénito. Aceitando que isso é verdade, é por isso que existem tecnicas como TDD que são usadas antes de planejar as iterações ( aquilo que se chama iteração zero). Em agil vc pode alocar quantos sprints quiser para achar o modelo que statisfaz todos os requisitos conhecidos, mas para cada sprint vc terá uma meta a alcançar. Apenas Scrum - porque é um processo que sublinha muito fortemente foco é que vc é obrigado a entregar funcionalidade demonstrável a cada sprint. Neste mecanismo vc tem no máximo 1 sprint para conseguir o modelo e algo outro algo que seja demonstrável. por isso é muito preferivel usar o sprint zero (Planning Metings) para polir o modelo ao máximo. E note que isto é feito por todos os participantes não apenas o implementador.
Num sistema cientifico o modelo é dado pela própria ciencia da coisa e o software atua apenas como um teste “unitário” desse modelo. Se o software está sendo usado para encontrar um modelo cientifico desconhecido então está sendo feita a exploração do modelo e não do software. Ou seja, não estamos lidando com um projeto de software como produto.
O ponto importante é que iterações ageis não são tentativas e erros. São coisas bem planejadas baseadas em coisas bem planejadas. Nada é ad doc.
Y
YvGa
Nao entendi o que voce quis dizer com polir o modelo ao maximo, pode exemplificar? Essa frase me passou a nitida impressao de waterfall.
Quando voce diz polir, voce diz implementar as funcionalidades o mais completo possivel e depois usar UI e infra estrutura para demonstrar o que foi implementado? Ou voce diz, debater e desenhar até ter bem definidas as funcionalidades e só entao implementar?
M
mochuara
Pode ser na sua estrategia waterfall porque ela exige saber de antemao quais são todos requisitos e todos os padrões que existem pra chegar numa solução.
Mas refactoing não é suicidio pra quem planeja baseado em iterações curtas, pelo contrario, é uma pratica essencial porque permite os developers se familiarizarem com o domínio e por conta disso evitar erros na implementação (ou modelo, dá no mesmo). Se vc acha que refactoring é prejudicial deveria ler mais sobre metodologias ageis como XP, Scrum aplicado a projetos reais.
O que tem de legal sobre agile la não sei, e confesso que não sinto motivado em ler sobre metodologias ageis num blog de alguém que diz ser suicidio fazer refactoring.
S
sergiotaborda
YvGa:
sergiotaborda:
Agora vc fala que é impossivel ter uma epifania para encontrar esse modelo primogénito. Aceitando que isso é verdade, é por isso que existem tecnicas como TDD que são usadas antes de planejar as iterações ( aquilo que se chama iteração zero). Em agil vc pode alocar quantos sprints quiser para achar o modelo que statisfaz todos os requisitos conhecidos, mas para cada sprint vc terá uma meta a alcançar. Apenas Scrum - porque é um processo que sublinha muito fortemente foco é que vc é obrigado a entregar funcionalidade demonstrável a cada sprint. Neste mecanismo vc tem no máximo 1 sprint para conseguir o modelo e algo outro algo que seja demonstrável. por isso é muito preferivel usar o sprint zero (Planning Metings) para polir o modelo ao máximo. E note que isto é feito por todos os participantes não apenas o implementador.
Nao entendi o que voce quis dizer com polir o modelo ao maximo, pode exemplificar? Essa frase me passou a nitida impressao de waterfall.
Quando voce diz polir, voce diz implementar as funcionalidades o mais completo possivel e depois usar UI e infra estrutura para demonstrar o que foi implementado?
Cruzes!! Não! Achei que todo o mundo soubesse que “modelo” sempre é conceptual. Falha minha.
Ou voce diz, debater e desenhar até ter bem definidas as funcionalidades e só entao implementar?
É mais por ai, debater e desenhar até que o modelo acomode as funcionalidades conhecidas.
Mas o ponto é o que significa na sua frase: “bem definida” ?
Em agil é comum ouvir o termo “well enought” (bem o suficiente). O que isto significa?
Significa que vc tem o modelo que atende os seus requisitos com o menos esforço possível. Mas isso não significa ser preguiçosos. Significa abstrair as coisas a um ponto que a programação é trivial.
Por isso que eu disse polir e não especificar.
VC sabe que todo e qualquer modelo que fizer será um modelo cru, que terá que ser melhorado. Mas isso não é desculpa para começar com um pedragulho de 2 tonelas e ir esculpindo com uma agulha.
Vc quer alterá-lo o menos vezes possivel ou seja, cada alteração tem que ser a mais eficaz possível.
Por exemplo, estamos fazendo um sistema de ERP e temos o modulos financeiro para fazer. Quem é o idiota que não usara o padrão de conta para modelar contas financeiras ? Simplesmente não faz sentido começar do zero com um modelo de entidades à toa para daqui a cinco anos descobrirmos por tentantiva e erro que o modelo de conta é o melhor para modelar este tipo de dominio. Estamos fazendo um sistema e-comerce que precisa atender um milhão de pessoas por dia. Quem vai ter a ideia de usar session para controlar os dados do usuário ? Clusterirzar session ? sim, claro, os constainers fazem isso, mas é muito melhor não precisar de fazer clustereização de session. Trabalhar com numeros e usar double? Todo o mundo já cansou de dizer que não é para usar double! A desculpa esfarrapada do costume :" … usamos double porque não necessitamos de muita precisão… " o que raios isso sequer signifca ? Ou pior ainda “usamos double porque é mais rápido que BigDecimal”…
Existem erros graves que vc pode cometer facilmente que podem facilmente ser retirados do modelo numa fase muito pre-liminar. Aplicar boas práticas e patterns é uma forma simples e rápida… bom, ok, não é simples, mas é rápida- de polir o modelo. Estamos falando de algumas horas , não dias. Estamos falando de juntar toda a equipa e sincronizar o que cada um pensa e o que pode trazer a mesa.
O exemplo muito tipo de falta de polimento é trabalhar com grandes massas de dados. O programador que caiu no conto da refactoração mágica e pensa que se retorar um List pode mandar quantos objetos forem precisos. Até que lhe aparece um OutofMemoryError na cara e ele fica desesperado e vem no GUJ perguntar como aumenta a memoria. Ai mandam-o fazer um profiling… o erro era claro do inicio. Se é preciso lidar com muitos dados List não fai dar. Pelo menos não ArrayList … o padrão Fast lane precisa ser usado. Afinal , como raios vcs pensam que funciona um ResultSet ? E ele implementa List ?
Muitos padrões são óbvios pelo próprio domínio, outros pelo contexto, outros apenas se vc tem experiencia e já viu o problema antes. Mas sempre, sempre , vc pode melhor o modelo.
O sistema manipula dinheiro ? Money de cara. Sem conversa. Não vamos perder tempo usando BigDecimal , DOuble ou double , ou pior , float, porque “o nosso sistema não precisa de precisão” ( pun intended)
Ha erros que são muito grosseiros e isso pode ser polido logo no inicio. Coisas mais complexas vc só descobre depois, mas por razão das circustancias, não que vc fez seu modelo ser limitado de propósito e esperou ele gritar para ir lá e mudá-lo.
Polir significa conversar, experimentar o modelo conceitualmente em vários cenários (aqueles que já foram levantados que serão necessários) e modelar. Modelar é legal! OO é só modelagem. Eescrever código qualquer cara de 10 anos sabe.
Vamos deixar uma coisa clara - mais uma - se modelar fosse tão ruim, tão anti-util , se tivessemos tanto que evitar modelar, porque raios somos bombardeados com metodologia focadas em encontra o mellhor modelo ? Porque se fala de patterns ? porque se fala de bad smells, anti-patterns, boas práticas , etc… ? Será que é porque modelar é ruim ? ou será que é porque a maioria das pessoas é um mau modelador ?
Porque estariamos interessados numa segunda edição do GoF se patterns não fosse realmente util ?
M
mochuara
sergiotaborda:
Vamos deixar uma coisa clara - mais uma - se modelar fosse tão ruim, tão anti-util , se tivessemos tanto que evitar modelar, porque raios somos bombardeados com metodologia focadas em encontra o mellhor modelo ? Porque se fala de patterns ? porque se fala de bad smells, anti-patterns, boas práticas , etc… ? Será que é porque modelar é ruim ? ou será que é porque a maioria das pessoas é um mau modelador ?
Se vc faz a modelagem no início que não é por meio de codigo, como vc comunica este modelo? UML? telepatia?
Se o modelo não é executável como podemos acreditar que ele funciona sem depender apenas da palavra do modelador? (eu penso que o modelo funcionar na cabeca de alguém é uma coisa, ser compilado e executado numa maquina é outra completamente diferente, logo se seu modelo não é executável não é um modelo confiável.).
Ninguem esta questionando modelagem, e sim o que VOCE considera modelagem. VOCE considera o modelo como algo que não é o código, mas não sabe dizer o que é alem de dizer que são “patterns” e eles irão salvar o mundo. Ao mesmo tempo vc diz que não faz BDUF, mas ta dificil ver isto como não-waterfall. (E veja bem, não tenho nada contra waterfall. O que tenho contra é chamar de Scrum o que é waterfall.)
Voce diz que qualquer garoto codifica, mas diz que não é qualquer um que modela. Qual é a sua atual definição para aqueles que modelam diretamente no código?
Se vc precisa lidar com patterns é sinal que sua linguagem falta abstrações necessarias (o que é muito comum no caso da linguagem Java). Ainda assim não acho que patterns sejam inuteis. Eles são uteis, no código da concorrência.
Y
YvGa
Bom, quando voce diz que se trata de horas e nao de dias, nao tenho porque discordar.
Só o que eu nao pude deixar de reparar é o seu desdem por TDD, me passou a impressao que voce considera TDD o mesmo que code and fix o que nao esta nem perto da verdade. Voce poderia dizer que TDD é design and fix, aí até posso concordar, mas de todas as formas de design que conheco é de longe a mais eficaz.
Se voce precisa do fix é porque errou e se errou precisa saber disso o quanto antes, se voce tem apenas um modelo conceitual nao é possivel saber se ele é o melhor modelo possivel, porque ele é apenas conceitual, até que ele seja testado. Mas se o modelo so vai ser implementado e testado depois de “conceitualmente pronto” voce vai estar testando seu codigo, nao seu design e se seu design esta errado os testes nao vao apontar o erro.
Se estou errado sobre sua impressao de TDD, ignore meu post.
Com certeza absoluta um de nos dois tem uma definicao errada sobre modelo. Onde voce viu alguem dizer que modelar é inutil? quem disse que temos que evitar modelar? O que é dito é que a tentativa de obter projetar de ante-mao o modelo perfeito é ruim, anti-util e que temos que evitar por motivos obvios.
P
Paulo_Silveira
YvGa:
Com certeza absoluta um de nos dois tem uma definicao errada sobre modelo. Onde voce viu alguem dizer que modelar é inutil? quem disse que temos que evitar modelar? O que é dito é que a tentativa de obter projetar de ante-mao o modelo perfeito é ruim, anti-util e que temos que evitar por motivos obvios.
Comentário perfeito! Evitar o big design up front. Tem gente contra (ou entao usam definicoes diferentes para BDUF, em quao BIG é esse B).
M
mochuara
Paulo Silveira:
YvGa:
Com certeza absoluta um de nos dois tem uma definicao errada sobre modelo. Onde voce viu alguem dizer que modelar é inutil? quem disse que temos que evitar modelar? O que é dito é que a tentativa de obter projetar de ante-mao o modelo perfeito é ruim, anti-util e que temos que evitar por motivos obvios.
Comentário perfeito! Evitar o big design up front. Tem gente contra (ou entao usam definicoes diferentes para BDUF, em quao BIG é esse B).
Posso ate concordar que na maioria dos casos fazer BDUF pode ser prejudicial. Mas dizer que precisa ser evitado sempre seria bom vir acompanhado do porque, senão saimos de um extremo (sergiotaborda) para o outro (paulosilveira).
A verdade é que, se vc programa em Java, .NET (e outras linguagens estaticas meia boca) algum tipo de BDUF precisa ser feito. Quem não gosta de BDUF deve preferir outra linguagem pra trabalhar.
Y
YvGa
mochuara:
Comentário perfeito! Evitar o big design up front. Tem gente contra (ou entao usam definicoes diferentes para BDUF, em quao BIG é esse B).
Posso ate concordar que na maioria dos casos fazer BDUF pode ser prejudicial. Mas dizer que precisa ser evitado sempre seria bom vir acompanhado do porque, senão saimos de um extremo (sergiotaborda) para o outro (paulosilveira).
A verdade é que, se vc programa em Java, .NET (e outras linguagens estaticas meia boca) algum tipo de BDUF precisa ser feito. Quem não gosta de BDUF deve preferir outra linguagem pra trabalhar.
Talvez seja porque sempre trabalhei num mesmo nicho de mercado (aplicacoes gerenciais) que nao consigo ver onde definir detalhes da implementacao possa ser benefico. E tambem nao creio que preciso dar exemplos, com BDUF voce esta desperdicando esforco, porque em 100% dos projetos que participei do inicio ao fim, o que se imaginava do software no inicio foi substancialmente diferente do que foi colocado em producao.
Como disse, nao sei se em outras areas projetar completamente antes de implementar é benefico de alguma forma.
O que seria bom vir acompanhado do porque sao as excecoes a regra.
T
Thiago_Senna
web2py é feito em python e toda sua api foi pensada e criada antes de sua implementação. Achei interessante postar isso pq as colocacoes do Mochuara, Yuga e Paulo foram interessantes e acho que o extremo sempre será perigoso. Qualquer um dos extremos é bom ter justificativa (ou ser evitado :P)
G
giulianocosta
Uma dúvida, estou metendo a mão agora num sisteminha de controle financeiro. Fico na dúvida de como eu usaria o Patter Account em outra linguagem dita mais dinâmica. Scala já tem esse Pattern? Ruby já tem esse Pattern?
M
mochuara
giulianocosta:
mochura:
Se vc precisa lidar com patterns é sinal que sua linguagem falta abstrações necessarias (o que é muito comum no caso da linguagem Java). Ainda assim não acho que patterns sejam inuteis. Eles são uteis, no código da concorrência.
Uma dúvida, estou metendo a mão agora num sisteminha de controle financeiro. Fico na dúvida de como eu usaria o Patter Account em outra linguagem dita mais dinâmica. Scala já tem esse Pattern? Ruby já tem esse Pattern?
A questão não é ser dinâmica (scala é estatica), mas sim ser estensivel. As linguagens que vc mencionou podem ser estendidas para introduzir o pattern que lhe faltam (de uma forma que não é possível com Java).
G
giulianocosta
mochuara:
giulianocosta:
mochura:
Se vc precisa lidar com patterns é sinal que sua linguagem falta abstrações necessarias (o que é muito comum no caso da linguagem Java). Ainda assim não acho que patterns sejam inuteis. Eles são uteis, no código da concorrência.
Uma dúvida, estou metendo a mão agora num sisteminha de controle financeiro. Fico na dúvida de como eu usaria o Patter Account em outra linguagem dita mais dinâmica. Scala já tem esse Pattern? Ruby já tem esse Pattern?
A questão não é ser dinâmica (scala é estatica), mas sim ser estensivel. As linguagens que vc mencionou podem ser estendidas para introduzir o pattern que lhe faltam (de uma forma que não é possível com Java).
E Java não? Eu posso criar um framework que me abstraia isso da aplicação. Lógico que java não terá alguns “tricks” que teria em Ruby, por exemplo.
Aqui a gente vai voltar a uma discussão lá do início do tópico. Patterns nada tem a ver com linguagens de programação. Pode ser que em algumas linguagens seja mais fácil de contornar um problema por ela te prover um acesso mais abstrato ao problema. Mas isso, em momento algum, torna falseável a utilização dos Patterns.
S
sergiotaborda
mochuara:
sergiotaborda:
Vamos deixar uma coisa clara - mais uma - se modelar fosse tão ruim, tão anti-util , se tivessemos tanto que evitar modelar, porque raios somos bombardeados com metodologia focadas em encontra o mellhor modelo ? Porque se fala de patterns ? porque se fala de bad smells, anti-patterns, boas práticas , etc… ? Será que é porque modelar é ruim ? ou será que é porque a maioria das pessoas é um mau modelador ?
Se vc faz a modelagem no início que não é por meio de codigo, como vc comunica este modelo? UML? telepatia?
Que tal conversar ? Já pensou nisso ?
Se vc modela em grupo vc modela na frente de um papel ou quadro e faz bonecos e pela participação de todos se chega num modelo. O modelo não é o que está escrito no papel/quadro. O modelo é aquilo que foi entendido. Ha pessoas que nem precisam de papel e lápis…mas são raras.
Se vc modela sozinho o processo é o mesmo, mas aqui, porque vc apenas pensa e não precisa verbalizar e argumentar é muito mais rápido. Claro que menos eficaz porque uma pessoa sozinha só tem uma prespectiva do problema.
Veja bem, o modelo não é executável porque ele não é fisico, rela, palpavel. Ele existe apenas na cabeça das pessoas e como “directriz” no código. O codigo não é o modelo, é uma representação do modelo. Um UML é outra representação, um teste unitário é outra, um teste de integração é outra e assim vai. São vais faces da mesma coisa, mas a coisa em si mesma não está lá na realidade.
As pessoas usam as suas cabeças para pensar -bom, algumas usam- se o modelo vai ou não ser compativel com os cenários levantados. Repare que um bom modelo pode ser dificil de implementar e uma fácil implementação não é necessáriamente um bom modelo. O modelo tem N implementações possiveis em uma linguagem. Multiplique isso pelas M linguagems que são candidatas e vc terá muitas opções de implementação. o modelo para somar dois numeros é simples, mas a implementação pode ser complexa se eles forem numeros complexos.
Quando vc implementa e executa e dá certo, vc está mostrando que a sua implementação do modelo é válida. Se não funciona não é necessáriamente porque o modelo falha, pode ser a implementação que está errada.
Modelo executável é muito lindo conceptualmente, mas não existe na prática. O que, na prática, se chama “modelo executável” é uma implementação que se vincula artificalmente ao modelo, como se o modelo só podesse ter uma,e apenas uma implementação.
Se isso fosse verdade e o modelo só tivesse uma implementação, essa implementação do modelo não poderia evoluir. E isso não acontece. Para um mesmo modelo a implementação pode evoluir por si.
bom, na realidade não precisa de mim para saber o que é o modelo. Leia sobre modelagem e vc vai entender se ainda restam duvidas. Está-se questionando modelagem sim. Está-se dizendo que não é preciso começar fazendo um modelo. que o modelo nascerá do codigo mágicamente depois de algumas iterações de tentativa e erro. Este modelo pode funcionar quando vc é amador, ou estudante, mas profissionalmente não funciona. Profissionalmente vc precisa dar aval e se comprometer com qualidade e resultados que vc não pode garantir se esperar por milagres do codigo.
Eu acho simples de entender. Vc tem o modelo e vc tem a implementação numa relação 1 para muitos. portanto não ha como dizer que a implementação é o modelo.
Independentemente do que considero que seja o modelo, se ele fica no codigo ou não, o ponto é que tem que existir um modelo.
Uma equipe não pode simplesmente sai programando cada um para seu lado sem que haja um objetivo comum, um algo a alcançar. E esse algo precisa ser compartilhado de forma que todos saibam o que estão tentado alcançar e um caminho tem que ser traçado.
quando vc usa um mapa vc escolhe um caminho. Vc não sabe o que irá acontecer ao longo do percurso que imprevistos haverão. Vc só sabe que a estrada x liga A a B. Agora imagine ir de A a B sem mapa. Vc chega lá, mas não de forma eficaz.
Vc quer ser um vagabundo de código que vai de A a B por tentativa e erro ou vc quer ser um profissional que sabe usar um mapa para ir de A a B ?
BDUF é muito mal compreendido e o pessoal de pseudo-agil usa isso para enganar as criancinhas. BDUF ser ruim é mesmo tipo de asneira que uma equipa sem PO dizer que scrum é ruim.
BDUF não é waterfall. Up front significa no principio. Não significa , “para sempre”.(aliás uma metodologia de desenho não pode comparado a um processo de gerenciamento, mas tudo bem… vou dar essa de barato …)
Como o Paulo falou o problema é na definição de “Big”. Tem uns que acham que Big significa “com todo o detalhe”. Se fosse assim seria big Specification up front. outros, como eu acham que Big design é uma expressão só, como “big picture”. Portanto, BDUF é uma forma compreensivel de enxergar agora as partes necessárias ao sistema. Desse entendimento (eu disse entendimento) são traçadas estratégias tanto de codificação como de organização, para os sprints. Por exemplo, das estorias do backlog vc sabe que existirá uma integração com um sistema proprietáriio de outra empresa. Vc faz um design logo de inicio que separa a responsabilidade da integração do uso. Vc usa truques de programação como uso de interfaces e bridge para isolar o problema da integração em si, que como sabemos é de risco elevado. no primeiro sprint essa estrutura é montada. Todo o mundo sabe o que está fazendo e porquê. No segundo sprint e feito um strub, ou seja,uma classe que parece se comportar como o serviço real, mas não é. Isso permite que sempre possa haver uma demo no final do sprint sem que aintegração exista de fato. lá pelo 8 sprint a integração real está completa. Porque foi implementada a classe real que comunica com o outro sistema. Refactoring zero. Risco zero. Porque houve um design logo de inicio que entendeu “the big picture” e solucionou sem esforço. O mecanismo é ha prova de alterações por design , não por engenharia. Imagine agora que no 5° sprint o PO fala que o contrato com a empresa que iria fornecer o serviço foi abortado e que em vez será feita a interface com outro sistema de outra companhia. O que mudou para a equipe e para o projeto ? Nada. A estratégia continua sendo a mesma e no 8° sprint continuaremos tendo a integração real completada. Reação à mudança se planeja. Simplesmente mudar tudo pela pura força bruta é um trabalho herculeano. E Hercules é um cara da mitologia, ou seja, não existe de facto ninguem que possa apenas pela força bruta mudar as coisas.
O problema com o BDUF é modelar coisas que serão inuteis. Coisas a mais. Se vc se deixar levar vc tá ferrado. Mas se vc modelar apenas o suficiente isso tem muitos ganhos. O fato de ter um plano, ter um design no inicio do projeto ajuda em muitas coisas. Ajuda na comunicação, ajuda no foco, ajuda do compromisso. Como as pessoas se podem comprometer como que é desconhecido ?
Scrum é planejamento. Tudo é planejado. A diferença para o processo tradicional é que o plano é mutável. Constantemente. Planejar é tudo , o plano é nada.
Mas um plano só pode ser mudado se ele existir. Essa é a máxima do scrum e do agil em geral. Panning Poker, Sprint Planning, Scrum Planning … nos livros vc lê “O scrum começa com o projet backlog” ,ok, mas como se chegou nisso ? magia ? epifania ?
Vc ainda não respondeu como cria o Product Backlog sem ter um modelo. Nem explicou como a equipe pode criar o sprint log sem ter um modelo. Como vc acha que se chega num backlog de produto. Como você chega em um ?
Se vc precisa lidar com patterns é sinal que sua linguagem falta abstrações necessarias (o que é muito comum no caso da linguagem Java). Ainda assim não acho que patterns sejam inuteis. Eles são uteis, no código da concorrência. :)
Ok, já sabemos a sua opinião sobre a utilidade do patterns e os fracasso das linguagens OO. não ha nenhuma que tenha todos os padrões incluidos, logo, todas são imcompletas se seguirmos a sua definição. informação tautologica é informação inutil.
C
Crocodilo
sergiotaborda:
Neste mecanismo vc tem no máximo 1 sprint para conseguir o modelo e algo outro algo que seja demonstrável. por isso é muito preferivel usar o sprint zero (Planning Metings) para polir o modelo ao máximo. E note que isto é feito por todos os participantes não apenas o implementador.
Que outras responsibilidades são compartilhadas no Sprint zero, como isso é feito por participantes que não são implementadores, simplesmente opinam ?
S
sergiotaborda
Crocodilo:
sergiotaborda:
Neste mecanismo vc tem no máximo 1 sprint para conseguir o modelo e algo outro algo que seja demonstrável. por isso é muito preferivel usar o sprint zero (Planning Metings) para polir o modelo ao máximo. E note que isto é feito por todos os participantes não apenas o implementador.
Que outras responsibilidades são compartilhadas no Sprint zero, como isso é feito por participantes que não são implementadores, simplesmente opinam ?
Antes de começar os sprints é preciso um backlog e é preciso estimá-lo em SP.
O desenho do backlog, o que vai e não vai, como vai, separação de estoria, fusão de estorias,etc é um trabalho conjunto do PO equipa e SM (para impor as regras scrum), mas o PO pode trazer que precisar, tlv um perito no dominio. A responsabilidade é do PO, mas ha feedback de todos os interessados, sobretudo da equipe de desenvolvedores. E sim, eles opinão. Argumentam, exercitam os cenários, etc… é um brainstorm completo. Galinhas podem participar também , mas eles participam como adjuntos ao processo para esclarecer coisas e ajudar ao brainstorm. (Galinhas são pessoas que não são diretamente comprometidas com o projeto mas participam dele de alguma forma. o exemplo simples: perito no dominio)
Veja o desenho aqui . Esta imagem acompanha um texto escrito pelo ken schwaber ( o cara que 'inventou" o scrum).
Veja que ha um passo que não é iterativo que dá o pontapé no ciclo de sprints. Este passo é o passo de planejamento.
R
rems
Onde isso foi dito? “refactor driven development é suicidio” para voce siginifica “refactor é suicidio”???
Acho que voce se enganou… ou voce tambem acha que dizer “não uso test driven development” é a mesma coisa de dizer “não faço testes nenhum”???
F
faelcavalcanti
falando em design patterns, e meio que de última hora, para quem é de recife, amanhã vai rolar um mini-curso que estarei dando sobre design patterns.
fiquei meio off, e achei muito legal esta thread, e não tinha visto! obrigado paulo por nos elucidar!
Se vc precisa lidar com patterns é sinal que sua linguagem falta abstrações necessarias (o que é muito comum no caso da linguagem Java). Ainda assim não acho que patterns sejam inuteis. Eles são uteis, no código da concorrência.
Uma dúvida, estou metendo a mão agora num sisteminha de controle financeiro. Fico na dúvida de como eu usaria o Patter Account em outra linguagem dita mais dinâmica. Scala já tem esse Pattern? Ruby já tem esse Pattern?
A questão não é ser dinâmica (scala é estatica), mas sim ser estensivel. As linguagens que vc mencionou podem ser estendidas para introduzir o pattern que lhe faltam (de uma forma que não é possível com Java).
E Java não? Eu posso criar um framework que me abstraia isso da aplicação. Lógico que java não terá alguns “tricks” que teria em Ruby, por exemplo.
Aqui a gente vai voltar a uma discussão lá do início do tópico. Patterns nada tem a ver com linguagens de programação. Pode ser que em algumas linguagens seja mais fácil de contornar um problema por ela te prover um acesso mais abstrato ao problema. Mas isso, em momento algum, torna falseável a utilização dos Patterns.
Não. A linguagem Java não foi feito pra ser extensível, por isso frameworks Java não chegam nem perto de obter o mesmo resultado que linguagens feitas pra serem extensíveis, eles apenas varrem a sujeita pra debaixo do tapete.
giulianocosta:
Aqui a gente vai voltar a uma discussão lá do início do tópico. Patterns nada tem a ver com linguagens de programação. Pode ser que em algumas linguagens seja mais fácil de contornar um problema por ela te prover um acesso mais abstrato ao problema. Mas isso, em momento algum, torna falseável a utilização dos Patterns.
É fato que patterns tem que ser utilizados aos montes por programadores Java, enquanto que outras linguagens ditas de alto-nivel é possivel abstrair os patterns dos seus programadores. Portanto não consigo chegar na mesma conclusão que vc, patterns tem TUDO A VER com a linguagem de programação utilizada.
M
mochuara
Não entendi essa parte.
Bom, eu trabalho com a perspectiva de que o código é o modelo, e o bytecode é uma representação deste modelo, gostaria de saber sua opinição sobre isto.
G
giulianocosta
O que tu entendes como uma linguagem “extensível”?
Bom, vamos partir para exemplor práticos. Estou construindo um sistema contábil em Java atualmente e quero utilizar o conceito de Contas, Lançamentos, Estornos, Eventos, etc… (Account Pattern)
Me diz, a “API” ou “Mandinga” do Ruby que vai resolver os problemas que esse Pattern em questão me resolve?
Neste link(http://www.dsc.ufcg.edu.br/~jacques/cursos/map/html/ap/fin/intro.html) tem uma referência do Pattern que estou falando.
M
mochuara
Eu chego a essas respostas com estimativas baseado, entre outras coisas, nos requisitos do sistema. Parece que o que vc chama de modelo é o que eu chamo de estimar, supor. Não concordo que patterns sejam uteis nessa fase inicial e por isso cheira waterfall o que vc descreve pra mim e outras pessoas aqui do forum.
G
Guerr
ccaneta:
Bom, gostaria de saber quais seriam as suas observações já que você Guerra é um conhecedor também sobre o assunto.
; )
Na verdade temos diversas técnicas para nos auxiliar no momento de realizar a modelagem de um sistema como a criação de diagramas, TDD, refactoring e etc… Antes do refactoring não existia nenhuma técnica que permitia que você trabalhasse em cima da modelagem depois que o código estivesse pronto. Por isso as técnicas de modelagem mais antigas buscavam uma solução definitiva que procurava prever todas futuras questões que poderiam surgir e isso é que as tornavam não-ágeis. Utilizando essas técnicas em conjunto com refactoring, não existe mais aquela idéia de encontrar “a solução” e sim de encontrar uma solução que funcione. Se ela não for a melhor, refatore depois!
O balanço do quanto de modelagem deve ser feito antes e depois acho que é um equilíbrio que cada equipe deve buscar. Se existisse uma receita de bolo, não teria muita graça, não é mesmo…
S
sergiotaborda
mochuara:
sergiotaborda:
Modelo executável é muito lindo conceptualmente, mas não existe na prática. O que, na prática, se chama “modelo executável” é uma implementação que se vincula artificalmente ao modelo, como se o modelo só podesse ter uma,e apenas uma implementação.
Se isso fosse verdade e o modelo só tivesse uma implementação, essa implementação do modelo não poderia evoluir. E isso não acontece. Para um mesmo modelo a implementação pode evoluir por si.
Não entendi essa parte.
Bom, eu trabalho com a perspectiva de que o código é o modelo, e o bytecode é uma representação deste modelo, gostaria de saber sua opinição sobre isto.
Bom, eu não vejo assim. Existe uma relação directa e até bijetiva entre o codigo e o bytecode chamadas compilador e descompilador.
Suponho que em algum contexto se possa pensar no codigo como sendo o modelo, mas é a primeira vez que ouço isso e simplesmente , para mim, não faz sentido. Modelo é o que deu origem ao código em primeiro lugar. Ou melhor, modelo é a razão para o codigo ser assim e não de outra forma.
S
sergiotaborda
mochuara:
sergiotaborda:
Scrum é planejamento. Tudo é planejado. A diferença para o processo tradicional é que o plano é mutável. Constantemente. Planejar é tudo , o plano é nada.
Mas um plano só pode ser mudado se ele existir. Essa é a máxima do scrum e do agil em geral. Panning Poker, Sprint Planning, Scrum Planning … nos livros vc lê "O scrum começa com o projet backlog" ,ok, mas como se chegou nisso ? magia ? epifania ?
Vc ainda não respondeu como cria o Product Backlog sem ter um modelo. Nem explicou como a equipe pode criar o sprint log sem ter um modelo. Como vc acha que se chega num backlog de produto. Como você chega em um ?
Eu chego a essas respostas com estimativas baseado, entre outras coisas, nos requisitos do sistema. Parece que o que vc chama de modelo é o que eu chamo de estimar, supor.
Não. Se é isso que lhe parece vc não está dentro do contexto. Modelo não é estimar. Isso não faz sentido.
Não concordo que patterns sejam uteis nessa fase inicial e por isso cheira waterfall o que vc descreve pra mim e outras pessoas aqui do forum.
Obviamente que design patterns não servem para estimar. Mas nunca ninguem falou que sim. Isso foi vc que entendeu.
Requisito é o que o cliente deseja, modelo é um conjunto de ideias de como podemos satisfazer esse desejo. Vc não implementa requisito por requisito. Com 1000 requisitos vc não tem 1000 softwares. O modelo é o que lhe permite condensar esses 1000 requisitos em N (N<<<< 1000) funcionalidades que serão implementadas.
por exemplo, existem inumeras formas de montar uma expressão matemática. Um interpretador de expressões matemáticas utiliza um modelo que permite tratar todas independentemente de quais são. O que estou dizendo é que para cada situação existe um modelo melhor que uma implementação ad hoc. O desenvolvedor deve procurar esse modelo e basear-se nele. Como vc faria um intepretador de expressões matemáticas? Cada um faria de um jeito. Mas se vc souber que o modelo - comprovadamente melhor- é o de um stack (pilha) vc estaria começando com muita vantagem em relação a alguem que começou ad doc. Pilha é um modelo. Utilizar a pilha para esse fim é um modelo. Depois teremos uma implmentação disso, mas o foco aqui é no modelo em si.
Agora que sei que devo ter uma pilha de expressões matemáticas tão simples que as possa computar, vou estruturar meu modelo de classes em torno disso. alguns padrões que me podem ser uteis eu já conheço ( Interpreter e Iterator, por exemplo) mas isso não significa que vou arranjar um jeito de os colocar lá. O que vou fazer é seguir OO até encontrar todas as classes e responsabilidade. Todo este mecanismo estara em uma classe de forma que possa fazer classe.calculate("2+4") e essa classe é por definição um interpreter. Isso já me dá uma visao de quais outras classes preciso, e assim vai. O padrão é uma ajuda, um catalizador do processo de modelagem mas o processo em si é guiado por regras OO como injeção de dependencia, inversão de controle, separação de responsabilidade, etc…
Depois que tiver o modelo completo que me permite obter de uma expressão matemática o resultado, ai eu vou estimar o esforço para fazer isso.
Eu sigo uma máxima que diz: "não precisa funcionar, tem que ser facil de alterar" se funcionar otimo, se não funcionar, porque é facil de alterar, vc colocar funcionando com pouco esforço.
O meu ponto é apenas que modelar seguindo padrões e boas práticas resulta em um modelo mais proximo do necessário e mais amigável à mudança.
M
mochuara
giulianocosta:
O que tu entendes como uma linguagem “extensível”?
Uma linguagem que permite ser extendida pra acomodar as abstrações que não pertecem ao core da minha aplicação.
giulianocosta:
Bom, vamos partir para exemplor práticos. Estou construindo um sistema contábil em Java atualmente e quero utilizar o conceito de Contas, Lançamentos, Estornos, Eventos, etc… (Account Pattern)
Me diz, a “API” ou “Mandinga” do Ruby que vai resolver os problemas que esse Pattern em questão me resolve?
Neste link(http://www.dsc.ufcg.edu.br/~jacques/cursos/map/html/ap/fin/intro.html) tem uma referência do Pattern que estou falando.
Como falei anteriormente, minha aplicacao deve refletir apenas o core da aplicacao. Não conheco sua aplicação nem o padrão mencionado, mas se este é identificado por vc mesmo como sendo o core não faz muito sentido em querer que a linguagem abstraia o core do seu próprio código.
Se ocasionalmente sua aplicação precisa persistir em banco de dados, expor uma interface web, exportar dados pra XML ou qualquer coisa que não faz parte do core da aplicação não deveria usar patterns pra isto numa linguagem de alto nivel, extensivel. (Não sou a pessoa mais indicada pra falar de Ruby, mas creio que Ruby seja um avanco em relação a Java nesse sentido).
S
sergiotaborda
mochuara:
giulianocosta:
Bom, vamos partir para exemplor práticos. Estou construindo um sistema contábil em Java atualmente e quero utilizar o conceito de Contas, Lançamentos, Estornos, Eventos, etc… (Account Pattern)
Me diz, a “API” ou “Mandinga” do Ruby que vai resolver os problemas que esse Pattern em questão me resolve?
Neste link(http://www.dsc.ufcg.edu.br/~jacques/cursos/map/html/ap/fin/intro.html) tem uma referência do Pattern que estou falando.
Como falei anteriormente, minha aplicacao deve refletir apenas o core da aplicacao. Não conheco sua aplicação nem o padrão mencionado, mas se este é identificado por vc mesmo como sendo o core não faz muito sentido em querer que a linguagem abstraia o core do seu próprio código.
Se ocasionalmente sua aplicação precisa persistir em banco de dados, expor uma interface web, exportar dados pra XML ou qualquer coisa que não faz parte do core da aplicação não deveria usar patterns pra isto numa linguagem de alto nivel, extensivel.
Você está claramente confundindo patterns com API. O que singifica que todo este tempo vc não sabia do que estava falando quando disse que patterns servem para compensar defeitos das linguagens. Linguagens não fazem nada. elas servem para criar quem faça. API padrão como a JSE são classes já criadas e testadas para diversos fins. A criação dessas classes é orientada a objetos e portanto deve seguir os mesmos padrões que qualquer outra classe seja de aplicação ou não. Padrões de Projeto são utilizados nessas API como em qualquer outra API. Nenhuma linguagem exporta para XML ou tem ORM sem ter uma API para isso. ActiveRecord do Ruby, embora utilize o nome e o conceito do padrão ActiveRecord é uma API , não é um design pattern que a linguagem tem. O que torna a API ActiveRecord do Ruby interessante é que ela usa o suporte a meta-class do ruby para adicionar métodos em runtime a qualquer classe. Isso tb pode ser feito em Java, apenas a implementação e a chamada no codigo será diferente porque a linguagem é diferente. Mas a API é a mesma e faz o mesmo.
Confundir a API ActiveRecord com o padrão ActiveRecord é um erro grosseiro. Se é isso que vem acontecendo neste e noutros topicos pelo pessoal que defende que patterns é defeito da linguagem e que java usa tantos patterns porque é imcompleta, bom, simplesmente vcs não sabem do que estão falando. Não a linguagem que usa padrões é a modelagem OO. E modelagem OO existe em qualquer linguagem OO.
G
giulianocosta
Cara, sinceramente não da pra te entender. Aqui tu diz:
Tu deixa claro que só Java tem que se usar Design Patterns e em outras linguagens de mais alto nível eles são absorvidos pela linguagem.
E aqui tu fala que não teria sentido, no caso o “Ruby”, a exemplo, abstrair o tal Pattern que estou citando. Mas ao mesmo tempo tu da a idéia que Patterns só são usados por Desenvolvedores Java e que em linguagens como Ruby não são necessários.
Sinceramente não consigo te entender. Ou você não leu todo o tópico ou você não faz a minima idéia do que um Pattern venha ser.
R
rems
sergiotaborda:
mochuara:
giulianocosta:
Bom, vamos partir para exemplor práticos. Estou construindo um sistema contábil em Java atualmente e quero utilizar o conceito de Contas, Lançamentos, Estornos, Eventos, etc… (Account Pattern)
Me diz, a “API” ou “Mandinga” do Ruby que vai resolver os problemas que esse Pattern em questão me resolve?
Neste link(http://www.dsc.ufcg.edu.br/~jacques/cursos/map/html/ap/fin/intro.html) tem uma referência do Pattern que estou falando.
Como falei anteriormente, minha aplicacao deve refletir apenas o core da aplicacao. Não conheco sua aplicação nem o padrão mencionado, mas se este é identificado por vc mesmo como sendo o core não faz muito sentido em querer que a linguagem abstraia o core do seu próprio código.
Se ocasionalmente sua aplicação precisa persistir em banco de dados, expor uma interface web, exportar dados pra XML ou qualquer coisa que não faz parte do core da aplicação não deveria usar patterns pra isto numa linguagem de alto nivel, extensivel.
Você está claramente confundindo patterns com API. O que singifica que todo este tempo vc não sabia do que estava falando quando disse que patterns servem para compensar defeitos das linguagens. Linguagens não fazem nada. elas servem para criar quem faça. API padrão como a JSE são classes já criadas e testadas para diversos fins. A criação dessas classes é orientada a objetos e portanto deve seguir os mesmos padrões que qualquer outra classe seja de aplicação ou não. Padrões de Projeto são utilizados nessas API como em qualquer outra API. Nenhuma linguagem exporta para XML ou tem ORM sem ter uma API para isso. ActiveRecord do Ruby, embora utilize o nome e o conceito do padrão ActiveRecord é uma API , não é um design pattern que a linguagem tem. O que torna a API ActiveRecord do Ruby interessante é que ela usa o suporte a meta-class do ruby para adicionar métodos em runtime a qualquer classe. Isso tb pode ser feito em Java, apenas a implementação e a chamada no codigo será diferente porque a linguagem é diferente. Mas a API é a mesma e faz o mesmo.
Confundir a API ActiveRecord com o padrão ActiveRecord é um erro grosseiro. Se é isso que vem acontecendo neste e noutros topicos pelo pessoal que defende que patterns é defeito da linguagem e que java usa tantos patterns porque é imcompleta, bom, simplesmente vcs não sabem do que estão falando. Não a linguagem que usa padrões é a modelagem OO. E modelagem OO existe em qualquer linguagem OO.
:shock: bem que parece mesmo que voces estavam falando sobre coisas diferentes…
M
mochuara
giulianocosta:
Sinceramente não consigo te entender.
Percebi que isso ia acontecer quando chamou de “tricks” se referindo aos recursos de metaprogramacao e DSLs do Ruby.
M
mochuara
sergiotaborda:
Você está claramente confundindo patterns com API. O que singifica que todo este tempo vc não sabia do que estava falando quando disse que patterns servem para compensar defeitos das linguagens. Linguagens não fazem nada. elas servem para criar quem faça. API padrão como a JSE são classes já criadas e testadas para diversos fins. A criação dessas classes é orientada a objetos e portanto deve seguir os mesmos padrões que qualquer outra classe seja de aplicação ou não. Padrões de Projeto são utilizados nessas API como em qualquer outra API. Nenhuma linguagem exporta para XML ou tem ORM sem ter uma API para isso. ActiveRecord do Ruby, embora utilize o nome e o conceito do padrão ActiveRecord é uma API , não é um design pattern que a linguagem tem. O que torna a API ActiveRecord do Ruby interessante é que ela usa o suporte a meta-class do ruby para adicionar métodos em runtime a qualquer classe. Isso tb pode ser feito em Java, apenas a implementação e a chamada no codigo será diferente porque a linguagem é diferente. Mas a API é a mesma e faz o mesmo.
Confundir a API ActiveRecord com o padrão ActiveRecord é um erro grosseiro. Se é isso que vem acontecendo neste e noutros topicos pelo pessoal que defende que patterns é defeito da linguagem e que java usa tantos patterns porque é imcompleta, bom, simplesmente vcs não sabem do que estão falando. Não a linguagem que usa padrões é a modelagem OO. E modelagem OO existe em qualquer linguagem OO.
Não lembro de ter mencionado o termo API neste tópico. Nem mesmo ActiveRecord. Nem mesmo que um era a mesma coisa do outro, ou deixava de ser. Portanto ou voce respondeu pra pessoa errada, ou esta fazendo BDUF das minhas palavras.
Mas não vou te responder agora porque sinceramente não entendi aonde quer chegar. (juro que li 3x mas não entendi nada.)
G
giulianocosta
Me diz qual outro termo eu poderia utilizar pra definir uma linguagem que o cara não precisa usar Design Patterns pra resolver certas situações?
O pensamento que tu vem espressando nos teus posts ao comparar uma linguagem de mais alto nível com uma de menor nível é que em Ruby os Patterns são coisas do Demo…
Um dia se criarem uma Linguagem com o nome de Chris Angel ou o David Copperfield e tu me fale que elas não precisam de DP, talvez eu dê o braço a torcer pra ti…heheheheheh
M
mochuara
giulianocosta:
mochuara:
Percebi que isso ia acontecer quando chamou de “tricks” se referindo aos recursos de metaprogramacao e DSLs do Ruby.
Me diz qual outro termo eu poderia utilizar pra definir uma linguagem que o cara não precisa usar Design Patterns pra resolver certas situações?
O pensamento que tu vem espressando nos teus posts ao comparar uma linguagem de mais alto nível com uma de menor nível é que em Ruby os Patterns são coisas do Demo…
Um dia se criarem uma Linguagem com o nome de Chris Angel ou o David Copperfield e tu me fale que elas não precisam de DP, talvez eu dê o braço a torcer pra ti…heheheheheh
O curioso é que quem trouxe Ruby pra discussão foi vc. E mais curioso ainda é alguém querer definir algo sem estar em condições pra isso.
R
rems
mochuara:
giulianocosta:
mochuara:
Percebi que isso ia acontecer quando chamou de “tricks” se referindo aos recursos de metaprogramacao e DSLs do Ruby.
Me diz qual outro termo eu poderia utilizar pra definir uma linguagem que o cara não precisa usar Design Patterns pra resolver certas situações?
O pensamento que tu vem espressando nos teus posts ao comparar uma linguagem de mais alto nível com uma de menor nível é que em Ruby os Patterns são coisas do Demo…
Um dia se criarem uma Linguagem com o nome de Chris Angel ou o David Copperfield e tu me fale que elas não precisam de DP, talvez eu dê o braço a torcer pra ti…heheheheheh
O curioso é que quem trouxe Ruby pra discussão foi vc. E mais curioso ainda é alguém querer definir algo sem estar em condições pra isso.
E sobre design patterns? você sabe o que é e conhece alguns padrões?
To achando boa a discussão, mas eu não consegui entender ou achar nenhum exemplo em que o uso de um padrão seja defeito da linguagem, java por exemplo.
G
giulianocosta
blz véio. Esqueçamos o nome “Ruby” da discussão (Nem vou voltar nos posts pra saber se fui eu ou não quem o referenciou primeiro). Vou assumir que fui eu quem o trouxe pra discussão. Me cite uma linguagem que o cara não precise se preocupar com DPs?
Aqui tu deixa claro que a linguagem que não absorve DPs é porque a linguagem não tem abstração necessária.
S
sergiotaborda
mochuara:
sergiotaborda:
Você está claramente confundindo patterns com API.
Esse é o problema. Você não identifica isto que vc escreveu:
“Se ocasionalmente sua aplicação precisa persistir em banco de dados, expor uma interface web, exportar dados pra XML ou qualquer coisa que não faz parte do core da aplicação”
como responsabilidades de API e confunde com patterns.
O que significa que toda a sua argumentação é inválida porque se vc não sabe distinguir, vc não tem base para argumentar que pattern é uma deficiência da linguagem. vc simplesmente não sabe o que “pattern” significa.
J
jhacker
sergiotaborda:
Esse é o problema. Você não identifica isto que vc escreveu:
“Se ocasionalmente sua aplicação precisa persistir em banco de dados, expor uma interface web, exportar dados pra XML ou qualquer coisa que não faz parte do core da aplicação”
como responsabilidades de API e confunde com patterns.
O que significa que toda a sua argumentação é inválida porque se vc não sabe distinguir, vc não tem base para argumentar que pattern é uma deficiência da linguagem. vc simplesmente não sabe o que “pattern” significa.
Boa tarde,
Sérgio Taborda
O que percebo, é que muitos que estão discutindo sobre padrões não tem muita introdução no assunto, acredito que isso seja uma deficiência de literatura e de bons estudos.
Abraçoss
V
victorwss
Bem, passei as últimas 2 horas lendo este tópico inteiro. No final já estava meio perdido porque isso é algo bem cansativo e difícil de ler.
Mas, tenho algo a acrescentar. Citando um texto que vi certa vez em algum lugar por aí, mas não lembro uem era o autor. Não lembro exatamente como ele era versado, mas era algo assim:
Algo que acho que serve mais ou menos como um exemplo: Imagine na década de 1950, onde ninguém nem sequer sonhava com qualquer coisa semelhante aos design patterns de hoje. Naquela época, o simples fato de separar hardware de software e de utilizar uma linguagem de montagem ao invés de utilizar-se a linguagem de máquina diretamente já eram os design patterns daquela época. Hoje em dia isto está tão eternizado no coração de todos (ou quase todos) os sistemas e linguagens de programação que ninguém mais discute.
Um pouco mais adiante, surge conceitos como modularização e a utilização de estruturas de dados mais complexas do que registradores e variáveis. De certa forma, pode-se dizer que a ideia de organizar o código em funções, ao invés de um gigantesco macarrão cheio de gotos promíscuos é um design pattern primitivo. Hoje em dia, isto está eternizado no coração das linguagens de programação de tal forma que ninguém mais percebe que era um design pattern. Implementar funções utilizando linguagens de montagem que não tenham instruções específicas necessita de certo conhecimento de modelagem do programador. Nota-se que isto não é muito diferente do que vemos hoje: para modelar uma certa situação que não está no coração da linguagem, o programador precisará saber usar um design pattern (mesmo que sem perceber).
Aliás, quanto ao goto, ele é um caso interessante. Em linguagens de programação extremamente primitivas, não muito diferentes das linguagens de autômatos e/ou máquinas de Turing minimalistas, o goto chega a ser um padrão que simplifica bastante as coisas. No entanto, a medida que as linguagens foram evoluindo, pode-se dizer que ele deixou de ser um padrão e virou um anti-padrão. Na verdade ele continua lá, na modelagem interna de fors, whiles e até de chamadas de funções, mas ele não é mais visível no nível de abstração das linguagens atuais.
E mais adiante ainda, já no final da década de 1970 e início da década de 1980, surgem as linguagens OO. A OO por si só não passa de um monte de design patterns em linguagens estruturadas. Conceitos como encapsulamento e polimorfismo tornam-se design patterns. Isso daí é bem estranho, mas é verdade. Implementar OO em uma linguagem não-OO requer o uso de alguns truques e não é uma tarefa trivial. Se não for algo bem feito, o resultado é uma grande gambiarra que cria muito mais problemas do que resolve. Se for algo bem feito, o resultado é uma modelagem que a primeira vista é estranha e incomum, mas que na verdade é muito melhor do que aquela que normalmente se esperaria da linguagem. Não é exatamente isso que ocorre com os Design Patterns?
Os design patterns GoF eram o estado da arte na OO em 1994. Não se passou muito tempo desde então, foram apenas 15 anos. E hoje GoF são feijão-com-arroz. Não faço ideia de quais serão os design patterns quentes de 2030 ou de 2050, mas certamente lá, os GoF (pelo menos alguns deles) já serão algo tão trivialmente eternizados no coração das linguagens de programação da moda, de tal forma que ninguém mais os discutirá.
Olhando do futuro para o passado, implementar OO em uma linguagem não-OO já é algo difícil. Implementar OO em linguagens de baixo nível é algo que poucos sequer ousam fazer (só vi um caso sério até hoje). Implementar OO em linguagens minimalistas de máquinas de Turing deve ser algo bem interessante, mas certamente é muito difícil e desafiador. É aí que entra a complexidade inerente como efeito colateral dos design patterns. Design patterns adicionam complexidade inerente quando usados nas linguagens OO tradicionais de hoje. A OO em si acrescenta complexidade inerente quando usada em linguagens estruturadas. A estruturação acrescenta complexidade inerente quando utilizada em linguagens não-estruturadas. A manipulação de variáveis, comandos e instruções adiciona complexidade inerente em linguagens de baixo nível. O conceito de instruções e registradores adicionam complexidade inerente a máquinas de Turing. É aí que eu imagino como seria implementar o seu Design Pattern OO preferido em uma linguagem minimalista de máquina de Turing. Certamente, por mais simples que seja o pattern, o resultado teria uma complexidade tão grande que certamente teria a cara de ser uma gigantesca gambiarra, e usar algo mais simples acabaria sendo certamente muito melhor e mais fácil.
Penso que a mesma coisa pode acabar ocorrendo com os design patterns de hoje. Alguns tornar-se-ão características tão intrínsecas e enraizadas nas linguagens do futuro que muitas vezes nem serão percebidas como design patterns (Iterator, Strategy, Observer e MVC são bons candidatos). Outros podem se tornar anti-padrões, mesmo que sejam coisas simples com finalidades simples e que se usadas corretamente não machucam ninguém, tal como ocorreu com o goto e está ocorrendo hoje com o Singleton e com os BOLOVO.
Aliás, o motivo pelo qual sou contra Singletons, não é muito diferente do motivo pelo qual sou contra gotos. Não há nada de errado neles por si só. São simples e muito úteis quando bem usados. O problema é que é tão difícil e raro utilizá-los diretamente de forma correta e legítima que geralmente só de pensar em usá-los já costuma ser besteira.
Aliás, voltando ao assunto do Singleton, cita-se frequentemente de colocar-se a conexão com o banco de dados em um singleton. Eu fazia isso em um projeto que usava Oracle e tudo era lindo e maravilhoso, até que em um certo dia tive uma surpresa: Chegou um requisito novo que tinha que ser implementado que necessitava de haver uma conexão com um segundo banco de dados em MySQL. Aí foi um sufoco implementar isso, e o singleton teve que ser literalmente explodido. E haja refatoração!
Mais tarde, um colega cometeu o mesmo erro, havia umas variáveis lá que guardavam os dados do usuário conectado no cliente swing. O colega decidiu usar o singleton. Pouco tempo depois, o cliente pediu um requisito de troca do usuário, que permitia haver mais de um usuário logado na mesma máquina ao mesmo tempo. Foi outra cirurgia de refatoração a ser feita.
Mais tarde em outro projeto em outro lugar estava lá um singleton que mantinha a conexão com o banco, dentro de um JAR de terceiros. Minha intuição já me disse que aquilo ia dar em m****. E foi o que aconteceu: Depois de um tempo surgiu a necessidade de conectar em dois bancos de dados ao mesmo tempo. Nem lembro como foi que isso foi resolvido.
A minha conclusão é que o singleton é hoje o que o goto foi a 40 anos atrás.
L
Luca
Olá
Vitor, você escreveu demais, isto é, ficou até parecido no tamanho com uns e outros, mas o que escreveu faz sentido. Pelo menos para mim. E achei muito legal comparar o Singletons com GOTO, se bem que bater em Singleton é o mesmo que bater em cachorro morto.
Antigamente a gente também tinha nossos padrões. Só que não eram públicos. Faziam parte do que chamávamos de nossa caixa de ferramentas.
O fato dos padrões hoje serem públicos é que acarretou o abuso deles.
Continuo com a mesma velha opinião de que os padrões devem ser usados quando reconhecidos ao invés de usados como demonstração de que o programador conhece padrões como já fui testemunha em mais de um projeto. E pior era ver os caras descrevendo o código usando padrões para complicar a linguagem dentro de uma equipe em que nem todos visualizam os padrões do mesmo jeito que o cara falava.
[]s
Luca
F
faelcavalcanti
Sempre haverá uma minimização dos esforço da solução, sem haver portanto anulação do padrão anteriormente existente. Um exemplo disto é a JSR 300 propõe uma saída para implementação do singleton utilizando @singleton como alvo de declaração em uma classe.
O mesmo vale para o padrão citado MVC, que trata-se de um padrão de arquitetura, e não um design pattern conforme victor citou, uma vez que, propõe esta disponibilidade em ditas camadas lógicas de sua aplicação, e conforme cita Craig Larman[2005] pág: 231
Os padrões de projeto têm sua importância, e ainda irão vingar por bom tempo, por resolver problemas de forma independente, e diante de suas desvantagem de forma agrupada com outros padrões, afim de minimizar estes problemas recorrentes.
Christopher Alexander em 1970 estabeleceu está proposta de padrões de projeto há quase 40 anos, e ainda assim eles continuam perssuadidos, mesmo que com certo esforço, visto que o contexto sempre tende a mudar.
Iterator, Strategy, Observer são padrões de projeto como proposta de soluções para problemas, ainda ditos recorrentes, mas que dependerá de como “quem” os está usando.
Não adianta somar problemas que um padrão não possa resolver, e a partir daí querer ditá-lo para o mundo todo depracated. O problema pode estar entre a cadeira e o teclado!
V
victorwss
faelcavalcanti:
Sempre haverá uma minimização dos esforço da solução, sem haver portanto anulação do padrão anteriormente existente. Um exemplo disto é a JSR 300 propõe uma saída para implementação do singleton utilizando @singleton como alvo de declaração em uma classe.
O mesmo vale para o padrão citado MVC, que trata-se de um padrão de arquitetura, e não um design pattern conforme victor citou, uma vez que, propõe esta disponibilidade em ditas camadas lógicas de sua aplicação, e conforme cita Craig Larman[2005] pág: 231
Os padrões de projeto têm sua importância, e ainda irão vingar por bom tempo, por resolver problemas de forma independente, e diante de suas desvantagem de forma agrupada com outros padrões, afim de minimizar estes problemas recorrentes.
Christopher Alexander em 1970 estabeleceu está proposta de padrões de projeto há quase 40 anos, e ainda assim eles continuam perssuadidos, mesmo que com certo esforço, visto que o contexto sempre tende a mudar.
Iterator, Strategy, Observer são padrões de projeto como proposta de soluções para problemas, ainda ditos recorrentes, mas que dependerá de como “quem” os está usando.
Não adianta somar problemas que um padrão não possa resolver, e a partir daí querer ditá-lo para o mundo todo depracated. O problema pode estar entre a cadeira e o teclado!
Bem, eu não quis me prender a terminologias quando equiparei coisas como Iterator, MVC, goto, polimorfismo, encapsulamento e criação de funções. O que eu quis mostrar aqui é o surgimento de técnicas de nível mais abstraído do que o que existe na linguagem em si. Talvez tenha sido falha minha, mas então ao invés de chamar estas coisas todas de design patterns vamos chamar de qualquer outra coisa que você queira.
E em momento nenhum eu quis dizer que Iterator, Strategy e Observer serão deprecated. Muito pelo contrário! Por exemplo, o for-each do java esconde que existe um Iterator por trás porque neste caso a linguagem absorveu o Iterator de forma natural (através de um syntatic sugar). Dependendo da linguagem e do ambiente, outras formas mais profundas de absorvê-los seriam possíveis que não apenas syntatic sugars. Por exemplo, instruções específicas da máquina virtual (ou até do hardware) poderiam ser criadas para implementar esses patterns sem que isso torne-se visível na lingaugem. Mas dizer que o Iterator é/foi/será absorvido pela linguagem é algo completamente diferente do que dizer que ele será deprecated.
Quanto ao Strategy, o uso de closures tende a ser um Strategy disfarçado.
Quanto ao Observer, imagine que em uma linguagem no futuro, seja possível adicionar algum tipo de listener diretamente no atributo independente do tipo que ele for sem precisar mantendo os objetos que representam os listeners em listas explícitas e disparando-os explicitamente. Neste caso, a linguagem terá absorvido o Observer.
Aliás, a própria ideia de usar um while é uma técnica recorrente (para não dizer padrão e usar uma terminologia inadequada) é o resultado de em linguagens não-estruturadas de utilizar-se desvios condicionais (if-goto) de forma que laços com escopo bem definido fossem criados. Em linguagens estruturadas isso tornou-se parte da própria linguagem.
Não obstante, agora olho para um dos próximos paradigmas que ainda está na infância: a programação orientada a aspectos. Conceitos de programação orientada a aspectos tais como injeção de dependências, interceptadores, eliminação de cross-cutting concerns entre outros são atualmente implementados de forma forçada, feia e um tanto limitadas nas linguagens OO. E não é difícil perceber-se que se as linguagens atuais suportassem isso nativamente, essas coisas ficariam muito mais fáceis e limpas de se fazer.
Aliás, anotações do java 5+ demonstram isso também. No java 1.4 e inferiores, as anotações eram simuladas por uma miríade de técnicas malucas e complicadas, tais como arquivos XML, geradores de código, herança de classes malucas de frameworks específicos entre outros meios. Bastou que a própria linguagem suportasse isso nativamente que a partir daí pode-se jogar fora toda ou quase toda essa parafernália inventada para simular um recurso que faltava na linguagem e que muitas vezes nem se notava que estava faltando. Como se não bastasse, a implementação nativa na linguagem é muito superior e muito mais simples do que as tentativas malucas que eram feitas para simulá-la.
Quanto ao MVC, não duvido que a próxima linguagem web da moda (moda que pode durar décadas inclusive) tenha construções de linguagens específicas para um design MVC, mas que estas construções sejam tão transparentes que muitas vezes o programador nem perceba que está usndo o MVC. Frameworks que tentam fazer isso artificialmente sem ser nativo da linguagem já temos aos montes, tal como foi o caso das anotações no java 5.
Além disso, isso não significa que todos os padrões vão ou ser condenados como o goto ou serem escondidos por construções da linguagem tal como o exemplo que dei do while. Muitas técnicas e padrões continuam as mesmas ao longo de décadas.
S
sergiotaborda
O fato de vc ter encontrado uma citação que tem as palavras “nivel de arquitura” e MVC no mesmo paragrafo não torna o MVC um padrão arquitetural. MVC não se dispoe a separar as coisas em camadas como vc citou - MVC é usado em apenas 1 camada - portanto, nunca poderá ser considerado padrão arquitetural. A confusão em considerá-lo padrão arquiterural é pensar os manipuladores de eventos, a IGU e os dados relacionados estão em camadas diferentes. Não estão.
O exemplo claro disto é o JavaFX. Se vc ja tiver uma aplicação swing corretamente desenvolvida, ou seja, com cliente, apresentação e as outras camadas separadas, então, vc pode modificar o cliente de swing para Fx no cliente sem retrabalho nas outras chamadas. afinal é isso que significa separação de camadas. Repare que o MVC está todo contido no proprio Fx e no Swing. Ele não vaza para a camada inferior que é a apresentação.
Porque o MVC está associado a controles fisicos como teclado e mouse, as pessoas assumem que é um padrão arqutietural, mas não é. Para ser um padrão arquitetural ele teria que interferir com plataformas, andares (que eu chamei camadas neste texto) , nodos ou protocolos de comunicação. Ele não interfere com nada disto, logo não é um padrão de arquitetura. Embora existam muitos desavisados que o chamam assim.
um padrão realmente de arquitetura é o Cluster, por exemplo.
M
mochuara
victorwss:
Penso que a mesma coisa pode acabar ocorrendo com os design patterns de hoje. Alguns tornar-se-ão características tão intrínsecas e enraizadas nas linguagens do futuro que muitas vezes nem serão percebidas como design patterns (Iterator, Strategy, Observer e MVC são bons candidatos).
Scala e Clojure que são linguagens bombando HOJE tem mecanismo de concorrencia enbutido na linguagem, Clojure vai além e conta ainda com controle transacional (UnitOfWork) e vc me diz que a linguagem do futuro vai conter Strategy e Observer?? :shock:
J
jhacker
“O Design é sempre a intenção da Arquitetura”
Singletons ou não-singletons
Para o Spring, todos os beans são singletons, ou seja, só existe uma instância de cada um deles para aquela instância do framework.Algumas vezes, os nossos objetos têm dependências que não podem ser singletons, ou seja, cada bean precisa de uma instância própria de sua dependência.Para que o Spring trate um objeto não-singleton, o atributo “singleton” do nó<bean> deve estar com o valor “false”.
Penso que a mesma coisa pode acabar ocorrendo com os design patterns de hoje. Alguns tornar-se-ão características tão intrínsecas e enraizadas nas linguagens do futuro que muitas vezes nem serão percebidas como design patterns (Iterator, Strategy, Observer e MVC são bons candidatos).
Scala e Clojure que são linguagens bombando HOJE tem mecanismo de concorrencia enbutido na linguagem, Clojure vai além e conta ainda com controle transacional (UnitOfWork) e vc me diz que a linguagem do futuro vai conter Strategy e Observer?? :shock:
Releia o que eu escrevi.
O goto por exemplo, continua existindo firme, forte, frequente e feliz nas profundezas dos sistemas e das linguagens mais modernas de hoje em dia, mas ele está escondido debaixo de tantas camadas de abstração que você não o vê, não mais o utiliza diretamente, mas isto não significa que ele não exista. O mesmo está acontecendo com o Strategy, Observer e Iterator.
No javafx, é bem interessante como é que o Observer foi absorvido pela linguagem em si na forma de triggers. Clojure também é um exemplo interessante de como as linguagens estão evoluindo.
Mas, há uma grande diferença entre Strategy, Observer, Iterator e goto. O goto quando utilizado diretamente pelo prograador é em 99,9% dos casos algo extremamente ruim que vai trazer muitos mais problemas do que benefícios. O Strategy, Observer e Iterator nas linguagens mais tradicionais de hoje (Java, C++, C#, smalltalk) decididamente não são o mesmo caso. Em linguagens mais avançadas como Clojure, JavaFX e Scala, o uso direto deles começa a se tornar um anti-pattern, mas acho que ainda não ao ponto que o goto tinha se tornado. Por outro lado o Singleton, já sofreu tanta entropia que está em situação cada vez mais semelhante ao goto: usá-lo diretamente é em 98% dos casos um tiro no pé, mas isso não significa que ele deixará de existir ou tornar-se-á deprecated, nem mesmo com o goto isto ocorreu. O seu uso direto é que poderá se tornar cada vez mais deprecated.
Bem, estou inventando agora: Poderíamos chamar de entropia a característica que uma determinada técnica ou padrão de programação tem que a deixa cada vez menos vantajosa e mais problemática quando usada diretamente a medida que cresce o nível de abstração. O goto por exemplo tem uma entropia altíssima, é vantajoso apenas nas camadas mais inferiores e menos abstraídas de linguagem de montagem, linguagens de máquina e bytecodes. O Singleton também já sofreu bastante entropia e não é mais vantajoso nas linguagens de hoje. O Iterator, Observer, Strategy e MVC já tem alguma entropia significativa também, mas ainda estão longe do ponto aonde o Singleton e o goto chegaram.
Algumas técnicas que surgem tendem a ganhar entropia de forma bem lenta, como por exemplo a modularização do código em procedimentos e funções. Esta técnica, apesar de bem antiga sofreu pouca entropia, mas isto não significa que um dia, em um futuro distante isso não vá ocorrer.
Minha conclusão empírica é que cada linguagem tem os seus padrões e técnicas apropriadas e específicas para o seu nível de abstração. Usar técnicas de níveis de abstração inferiores ao da linguagem tende a trazer gambiarras, problemas e bad smells. Usar técnicas de níveis de abstração superiores ao da linguagem tende a trazer complexidade e verbosidade. Quanto maior a diferença entre o nível de abstração da técnica e da linguagem, pior fica este problema.
V
victorwss
jhacker:
“O Design é sempre a intenção da Arquitetura”
Singletons ou não-singletons
Para o Spring, todos os beans são singletons, ou seja, só existe uma instância de cada um deles para aquela instância do framework.Algumas vezes, os nossos objetos têm dependências que não podem ser singletons, ou seja, cada bean precisa de uma instância própria de sua dependência.Para que o Spring trate um objeto não-singleton, o atributo “singleton” do nó<bean> deve estar com o valor “false”.
Isto já foi bastante discutido páginas atrás. É um erro de conceito. Embora sejam chamados erroneamente de singletons, não são singletons, são shared objects.
F
faelcavalcanti
sergiotaborda:
Porque o MVC está associado a controles fisicos como teclado e mouse, as pessoas assumem que é um padrão arqutietural, mas não é. Para ser um padrão arquitetural ele teria que interferir com plataformas, andares (que eu chamei camadas neste texto) , nodos ou protocolos de comunicação. Ele não interfere com nada disto, logo não é um padrão de arquitetura. Embora existam muitos desavisados que o chamam assim.
um padrão realmente de arquitetura é o Cluster, por exemplo.
você demonstrou um exemplo, não necessariamente, ele, se resume a isto! sempre tenho visto o modelo MVC como padrão arquiteturial, me mostre uma referência que o dita que não o seja, que eu me convencerei!
a citação que mencionei, expôe também as vertentes de como o padrão MVC surgiu mesmo que com propósito limitado na época.
acho que temos que esclarecer ao pessoal agora algumas perguntas como:
1. Qual conceito de um padrão arquiteturial ? (motivado por referências)
2. Como um padrão arquiteturial pode ser classificado ?
entre outras perguntas interessantes que poderiamos incluir aqui, mas acho que isto pode ser melhor discutido em um novo tópico!
F
faelcavalcanti
também concordo luca.
por exemplo, se você dispõe dos conceitos e princípios de O.O, você acaba usando um padrão sem saber. antigamente eu utilizava o template method sem saber.
a didática de aprender padrões de projeto, tratando-se de padrões da GoF ou GRASP neste caso, é justamente um ato de exercitar bons princípios de O.O, para velhos problemas conhecidos e que serão recorrentes ao longo da nossa atuação profissional, de forma que um determinado design descreva características de um ou mais padrões, resumindo-se em poucas palavras.
agora, se você souber fazer bom uso disto sem conhecer padrões e explicar como algo foi desenvolvido, você está no caminho mais do que certo, visto vez que, eles devem ser mencionados quando necessário, e isto é verdade porque nosso objetivo final é concluir um projeto atendendo a contento o mais simples possível de forma a minimizar custo, em prazo e que possibilite que a equipe se comunique em seu ritmo natural de forma a evoluir sem depender de padrões e catálogos como referências e normas em suas práticas atuais, e futuras pois podem acabar não sendo promissoras.
abusar do uso de padrões de projeto pode fazer mal a nossa saúde e a do projeto que estamos tratando!
V
victorwss
também concordo luca.
por exemplo, se você dispõe dos conceitos e princípios de O.O, você acaba usando um padrão sem saber. antigamente eu utilizava o template method sem saber.
a didática de aprender padrões de projeto, tratando-se de padrões da GoF ou GRASP neste caso, é justamente um ato de exercitar bons princípios de O.O, para velhos problemas conhecidos e que serão recorrentes ao longo da nossa atuação profissional, de forma que um determinado design descreva características de um ou mais padrões, resumindo-se em poucas palavras.
agora, se você souber fazer bom uso disto sem conhecer padrões e explicar como algo foi desenvolvido, você está no caminho mais do que certo, visto vez que, eles devem ser mencionados quando necessário, e isto é verdade porque nosso objetivo final é concluir um projeto atendendo a contento o mais simples possível de forma a minimizar custo, em prazo e que possibilite que a equipe se comunique em seu ritmo natural de forma a evoluir sem depender de padrões e catálogos como referências e normas em suas práticas atuais, e futuras pois podem acabar não sendo promissoras.
abusar do uso de padrões de projeto pode fazer mal a nossa saúde e a do projeto que estamos tratando!
Há uma sutil, mas gritante diferença entre saber como usar padrões de projeto e saber quando usar padrões de projeto.
F
faelcavalcanti
sutil, mas gritante ??? por exemplo ???
V
victorwss
sutil, mas gritante ??? por exemplo ???
Sim, sutil e gritante ao mesmo tempo.
É uma diferença pequena, mas que pode decidir entre a vida e a morte.
Saber como usar é entender como funciona o Façade, por exemplo, que cara ele tem, como implementar e que mecanismo ele usa.
Saber quando usar é identificar onde ele deve ser usado e onde ele não deve ser usado. Afinal, como eu já disse outras vezes aqui no GUJ, usar um padrão no lugar errado, na circunstância errada, transforma o padrão em anti-padrão.
Enfim, eu estava concordando com você. Abusar de padrões é ruim.
Os padrões podem ser comparados a remédios, para curar problemas no código. Pessoas que abusam de remédios tem saúde pior do que aqueles que não tomam nenhum.
E se você tem um problema no coração, deve tomar o remédio para o coração, não o remédio para o fígado!
Larry: For a while, everything became a “pattern.” There were patterns for architecture, organizational behavior, analysis, etc. What was less apparent, though, was an evolution where the 23 patterns in the DP catalog were extended by X other design patterns or related to, say, architectural patterns. There are a lot of patterns out there. Is there a new “Figure 1.1: Design pattern relationships”?
Ralph: If you mean “Do we have a figure to give you?” the answer is “No.” If you mean “Should someone create a new figure?” the answer is “Yes.”
Então eu os pergunto:
Mais abaixo do texto Erich menciona sobre os 200 padrões de Linda Rising. Ela deve ter dado um duro danado para juntar isto tudo, mas que Erich defende bem a idéia, “In other words, not all patterns have the same relevance and weight.”, justificando a afortunação que eles devem ter passado, no qual faltou um pouquinho mais de engenharia social no trabalho tanto dela como deles, como por exemplo: juntando opinião de outros a respeito, defendendo e criticando, e não uma coisa imóvel como uma peça em um museu.
Interpreter and Flyweight should be moved into a separate category that we referred to as “Other/Compound” since they really are different beasts than the other patterns. Factory Method would be generalized to Factory.
The categories are: Core, Creational, Peripheral and Other. The intent here is to emphasize the important patterns and to separate them from the less frequently used ones.
The new members are: Null Object, Type Object, Dependency Injection, and Extension Object/Interface (see “Extension Object” in Pattern Languages of Program Design 3, Addison- Wesley, 1997).
These were the categories:
Core: Composite, Strategy, State, Command, Iterator, Proxy, Template Method, Facade
Creational: Factory, Prototype, Builder, Dependency Injection
Peripheral: Abstract Factory, Visitor, Decorator, Mediator, Type Object, Null Object, Extension Object
Other: Flyweight, Interpreter
Alguns padrões notoriamente foram inseridos, e outros ele não mencionou que não seriam removidos ou melhor justificado, apenas o caso do singleton, que ele declarou amá-lo de certa forma, como mencionado abaixo:
Mas o que não entendi foi esta nova terminologia adicionando-se core e outros!
Ora, então vejamos a classificação anteriormente proposta pela GoF
Metsker, autor de alguns livros como: Design Patterns in Java, propôs uma abordagem diferente, e, me pareceu mais apropriado, por intenção, lembrando que a intenção parte do pressuposto de um problema em um contexto inserido a ser solucionado. Segue abaixo:
Já que falamos tanto de singleton, ele encontra-se como criação no GoF, mas como responsabilidade na classificação de Metsker, entre outros padrões variadamente.
Sei que ao final ele mencionou ser um rascunho apenas, mas esta taxonomia, dentro destas mudanças citadas, foi apropriada ?
isto tudo, se resumiria em uma resenha a esta entrevista, complementando-se destes questionamentos!
V
victorwss
faelcavalcanti:
Interpreter and Flyweight should be moved into a separate category that we referred to as “Other/Compound” since they really are different beasts than the other patterns. Factory Method would be generalized to Factory.
The categories are: Core, Creational, Peripheral and Other. The intent here is to emphasize the important patterns and to separate them from the less frequently used ones.
The new members are: Null Object, Type Object, Dependency Injection, and Extension Object/Interface (see “Extension Object” in Pattern Languages of Program Design 3, Addison- Wesley, 1997).
These were the categories:
Core: Composite, Strategy, State, Command, Iterator, Proxy, Template Method, Facade
Creational: Factory, Prototype, Builder, Dependency Injection
Peripheral: Abstract Factory, Visitor, Decorator, Mediator, Type Object, Null Object, Extension Object
Other: Flyweight, Interpreter
Alguns padrões notoriamente foram inseridos, e outros ele não mencionou que não seriam removidos ou melhor justificado, apenas o caso do singleton, que ele declarou amá-lo de certa forma, como mencionado abaixo:
Pois é. O que haveria de errado no Chain of Responsability, Adapter, Proxy, Memento e Bridge?
Ah, e na minha opinião esse negócio de criar figurinha com um grafo relacionando os patterns é pura bobagem. Não ajuda em nada e serve para confundir.
S
sergiotaborda
faelcavalcanti:
sergiotaborda:
Porque o MVC está associado a controles fisicos como teclado e mouse, as pessoas assumem que é um padrão arqutietural, mas não é. Para ser um padrão arquitetural ele teria que interferir com plataformas, andares (que eu chamei camadas neste texto) , nodos ou protocolos de comunicação. Ele não interfere com nada disto, logo não é um padrão de arquitetura. Embora existam muitos desavisados que o chamam assim.
um padrão realmente de arquitetura é o Cluster, por exemplo.
você demonstrou um exemplo, não necessariamente, ele, se resume a isto! sempre tenho visto o modelo MVC como padrão arquiteturial, me mostre uma referência que o dita que não o seja, que eu me convencerei!
Primeiro que tudo não estou preocupado se vc está convencido. Segundo , não estou preocupado com o seu complexo de são tomé.
Terceiro se realmente quer entender , pense um pouco. Vc acha que MVC está no mesmo nivel de responsabilidade que padrões arquiteturais como cluster, peer-to-peer , soa ou pipeline ? Se não acha, ai está a sua demonstração. Se acha, então tente explicar o que MVC têm em comum com pipeline ou p2p ou mesmo cluster, e como essas coisas em comum dizem respeito a arquitetura. (este é um desafio retorico)
Bom, antes que pergunte : arquitetura trata sobre a interação de sistemas. Aplicações são constituidas por um mais sistemas.
Por exemplo, falamos em “arquitetura web” porque estamos falando de 2 sistemas : o browser e o servidor.
Arquitetura não trata de codigo, linguagens, OO ou coisa semelhante.
F
faelcavalcanti
sergiotaborda:
Primeiro que tudo não estou preocupado se vc está convencido. Segundo , não estou preocupado com o seu complexo de são tomé.
Terceiro se realmente quer entender , pense um pouco. Vc acha que MVC está no mesmo nivel de responsabilidade que padrões arquiteturais como cluster, peer-to-peer , soa ou pipeline ? Se não acha, ai está a sua demonstração. Se acha, então tente explicar o que MVC têm em comum com pipeline ou p2p ou mesmo cluster, e como essas coisas em comum dizem respeito a arquitetura. (este é um desafio retorico)
sua arrogância está complicando você mesmo, além dos outros leitores deste tópico.
eu não disse que está no mesmo nível de responsabilidade, você está misturando as coisas e, complementando com falsas informações suas.
pedi a você que me contextualize de suas afirmações com referências, não com afirmações indiretas e excrupulosas. e por favor guarde as para você, e isso não é nada bom para você! :?
temos o direito de divergir, e respeito opniões, contradições, conceitos, preceitos e hoje no mundo moderno: preconceitos!
argumento válido, mas se resume a isto?
parece que você bateu com a cabeça, mas vamos lá: segundo POSA1, temos inúmeros modelos de arquitetura com propósitos específicos ditos por Buschman, 1996, eis alguns como:
agora, Buschman 1996, muito tempo se passou de lá para cá, e sei disto! eu sinceramente ainda concordo com outras vertentes, assim como Fowler/06 com alguns pontos de vistas dele com artigo GUI Architectures, como consequente review do seu livro de EEAI, no qual menciona visão do MVC clássico com, dito por alguns WEB MVC.
outro ponto, por favor, não vamos ficar no blablabla aqui sobre MVC, não estamos na época do barroco! eu propus a idéia de abordar isto em outro tópico sobre padrões de arquitetura, como premissa discutindo duas perguntas iniciais que citei.
Você concorde ou não um trabalho bem mais exaustivo disto renderia no mínimo um artigo acadêmico.
Novamente, não estamos na era do barroco, no filme hair, ou quer que seja época você vive, mas podemos discutir outras vertentes que te motivaram ao seu pensamento e ponto de vista, … em outro tópico ou via MP! A decisão é sua, e paro por aqui!