wiki:versoes/24/HowTo/Templating/BoasPraticas

Version 5 (modified by alexandrecorreia, 12 years ago) (diff)

--

Boas práticas no desenvolvimento de interfaces

Apresentação

Este documento apresenta uma compilação das boas práticas de desenvolvimento de interfaces no ExpressoMail, adotadas pela Prognus, definidas através de consultas à modelos e práticas consolidadas no mercado e da experiência dos nossos desenvolvedores.

Príncípios

Obediência aos padrões

  • <Marcação semântica>
  • <jQuery ao invés de DOM>
  • <JSON>

  • <utilização moderada de id>
  • <templates em EJS>
  • <marcação adequada com classes significativas e pouco específicas nos elementos HTML>
  • <seletores mais específicos (compostos) no jQuery e no CSS>

Separação de código e baixo acoplamento

Separação de código (coesão)

Uma boa forma de manter o desenvolvimento de interfaces simples e de fácil manutenção é cultivando a separação de código. Isso inclui principalmente:

  • não utilizar estilos CSS inline
  • não utilizar código javascript inline
  • não construir HTML através de código javascript
  • minimizar a aplicação de CSS através de código javascript

JAVASCRIPT:
A utilização de jQuery nos permite fazer uma manipulação adequada do comportamento dos elementos na interface. O tratamento de eventos (click, mousemove, keydown, keyup, etc.) é extremamante facilitado e nos possibilita evitar de fazê-lo inline no HTML, por exemplo.

<sem javascript de comportamento no template (o js do template é só de conteúdo)...>

HTML:

CSS:

Desacoplamento

A forma mais comum de experimentar o desacoplamento no desenvolvimento de interfaces é a construção de templates mínimos e sua principal vantagem é o reaproveitamento de código através de templates reusáveis.

Um bom exemplo para se aplicar tal reúso é visto na Figura 1, onde é mostrada a duas listas de marcadores no módulo ExpressoMail, uma na tela principal e outra na tela de configuração dos marcadores. Apesar de tratar-se da mesma lista, o desenvolvedor poderia se sentir tentado a criar um template para cada uma delas, já que a diferênça entre elas é claramente visível.

No image "configuracaoMarcadores.png" attached to versions/24/HowTo/Templating/BoasPraticas
Figura 1: Exemplo de reúso de template 1

Porém uma análise mais criteriosa revelaria que ambas as listas são idênticas em conteúdo e diferem apenas em aparência (cores e visibilidade dos elementos) e comportamento (clicks e demais eventos gerados pela interação do usuário). Assim, o trecho de código abaixo define um template que atenderia, sem nenhum problema, ao conteúdo necessário a qualquer uma das listas:

        <ul class="label-list">
                <%for (var i=0; i<data.labels.length; i++){ %>
                        <li class="label-item label-item-<%= (data.labels[i].id) ? data.labels[i].id : ''%>" style="
                                background: <%= (data.labels[i].backgroundColor) ? data.labels[i].backgroundColor : '#ebebeb' %>;
                                color: <%= (data.labels[i].fontColor) ? data.labels[i].fontColor : '#000000' %>;
                                border-color: <%= (data.labels[i].borderColor) ? data.labels[i].borderColor : '#000000' %>;">
                           
                                <span class="text-list"><%= (data.labels[i].name) ? data.labels[i].name : '' %></span>
                                <input type="hidden" value="<%= data.labels[i].id%>" name="labelItemId" class="id-item-list" />
                                
                                <div class="square-color ui-corner-all" 
                                     style="background: <%= (data.labels[i].backgroundColor) ? data.labels[i].backgroundColor : '#ffffff' %>;">
                                </div>

                                <div class="button close tiny" style="float: right"></div>
                                <div class="button edit tiny" style="float: right"></div>
                        </li>
                <%}%>
        </ul>

Para ficar mais interessante, vamos olhar para mais uma lista de marcadores. A Figura 2 mostra a lista de marcadores aplicados a uma mensagem. Apesar de o conteúdo das listas diferirem um pouco (na quantidade de marcadores) a estrutura da lista é a mesma e, devido a forma como foi construído o template das duas listas anteriores, não haveria problema nenhum em utilizá-lo aqui também. Tudo que teríamos que fazer é a definição adequada do CSS para cada contexto.

No image "mensagemMarcadores.png" attached to versions/24/HowTo/Templating/BoasPraticas
Exemplo de reúso de template 2

/* definições gerais para todas as três listas de marcadores */

.label-configure-win .label-list-container .label-list,
.expressomail-label-container .label-list-container .label-list,
.message-container .label-list-container .label-list
{ overflow: auto; height: 293px; margin:0px; }
...
...

/* definições específicas para a listas de marcadores presente na visualização da mensagem */

.message-container .label-list-container .label-list li
{ display: inline }
...
...

OBSERVAÇÃO 1:
Na lista de marcadores da tela principal do módulo ExpressoMail, diferentemente das outras duas, a cor do marcador é exibida somente dentro do botão de edição do marcador. A uma primeira vista, o tratamento destas diferenças pode parecer inserção de complexidade desnecessária, porém vejamos como é simples e coerente mantermos desta forma.

Tudo que precisamos fazer para adequar isto é utilizar javascript para dispor estas cores de acordo com o local para o qual o template foi chamado. O que soa bastante natural já que o javascript que deve tratar do comportamentamento da tela e saber onde foi requisitado o template e quais as expectativas do usuário quanto a visualização e interação com ele. Assim, o trecho de código abaixo é suficiente para efetuar este ajuste:

/* carrega o template da lista de marcadores e aplica na janela de configuração de marcadores */
var container = $('.label-configure-win .label-list-container').html(DataLayer.render('<template_path>', data));

/* oculta o botão de edição do marcador, o qual não é utilizado nesta tela */
container.find('.square-color').hide();

OBSERVAÇÃO 2:
Aliado a uma marcação HTML e uma estrutura de classes semanticamente coerente, podemos elevar consideravelmente o reúso de código dos templates.

Nos códigos acima, pôde-se observar que a flexibilidade alcançada pelo template não seria possível sem a separação adequada de XHTML, CSS e Javascript experiemntada. Por exemplo:

  1. a utilização de nomes de classes que remetam ao conteúdo e não à apresentação
  2. a ausência de código javascript e css inline (dentro das tags)

Como exemplo, imagine que o elemento HTML que representa a lista contivesse a seguinte classe:

<ul class="left-side-labels">
...

Neste caso o reaproveitamento do template em qualquer lugar que não estivesse necessáriamente no lado esquerdo (left-side-) pareceria incoerente.

Vejamos outros casos em que a má separação de código poderia influenciar:

/* impede ou dificulta a utilização onde os itens da lista não sejam inline, ou mesmo onde a lista possua tamanho diferente */
<ul style="overflow: auto; height: 293px; margin:0px;">
	<li style="display: inline;">
	...
...
/* impede ou dificulta a utilização em outros locais onde a ação de click seja diferente ou dispensável */
<ul>
	<li onlcick="javascript:abre_configuracao_label(this.id)">
	...
...

Modularidade, componentização e reúso

  • Modularidade: <...>
  • Componentização: <plugins, widgets, ...>
  • Reúso: <...>
  • Classes genéricas: <...>

Padronização

Padronização de nomencatura

  • <ids com todas minúsculas e underline>
  • <classes com todas minúsculas e ífem>

Attachments