Janeiro de 2019

Volume 34 – Número 1

[O programador]

Codificação nua

De Ted Neward | Janeiro de 2019

Ted NewardOs leitores que não leram a última coluna vão se surpreender ao ver que ainda não estou falando sobre a pilha MEAN (Mongo, Express, Angular, Nó). Isso ocorre porque eu encerrei a série na última vez, e agora é hora de voltar a atenção para algo um pouco diferente.

Na série MEAN, eu desconstruí sistematicamente a pilha inteira e examinei em detalhes todas as suas partes constituintes. Agora vou dar uma olhada em uma pilha (bem, tecnologia, singular, realmente) que foi projetada para combinar todas as suas partes em um todo único e contínuo a ser usado para ocultar grande parte do trabalho de detalhe de baixo nível necessário. Em outras palavras, às vezes, os desenvolvedores "só querem trabalhar com objetos," sem precisar se preocupar com a criação de uma interface do usuário, um banco de dados ou o middleware intermediário. Em muitos aspectos, essa é a expressão final do que Alan Kay tinha em mente quando inventou os objetos na época do Smalltalk (que era a linguagem original orientada a objeto de Kay) e é uma extensão natural e lógica do conceito do Design orientado a domínio (DDD) (ou, talvez mais precisamente, o contrário).

O Smalltalk, quando executado, sempre é executado dentro de um ambiente maior chamado navegador. Em essência, o navegador é um ambiente de execução de tempo de execução, um ambiente de desenvolvimento integrado e um host da interface do usuário encapsulados em uma só coisa. (Para fins de comparação, normalmente um navegador HTML é apenas um host da interface do usuário, embora vários fornecedores, incluindo a Microsoft, estejam tentando de tudo fazer o navegador HTML em um ambiente de execução e um ambiente de desenvolvimento integrado.) Quando um desenvolvedor define uma nova classe no Smalltalk, o navegador sabe como criar uma interface do usuário genérica em torno de um determinado objeto e (dependendo do Smalltalk de qual fornecedor) sabe como persistir nisso para um relational store ou seu próprio banco de dados do objeto. O desenvolvedor não precisa definir "exibições" ou "controladores", e os "modelos" não são classes anêmicas somente de dados que, essencialmente, só definem um esquema de banco de dados. Em muitos aspectos, isso é orientado a objeto, do jeito que foi projetado para ser: Os desenvolvedores interagem com os clientes, localizam os objetos, definem as propriedades nesses objetos (e as relações entre eles), definem comportamentos nesses objetos e enviam o projeto. Foi por isso que Kay disse uma vez "Eu inventei o termo ‘orientado a objeto’, e posso dizer que o C++ não era o que eu tinha em mente." Deixando de lado as piadas com linguagem C++, a desaprovação dele era com os milhares de objetos entre o usuário e o objeto de domínio real que está sendo manipulado. (Isso e toda a coisa de manipular a memória diretamente por meio de ponteiros, mas vamos manter o foco aqui.) E isso significa que suponho que ele se decepcionaria da mesma forma com C# e Java. (E Node.js, para a inicialização.)

Sem dúvida, os desenvolvedores têm procurado recriar esse Santo Graal da programação de objetos, e vou examinar uma dessas tentativas, chamada de Objetos Nus. (Não, eu estou falando sério, esse é o nome dele, que deriva da ideia de que os desenvolvedores devem se concentrar apenas no domínio de negócios, enquanto os usuários devem poder trabalhar com os objetos diretamente "sem decoração adicional", se você preferir. Ou, em outras palavras, os usuários devem trabalhar com objetos em seu estado natural "nu".)

Em essência, o que está acontecendo nessa abordagem é igualmente intrigante e intimidador: Com base nos metadados coletados de um objeto no tempo de execução (por meio de chamadas de reflexão, normalmente), você gera uma interface do usuário que sabe como exibir e editar as propriedades no objeto, validar as edições com base em metadados adicionais especificados no objeto (geralmente por meio de atributos personalizados) e, se necessário, rejeitar as alterações que não atendem à validação. A partir daí, você pode consultar e armazenar o objeto no banco de dados (normalmente por meio de um objeto/camada de mapeamento relacional), juntamente com todos os objetos adicionais que podem exigir atualizações, como objetos vinculados por propriedade ou alguma outra relação.

Obviamente, uma das coisas legais em usar a estrutura de objetos nus são as piadas e trocadilhos que podem ser feitos. Pronto para despi-la e se aprofundar?

Ficando nu

Abra um navegador, acesse nakedobjects.org e observe que o site é um site de redirecionamento simples que permite escolher aonde ir, dependendo da plataforma que mantém seu interesse: Há o tipo .NET (que será o meu foco) e o tipo Java, também chamado de Apache Isis. (Novamente, falando sério: o pessoal responsável pelo Isis está pensando em mudar o nome, mas para ser justo, eles escolheram o nome muito antes do pessoal do Oriente Médio.)

Quando redirecionado para o tipo .NET, você acaba na página de projeto do GitHub para o projeto Estrutura de Objetos Nus, que, no momento da redação deste artigo, está na versão 9. A página do projeto tem dois links importantes na home page do LEIAME: Um é o guia do desenvolvedor, obrigatório ao se trabalhar com a rede (e um ótimo exemplo de documentação bem feita), e o outro é um arquivo .ZIP que contém uma solução de modelo a ser usada como um ponto de partida. Embora os assemblies da Estrutura de Objetos Nus (abreviado como EON) estejam disponíveis por meio do NuGet, normalmente é mais fácil usar o modelo .ZIP para iniciar seu novo projeto EON, por motivos que se tornarão mais aparentes depois. Por enquanto, pegue o modelo .ZIP, exploda-o em um subdiretório de código e abra o arquivo de solução em sua instância de favoritos do Visual Studio.

Quando o Visual Studio terminar de carregar, você observará que a solução é composta de vários projetos diferentes, de cinco para ser exato. Quase sempre os nomes deles são autoexplicativos: Template.Client será um cliente da Web, Template.Server é o servidor da Web e Template.DataBase e Template.SeedData representam as camadas para conversar com o banco de dados. (Essencialmente os dois últimos são projetos bem simples da Entity Framework. Portanto, se você já souber de EF, também já terá dominado a parte de persistência da EON.)

O último projeto na solução, Template.Model, é onde a maior parte do trabalho de desenvolvedor, se não ele inteiro, ocorrerá. Essa é a coleção de classes que representam o modelo de domínio do projeto. Portanto, a maior parte do trabalho que um desenvolvedor terá de fazer deve ser — e geralmente será — feita aqui. Ainda bem que o modelo de EON já tem um pouco de código de exemplo — o tipo Aluno, que representa uma dessas criaturas que adora estudar. Então vamos iniciá-lo e vê-lo funcionar. Certifique-se de que Template.Server esteja definido como o projeto de inicialização (que já deve estar). Pressione F5 e relaxe.

Execução nua

Primeiro o Visual Studio iniciará o componente de servidor e, devido à configuração padrão da EF, levará alguns minutos para fazer o banco de dados iniciar do nada. Alguns segundos após a inicialização, alguns JSON aparecerão na janela do navegador. Isso ocorre porque o Template.Server é, na verdade, um servidor RESTful, o que significa que ele não só opera sobre HTTP, ele retorna JSON que descreve toda a coleção de opções que um usuário pode aproveitar se quiser. Observe que o JSON consiste no que basicamente parece hiperlinks: "rel" para "relação", "href" para a URL a ser usada, "tipo" para descrever o que se espera e assim por diante. É assim para que os desenvolvedores que não querem usar a interface do usuário genérica (que examinarei em seguida) possam criar a própria interface do usuário que sabe como trabalhar com base no JSON que está sendo retornado.

Vamos examinar a interface do usuário que a EON cria para você. Em uma nova guia do navegador, navegue para http://localhost:5001. O resultado retornado é... forte. Claramente ele não foi criado para ser visualmente agradável e, para quem não conhece, pode parecer que não há nenhum ponto de partida real. No entanto, lembre-se de que a REST (na concepção original de Fielding) e o Smalltalk tinham objetivos parecidos: uma interface de usuário universal para que, independentemente do domínio, o usuário soubesse operá-la. A EON basicamente está criando a interface do usuário coletivamente com base em alguns métodos estáticos de classes, os quais serão exibidos no menu de nível superior pela home page. Clique nele para revelar três opções: "Todos os alunos", "Criar novo aluno" e "Localizar aluno por nome". Fica claro que são métodos CRUD simples (bem, C e R, mesmo assim). Então, vamos ver quem já está no sistema. Clique em Todos os Alunos, e três alunos (que são transmitidos do projeto Template.SeedData para a EF na inicialização) serão exibidos, junto com um ícone curioso no canto superior direito da lista retornada. Clicar nesse ícone exibirá os resultados como uma tabela em vez de apenas uma lista, mas como Alunos têm apenas uma propriedade FullName e nada mais, isso ainda não parece ser tão interessante.

Selecionar um aluno da lista ocupará toda a página. Vamos supor que "James Java" mudou de ideia e quer fazer uma alteração de nome legal. Então, selecione-o na lista e, quando ele aparecer, selecione Editar. Observe que a interface do usuário será alterada para tornar o nome dele editável, então vamos alterá-lo para "James Clr". Clique em Salvar, e você volta para uma interface do usuário de somente leitura. Vamos voltar e ver a lista de alunos novamente. Selecione o ícone de Página Inicial (a casinha no canto inferior esquerdo) para voltar ao menu inicial novamente. Você poderia procurar por James selecionando Menu | Todos os Alunos novamente, mas o ícone de área de transferência mostra uma lista de todos os objetos que você usou recentemente. Selecione-o e, claro, "James Clr" aparece. (O "Aluno" lá é o tipo de objeto referente a James. Isso não é importante em uma demonstração que tem apenas um tipo de objeto, mas, à medida que o sistema cresce, também aumentam as chances de que os objetos denominados James possam ser tanto um aluno quanto um RegistrationHistory, por exemplo.)

Estudantes e cursos

O modelo Aluno parece bastante anêmico — os alunos são mais do que apenas um nome! Eles também são uma matéria, portanto, vamos adicionar isso ao modelo. Interrompa o Visual Studio e abra o arquivo Student.cs no projeto Template.Model. O aluno atualmente se parece com o código mostrado na Figura 1.

Figura 1 O tipo de aluno básico

using NakedObjects;
namespace Template.Model
{
  public class Student
  {
    // All persisted properties on a domain object must be 'virtual'
    NakedObjectsIgnore] // Indicates that this property
                        // will never be seen in the UI
    public virtual int Id { get; set; }
    [Title]// This property will be used for the object's title at
           // the top of the view and in a link
    public virtual string FullName { get; set; }
  }
}

Adicione uma nova propriedade ao Aluno, digamos "Matéria", também uma cadeia de caracteres, também pública e virtual e, em seguida, pressione F5 novamente. Graças às configurações padrão de desenvolvimento na EF, o James Java perderá a alteração de seu nome, mas observe o que se ganha: Em toda a interface do usuário e o banco de dados, agora você tem alunos com matérias. Todas elas estão vazias no momento, mas muitos alunos universitários não têm ideia do que eles estão estudando. A questão maior é que, com essa propriedade única, você já obteve suporte completo para a interface do usuário, bem como suporte para o banco de dados, sem precisar escrever nenhum código para criar a interface do usuário, validar a entrada ou persistir os dados.

Conclusão

Obviamente, há muita coisa aqui que estou ignorando, e não faria sentido não explorar um pouco mais. Então, vou escrever alguns artigos examinando a EON e determinando suas limitações. O ponto importante é que, especialmente para aplicativos que não são de consumo, nem tudo deve ser um banco de dados e uma interface do usuário artesanal. Às vezes, a velocidade com que um aplicativo pode ser gerado é muito mais importante do que sua beleza. A EON e outros tipos de ferramentas inspirados em DDD podem ser exatamente o que o doutor pediu nesses tipos de situações, e você ainda tem algum espaço para tornar as coisas "mais bonitas" pela criação de um front-end angular mais personalizado (ou outra estrutura de SPA). Na próxima vez, vou explorar algumas das opções e recursos de classes de domínio na EON, e veremos o quão bem a EON consegue lidar com preocupações comuns da interface do usuário. Enquanto isso, boa codificação!


Ted Neward é um consultor de politecnologia, palestrante e mentor de Seattle. Ele já escreveu uma enormidade de artigos, é autor e coautor de dezenas de livros e faz palestras no mundo inteiro. Entre em contato com ele em ted@tedneward.com ou leia seu blog em blogs.tedneward.com.