Ultimamente vi uma série de posts no meu feed reader coincidentemente encadeados falando sobre padrões de projeto e os considerando genericamente gambiarras.

Tudo comecou no post do Giovane Roslindo Kuhn falando como é legal usar patterns para a comunicação da equipe. O entendimento que se dá no código quando ele é estruturado seguindo convenções estabelecidas em padrões. Claro que esse não é uma das características de se usar um padrão, mas sim um beneficiamento dele (mesmo quando evidentemente não necessitaria haver a presença de um padrão).

Motivado por esse post, o Vítor Ferreira Pamplona escreveu um outro dedicado aos anti-patterns e a prejudicial característica da comunidade java ser reconhecida como a comunidade pattern. Evidenciou a necessidade que programadores empolgados com uma nova linguagem agirem como se essa linguagem fosse uma bala-de-prata e resolvesse todos e quaisquer problemas.

Os próprios padrões de projeto conhecidos podem se tornar um anti-pattern se forem usados para um contexto diferente do que se propõe inicialmente. Quem nunca viu aí uma estrutura cheia de commands para simular MVC em um sistema web levante a mão.

Após o post do Vítor o Thiago Arrais publicou um artigo chamando os padrões de "gambiarra com nomes" que acabou gerando outro artigo do Marcos Tapajós no blog da Improve It na mesma linha.

Concordo com muitos pontos colocados por ambos mas quero fazer uma ressalva, uma gambiarra é uma solução improvisada (deveria também ser temporária) e fora dos procedimentos legais. Um padrão pode ser uma gambiarra mas em essência não é.

Gambiarra "Orientação a Objetos"

Se levarmos ao pé da letra essa consideração podemos então supor que Orientação a objetos seria uma gambiarra, porque os desenvolvedores C já simulavam os conceitos de orientação antes do surgimento do C++, que apenas forneceu ADTs nativos específicos para o desenvolvedor. Linguagens como Smalltalk que foram concebidas tendo em mente a orientação a objetos seria únicas verdadeiras OO mesmo que internamente seu interpretador faça algo parecido com uma linguagem não pura. Mas a única diferença entre as duas é a familiaridade da arquitetura interna da linguagem com o padrão/conceito que se deseja implementar. Uma esconde do desenvolvedor a implementação a outra temos que criar nosso próprio dialeto e não se beneficiar das otimizações e checagens que por ventura a plataforma faça.

Vícios

Temos programadores que acham que podem viver conhecendo apenas uma linguagem e que esta deve servir para tudo, com isso aceitam estruturas estabelecidas mesmo que sejam nocivas.

A Sun criou o conceito de Java Beans para componentes visuais e extendeu esse conceito para sua plataforma Enterprise para designar ADTs que encapsulam suas propriedades.

Hoje a maioria dos desenvolvedores quando codificam suas classes o fazem com um passo-a-passo em mente:

  1. Cria uma classe que representa uma tabela no banco de dados;
  2. Cria as propriedades referentes as colunas nessa tabela;
  3. Atribui private para todas as propriedades;
  4. E por fim cria métodos "set" e "get" para todas as propriedades indiscriminadamente.

Se voce criar uma construção que acesse "objeto.propriedade" é pecado mortal em java, não segue a "convenção".

Em linguagens que implementam o ECMAscript voce tem no BOM (Browser Object Model) o método setProperty(chave, valor) nativo que atribui um valor à propriedade  indicada e não necessita implementar um atribuidor para cada método. Sabiamente não existe um getProperty, voce acessa diretamente.

Em java se uma propriedade é read-only tem coerência voce aplicar um private no qualificador e criar um método getX, outra situação é se voce deseja manipular o valor em tempo de execução, então um método get e ou set tem necessidade. Fora isso  é desnecessário e a propriedade é pública.

Generalidade vs Especificidade

O problema maior com padrões é querer extender uma linguagem além do que ela foi arquiteturada. Como simular Continuations que é nativo da linguagem Scheme, ou Design By Contract do Eiffel. Voce pode fazer ambos em Java, tanto Continuations como DbC podem ser feitas mas com gambiarras, não são inerentes da arquitetura concebida na plataforma Java. Existem até Framework e Container Java que implementam continuations, mas sofridamente.

Inclusive alguns entusiastas do Ruby mais afoitos (A.K.A novatos) fazem bastante algazarra em listas de discussões de como conseguem fazer uma iteração ou outra operação específica com menos linha de código que linguagens como Java ou C++. Claro que é perda de tempo total tentar dialogar e mostrar a necessidade da escolha ideal para o determinado propósito, os programadores de verdade sabem que Ruby também não será o fim dos tempos, conceitos surgirão e retornarão dependendo da situação.

Outra situação depende do ambiente, como simular MVC em uma ambiente web, devido a diferença de contexto do ambiente http em detrimento ao ambiente standalone de um desktop surgiu o famigerado MVC model 2 que deu cria a aberrações como Struts e derivados. Isso hoje pode ser contornado mas ainda é incipiente.

Na mesma forma acontece com padrões, como o contexto de uma linguagem está atrelada a determinado ambiente é vital incorporar conceitos deste contexto na sua semântica e deixar a extensão para o desenvolvedor do que ser genérica e causar improdutividade com tarefas repetitivas, vide sucesso do ruby na construção de aplicações web com o Ruby On Rails.

Em diversas épocas os padrões como Singleton e Factory vão e voltam com desenvoltura, em momento amado e indispensável, outro odiado e suplantado. Mas são padrões universais para resolver um determinado problema, catalogado e disponível para quando forem requisitados.

Padrões são assim, como quase tudo na vida, desnecessários as vezes e se usados com moderação são benéficos. Como dizia minha vó, "tudo demais é veneno".

O Bruno Torres iniciou uma série de artigos em um blog intitulado "O Básico da web" para publicar uma espécie de curso dinâmico sobre desenvolvimento web onde os arquivos vão amadurecendo com o tempo como ele mesmo explica nesse post.

Assine o feed do blog e acompanhe a evolução dessa excelente iniciativa se voce pretende aprender sobre o desenvolvimento web, ainda mais sendo escrito por quem é, um guru do web development tupiniquim.

ps. É inusitado mas tem muita gente que não utiliza um agregador de feeds e pior, nem sabe o que é feed. Aqui tem um passo-a-passo básico sobre isso. 

Iniciarei uma série de artigos mostrando na prática como criar um sistema usando o framework Yahoo! YUI.

Nesse primeiro artigo usarei os templates "Grids CSS" para criar a(s) página(s) sem se preocupar com css (já iniciando dentro dos padrões web) e definirei os menus da aplicação usando os componentes de Menu do yui. Os modelos do framework são importantes principalmente se você não tem prática ou desconhece sobre Web Standards.

O framework

Primeiro vamos baixar e adicionar ao projeto as bibliotecas e templates do Framework. A pasta build contém as bibliotecas e folhas de estilo e a pasta examples contém modelos de usabilidade do framework.

Criando o modelo

Vamos criar uma página que será o front da aplicação. Crie um index.html e escolheremos um dos templates já disponibilizados. 

O próprio Yahoo! recomenda o uso do modo Strict mostrando que se comprometem com os padrões. Indicam no Getting Started a seguinte assinatura doctype:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<!-- layouts require "Standards Mode" rendering,  hich the 401-strict doctype triggers -->

Precisamos acrescentar a referência para os arquivos css do yui:

<link type="text/css" rel="stylesheet" href="js/yui/build/reset/reset.css" />
<link type="text/css" rel="stylesheet" href="js/yui/build/fonts/fonts.css" />
<link type="text/css" rel="stylesheet" href="js/yui/build/grids/grids.css" />

Definindo o esboço da página

Para usar o Grid CSS espera-se que exista a seguinte estrutura, onde os elementos já sao definicos como:

<div id="doc">
 <div id="hd"></div> <!-- header -->
 <div id="bd"></div> <!-- body -->
 <div id="ft"></div> <!-- footer -->
</div> 

Dividindo a página em 3 regiões: hd (Cabeçalho), bd (Corpo) e ft (Rodapé).

Escolhendo o template 

 

Após criar-mos as marcações exigidas pelo Grids CSS escolheremos um dos templates definidos para controlar as regiões de conteúdo.

Esses templates controlam duas regiões de conteúdo pré-definidas pelo framework denominadas em região "primária" e "secundária" (ou sidebar)  como na imagem ao lado.

 

O Grids CSS provê 7 templates onde 6 deles especificam a estrutura de conteúdo em  região "principal" e "barra lateral". o Sétimo template define um layout sem a barra lateral onde a região principal ocupa toda a extensão da página.

A imagem ao lado exibe os templates com suas respectivas identificações.

Utilizarei o "yui-t2" nessa série. 

Esse template escolhido está mais próximo de um sistema padrão com boa largura (180px) para a região lateral onde ficarão os menus e 550px para a região de conteúdo.

Especificando o template

Acrescente no div "doc" a referência ao "class" do modelo escolhido.

<div id="doc" class="yui-t2">

 A página ficará assim:

… 

<body>
<div id=
"doc" class="yui-t2">
   <div id=
"hd"></div> <!-- header -->
   <div id="bd"></div> <!-- body -->
   <div id="ft"></div> <!-- footer -->
</div>
</body>

… 

Definindo o conteúdo

Escolhemos um modelo que tem duas regiões de conteúdo. Vou acrescentar duas regiões definindo a área de menus e de conteúdo principal no corpo da aplicação:

<div id="doc" class="yui-t2">
  <div id="hd"></div>
   <div id="bd">
     <div id="menu" class="yui-b"></div>
     <div id="conteudo" class="yui-main"></div>
   </div>
   <div id="ft"></div>
</div>

Observe que a disposição não tem importancia porque a ordem dos elementos que definem as regiões de conteúdo é controlada no css que determina que o estilo "yui-main"(o principal) será à direita (no caso do nosso template escolhido).

Acrescentarei  na região do conteúdo principal (yui-main) mais duas regiões. Uma será para apresentar os formulários em cima da coluna "main" e os grids resultantes das ações dessess formulários na região de baixo, ficando assim: 

<div id="doc" class="yui-t2">
  <div id="hd"></div>
  <div id="bd">
   <div id="menu" class="yui-b"></div>
   <div id="conteudo" class="yui-main">
       <div class="yui-b">
         <div id="formulario" class="yui-g"></div>
         <div id="grid" class="yui-g"></div>
      </div>
   </div>
  </div>
  <div id="ft"></div>
</div>

Adicionando os Menus

Importarei os componentes usados para criar os menus dinâmicos. Acrescente:

<!-- Dependências -->
<link type="text/css" rel="stylesheet" href="js/yui/build/menu/assets/menu.css" />
<script type="text/javascript" src="js/yui/build/yahoo/yahoo.js"></script>
<script type="text/javascript" src="js/yui/build/event/event.js"></script>
<script type="text/javascript" src="js/yui/build/dom/dom.js"></script>
<script type="text/javascript" src="js/yui/build/container/container_core.js"></script>
<!-- Componente -->
<script type="text/javascript" src="js/yui/build/menu/menu.js"></script>

Escolhi usar um modelo de menu clássico, para isso definimos a estrutura deles:

<div id="bd">
    <!-- Menu -->
   <div id="menu" class="yui-b">
      <div id="basicmenu" class="yuimenu">
         <div class="bd">
             <ul>
               <li class="yuimenuitem first-of-type">Documentos
                  <div id="doc_menu" class="yuimenu">
                     <div class="bd">
                        <ul>
                        <li class="yuimenuitem"><a href="#">Novo Documento</a></li>
                        <li class="yuimenuitem"><a href="#">Pesquisa</a></li>
                        </ul>
                     </div>
                   </div>
                </li>
               <li class="yuimenuitem">Processo</li>
               <li class="yuimenuitem">Sair</li>
            </ul>
          </div>
      </div>
   </div>
   <!-- Fim Menu -->
</div> 

Modifiquei alguns estilos padrões criando um outro arquivo css com as seguintes definições(aconselho a não alterar diretamente nos arquivos do framework, crie um outro arquivo de css e acrescente suas customizações porque no caso de um upgrade do framework você não as perde) :

div.yui-b p {
    margin:0 0 .5em 0;
    color:#999;
}
           
div.yui-b p strong {
    font-weight:bold;
    color:#000;
}
           
div.yui-b p em {
   color:#000;
}           
           
h1 {
   padding:.25em .5em;
   background-color:#ccc;
}

div.yuimenu {
    position:absolute;
   visibility:hidden;
   border:0px;
}

div.yuimenu li a {
   color: #3333FF;
}

#basicmenu {
    position:static;
    visibility:visible;
}
#bd{
   height:400px;
   /*background-color: #0059A5;*/
   width: 760px;
   margin-top: -13px;
}
          
#doc {
   width:760px;
}
          
.yui-b{
   width: 550px;
}
.yui-main{
   width: 550px;
}
.yui-g{
   width: 550px;
}

Instanciando o componente Menu

Acrescente os componentes:

<script type="text/javascript" src="js/yui/build/yahoo/yahoo.js"></script>
<script type="text/javascript" src="js/yui/build/event/event.js"></script>

Adicione um evento para carregar os menus ao carregar a página.

YAHOO.util.Event.addListener(window, "load", YAHOO.example.onWindowLoad);

A função YAHOO.example.onWindowLoad é um Listener para o evento "load" do objeto window.

Definiremos o objeto Menu na função YAHOO.example.onWindowLoad

/**
 * @id YAHOO.example.onWindowLoad
 * @classDescription Instancia Menus
 * @param {Object} p_oEvent
 */

YAHOO.example.onWindowLoad = function(p_oEvent) {
    function hideSubmenus() {
        if(oMenu.activeItem) {
            var oSubmenu = oMenu.activeItem.cfg.getProperty("submenu");
            if(oSubmenu) {
                oSubmenu.hide();
            }
        }
    }

    function cancelTimer() {
        if(nTimeoutId) {
            window.clearTimeout(nTimeoutId);
        }
    }
   
    function onSubmenuMouseOut(p_sType, p_aArguments, p_oMenu) {
        cancelTimer();
        nTimeoutId = window.setTimeout(hideSubmenus, 100);
    }

    var nTimeoutId;
    var oMenu = new YAHOO.widget.Menu("basicmenu", { position: "static" });
    oMenu.render();
    var doc = oMenu.getItem(0).cfg.getProperty("submenu");
    oMenu.mouseOverEvent.subscribe(cancelTimer);
    doc.mouseOverEvent.subscribe(cancelTimer);
    doc.mouseOutEvent.subscribe(onSubmenuMouseOut, doc, true);

    YAHOO.util.Event.addListener(document, "click", hideSubmenus);
}

Criei funções para controlar o aspecto de "tirar o mouse sobre um Menu" para ele se recolher porque por padrão isso não acontece e é chato.

Definindo a estrutura dinâmica

No próximo artigo mostrarei como fazer um cadastro com upload de arquivos, por enquanto ficamos com esse exemplo já chamando um formulário no menu documento -> Novo Documento.

Um artigo interessante saiu hoje no Ajaxian sobre os estágios de adoção do ajax. Identifiquei-me imediatamente com o artigo, menos no item 1, eu sempre fui favorável ao ajax e já usava DHTML de forma tímida antes da popularização.

Depois da popularização da tecnologia e consequente surgimento de frameworks que tornaram o desenvolvimento produtivo não vejo um site ou sistemas iniciando sem os benefícios que o ajax proporciona principalmente no quesito usabilidade.

Acompanhem o artigo http://ajaxian.com/archives/the-4-states-of-ajax-adoption

É desonroso para os homens sábios desperdiçarem seu tempo como escravos no trabalho de cálculo, que poderia ser relegado, com segurança, a qualquer um que usasse uma máquina.
(Leibnitz, 1646-1716)
Isso reflete meu humor hoje, com uma grade dessas nos ultimos semestres da faculdade:

  1. Métodos Numéricos;
  2. Matemática II;
  3. Matemática Discreta.

Se o gênio da matemática disse isso, com certeza vou mostrar pra professora de Calculo II para ela manerar, eita preguiça de resolver o “dever de casa” “valendo ponto” que ela passou.

Alguém aí poderia abrir o Leithold na página 294, exercício 5.1, itens 1 a 17 e resolver para mim por favor?

Essa mulher acha que eu não tenho o que fazer! O.o !

obs. Manda logo pro nêgo ganhar os pontos :p

« Previous PageNext Page »