Ultimamente tenho visto nos fóruns e blogs pelo mundo comentários inflamados sobre Struts em comparação com outros “MVC web application frameworks”, como o Webwork.
Trabalho com o Struts e acho que ele é uma mão na roda, mas eu queria saber em poucas palavras em que o Webwork é definitivamente melhor do que o struts, sem “hype marketing”.
Em menos palavras do que isso não dá: WebWork é mais simples.
marciolx
ok, já é muita coisa
Guilherme_Silveira
o cv falou o q era preciso
vc nao precisa ler um livro de webwork para fazer o q quer fazer com ele.
a forma que o webwork é utilizado é MAIS NATURAL que o struts… a lógica, o funcionamento.
ainda tenho meus preconceitos contra webwork tambem pq peguei versoes com muito bugs, mas isso já é apelo pessoal.
creio que hoje em dia no brasil struts só serve para arranjar emprego e espero que isso não fique muito tempo assim.
Paulo_Silveira
soh aquela assinatura gigante de metodo que as action tem de implementar da arrepio. ficar passando request, response e mais um monte de coisa pra tudo que eh lado eh no minimo estranho, sem contar que voce nao esta trabalhando nem estaticamente, nem orientado a objeto, esta TUDO orientado a request, quase thread local
ricardolecheta
a verdade é que vc escreve menos código.
(obs: trabalho com Struts a quase de 1,5 anos )
urubatan
menos código com o struts??
como?? (ou entendi errado o que vc quiz dizer??)
ricardolecheta
“urubatan”:
menos código com o struts??
como?? (ou entendi errado o que vc quiz dizer??)
eu me expressei mau . Menos código com o WebWork.
T
tanque
Em relacao a grande assinatura dos metodos no struts, isso se deve ao fato de ele seguir a orientacao de servlets, de nao utilizar atributos de objetos para armazenar essas informacoes.
Isto quer dizer que somente uma instancia do Action pode tratar todas as requisicoes desse action no container.
Nao conheco muito o WebWorks, mas parece que cada requisicao implica na criacao (ou uso de pool) de instancias do action. Dependendo da complexidade esse cria/destroi pode vir a ser um problema de performance, por sucessivas chamadas do GC. Obvio que hoje em dia as JVM estao muito boas nesse sentido, mas eh uma linha diferente que o Struts segue, de ser mais proximo ao modelo de servlet, e nao acho justo crucifica-lo por isso.
Acredito que existe espaco para os dois Frameworks no mercado. O fato que mesmo com suas limitacoes, o Struts virou um padrao de mercado, sendo usado como base ate pela Oracle. Hoje em dia conhecer struts, no minimo, eh interessante, ate por causa do grande numero de aplicacoes usando ele e seus derivados.
cv1
Eu acho perfeitamente justo crucificar o Struts por ter tomado uma decisao de design baseada em dados de performance que nem sequer existiam. Numa requisiçãozinha qualquer, o seu Servlet container já cria objetos adoidado, e não vai ser um mero new a mais ou a menos que vai fazer muita diferença. Isso é crucial no caso de um framework como esses, já que o fato de o Struts evitar criar novas instâncias das Actions trouxe a maior parte da complexidade dele (ActionForms, FormBeans e tudo mais), que é absolutamente desnecessária (e o WebWork prova).
E é WebWork, não WebWorks.
urubatan
IMHO o motivo pelo qual o struts virou um padrão de mercado, é que até pouco tempo atraz, não existiam outras opções a altura,
e este é o mesmo motivo pelo qual o struts não evoluiu muito também, des da primeira versão do struts, muito pouco foi adicionado ao core do struts, ele continua basicamente a mesma coisa.
Acho que o struts é um projeto que deveria ser mantido apenas para dar suporte aos projetos ja existentes, e ser desenvolvido um “struts 2.0” a partir do nada, e sem muitas preocupações com compatibilidade ou alguma coisa do genero.
se bem que parece que o “dono” do struts, também acha isto, tanto que ele esta no expert group da JSF e quer para as novas versões da JSF integrar as funcionalidades de MVC na especificação para matar a necessidade do struts
T
tanque
“cv”:
Eu acho perfeitamente justo crucificar o Struts por ter tomado uma decisao de design baseada em dados de performance que nem sequer existiam. Numa requisiçãozinha qualquer, o seu Servlet container já cria objetos adoidado, e não vai ser um mero new a mais ou a menos que vai fazer muita diferença. Isso é crucial no caso de um framework como esses, já que o fato de o Struts evitar criar novas instâncias das Actions trouxe a maior parte da complexidade dele (ActionForms, FormBeans e tudo mais), que é absolutamente desnecessária (e o WebWork prova).
E é WebWork, não WebWorks. :D
Bem esta eh a SUA opiniao. O fato de voce ler a pagina de comparativo entre Webwork(obrigado pela correcao) e Struts nao implica que tudo esta certo. Eh uma visao unilateral e cada um quer vender seu peixe.
O fato eh que os objetos criados pelo container, como Request, por exemplo sao simples, com pouca informacao. Alem disso, o Servlet Conteiner pode tranquilmanete fazer pool desses objetos evitando criacao desnecessaria. Agora o custo de criacao de um Action do WebWork, eu nao sei qual é. Sei la, vai que um maluco manda criar um array de 10 mega no contrutor do action. Bem , no struts isso nao tem problema (muito grave) ja que isso sera feito uma vez soh.
Mas realmente voce tem razao em falar que o Struts possui um design um pouco antiquado, nao ha duvida disso. Na verdade o que mais me irrita no Struts eh a obrigatoriedade de ter que derivar das classes dele( ou seria um problema do java nao ter heranca multipla ).
ricardolecheta
nao vamos tirar os métodos do Struts :-), ele foi o pioneiro e salvou a vida de muitos já.
O Mike Tyson “foi” o campeao mundial já, hoje não é mais. Mas alguem vai dizer que o cara não é bom de briga? Ele apenas não é mais o melhor. .
Ninguem pode negar que o Struts agiliza o desenvolvimento MVC. Se o WW é melhor é outra coisa, o Struts continua com todos os seus méritos.
Guilherme_Silveira
disse tudo ai.
tanque, objetos como o Request criado pelo Tomcat nao sao leves, pelo contraruio, sao muito mais “pesados” que objetos de logica de negocios, as actionss no caso. Um mero newInstance eh algo que sai de graca! ficar com um objeto soh para as acoes na memoria implica em ter de pensar em thread safety, alem de voce passar a trabalhar nao orientado a obnjetos: aquilo vira uma funcao.
T
tanque
“Guilherme Silveira”:
disse tudo ai.
tanque, objetos como o Request criado pelo Tomcat nao sao leves, pelo contraruio, sao muito mais “pesados” que objetos de logica de negocios, as actionss no caso. Um mero newInstance eh algo que sai de graca! ficar com um objeto soh para as acoes na memoria implica em ter de pensar em thread safety, alem de voce passar a trabalhar nao orientado a obnjetos: aquilo vira uma funcao.
Bem, os Request ate podem ser pesados, ocuparem memoria. Mas, eu nao tenho como fugir deles, a nao ser que eu abandone java, ou servlets e jsp ao menos.
Mas o grande diferencial ai eh que eu tenho liberdade de escolha. Nao estou contente do jeito que o tomcat trata as requisicoes, posso mudar para o weblogic, para o jetty, resin, qualquer web container.
Agora se eu ficar descontente com o struts, ou o wework, nao tem jeito. Tenho que reescrever minha aplicacao. Nao posso simplesmente trocar de fornecedor. Se por acaso o fato do webwork criar sempre os actions, num futuro teste de performance, se mostrar inviavel (acredito que nao o sera) eu nao vou ter escolha a nao recomecar o projeto. Nesse sentido acho interessante ter tecnologias de mais alto nivel, como webwork e de mais baixo nivel, como o struts. Ha espaco para ambos.
Alem do mais, se eh para criticar coisas, jogar m**** no ventilador, falemos dos servlets. Para que menos orientado a objeto que o proprio servlet, um amontoado de funcao tambem. E o jsp entao, ficar misturando codigo com html, muito sem nocao.
Felizmente, ou infelizmente , heheheeh, foi criado um elefante branco chamado JSF. Esse finalmente sera uma tecnologia MVC que dara liberdade de escolha para o fornecedor (nao estou falando que o JSF eh bom, mas se voce quiser trocar seu myfaces para o jsf da sun, ou da ibm voce podera.)
Soh para finalizar, citando o livro o Java™ Performance and Scalability Volume 1: Server-Side Programming Techniques de Dov Bulka (Addison Wesley) que eu li, ele realiza testes em varios aspectos da linguagem java, fazendo microbenchmarks em streams, strings, comparar LinkedList e ArrayList, bem, no quisito criacao de objetos comparado com pool, o uso de pool eh 2 vezes mais rapido que a criacao de objetos novos. Bem, o Struts nem criar o objeto do Action precisa.
Nao quero dizer , em nenhum momento, que a criacao constante de objetos do webwork vai inviabilizar um projeto. Hoje em dia, com o poder computacional isso eh minimo. Soh estou expondo dois pontos chaves: nem todo mundo pode gostar da constante criacao de objetos do webwork, e para isso existe alternativa, o struts e outro ponto eh que o modelo do struts, de nao poder usar atributos, nem vem dele, ja vem do proprio modelo de servlet, e por que ninguem fala mal do modelo de servlet e propoe uma alternativa.
Paulo_Silveira
“tanque”:
…
falemos dos servlets. Para que menos orientado a objeto que o proprio servlet, um amontoado de funcao tambem. E o jsp entao, ficar misturando codigo com html, muito sem nocao.
tem toda a razao!
“tanque”:
…
Soh para finalizar, citando o livro o Java™ Performance and Scalability Volume 1: Server-Side Programming Techniques de Dov Bulka (Addison Wesley) que eu li, ele realiza testes em varios aspectos da linguagem java, fazendo microbenchmarks em streams, strings, comparar LinkedList e ArrayList, bem, no quisito criacao de objetos comparado com pool, o uso de pool eh 2 vezes mais rapido que a criacao de objetos novos. Bem, o Struts nem criar o objeto do Action precisa.
Esse livro eh de java 1.2! Eh incomparavel a runtime do java 1.4 com a do 1.2, em especial em relacao a essas coisas de criacao de objetos pequenos, etc. Hoje em dia nao compensa usar pool de jeito nenhum para objetos simples.
pcalcado
“Paulo Silveira”:
“tanque”:
…
falemos dos servlets. Para que menos orientado a objeto que o proprio servlet, um amontoado de funcao tambem. E o jsp entao, ficar misturando codigo com html, muito sem nocao.
tem toda a razao!
Temos um problema aqui.
HTTP não é orienteado à objetos, existe uma fronteira entre paradigmas. É como falar que Hibernate é ruim porque lida com o paradigma relacional.
Um ‘adaptador’ como servlets encapsula a requisição para você, ora, quando você usa um servlet, você está trabalhando OO! Eu não conheço nenhum browser RMI/IIOP que minha mão conseiga usar como o browser HTMP sobre HTTP dela. Pelo menos, não por enquanto.
Não vejo motivos para tanta reclamação mesmo, o Servlet te entrega o Request como um objeto. Response, session, etc. também. Em HTTP, são mensagens de texto!
Se for pra jogar pedra na API, é melhor arrumar outro motivo
[]s
T
tanque
Nao quis chegar a tanto, soh quis exemplificar um caso que a abordagem nao eh tao orientada a objeto como poderia, mas tudo bem. Vamos as argumentacoes. O fato do HTTP nao ser orientado a objeto nao quer dizer que o tratamento dele nao precise ser orientado a objeto. Citemos alguns exemplos, a API do windows eh orientada a eventos, e existem varios wrappers para ela orientado a objeto, como por exemplo a MFC, OWL. Ate a VCL do delphi tem esses conceitos. A Xlib do unix eh a mesma coisa, mesmo assim existem modelos orientados a objetos, como o QT por exemplo.
Orientacao a objetos tambem eh realmente isso, esconder complexidade do software em involucros tipo caixa preta, entao essas bibliotecas escondem o modelo do xlib e do WIN32 em uma casca orientado a objeto.
A minha critica em relacao ao Servlets, que vem a ser a mesma critica que defensores do WebWork fazem relacao ao struts eh o fato de nao grudarem os Request, Response, etc, em atributos da Classe. Houve motivos para fazer isso, e passar esses elementos como parametros. O Fato que o struts usa a mesma abordagem e eh criticado. Bem, entao antes de tudo critiquem servlet, e nao soh o struts. Nao eh a primeira vez que houve erros de Design da linguagem / APIs do java e nao sera a ultima. Mas tudo bem, vamos levando, vamos consertando onde da, criando framewors que resolvem nossos problemas do dia a dia como por exemplo o struts e o webwork
O Hibernate nao se enquadra no mesmo ponto, porque apesar de lidar com um paradigma nao orientado a objeto , prove uma bela prova que se pode contruir uma boa camada de mapeamento orientada a objeto. Eh a mesma coisa das bibliotecas graficas que citei anteriormente. Prove uma boa abordagem orientada a objeto para algo que nao o eh.
pcalcado
Concordo, e é exatamente isso que a AP de Servlets faz.
GET/Stuff/Funny/silly.htmlHTTP/1.0
User-agent: NCSA Mosaic for the X Window System/2.5
Accept: text/plain
Accept: text/html
Accept: application/postscript
Accept: image/gif
Ok, são propriedade de um pedido de conexão. Ate’onde eu aprendi, um objeto reúne dados [propriedades] e operações, logo estes deveriam estar contidos em um objeto ‘request’ utilizado. Você rpecisa fazer o parse destes dados de texto para objetos? Não, a especificação diz que você não precisa se preocupar com isso.
Note que encapsulamento não é um conceito exclusivo de programação OO, programação estruturada/procedural também utiliza este conceito.
Bem, afinal, qual o problema com os servlets? Onde você não programa orientado à objetos em um servlet? A encapsulação do HTTP em objetos é falha onde? Ok, nada é perfeito [e não estou ganhando nenhuma grana da Sun pra defender sua especificação], mas gostaria de algum argumento.
Hei, coisas diferentes aqui. Se você trabalhar com Struts, WebWork [creio], etc., vai estar colocando uma camada de abstração em cima dos servlets. Se os servlets [que são de baixo nível] encapsulassem o HTTP, me diga como você poderia ter acesso a um parâmetro passado por GET ou POST. ‘Ah, poderíamos ter tudo encapsulado em um modelo que livrasse o programador de sequer saber que aquilo é HTTP…’ e a curva de aprendizado seria enorme para alguém entender este adaptador. Seria criado um novo protocolo em cima do HTTP…
Servlets são baixo nível nesta especificação, não é a toa que tanta coisa é construída com base em servlets, de JSP à WebServices. Como são tão baixo nível, é preciso que reflitam o HTTP como ele é, é claro que de uma maneira OO, mas não podem esconder muitos detalhes. Se eu preciso saber que meu usuário me mandou um parâmetro num form HTML, isso não pode/deve ser muito diferente de qualquer outro programa que use HTTP!
O adaptador é provido pelo framework MVC ou o quer que você use em cima do Servlet. O ponto é que o Struts não abstrai tudo do programador, como deveria. Note também que não tenho nada contra Struts, mas a idéia de que ele parou de evoluir tem muito sentido para mim.
“tanque”:
O Hibernate nao se enquadra no mesmo ponto, porque apesar de lidar com um paradigma nao orientado a objeto , prove uma bela prova que se pode contruir uma boa camada de mapeamento orientada a objeto. Eh a mesma coisa das bibliotecas graficas que citei anteriormente. Prove uma boa abordagem orientada a objeto para algo que nao o eh.
Exatamente como os Servlets. Encapsula algo que não é OO em adaptadores.
Por que usar Hibernate? JDBC não é OO?
Pois bem, com Mapemaentos O-R em geral, você colcoa algo acima da JDBC, nada mais de se preocupar com connections, statements… Assim como em uma camada de abstração sobre os servlets você não deveria se preocupar com request/response, isso é papel do seu framework que encapsula a APId e servlets, logo os processos HTTP.
Servlets/HTTP estão para o MVC como a JDBC está para um mapeamento O-R. Podeia ser melhor desenhada? Tudo pode ser malhor desenhado! Mas não é ruim, pelo cotnrário, serve à que se propõe, e muito bem.
[]s
T
tanque
Parece que voce mesmo responde sua pergunta:
em
Se eu derivar um HttpServlet, eu nao posso criar propriedades, somente operacao. Segundo o que voce mesmo definiu, eu tenho meio objeto, ja que nao posso ter propriedades, soh operacoes.
pcalcado
Ei, não é só hernaça que promove a reusabilidade, pelo contrário!
[list]
[b]- Minimize a acessibilidade de classes e membros
Prefira a imutabilidade
Prefira composição ao invés de herança
Especifique e documente para herança, caso contrário, proíba-a[/b]
[/list]
Herança é utilizada para definir subtipos. Quem criou o tipo HttpServlet achou [talvez com razão] que você não tem motivos para quebrar o encapsulamento, afinal: não era essa a sua queixa? Se você quer encapsulamento, por que fazer isso?
Se você precisa criar um Servlet HTTP novo, crie o seu do zero ou faça um adaptador [padrão da GoF] em cima do existente. Se você que um Servlet não-HTTP, extenda a superclasse.
Essa história de que toda classe rpecisa ser extensível é papo-furado
Sinceramente, você tá procurando chifre na cabeça de cavalo
[]s
T
tanque
Ate gostaria de poder seguir as dicas que voce passou. O fato eh que o modelo de servlets me obriga a seguir o modelo deles. Por exemplo, voce falou que prefira composicao a heranca. Bem, eu nao posso fazer uma composicao, porque envolveria criar um atributo, que nao funcionara direito em um ambiente multithread do Container WEB. Realmente estou pondo chifres em cabeca de cavalo. Fato: preciso criar um servlet. Fato: Meu servlet nao pode ter propriedades (nao eh thread safe).
Que opcoes eu tenho para contornar isso: Ficar grudando coisas do request, na sessao, que eh tosco, do ponto de vista de orientacao a objeto. Se eu tenho uma Classe que eh um Servlet que trata da logica do dominio X, nada mais justo que informacoes sobre esse dominio possam ser armazenadas nele. Pois bem, eu nao posso. Tenho que ficar grudando essas coisas em session, request.
Mesmo que eu extenda a Servlet, nao a HttpServet, o container esta preparado para pensar em instanciar somente um unico Servlet do meu tipo. O contrato da API especifica que o Servlet, e o HttpServlet precisa ser thread safe, ou seja nao permite o uso de atributos. Ate existe um SingleThreadModel, que eh altamente nao recomendavel, que faz um lock do objeto inteiro, serializando os acessos ao servlet, sem nocao.
Acho que essa discussao esta se distanciando muito do seu foco. Mesmo com todos esses problemas conceituais do Servlet, eh possivel usar ele com destreza. Fazer programas otimos.
Nao venha tambem me dizer que os genios que inventam essas nabas estao certos. Citando exemplo, o controle de thread , por exemplo, na versao do java 1.0 possuia o infame metodo stop. Ele foi deprecated e altamente desaconselhado porque podia segurar locks de monitores e de recursos. Erros de design ocorrem a todo o momento. Soh nos resta aprender a confivever com eles. Eh o caso do servlets. Tem que ir consertando aonde da. Eh ai que entram frameworks tipo Struts e WebWork.
pcalcado
Bom, se você coloca regras de negócio nos servlets, acho que o problema não é bem da API…
Eles servem apenas para executar métodos em resposta à eventos HTTP, você não deveria estar precisando colocar atributos em cima dele, porque servlets NÃO fazem parte da lógica de negócios, são clientes dela!!
O padrão Adapter poderia muito bem ser utilizado em um contexto multithread, o Servlet encapsulado recebe as solicitações, qual o problema?
O problema é que você está colocando sua lógica de negócios no lugar errado. Me dê um bom motivo para colocar um atributo em um servlet.
Problemas acontecem em qualqeur projeto, acho que até você falou isso neste t’ópico. Qual o problema em errar? Nada é perfeito, nem ninguém…
Tudo baseado nos servlets. Um exemplo clássico é JSP: são abstrações dos servlets!! Não são gambiarras para melhorar o modelo, são um método de implantar MVC, servlets são apenas conectores entre o programa e o mundo HTTP, estes frameworks não substituem servlets, eles os encapsulam e põe um lindo ‘COLOQUE SUA REGRA DE NEGÓCIO AQUI’ para facilitar as coisas.
Antes de falar que servlets são mal-projetados [eles não são perfeitos, ok, ams seus argumentos não apontaram nada], revise quantas camadas tem seu sistema. Qual a diferença entre um servlet ‘faz-tudo’ e uma aplicação Delphi/VB conectando com o banco? Novamente: me dê um bom motivo para extender um servlet ou colocar um atributo nele, a menos que você não esteja usando HTTP.
[]s
Guilherme_Silveira
atributos:
logger
pool de conexao
registro de usuarios online
qquer outra coisa com caracteristica estatica
extendendo uma servlet pra:
na epoca que nao tinha filtro, todo mundo criava uma SecurityServlet que o doRequest6 verifica se o cara estava logado, e se estivesse3 chamava o metodo abstrato execute(). Eu nao gosto disso, mas eh um motivo ai, template method.
mas meu ponto nao eh esse, meu ponto eh que sua aplicacao deve ser agnostica a api do servlet, como o webwork.
cv1
[chato=on]
Pq?
Paulo_Silveira
[chato=on]
Pq?
bem, realmente nao eh algo super necessario. mas ficar agnostico o codigo fica mais limpo, e mais facil de ler. alem disso fica mais facil de testar (apesar de eu nao ser o homem teste, como o cv bem sabe :))
achava que voce tambem curtia o webwork pela agnosticidade com a api de servlet cv, qual a sua opiniao/gosto?
cv1
E eu curto, eu acho uma das coiasas mais legais do WebWork o fato de ele te isolar da API que ta por baixo dos panos. Mas dizer que todos os casos devem ser tratados assim tira muito do seu leque de opcoes. Legal, vc pode pegar uma app escrita em cima do WW2/XW e fazer suas Actions rodarem em cima de um ambiente totalmente diferente (sei la, Swing), mas toda abstracao falha, e alguma hora voce precisa de um cookie. Whoops.
Entao, reiterando, eu gosto da liberdade de nao ter que me preocupar com o HttpServletRequest ou o que mais for. Mas dizer que é errado ou anti-pattern descer pras camadas de abstração mais baixas quando necessário, eu discordo, e foi mais ou menos isso que eu interpretei do post do Guilherme. Pronto, pode me chamar de mala
black_fire
E ai galera, entrando no fogo cruzado!
Trabalho só com o WW 1.4 faz um ano ±, e a única coisa que que tenho tenho a dizer é que o WW é bom dependendo do que vc quer fazer… nào uso o WW2 pq ele nunca fica pronto, tbm não posso me dar ao luxo e ficar mudando minha aplicação pq alguem resolveu tirar esse ou aquele método e por último se a documentação do 1.4 já é muito fraca imaginem a do 2.
Hoje predendo implementar uma aplicação um pouco maior e estou estudando o struts pra fazer isso… por dois motivos, achei o struts mais parrudo, principalmente na parte de Internacionalização e Localização, muito mais recurso que o WW1.4 e o motivo principal, a documentação é esmagadoramente maior… Como que com o WW eu não uso velocity ou similares, prefiro trabalhar com tags, na parte do view não vou ter problemas…
Na minha opnião, quando vc usa ferramentas openSource em projetos profissionais vc não pode arriscar… Sem contar a disponibilidade de profissionais caso você precise… Usando uma ferramenta popular posso ter um programador que já “vai chegar programando”… essa é uma vantagem tbm.
Vou continuar usando o WW para aplicações menores e mais simples uma vez que a lógia é muito semelhante entre o WW e o Struts.
Creio q radicalizar não é muito legal… Gosto muito do WW, é uma maneira fácil e rápida de alguém que tá ingressando no mundo MVC, criar suas aplicações, talvez se eu tivesse entrado diretamente no Struts teria pastado muito mais!!! Mas quando o bicho pega vc precisa de uma solução mais Robusta…
:arrow: Mas é minha opnião particular!
duardor
Ola pessoal
Entrando no meio aki… Eu tb nao gosto de extender x ou y, implementar teta e o escambal… Meu trabalho de diplomacao aborda programacao orientada por aspectos, e nele estou fazendo uma aplicacao web simples (simples messssmmmmoooo) e usando o AspectJ para em alguns casos funcionar como “cola” entre as api’s e minha lógica de negócios…
Quando terminar , defende-la e corrigi-la (espero q nao precise) publico aki pra vcs darem uma olhada (e jogaram pedras )…
na epoca que nao tinha filtro, todo mundo criava uma SecurityServlet que o doRequest6 verifica se o cara estava logado, e se estivesse3 chamava o metodo abstrato execute(). Eu nao gosto disso, mas eh um motivo ai, template method.
Na época que eu fazia CGI, era bem legal. Hoje você me pede um CGI e eu te mando pra PQP