Repositories dentro de Entities ou Repositories manipulados por Services?  XML
Índice dos Fóruns » Arquitetura de Sistemas
Autor Mensagem
rpffoz
JavaChild
[Avatar]

Membro desde: 07/01/2008 10:13:47
Mensagens: 107
Offline

Olá Pessoal,

Sei que já foi discutido muito aqui, algo que já gerou em torno de 8 páginas por tópico,
mas não ficou claro para mim.

Como o título descreve, aonde eu coloco os Repositories, dentro de Entities ou manipulados por Services?

Assim:


Ou partindo do princípio que devo modelar meu domínio, e que persistência é uma necessidade da infra estrutura
Tenho uma Service assim:



Se a segunda abordagem estiver errada, por favor me mostrem as falhas!

Abraços!
\o/

This message was edited 4 times. Last update was at 04/02/2008 17:03:56


Rodrigo Pereira Fraga
http://www.digows.com/
http://www.apollo-ti.com/
http://forum.flexbrasil.com.br/
[Email] [WWW] [MSN]
sergiotaborda
GUJ Expert
[Avatar]

Membro desde: 22/03/2005 20:57:48
Mensagens: 3433
Offline

rpffoz wrote:




Essa método ai é um problema, Vc o usaria +- assim




O que é redundante.Opções:
1) tornar o método sem parametros com codigo usando this: isto equivale a tornar Categoria num ActiveRegistry. Nada contra se vc fizer assim. Eu não faria.
2) torna o metodo estático. Isto equivale a torna Categoria um façade do seu proprio repositorio.
O que não deixa de ser um pouco redundate.
3) eliminar o método e usar o repositorio directamente





Ou partindo do princípio que devo modelar meu domínio, e que persistência é uma necessidade da infra estrutura. Tenho uma Service assim:

Se a segunda abordagem estiver errada, por favor me mostrem as falhas!


A segunda abordagem parte do principio que vc está usando a opção 3 da lista anterior.
Se vc usar algumas das outras o codigo será diferente.
O ponto é que vc não amarrou a entidade com o seu repositorio e precisa perder tempo
procurando o repositorio certo, ou vê-lo injectado.

O codigo do serviço não tem nenhum problema (além de falta de separação de responsabilidade em categoria.valida(). Mas isso é uma escolha que nada tem a haver com repository.)

Nada impede se construir algo mais sofisticado.



(1) Assume que todos os Repository tem a mesma interface básica. Por exemplo save(Object obj). Isso não
é dificil. De resto é apenas um mapa do tipo Map<Class, Repository> e o codigo é muito simples




É claro que existem outras formas de amarrar a classe ao seu repositorio mas
esta é bem simples.

Em adição como está programando para interface o repositorio real pode ser sempre o mesmo.


Criando sua própria API de Validação



Blog do MiddleHeaven
[WWW]
rpffoz
JavaChild
[Avatar]

Membro desde: 07/01/2008 10:13:47
Mensagens: 107
Offline

Olá,

Então estou usando o Spring Framework para injetar as depêndencias na segunda abordagem ficaria algo assim:

ServiceCategoria



O valida aquela hora foi simbólico, apenas quero demonstrar que antes de aplicar o objeto a um repositório, aplico os comportamentos ao que for necessário, como por exemplo em uma Service de um Financeiro, ficaria algo assim:

ServiceFinanceiro



Uma recuperação de lista, eu iria fazer uma Classe do Tipo service acessar um repository como exemplo:

ServiceCategoria



Então, é correto desaclopar o Repository de um Entity e fazer com que Service manipule o Respository?

This message was edited 3 times. Last update was at 04/02/2008 20:08:23


Rodrigo Pereira Fraga
http://www.digows.com/
http://www.apollo-ti.com/
http://forum.flexbrasil.com.br/
[Email] [WWW] [MSN]
sergiotaborda
GUJ Expert
[Avatar]

Membro desde: 22/03/2005 20:57:48
Mensagens: 3433
Offline

rpffoz wrote:



O catch de CategoriaException é redundate. Remova-o.


Uma recuperação de lista, eu iria fazer uma Classe do Tipo service acessar um repository como exemplo:


não faça isso. Use o repositorio directamente. Caso contrário vc está criando fachadas para o repositorio sem nenhum propósito.


Então, é correto desaclopar o Repository de um Entity e fazer com que Service manipule o Respository?


O service usar o repositorio directamente não tem problema algum.
O entity usar o repositorio de outros entity tb não. O que é estranho é o entity usar o seu proprio repositorio apenas para delegar. Faria sentido se o entitity tem caracteristicas de nodo de arvore ( por exemplo Tarefa que contém outras Tarefa). Não é proibido o entity usar o repository, mas tem que o fazer com algum objetivo mais "elevado" que simplesmente delegar. Caso contrario estamos criado Façade ou ActiveRecord sem nenhum ganho.

This message was edited 2 times. Last update was at 05/02/2008 10:48:30


Criando sua própria API de Validação



Blog do MiddleHeaven
[WWW]
pcalcado
Moderador
[Avatar]

Membro desde: 08/03/2004 17:19:35
Mensagens: 5174
Localização: Sydney - Australia
Offline

As duas abordagens estão "corretas". A coisa mais importante é que repositório não tem a ver com persistência, pelo menos não diretamente. Um bom exemplo disso é que se você usasse um DAO diretamente ao invés do Repositório no primeirot recho teria algo arecido com um Active Record, onde a persistência do objeto fica a cargo dele mesmo 9que pode delegar para o DAO) mas quando é um repositório isso não é verdade, o objeto não se persiste ou consulta o banco de dados, ele consulta o repositório e a implementaçao deste é opaca à Camada de negócios.

Phillip Calçado "Shoes"
http://fragmental.tw/
http://blog.fragmental.com.br/
"It is unfortunate that much of what is called 'object-oriented programming today is simply old style programming with fancier constructs." - Alan Kay
[Email] [WWW] [Yahoo!] [MSN]
rpffoz
JavaChild
[Avatar]

Membro desde: 07/01/2008 10:13:47
Mensagens: 107
Offline

Olá,

sergiotaborda wrote:
O catch de CategoriaException é redundate. Remova-o.


Não sei se fiz correto, mas abaixo da service, apenas são tratadas e disparadas Exceptions do Tipo CategoriaException, logo esse catch exibi uma mensagem formatada.

Aproveitando, gostaria de saber se vocês tem uma referência para tratamento de exceptions, e usando AOP para as exceptions corriqueiras.


sergiotaborda wrote:
não faça isso. Use o repositorio directamente. Caso contrário vc está criando fachadas para o repositorio sem nenhum propósito.



Hun... não sei conseguiria fazer isso, prefiro delegar pelo menos uma facade para minhas layers abaixo, seja para tratar exceptions e afins.
Outro detalhe, é que talvez antes de recuperar a lista, talvez seja necessário um categoria.fazAlgo(); e então recuperar os dados.


sergiotaborda wrote:
As duas abordagens estão "corretas". A coisa mais importante é que repositório não tem a ver com persistência, pelo menos não diretamente. Um bom exemplo disso é que se você usasse um DAO diretamente ao invés do Repositório no primeirot recho teria algo arecido com um Active Record, onde a persistência do objeto fica a cargo dele mesmo 9que pode delegar para o DAO) mas quando é um repositório isso não é verdade, o objeto não se persiste ou consulta o banco de dados, ele consulta o repositório e a implementaçao deste é opaca à Camada de negócios.


Ok! Shoes, apesar do "correta" o.O

Quanto a abstração do Repository, acredito que para mim está clara. Abaixo do Repository, tenho DAO's seja do Hibernate ou JDBC, que implementam esta interface Repository, e a injeção da dependência é feita pelo Spring.


Obrigado a todos pela atenção.
\o/

This message was edited 2 times. Last update was at 05/02/2008 11:24:22


Rodrigo Pereira Fraga
http://www.digows.com/
http://www.apollo-ti.com/
http://forum.flexbrasil.com.br/
[Email] [WWW] [MSN]
sergiotaborda
GUJ Expert
[Avatar]

Membro desde: 22/03/2005 20:57:48
Mensagens: 3433
Offline

rpffoz wrote:Olá,

sergiotaborda wrote:
O catch de CategoriaException é redundate. Remova-o.


Não sei se fiz correto, mas abaixo da service, apenas são tratadas e disparadas Exceptions do Tipo CategoriaException, logo esse catch exibi uma mensagem formatada.


Exceptions não servem para formatar informação.
Quem faz isso é UI. Vc está caputrando uma CategoriaException e produzindo outra igual. Isso é desnecessário.
A informação do erro ja está na primeiroa exception. Se não está, deveria.

"Não foi possivel salvar" não contém informação nenhuma. É obvio que não foi possivel : uma exceção foi lancada. E analizando o stacktrace é obvio onde foi lançada e o quê "não pode acontecer".
Escrever mensagens como esta na exception é inutil. Mas se o quiser fazer deve ser feito na camada de UI
por um formatador (Format) ou dentro de um ExceptionHandler.

Encapsular uma exception em outra de tipo diferente é lictio. Mas não de os tipos são iguais.


Aproveitando, gostaria de saber se vocês tem uma referência para tratamento de exceptions, e usando AOP para as exceptions corriqueiras.


Não com AOP mas no meu blog tem algo sobre tratamento de exceptions.

sergiotaborda wrote:
não faça isso. Use o repositorio directamente. Caso contrário vc está criando fachadas para o repositorio sem nenhum propósito.



Hun... não sei conseguiria fazer isso, prefiro delegar pelo menos uma facade para minhas layers abaixo, seja para tratar exceptions e afins.
Outro detalhe, é que talvez antes de recuperar a lista, talvez seja necessário um categoria.fazAlgo(); e então recuperar os dados.


Se e quanto vc sentir essa necessidade é porque vc não está mais utilizando o repositorio puro. E nesse caso tlv vc tenha que delegar a outro serviço ou incluir mais codigo no repositorio.
Tudo dependende da responsabilidade de cada objeto e não do que vc precisa fazer.
Se vc não quer repartir o que ha a fazer por quem o deve fazer então não precisava de OO em primeiro lugar.

Uma fachada que apenas delega é um empecilho.




Criando sua própria API de Validação



Blog do MiddleHeaven
[WWW]
Rubem Azenha
GUJ Master
[Avatar]

Membro desde: 28/06/2004 00:10:43
Mensagens: 1933
Localização: São Paulo, SP
Offline

pcalcado wrote:As duas abordagens estão "corretas". A coisa mais importante é que repositório não tem a ver com persistência, pelo menos não diretamente. Um bom exemplo disso é que se você usasse um DAO diretamente ao invés do Repositório no primeirot recho teria algo arecido com um Active Record, onde a persistência do objeto fica a cargo dele mesmo 9que pode delegar para o DAO) mas quando é um repositório isso não é verdade, o objeto não se persiste ou consulta o banco de dados, ele consulta o repositório e a implementaçao deste é opaca à Camada de negócios.


Shoes,

Pense comigo: se vc usa um "service", você possívelmente utiliza algum Spring da vida ou até mesmo EJBs para instanciar os seus "services". Ou seja, você tem em um ponto de entrada "único" para a camada de apresentação chamar a camada de negócios. Com isso, vc pode tirar proveito das facilidades do Spring ou EJB, por exemplo, Transaction Management, injeção do Entity Manager, e coisas desse tipo.

Se você utiliza o repository direto na "entity", fica difícil tirar proveito dessas facilidades (eu imagino que a entity é geralmente instanciada com new e não via IoC\Lookup), ou pelo menos do tranasction management.

Nesse cenário, será que não é melhor utilizar um "service"?



Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning
[WWW]
Alessandro Lazarotti
Virtual Machine Man
[Avatar]

Membro desde: 21/01/2004 14:12:54
Mensagens: 719
Offline

"Se você utiliza o repository direto na "entity", fica difícil tirar proveito dessas facilidades (eu imagino que a entity é geralmente instanciada com new e não via IoC\Lookup), ou pelo menos do tranasction management."


Não sou o Shoes mas vou opiniar Microfilo.
Quando se usa Repositories, teoricamente sua modelagem deve estar sendo criada com base em Domain-Driven Design (pelo menos tende a ser).

Portanto o design é para o negócio e não para a arquitetura na camada de aplicação. Uma Façade qualquer pode isolar seu Domínio de Negócio do Domínio da Aplicação. Hoje em dia, nem mesmo isso é necessário, eu por exemplo faço isso usando o JbossSeam:




... diretamente em meu xhtml.

Em outros pontos da aplicação eu faço:




... onde o método na entidade Client faz acesso a seu repositório buscando as ultimas compras deste cliente.


... Lezinho
------------------------
twitter: @lazarotti
http://alessandrolazarotti.wordpress.com/
http://jbossbrasil.org/

[Email] [MSN]
Alessandro Lazarotti
Virtual Machine Man
[Avatar]

Membro desde: 21/01/2004 14:12:54
Mensagens: 719
Offline

rpffoz wrote: Aproveitando, gostaria de saber se vocês tem uma referência para tratamento de exceptions, e usando AOP para as exceptions corriqueiras.


Utilize o advice "around" com o AspectJ. Com ele vc consegue contornar qualquer pointcut que desejar com try/catch.

This message was edited 1 time. Last update was at 05/02/2008 17:55:55


... Lezinho
------------------------
twitter: @lazarotti
http://alessandrolazarotti.wordpress.com/
http://jbossbrasil.org/

[Email] [MSN]
Rubem Azenha
GUJ Master
[Avatar]

Membro desde: 28/06/2004 00:10:43
Mensagens: 1933
Localização: São Paulo, SP
Offline

Lezinho wrote:
Não sou o Shoes mas vou opiniar Microfilo.
Quando se usa Repositories, teoricamente sua modelagem deve estar sendo criada com base em Domain-Driven Design (pelo menos tende a ser).

Portanto o design é para o negócio e não para a arquitetura na camada de aplicação. Uma Façade qualquer pode isolar seu Domínio de Negócio do Domínio da Aplicação. Hoje em dia, nem mesmo isso é necessário, eu por exemplo faço isso usando o JbossSeam:


Então Lezinho... a questão é: quando se usa um Spring da vida ou EJB, você ganha algumas facilidades como Transaction Management, injeção do EntityManager (ou Hibernate Session/JDBC Connection), entre outras. Só que dificilmente você instanciaria um "Entity" com Spring ou EJB. Por isso você acaba ficando sem poder utilizar as facilidades deles diretamente do "Entity". Por isso que eu acho que é mais negócio utilizar o Repository (ou DAO) no "service", uma vez que esse provavelmente é instanciado pelo Spring\EJB e pode aproveitar das facilidades do framework diretamente em si mesmo.
Não sei se ficou bem claro...

Lezinho wrote:


... diretamente em meu xhtml.

Em outros pontos da aplicação eu faço:




... onde o método na entidade Client faz acesso a seu repositório buscando as ultimas compras deste cliente.



As chamadas são server-side ou client-side?

(PS.: espero que os trolls fiquem LONGE dessa thread, ta com cara de que vai virar um debate muito interessante)





Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning
[WWW]
Alessandro Lazarotti
Virtual Machine Man
[Avatar]

Membro desde: 21/01/2004 14:12:54
Mensagens: 719
Offline

Entendi microfilo, mas mais uma vez o limite é tecnológico (utilizar facilidades do EJB/Spring).

Neste caso mais específico, o EJB pode ser a façade que mencionei e usar os controles transacionais necessários, ou até mesmo ser seu Repository (um EJB3 sendo a implementação de um repository não é ruim, muito pelo contrário).

De forma geral um repository pode estar dentro ou fora da entidade, conforme sua necessidade. Uma abordagem como entidade.salvar não me agrada nem um pouco, neste caso utilizo um repository fora da entidade. Porém a entidade como objeto de negócio que é, certamente irá precisar em algum momento de acesso a dados via repository, em seus próprios métodos, como o comportamento que citei em "client.latestPurchases", neste caso uso um Repository interno.

Mas sei que isso pode gerar outros problemas, como:
"Mas como vou injetar Repositories em minha entidade se ela não é gerenciada pelo meu container IoC, é instanciada via new ou por frameworks de persistência?"

... bom, se sua dúvida for essa, eu postei uma solução aqui:

http://www.guj.com.br/posts/list/70275.java


microfilo wrote:As chamadas são server-side ou client-side?


Server-side, embora poderia ser client-side em vista que consigo invocar qualquer metodo mesmo com Javascript, bastando ele estar anotado por @WebRemote para esta ultima.

This message was edited 2 times. Last update was at 05/02/2008 18:50:57


... Lezinho
------------------------
twitter: @lazarotti
http://alessandrolazarotti.wordpress.com/
http://jbossbrasil.org/

[Email] [MSN]
Rubem Azenha
GUJ Master
[Avatar]

Membro desde: 28/06/2004 00:10:43
Mensagens: 1933
Localização: São Paulo, SP
Offline

Lezinho wrote:
Neste caso mais específico, o EJB pode ser a façade que mencionei e usar os controles transacionais necessários, ou até mesmo ser seu Repository (um EJB3 sendo a implementação de um repository não é ruim, muito pelo contrário).

Acredito que na maioria dos demarcadores transcionais não podem ficar no repository.

Lezinho wrote:
De forma geral um repository pode estar dentro ou fora da entidade, conforme sua necessidade. Uma abordagem como entidade.salvar não me agrada nem um pouco, neste caso utilizo um repository fora da entidade. Porém a entidade como objeto de negócio que é, certamente irá precisar em algum momento de acesso a dados via repository, em seus próprios métodos, como o comportamento que citei em "client.latestPurchases", neste caso uso um Repository interno.

Entendo Lezinho, mas em todo o caso, haverá momentos em que a "entity" precisara efetuar operações de update e, em alguns casos, precisara que essas operações estejam em transações isoladas. Como minha "entity" não é instanciada via spring\ejb, ela não possui demarcação de transação. E, como eu disse acima, não acho que seria correto demarcar a transação no repository, na maioria dos casos.

Lezinho wrote:
Mas sei que isso pode gerar outros problemas, como:
"Mas como vou injetar Repositories em minha entidade se ela não é gerenciada pelo meu container IoC, é instanciada via new ou por frameworks de persistência?"

... bom, se sua dúvida for essa, eu postei uma solução aqui:

http://www.guj.com.br/posts/list/70275.java


Você se refere ao esquema com AOP? Legal Não estou acostumado a utilizar AOP capturando a execução do construtor. Será que da para fazer algum transaction management diretamente na "entity" utilizando AOP? Nesse caso, a entity não ficaria muito "parruda"?


Lezinho wrote:
Server-side, embora poderia ser client-side em vista que consigo invocar qualquer metodo mesmo com Javascript, bastando ele estar anotado por @WebRemote para esta ultima.

Bacana, bem parecido com DWR, não?



Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning
[WWW]
Alessandro Lazarotti
Virtual Machine Man
[Avatar]

Membro desde: 21/01/2004 14:12:54
Mensagens: 719
Offline

microfilo wrote: Acredito que na maioria dos demarcadores transcionais não podem ficar no repository.


Concordo. Citei um Repository como EJB3 apenas para questão do uso de injeção convencional do EntityManager.

microfilo wrote: Entendo Lezinho, mas em todo o caso, haverá momentos em que a "entity" precisara efetuar operações de update e, em alguns casos, precisara que essas operações estejam em transações isoladas. Como minha "entity" não é instanciada via spring\ejb, ela não possui demarcação de transação. E, como eu disse acima, não acho que seria correto demarcar a transação no repository, na maioria dos casos.


Em caso de transações isoladas em entidades para entidades poderia ser feito:

1) Construir uma Strategy de um objeto de transação fake (para poder mudar a implementação se necessário). Esta strategy é um atributo injetado em sua entidade (portanto controlado pelo ciclo de vida do seu framework de injeção/transação). Ele tem um atributo que inicia uma nova transação isolada e que a finaliza. Você pode chamar este atributo nos pontos necessários de sua entidade.

2) Criar uma anotação para novas transações na entidade. Funcionaria exatamente como descrevi acima, com a chamada para um objeto de transação sob o controle de seu framework, exceto pelo fato de você não ter que fazer um atributo a mais na sua entidade... mas sim anotar um método. Um "aspecto"deverá fazer a leitura para efetuar a transação.

3) Fazer todo o processo transacional por fora, em um service. É a forma mais simples e direta, porém pode compromete um pouco o modelo.

Costumo utilizar controle de transação otimista, onde ela se inicia no começo de um request e finaliza no seu fim (via filtros).
Em caso de transações atômicas uso flushMode manual do hibernate, onde os DAOs (e não repositories) possuem métodos com flush explícito. Para o Repositories isso é transparente e não vaza para o domínio. Claro que o filtro é informado quando a transação é atômica ou não (na realidade isso é feito pelo Seam).

microfilo wrote:Será que da para fazer algum transaction management diretamente na "entity" utilizando AOP? Nesse caso, a entity não ficaria muito "parruda"?


Eu acho que não fica ruim. Ela é parruda tão quanto o modelo assim o faz, eu acho justo.

microfilo wrote:
Lezinho wrote: Server-side, embora poderia ser client-side em vista que consigo invocar qualquer metodo mesmo com Javascript, bastando ele estar anotado por @WebRemote para esta ultima.

Bacana, bem parecido com DWR, não?


Na realidade bem mais transparente. Com a EL dele é possível invocar qualquer método de classes de negócio sem ter um Command por trás disso em qualquer página, e sem javaScript adicionais (é server-side). Mais se acaso vc tiver um JavaScript e precisar invocar um método de um objeto de negócio que esta em algum escopo, neste caso vc utiliza a anotação @WebRemote... somente isso.

... Lezinho
------------------------
twitter: @lazarotti
http://alessandrolazarotti.wordpress.com/
http://jbossbrasil.org/

[Email] [MSN]
Rubem Azenha
GUJ Master
[Avatar]

Membro desde: 28/06/2004 00:10:43
Mensagens: 1933
Localização: São Paulo, SP
Offline

Lezinho wrote:
1) Construir uma Strategy de um objeto de transação fake (para poder mudar a implementação se necessário). Esta strategy é um atributo injetado em sua entidade (portanto controlado pelo ciclo de vida do seu framework de injeção/transação). Ele tem um atributo que inicia uma nova transação isolada e que a finaliza. Você pode chamar este atributo nos pontos necessários de sua entidade.

Aí eu não tenho um mecanismo que gerencia a transação. Seria o mesmo que controlar a UserTransaction na mão. Da muito trabalho e obriga os meus objetos de dominio a lidar com transação, algo que eu não acho legal.

Lezinho wrote:
2) Criar uma anotação para novas transações na entidade. Funcionaria exatamente como descrevi acima, com a chamada para um objeto de transação sob o controle de seu framework, exceto pelo fato de você não ter que fazer um atributo a mais na sua entidade... mas sim anotar um método. Um "aspecto"deverá fazer a leitura para efetuar a transação.

Talvez seja uma opção viável. Mas seria a "entity" o local mais adequado para demarcar as transações? e se eu for utilizar uma mesma "entity" em um outro contexto em que o isolamento transacional é diferente?

Lezinho wrote:
3) Fazer todo o processo transacional por fora, em um service. É a forma mais simples e direta, porém pode compromete um pouco o modelo.

Depende, podemos fazer o service apenas cuidar de coisas de "infraestrutura", como demarcação de transações e delegar a execução de regra de negócio á "entity".

Lezinho wrote:
Costumo utilizar controle de transação otimista, onde ela se inicia no começo de um request e finaliza no seu fim (via filtros).

Acredito que isso é o suficiente na maioria dos casos. Mas existem as exceções. E nesse caso, não são tão raras...

Lezinho wrote:
Em caso de transações atômicas uso flushMode manual do hibernate, onde os DAOs (e não repositories) possuem métodos com flush explícito. Para o Repositories isso é transparente e não vaza para o domínio. Claro que o filtro é informado quando a transação é atômica ou não (na realidade isso é feito pelo Seam).

O flush sem si não resolve... Mesmo que você faça o flush, se você fizer o rollback da transação, o seu update não sera refletido no banco de dados.


Lezinho wrote:
Na realidade bem mais transparente. Com a EL dele é possível invocar qualquer método de classes de negócio sem ter um Command por trás disso em qualquer página, e sem javaScript adicionais (é server-side). Mais se acaso vc tiver um JavaScript e precisar invocar um método de um objeto de negócio que esta em algum escopo, neste caso vc utiliza a anotação @WebRemote... somente isso.


Acho que a gente se confundiu, heheh. Para invocações client-side é bem parecido com DWR.



Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning
[WWW]
 
Índice dos Fóruns » Arquitetura de Sistemas
Ir para:   
Powered by JForum 2.1.8 © JForum Team