DEV Community

Cover image for Sobre os critérios a serem usados na decomposição de Interfaces em Componentes e Módulos
Gurigraphics
Gurigraphics

Posted on

Sobre os critérios a serem usados na decomposição de Interfaces em Componentes e Módulos

--> Versão em Inglês


Resumo

Esse artigo contém os FUNDAMENTOS para desenvolver interfaces menos confusas. Nada aqui é uma "verdade absoluta". Mas considero leitura obrigatória para quem quiser começar a pensar sobre User Interfaces.


Start

Em uma interface 2D, tudo o que você vê existe dentro de uma hierarquia.
Cada nível contém o próximo, como caixas aninhadas.


Nível 0: Window — O Observador

O que é: A janela de visualização do navegador. O espaço de visualização do seu monitor.

Distinção crítica: Window não faz parte da estrutura da interface. Window é o meio pelo qual você observa a interface.

Analogia: Livro vs. Olho
- Livro completo = Pages (pode ter 100 páginas de conteúdo)
- Seu campo de visão = Window (vê 2 páginas por vez)
- Virar a página = scroll
Enter fullscreen mode Exit fullscreen mode

A relação:

  • Page com 3000px de altura
  • Window com 800px de altura
  • Você vê ~27% da Page de uma só vez
  • Scroll revela a parte invisível

Lembre-se: Window ≠ Page


Nível 1: Page — O Universo

O que é: A maior unidade indivisível. O espaço total de conteúdo.

Propriedade principal: Uma Page é indivisível como entidade. Você não "divide uma Página em duas Páginas". Você organiza uma Page usando Regions (Regiões).

<div class="page-home">
<!-- Tudo aqui é A Página -->
<!-- Não "duas páginas", mas UMA página com divisões -->
</div>
Enter fullscreen mode Exit fullscreen mode

Distinções importantes:

Estrutural (delimitado por HTML):

<div class="page-home">
<!-- Estrutura explícita na marcação -->
</div>
Enter fullscreen mode Exit fullscreen mode

Conceitual (delimitado por CSS):

.page-home {
display: grid;
grid-template-columns: 1fr 1fr; /* a divisão esquerda/direita existe apenas em CSS */
}
Enter fullscreen mode Exit fullscreen mode

Ambas são válidas. Uma é explícita (estrutural), a outra é implícita (conceitual).

Camadas de índice Z:

Page (z-index: 0) ← Camada base, 
Page (z-index: 1) ← Sobreposição (modal, foreground)
Page (z-index: -1) ← Camada de fundo, background
Enter fullscreen mode Exit fullscreen mode

Uma Page pode possuir vários Layers, camadas.
Pense nelas como folhas transparentes empilhadas umas sobre as outras.
Page é a combinação desses layers quando existir mais de um.


Nível 2: Region — Divisões Espaciais

O que é: Uma Page contém Regions. As Regions organizam o espaço, não substituem a Page.

O princípio da divisibilidade:

Pensamento errado:
"Uma Page se divide em esquerda e direita, criando duas novas Pages"

Pensamento correto:
"Uma Page contém a Region Left e a Region right"

Exemplo:

<div class="page-home">
  <div class="region-top"></div> <!-- Região 1 -->
  <div class="region-bottom"></div> <!-- Região 2 -->
</div>
Enter fullscreen mode Exit fullscreen mode

Estrutural vs. Conceitual:

Estrutural:

<div class="region-left">
<!-- Elemento HTML explícito -->
</div>
Enter fullscreen mode Exit fullscreen mode

Conceitual:

.page-home {
  display: flex;
/* A "região" da esquerda são os primeiros 300px, a "região" da direita é o espaço restante */
/* Não há elementos HTML explícitos, mas as regiões existem conceitualmente */
}
Enter fullscreen mode Exit fullscreen mode

Espaço entre Regiões:

<div class="page">
  <div class="region-top"></div>
  <div class="region-bottom" style="margin-top: 30px"></div>
<!-- O espaço de 30px é PARTE DA PÁGINA, não uma terceira região -->
</div>
Enter fullscreen mode Exit fullscreen mode

O espaço disponível não é uma região. Ele pode ser ocupado por uma região


Nível 3: Section — Divisões Funcionais

O que é: Uma Region contém Sections. As sections são organizadas por propósito/função.

Diferença:

  • Region = organização espacial ("onde na tela": superior, esquerda, direita, inferior)
  • Section = organização funcional ("o que faz": cabeçalho, navegação, conteúdo)

Exemplo:

<div class="page-home">
  <div class="region-top">
   <div class="section-header">Conteúdo do cabeçalho</div>
  </div>

  <div class="region-bottom">
    <div class="section-left">Navegação da barra lateral</div>
    <div class="section-right">Conteúdo principal</div>
  </div>
</div>
Enter fullscreen mode Exit fullscreen mode

Estrutural vs. Conceitual:

Estrutural:

<div class="section-navigation">
<!-- Elemento explícito -->
</div>
Enter fullscreen mode Exit fullscreen mode

Conceitual:

.region-sidebar {
display: flex;
flex-direction: column;
/* Os 100px superiores são conceitualmente "seção de navegação" */
/* O espaço restante é conceitualmente "seção de conteúdo" */
/* Sem HTML explícito, mas as seções existem conceitualmente */
}
Enter fullscreen mode Exit fullscreen mode

Nível 4: Component — A Parte Complexa

O que é: Uma Section exibe Components. Components são unidades operacionais que podem ter estado e comportamento.

<div class="section-header">
  <app-header>Componente de Cabeçalho</app-header>
</div>
Enter fullscreen mode Exit fullscreen mode

Tipos de Components

É aqui que fica interessante. Existem várias maneiras de classificar Componentes:

Classificação 1: Por Divisão Espacial

Componente Simples:

<div class="card">
<img /> <!-- Element -->
<h3></h3> <!-- Element -->
<p></p> <!-- Element -->
</div>
Enter fullscreen mode Exit fullscreen mode

Sem divisões espaciais. Apenas um conjunto de Elements.

Component Formal (Micro Pages / Fractal Pages):

<div class="card-complex">
<div class="region-header"> <!-- Possui Regiões -->
<div class="section-title"> <!-- Possui Seções -->
<h3></h3> <!-- Possui Elementos -->
</div>
</div>
<div class="region-content">
<!-- ... -->
</div>
</div>
Enter fullscreen mode Exit fullscreen mode

Contém a estrutura completa: Regions → Sections → Elements (em vez de Componentes).

Essa classificação é contextual e dinâmica, não fixa.

Classificação 2: Por Composição

Composite Component (componente composto):

<div class="user-profile">
<app-avatar /> <!-- Subcomponente -->
<app-user-info /> <!-- Subcomponente -->
<app-actions /> <!-- Subcomponente -->
</div>
Enter fullscreen mode Exit fullscreen mode

Composto por outros Componentes (Subcomponents).

Subcomponent: Qualquer Component exibido dentro de outro Component.

Classificação 3: Por Utilização

Composite Component (componente composto):

<div class="sidebar">
  <app-button name="home" /> <!-- Subcomponente -->
</div>
<div class="menu">
  <app-button name="options" /> <!-- Subcomponente -->
</div>
<app-button name="start" /> <!-- Element -->
Enter fullscreen mode Exit fullscreen mode

Quando um elemento é utilizado em diversos components ele pode ser considerado um Element
E pertencer a uma lib de elements, não de components

Classificação 4: Por Complexidade

Complex Component:

<div class="data-table">
<app-table-header /> <!-- Subcomponente -->
<app-table-body /> <!-- Subcomponente -->
<app-pagination /> <!-- Subcomponente -->
<!-- Cada subcomponente também é um componente complexo -->
</div>
Enter fullscreen mode Exit fullscreen mode

Formado por vários subcomponentes que trabalham juntos.

Nível 5: Element — O Átomo

O que é: A menor unidade funcional.

Exemplos:

  • <button> — um botão
  • <input> — um campo de entrada
  • <a> — um link
  • <img> — uma imagem

Importante: Os elementos também podem ser Simples ou Formais.

Elemento Simples

<button>Clique aqui</button>
Enter fullscreen mode Exit fullscreen mode

Apenas texto. Sem estrutura interna.

Elemento Formal

<button class="complex-button">
<div class="section-left">
<svg class="icon"></svg> <!-- Subelement: icon -->
</div>
<div class="section-center">
<span class="text">Click</span> <!-- Subelement: text -->
</div>
<div class="section-right">
<svg class="dropdown"></svg> <!-- Subelement: dropdown icon -->
</div>
</button>
Enter fullscreen mode Exit fullscreen mode

Possui Regions e Sections estruturais ou conceituais.

A mudança de classificação:

Quando um item deixa de ser um Element e se torna um Subelement ou Component?

O contexto determina:

<button>Clique aqui</button> <!-- Element -->
Enter fullscreen mode Exit fullscreen mode
<button class="icon-button"> <!-- Element -->
<span>Texto</span> <!-- Subelement -->
</button>
Enter fullscreen mode Exit fullscreen mode

Este é um Element (unidade de interação atômica).

Quando exibe um menu:

<button class="dropdown-button" @click="showMenu">
<svg></svg>
<span>Texto</span>
<svg class="arrow"></svg>
</button>
<div class="dropdown-menu" v-if="menuVisible">
<!-- Itens de menu -->
</div>
Enter fullscreen mode Exit fullscreen mode

Agora é um Component (tem estado, comportamento e gerencia subelements).

Quando usado dentro de outro component:

<div class="toolbar"> <!-- Component -->
<icon-button /> <!-- Agora é um Subcomponente -->
<icon-button />
<icon-button />
</div>
Enter fullscreen mode Exit fullscreen mode

Agora é um Subcomponent (Component dentro de Component).


A Natureza Dinâmica da Classificação

Exemplo: Evolução do Botão Ícone

Estágio 1 - Simple Element:

<button>
<svg></svg>
</button>
Enter fullscreen mode Exit fullscreen mode

Classificação: Element
Motivo: Unidade atômica, sem divisões internas

Estágio 2 - Formal Element:

<button>
<div class="section-left"><svg></svg></div>
<div class="section-center"><span>Texto</span></div>
<div class="section-right"><svg></svg></div>
</button>
Enter fullscreen mode Exit fullscreen mode

Classificação: Element (ainda) ou Component (depende do contexto)
Motivo: Possui estrutura interna, mas ainda é uma unidade funcional

Estágio 3 - Simple Component:

<icon-button icon="search" text="Search" />
Enter fullscreen mode Exit fullscreen mode

Classificação: Component
Motivo: pode ser decomposto em mais de uma funcionalidade

Etapa 4 - Subcomponent:

<div class="search-bar">
<icon-button icon="search" /> <!-- Este -->
<input />
<icon-button icon="clear" />
</div>
Enter fullscreen mode Exit fullscreen mode

Classificação: Subcomponente
Motivo: Component usado dentro de outro component

Etapa 5 - Complex Component:

<icon-button-with-dropdown
icon="more"
@click="toggleMenu"
>
<dropdown-menu v-if="open">
<menu-item />
<menu-item />
</dropdown-menu>
</icon-button-with-dropdown>
Enter fullscreen mode Exit fullscreen mode

Classificação: Complex Component
Motivo: Gerencia estado, possui subcomponentes, comportamento complexo


Controle de Visibilidade

Todas categorias podem ser hide and show:

// Ocultar Região
page.regions.top.hide()

// Ocultar Seção
page.regions.main.sections.sidebar.hide()

// Ocultar Componente
page.regions.main.sections.content.components.userCard.hide()

// Ocultar Elemento
page.regions.header.sections.nav.components.menu.elements.loginButton.hide()
Enter fullscreen mode Exit fullscreen mode

Exemplo:

<div class="page">
  <div class="region-top" v-if="showHeader"> <!-- Pode ocultar Região inteira -->
    <div class="section-nav" v-if="showNav"> <!-- Pode ocultar Seção -->
      <app-menu v-if="isLoggedIn"> <!-- Pode ocultar Componente -->
        <button v-if="canEdit">Editar</button> <!-- Pode ocultar o Elemento -->
      </app-menu>
    </div>
  </div>
</div>
Enter fullscreen mode Exit fullscreen mode

Hierarquia Completa com Exemplos

Window (janela de visualização do navegador: 1920×1080)
↓ observa
Page (conteúdo total: 1920×3000)
↓ contém
Region (superior: 1920×100, principal: 1920×2800, rodapé: 1920×100)
↓ contém
Section (na região principal: barra lateral esquerda: 300×2800, conteúdo: 1620×2800)
↓ contém
Component (na barra lateral: componente do menu de navegação)
↓ contém
Sub-components (menu dropdown)
↓ contém 
Elements (botões, inputs)
↓ contém 
Sub-Elements (svg, text)
Enter fullscreen mode Exit fullscreen mode

Modulos e Sub-modules — Agrupamento Funcional

O que é: Um eixo de classificação diferente. Enquanto a classificação espacial hierárquica se refere à contenção espacial (o que está dentro do quê), os Módulos se referem à coesão funcional (o que funciona em conjunto).

Insight principal: Os components podem ser separados espacialmente, mas unidos funcionalmente.

A Natureza Transversal

A classificação espacial hierárquica diz: "Este Component está dentro desta Section"
Module diz: "Estes Components, onde quer que estejam, pertencem a mesma Feature (recurso)"

Exemplo: Module Editor de Código

<div class="page">
<div class="region-left">
<div class="section-sidebar">
<file-tree /> <!-- Parte do Module Editor -->
<search-panel /> <!-- Parte do Module Editor -->
</div>
</div>

<div class="region-right">
<div class="section-main">
<code-editor /> <!-- Parte do Module Editor -->
<status-bar /> <!-- Parte do Module Editor -->
</div>
</div>

<div class="region-bottom">
<div class="section-terminal">
<terminal-panel /> <!-- Parte do Module Editor -->
</div>
</div>
</div>
Enter fullscreen mode Exit fullscreen mode

Todos esses Components são espacialmente separados (diferentes Regions/Sections), mas funcionalmente unidos (Módulo Editor).

Definição de Module

Um Module é:

  • Uma coleção de Components que trabalham juntos
  • Pode abranger várias Regions/Sections
  • Compartilha estado, dados ou comportamento
  • Implementa um recurso/funcionalidade completo

Sub-modules

O que é: Modules podem conter Sub-modules para maior granularidade funcional.

Exemplo: Module Editor com Sub-modules

Editor Module
├─ File Management Sub-module
│  ├─ file-tree (in left sidebar)
│  ├─ file-tabs (in top bar)
│  └─ file-actions (in context menu)
│
├─ Code Editing Sub-module
│  ├─ code-editor (in main area)
│  ├─ syntax-highlighter (inside editor)
│  └─ autocomplete (overlay)
│
└─ Debugging Sub-module
   ├─ breakpoint-gutter (in editor margin)
   ├─ debug-toolbar (in top bar)
   └─ variables-panel (in right sidebar)
Enter fullscreen mode Exit fullscreen mode

Todos os components no "Sub-module de Gerenciamento de Arquivos" compartilham o estado:

  • Abrir um arquivo em file-tree atualiza file-tabs
  • Fechar uma aba em file-tabs atualiza a seleção de file-tree
  • file-actions opera no estado de ambos

Distinção de Outras Classificações

Component vs. Module:

Component Module
Um único item de UI Vários items de UI
Um lugar na hierarquia Pode abranger vários lugares
Contido em Section Atravessa Sections
Exemplo: <button> Exemplo: Recurso "Autenticação"

Exemplo: Module de Autenticação

<!-- Spatially: different locations -->

<!-- In top-right Region -->
<user-avatar />          <!-- Auth Module Component -->

<!-- In dropdown overlay -->
<login-form />           <!-- Auth Module Component -->

<!-- In settings Section -->
<account-settings />     <!-- Auth Module Component -->

<!-- In modal -->
<change-password />      <!-- Auth Module Component -->
Enter fullscreen mode Exit fullscreen mode

Todos esses components pertencem ao Module de Autenticação, apesar de estarem em partes completamente diferentes da interface.

Comunicação de Modules

Modules podem:

  • Compartilhar estado global
  • Comunicar-se por meio de eventos
  • Acessar serviços compartilhados
  • Coordenar comportamentos

Exemplo:

// Editor Module components communicate
fileTree.onSelect(file => {
  codeEditor.open(file)        // Different Component, same Module
  statusBar.update(file.path)  // Different Component, same Module
  terminal.setContext(file.dir) // Different Component, same Module
})
Enter fullscreen mode Exit fullscreen mode

Hierarquia de Module vs. Component

São conceitos ortogonais:

Hierarquia Espacial:
Page → Region → Section → Component

Agrupamento Funcional:
Modulo → Sub-module → Component
Enter fullscreen mode Exit fullscreen mode

Um Component existe em AMBOS:

<file-tree />

Spatial location:
Page → region-left → section-sidebar → file-tree

Functional membership:
Editor Module → File Management Sub-module → file-tree
Enter fullscreen mode Exit fullscreen mode

Guia Prático de Decisões

Ao construir uma interface, pergunte-se:

É um Componente ou Elemento?

É um Element se:

  • Ponto de interação único
  • Não pode ser dividido significativamente
  • Sem gerenciamento de estado interno
  • Pode ser utilizado por outros componentes
  • Exemplo: <button>, <input>, <a>

É um Component se:

  • Possui estrutura interna
  • Gerencia estado ou comportamento
  • Exemplo: <search-bar>, <user-card>, <data-table>

É uma Region ou Section?

É uma Região se:

  • Divisão principalmente espacial
  • Responde "onde?" (superior, esquerda, direita, inferior)
  • Focado no layout

É uma Section se:

  • Divisão principalmente funcional
  • Responde "o quê?" (navegação, conteúdo, cabeçalho)
  • Focado no propósito

É estrutural ou conceitual?

Estrutural:

<div class="region-sidebar">
<!-- Explícito em HTML -->
</div>
Enter fullscreen mode Exit fullscreen mode

Conceitual:

.page {
display: grid;
grid-template-columns: 300px 1fr;
/* A área esquerda é conceitualmente "region-sidebar" */
/* Nenhum elemento HTML explícito necessário */
}
Enter fullscreen mode Exit fullscreen mode

Princípios-chave

  1. Window define o espaço, não o conteúdo
    Window ≠ Page. A window exibe a Page.

  2. Indivisibilidade significa integridade da entidade
    Uma Page não se divide em duas páginas. Uma Page contém Regions.

  3. A classificação é contextual
    Um mesmo item pode ser Element, Sub-element, Component ou Sub-component, dependendo do uso.

  4. A estrutura pode ser explícita ou implícita
    A estrutura HTML ou o layout CSS criam divisões válidas.

  5. Existe fractalidade
    Os components podem conter uma estrutura completa semelhante à de uma Page (Regions → Sections → Elements).

  6. A visibilidade é hierárquica
    Ocultar uma região → todas as suas seções/componentes/elementos também são ocultados.


Erros Comuns

"Minha página tem duas páginas: esquerda e direita"
✅ "Minha página tem duas regiões: esquerda e direita"

"Janela é o contêiner da página"
✅ "Janela é a janela de visualização que observa a página"

"Este botão é sempre um elemento"
✅ "Este botão é um elemento neste contexto, componente em outro"

"Todas as divisões devem estar em HTML"
✅ "As divisões podem ser estruturais (HTML) ou conceituais (CSS)"

"Componentes não podem conter regiões"
✅ "Componentes formais são micropáginas com estrutura completa"


Lista de Verificação Final

Criando uma interface? Verifique:

  • [ ] Window: Quais tamanhos de janela de visualização eu suporto?
  • [ ] Page: O conteúdo cabe? Precisa de rolagem? Várias camadas de índice z?
  • [ ] Region:** Como divido o espaço? (Estrutural ou conceitual?)
  • [ ] Section: Quais áreas funcionais existem em cada região?
  • [ ] Component: O que é reutilizável? Simples ou formal? Composto?
  • [ ] Element: Quais são os pontos de interação atômicos?
  • [ ] Classificação: Minha nomenclatura está contextualmente correta?

Fim. Agora você entende a estrutura completa de uma interface 2D, da janela de visualização ao átomo.

Referências:

PARNAS, David L. On the Criteria To Be Used in Decomposing Systems into Modules. Communications of the ACM, Vol. 15, No. 12, pp. 1053 – 1058, 1972.

DESCARTES, René. Discurso do método. 2. ed. São Paulo: Martins Fontes, 2001. 102 p.
(“Dividir cada uma das dificuldades que eu examinasse em tantas parcelas quantas possíveis e quantas necessárias fossem para melhor resolvê-las”)

Top comments (0)