
A segunda parte da linguagem lsFusion e da trilogia de plataformas. A primeira parte pode ser encontrada
aqui .
Ele se concentrará na lógica das representações, ou seja, em tudo relacionado à combinação de dados e exibição ao usuário ou a outros sistemas de informação.
É claro que muitos podem não estar tão interessados em olhar para a apresentação do lutador, e gostariam de ver uma luta real, se possível com sangue (e será, já que a discussão dos artigos anteriores ajudou a entender melhor os lugares desprotegidos dos concorrentes em potencial e onde vencê-los) . Mas há duas coisas a considerar:
a) este é Habr. Ou seja, um recurso técnico, eles não gostam de belas fotos e slogans publicitários aqui - para dizer algo, você precisa de detalhes sobre como conseguir isso.
b) é um mercado para o desenvolvimento de sistemas de informação e é muito semelhante ao mercado de produtos para perda de peso. Aqui, todo mundo diz que temos um rápido e fácil. Mas quando se trata de detalhes, nos quais, como você sabe, o diabo está, os CRUDs mais simples são usados como exemplos ou recorrem a vários truques: eles mostram alguns trechos de código e ocultam a parte principal com as palavras "isso não importa" "," Feito em alguns minutos "e tudo mais.
Na verdade, é por isso que tínhamos duas opções: começar com os benefícios e o risco de ser criticado por besteiras de marketing ou começar com uma descrição técnica e as perguntas "por que precisamos de mais um idioma". Teoricamente, é claro, tudo isso poderia ser feito em um artigo, mas esse artigo seria difícil não apenas de ler, mas também de rolar. Dessa forma, escolhemos a segunda opção, embora seja importante que alguém aprenda sobre os motivos da aparência e vantagens do idioma no momento (e não em artigos futuros), seja bem-vindo ao
site . Consiste em apenas três páginas: o que, como e por que não, e fornece, na minha opinião, informações suficientes para responder a todas essas perguntas. Além disso, você também pode experimentar a plataforma
on-line , inclusive para garantir que não haja "piano nos arbustos", e o código dos exemplos neste artigo é realmente todo o código necessário para executar o aplicativo.
Mas basta digressões líricas, voltamos à
apresentação da descrição do
lutador da lógica das representações.
Como na lógica de domínio (primeiro artigo), todos os conceitos de lógica de apresentação no lsFusion formam uma pilha:

e é na ordem dessa pilha que falarei sobre eles.
Formulários
Um formulário é o conceito mais importante (e de fato praticamente o único) na lógica de apresentação, responsável por tudo - tanto pela interação do usuário quanto pela impressão, exportação e importação de dados.
O formulário pode ser logicamente dividido em duas partes:
- A estrutura do formulário determina quais dados o formulário mostra.
- A apresentação do formulário determina como ele exibe esses dados.
Estrutura de forma
Começamos, naturalmente, com a estrutura do formulário.
Os objetos
Ao criar um formulário, você deve primeiro determinar quais objetos serão exibidos. Vale a pena notar que pode haver uma ligeira confusão na terminologia entre os objetos do formulário e os objetos exibidos nesses objetos do formulário. Portanto, no futuro, se isso não for óbvio no contexto, usaremos os termos “objetos de formulário” (para o primeiro caso) e “objetos no banco de dados” (para o segundo).
Para cada objeto de formulário, você precisa definir sua classe. Essa classe pode ser primitiva (interna) ou objeto (personalizada).
De acordo com a ordem de adicionar objetos ao formulário, é formada uma lista ordenada de objetos. Dessa forma, o último objeto para um determinado conjunto de objetos será chamado de objeto desse conjunto com o número de série máximo nesta lista (ou seja, o mais recente).
Cada objeto no formulário em um determinado momento tem um valor atual. Sua alteração ocorre dependendo da apresentação, como resultado das ações correspondentes do usuário na apresentação interativa ou "virtualmente" no processo de leitura de dados em uma representação estática.
Propriedades e ações
Depois de definir os objetos no formulário, você pode adicionar propriedades e ações, substituindo os objetos descritos acima por eles como entrada para os argumentos.
Observe que a adição de ações é relevante apenas para apresentações interativas, pois elas são ignoradas nos relatórios e nas exportações. Além disso, considerando que o comportamento das propriedades e ações do ponto de vista de sua exibição no formulário é exatamente o mesmo, no futuro usaremos apenas o termo propriedade (para ações, o comportamento é exatamente o mesmo).
Objeto de exibição
Cada propriedade é exibida em exatamente um objeto no formulário (nós o chamaremos de objeto de exibição dessa propriedade). Por padrão, o objeto de exibição é um objeto, o último para o conjunto de objetos que são passados para a entrada dessa propriedade. Por exemplo, se tivermos uma forma de saldos atuais com dois objetos - um armazém e mercadorias e três propriedades - nomes do armazém e mercadorias e o saldo de mercadorias no armazém:
Então, para o nome do depósito, o objeto de exibição será s (depósito), e para o nome da mercadoria e o saldo, i (mercadoria).
No entanto, se necessário, o desenvolvedor pode especificar o objeto de exibição explicitamente (por exemplo, em uma exibição interativa, mostre a propriedade com o restante na tabela de armazéns, não mercadorias).
Filtros e Classificação
Para cada formulário, o desenvolvedor pode definir filtros e pedidos que limitarão a lista de objetos disponíveis para visualização / seleção no formulário, bem como a ordem em que são exibidos.
Para definir um filtro, você deve especificar uma propriedade que será usada como critério de filtro. O filtro será aplicado à tabela desse objeto, que é a última para o conjunto de objetos transmitidos para a entrada dessa propriedade (ou seja, da mesma forma que a definição do objeto de exibição da propriedade). Nesse caso, apenas os conjuntos de objetos (séries) serão mostrados para os quais os valores da propriedade não são NULL. Por exemplo, se adicionarmos o filtro currentBalance (s, i) OR isActive (i) ao formulário acima:
Captura de tela do formulário ao exibir produtos, apenas os produtos que estão na balança ou marcados como ativos serão exibidos.
As classificações são definidas como uma lista de propriedades no formulário em que os objetos de ordem devem ser exibidos. Caso contrário, tudo é semelhante aos filtros.
Grupos de objetos
A plataforma também tem a capacidade de combinar objetos em um
grupo de objetos . Nesse caso, o “produto cartesiano” desses objetos será mostrado nas tabelas / listas (ou seja, para dois objetos - todos os pares, três objetos - triplos, etc.).
Captura de tela do formulário Assim, em quase todos os lugares, antes e depois, em vez de objetos únicos do formulário, você pode usar grupos de objetos.
Na verdade, foi o que foi feito na documentação: o termo mais geral "grupo de objetos" é usado em todos os lugares, mas para não complicar as coisas neste artigo (e grupos de objetos compostos por vários objetos são usados com muito menos frequência), foi decidido esquecer e contar sobre grupos de objetos, que um grupo de objetos sempre consiste em exatamente um objeto e, portanto, use o termo "objeto" em qualquer lugar, em vez do mais complexo "grupo de objetos" e "conjunto de objetos".
Grupos de propriedades
As propriedades no formulário, como objetos, também podem ser combinadas em grupos, que, por sua vez, são usados nas representações interativas (design padrão) e hierárquicas do formulário (sobre elas um pouco mais tarde). Por padrão, a ligação de uma propriedade a um grupo é global (ou seja, é definida para uma propriedade para todos os formulários de uma só vez); no entanto, se necessário, para formulários individuais, essa ligação pode ser redefinida.
Objetos de coluna
Por padrão, uma propriedade é exibida exatamente uma vez em seu objeto de exibição. Nesse caso, como os valores de objetos diferentes do objeto de exibição desta propriedade (os chamamos de superiores), seus valores atuais são usados. No entanto, a plataforma também pode exibir uma propriedade várias vezes, para que os valores de alguns objetos principais não sejam usados pelos valores atuais, mas todos os objetos no banco de dados adequados para filtros. Com esse mapeamento de propriedades, um tipo de "matriz" é formado - (objeto de exibição) x (objetos superiores). Portanto, para criar uma matriz, ao adicionar uma propriedade ao formulário, é necessário indicar quais objetos superiores devem ser usados para criar colunas (chamaremos esses objetos de objetos em colunas).
Captura de tela do formulário Então, com o que o formulário exibe, mais ou menos descoberto, vamos seguir como ele pode fazer isso.
Submissões de formulário
Existem três envios de formulário:

Visualizar capturas de telaInterativo:

Impresso:

Estruturado:

- Interativo. Uma visão com a qual o usuário pode interagir é alterar dados e objetos atuais, disparando vários eventos. Na verdade, essa representação é geralmente chamada de formulário.
- Impresso. Geralmente, isso é chamado de relatório - upload de todos os dados do formulário e apresentação em forma gráfica. Inclusive com a possibilidade de imprimi-los (de onde tirou o nome).
- Estruturado - representação do formulário em vários formatos estruturados (JSON, XML, DBF, etc.). Normalmente usado para maior integração com outros sistemas.
As representações interativas e impressas são gráficas, ou seja, exibem os dados recebidos no espaço bidimensional: papel ou a tela do dispositivo. Consequentemente, cada uma dessas representações possui um design que, dependendo da representação específica, pode ser configurado usando mecanismos apropriados (sobre eles um pouco mais tarde).
A apresentação impressa e estruturada é estática, ou seja, eles lêem todos os dados no momento em que o formulário é aberto (em oposição à interativa, que lê os dados conforme necessário).
A descrição das performances começará, talvez, com a mais difícil - a apresentação interativa.
Apresentação interativa
Em uma exibição interativa, os objetos de formulário são exibidos no formato de tabela. As linhas nesta tabela correspondem aos objetos no banco de dados que satisfazem os filtros especificados, as colunas, por sua vez, correspondem às propriedades.
No entanto, se necessário, a propriedade pode ser exibida não como uma coluna da tabela, ou seja, para todas as suas linhas, mas como um campo separado no formulário, ou seja, apenas para o valor atual do objeto de formulário. Por exemplo:
Captura de tela do formulário A alteração do valor atual de um objeto de formulário ocorre como resultado de um usuário alterando a linha atual da tabela ou como resultado da execução de uma ação criada usando um operador de pesquisa especial (SEEK).
Observe que a maneira como uma propriedade é exibida em um painel ou tabela, como regra, é configurada não para cada propriedade separadamente, mas como um todo para um objeto de formulário. Portanto, se o objeto de formulário estiver marcado como PANEL, todas as suas propriedades serão exibidas no painel (ou seja, para o valor atual), caso contrário (por padrão) todas as suas propriedades serão exibidas na tabela. Propriedades sem parâmetros e ações padrão são exibidas no painel.
Todas as tabelas na exibição interativa são dinâmicas por padrão, ou seja, apenas um número limitado de objetos no banco de dados é lido e o restante é lido à medida que o objeto atual na tabela é alterado. O número de objetos exibidos nesse caso pode ser determinado automaticamente com base na altura da parte visível da tabela ou definido explicitamente pelo desenvolvedor ao criar o formulário.
Além disso, o formulário na apresentação interativa é completamente reativo, ou seja, atualiza automaticamente todos os dados no formulário quando quaisquer dados que os afetam são alterados (como React, apenas no caso geral). Além disso, tudo isso é feito não por recálculo completo (como no mesmo React), mas, além disso, de maneira incremental, no servidor SQL.
Em geral, é engraçado quando, ao comparar com outras tecnologias, você tenta incluir os três principais requisitos na tarefa, as pessoas geralmente olham em volta, como se lhes pedissem para lançar uma pessoa no espaço. Embora o não atendimento do segundo requisito por qualquer usuário normal seja classificado como um bug, o primeiro e o terceiro requisito é que o formulário desenvolvido funcione normalmente quando pelo menos um pouco de dados aparecer no banco de dados (várias dezenas de milhares de registros, por exemplo).
A apresentação interativa é suportada no modo de cliente da web (ou seja, aplicativos da web em um navegador) e no modo de cliente de desktop (aplicativos Java). O cliente de desktop, como qualquer cliente nativo, possui uma capacidade de resposta um pouco melhor da interface, mas, o mais importante, permite trabalhar com o equipamento e executar outras operações que não estão disponíveis no navegador (principalmente devido a problemas de segurança).
Árvores de Objetos
Além das tabelas, a plataforma também permite organizar a exibição de objetos na forma de árvores, planas ("aninhadas" umas nas outras tabelas) e recursivas (por exemplo, objetos "aninhadas" no banco de dados).
Árvores planas, de fato, são uma generalização de tabelas, quando várias tabelas são "combinadas" em uma tabela ao mesmo tempo:
Captura de tela do formulário Este é um mecanismo relativamente complexo e raramente é usado na prática; portanto, não iremos nos aprofundar nele em detalhes.
Mas as árvores recursivas, pelo contrário, são usadas com bastante frequência (por exemplo, para implementar classificadores). Para exibir um objeto de formulário na forma de uma árvore, é necessário definir um filtro adicional para ele - uma propriedade cujo valor para os objetos inferiores deve ser igual ao objeto superior. Inicialmente, o objeto superior é considerado NULL.
Captura de tela do formulário Gerenciamento de formulário de usuário
Para garantir uma melhor ergonomia do sistema (inclusive para não criar formulários para todos), parte das operações para configurar a apresentação interativa do formulário pode ser realizada pelos próprios usuários. Por exemplo, essas operações são:
- configuração de tabelas (colunas visíveis, ordem, fontes, etc.),
- criando filtros e tipos personalizados,
- agrupando dados por valores de coluna,
- imprima uma tabela e faça o upload para o Excel.
Além disso, o desenvolvedor pode criar os chamados grupos de filtros, que o usuário pode ativar / desativar independentemente. Por exemplo:
Essas não são todas as possibilidades de personalização do sistema pelo usuário, mas retornaremos às outras possibilidades no terceiro artigo, pois a maioria delas ainda não possui relação direta com a lógica de apresentação.
Observe que a funcionalidade descrita acima se refere mais provavelmente à funcionalidade das plataformas ERP, que já é completamente discordante com o título do artigo. Por outro lado, como mencionado no primeiro artigo, no futuro, o idioma / plataforma alega ser um substituto, incluindo essa classe de plataformas, portanto seria errado não mencionar esses recursos.
Operadores de Objetos
Um dos cenários mais comuns de trabalhar com um formulário é adicionar / excluir um objeto e editá-lo em um novo formulário. Para implementar esses cenários, a plataforma possui um conjunto predefinido de operadores que permite criar as ações necessárias em uma palavra diretamente no operador de criação de formulário:
- NOVO - criar um objeto
- EDIT - editando um objeto
- NEWEDIT - criando e editando um objeto
- DELETE - excluir um objeto
Além disso, como muitas vezes é necessário executar essas ações em uma nova sessão (se você precisar separar as ações de criação de objetos das ações no formulário a partir do qual esses objetos são criados), a plataforma suporta o açúcar sintático correspondente - as opções NEWSESSION e NESTEDSESSION, que funcionam de maneira semelhante aos operadores com o mesmo nome criando ações, mas, como os próprios operadores que trabalham com objetos, não exige que o desenvolvedor crie e nomeie novas ações. Por exemplo:
Por padrão, ao editar um objeto, o formulário de edição é chamado, que é gerado automaticamente para a classe do objeto de formulário passado. No entanto, muitas vezes é necessário redefinir este formulário (por exemplo, adicionar informações adicionais, alterar o design etc.) Para fazer isso, basta criar o formulário de edição necessário e indicar que é o formulário padrão para editar objetos de uma determinada classe:
Da mesma forma, os formulários para selecionar objetos de uma determinada classe são redefinidos.
Projeto da forma
Como na maioria das GUIs existentes, o design de uma apresentação interativa de um formulário é uma hierarquia cujos nós são componentes. Os componentes, por sua vez, podem ser:
- containers - componentes que contêm outros componentes.
- componentes básicos - representações gráficas de elementos básicos: tabelas, painéis de propriedades, grupos de filtros, etc.
O mecanismo para organizar os componentes dentro dos contêineres repete essencialmente o
CSS Flexible Box Layout (e é implementado no Web client com ele), portanto, não vamos nos deter sobre esse mecanismo em detalhes.
Observe que o design do formulário geralmente não é criado a partir do zero (pois é bastante demorado). Normalmente, um design de formulário é criado automaticamente com base na estrutura do formulário e, em seguida, o desenvolvedor o altera apenas um pouco: por exemplo, adiciona um novo contêiner e transfere componentes existentes para ele:
Exemplo de design de formulário padrãoA hierarquia de contêineres e componentes no design padrão terá a seguinte aparência:

Captura de tela do formulário Design de Formulário 2.0 (Reagir)
Observando as representações interativas dos formulários nas capturas de tela acima (ou, por exemplo, em uma demonstração online), você pode ver que o design atual do formulário na interface do usuário é, digamos, bastante ascético. Obviamente, isso nunca foi um problema específico para sistemas de informação, onde os principais usuários são funcionários ou parceiros da empresa que possui esses sistemas de informação. Além disso, apesar do ascetismo, o mecanismo atual de criação de formulários permite implementar casos muito difíceis, por exemplo, POS:
Captura de tela do formulário Mas se, digamos, SaaS B2B ou B2C, quanto mais serviços bancários na Internet, por exemplo, então começam a surgir perguntas sobre como tornar o design mais ergonômico.
No estágio atual, para resolver esse problema, uma
biblioteca javascript especial
foi desenvolvida, cuja principal tarefa é criar e atualizar um objeto js especial contendo dados do formulário. Assim, esse objeto pode ser usado como estado para o componente React e, assim, criar qualquer design e qualquer interatividade adicional do formulário que está sendo desenvolvido. Por exemplo:
Reagir exemplo de formulário (no codesandbox)Ou um exemplo mais complexo - com listas suspensas e usando a API REST (ou melhor, Stateless) para isso:
Reagir exemplo de formulário com listas suspensas (na codesandbox)É verdade que o problema dessa abordagem é que os formulários dos exemplos acima não serão incorporados nem na interface geral da plataforma nem no fluxo geral de ações de controle. Portanto, uma das tarefas mais imediatas no desenvolvimento da plataforma é a tradução do mecanismo de design do formulário no esquema usado no design do relatório (apresentação impressa):
- A plataforma gera automaticamente um design de reação com base na estrutura do formulário, como no exemplo acima.
- Se necessário, o desenvolvedor pode salvá-lo e editar como quiser. Assim, a plataforma usará esse design editado ao abrir o formulário.
Além disso, essa abordagem permitirá gerar formulários React Native e, assim, permitirá criar aplicativos móveis nativos. Embora esse problema (com aplicativos móveis nativos) ainda não tenhamos trabalhado muito profundamente.
É verdade que observamos que o mecanismo de design antigo também será suportado, pois, para os mesmos aplicativos de negócios, ele desempenha perfeitamente sua função.
Eventos de formulário
Eventos de formulário são o segundo mecanismo chave após eventos de domínio, responsável por determinar quando executar ações.
A plataforma possui todo um conjunto de vários eventos de formulário que surgem como resultado de determinadas ações do usuário, mas neste artigo consideraremos apenas um, o mais usado deles - o evento CHANGE. Esse evento ocorre quando o usuário iniciou uma chamada de alteração / ação de propriedade, por exemplo, pressionando qualquer tecla que não seja do sistema no teclado, no campo da propriedade que está sendo alterada ou clicando nesse campo com o mouse.
Quanto aos eventos da área de assunto, para eventos do formulário, você pode especificar o processamento - a ação que será executada quando o evento especificado ocorrer. Observe que a maioria dos eventos de formulário já possui algum processamento padrão que, imediatamente, implementa o comportamento mais esperado pelo usuário (por exemplo, com o evento CHANGE mencionado acima, solicite a entrada do usuário e altere a propriedade para o valor inserido). No entanto, na prática, às vezes surgem situações em que, para algum evento de formulário, é necessário especificar algum processamento específico, por exemplo:
, – , ( , , , paste , ). . .
, , , , , , , , INPUT.
, , , , , , . Por exemplo:
, , :
, INPUT – . (ASK):
(DIALOG) , , , , .
.
, . , , . , «» . , A B, A B, A A, B (A, B) B, A B ( «» ).
, , :
Por exemplo:

, , , , .
LGPL – JasperReports.
, JasperReports , . , :
- «» ( , O1, O2, O3,… On, O2 – O1, O3 – O2 ..) ;
- , .
«» , SUBREPORT ( , -):

:
JasperReports (, lsFusion). , . , JasperSoft Studio.
, lsFusion- IDEA, Eclipse, ( Eclipse JasperReports ). IDEA , language injection, jrxml-, , , , , , . , , Eclipse GrammarKit autocomplete (, ), stub-, lazy chameleon- ( ), , . .
() :
- (XML, JSON) – , () -.
- (DBF, CSV, XLS) – - . parent, «» -.
, (- ), , , ( ). . , .
– XML, JSON. , , JSON ( XML ).
/ JSON , : JSON-, – , – . :
JSON/ , / :
, / :
JSON ::= { JSON , / } JSON , / ::= JSON 1 | JSON 1 | JSON 1 JSON 2 | JSON 2 | JSON 2 ... JSON M | JSON M | JSON M JSON ::= " " : JSON ::= " " : { JSON , / } JSON ::= " " : [ { JSON , / 1 }, { JSON , / 2 }, ... { JSON , / N }, ]
:
{ "s": [ { "date": "21.02.19", "sd": [ { "money": { "item": " 3", "quantity": 1, "price": 5, "index": 1 } } ], "stock": " 2", "customer": " 2" }, { "date": "15.03.19", "sd": [ { "money": { "item": " 1", "quantity": 1, "price": 5, "index": 1 } }, { "money": { "item": " 2", "quantity": 1, "price": 10, "index": 2 } }, { "money": { "item": " 3", "quantity": 1, "price": 15, "index": 3 } }, { "money": { "item": " 4", "quantity": 1, "price": 20, "index": 4 } }, { "money": { "item": "Milk", "quantity": 1, "price": 50, "index": 5 } } ], "stock": " 1", "customer": " 3" }, { "date": "04.03.19", "sd": [ { "money": { "item": " 1", "quantity": 2, "price": 4, "index": 1 } }, { "money": { "item": " 2", "quantity": 3, "price": 4, "index": 2 } }, { "money": { "item": " 1", "quantity": 2, "price": 5, "index": 3 } } ], "stock": " 1", "customer": " 2" }, { "date": "04.03.19", "sd": [ { "money": { "item": " 1", "quantity": 3, "price": 1, "index": 1 } }, { "money": { "item": " 2", "quantity": 2, "price": 1, "index": 2 } } ], "stock": " 1", "customer": " 2" }, { "date": "14.03.19", "sd": [ { "money": { "item": " 2", "quantity": 1, "price": 2, "index": 1 } } ], "stock": " 1", "customer": " 2" }, { "date": "17.04.19", "sd": [ { "money": { "item": " 2", "quantity": 5, "price": 6, "index": 1 } }, { "money": { "item": " 1", "quantity": 2, "price": 6, "index": 2 } } ], "stock": " 1", "customer": " 1" }, { "date": "21.02.19", "sd": [ { "money": { "item": " 3", "quantity": 1, "price": 22, "index": 1 } } ], "stock": " 2", "customer": " 1" }, { "date": "21.02.19", "sd": [ { "money": { "item": " 3", "quantity": 1, "price": 22, "index": 1 } } ], "stock": " 2", "customer": " 1" }, { "date": "20.02.19", "sd": [ { "money": { "item": " 3", "quantity": 1, "price": 22, "index": 1 } } ], "stock": " 2", "customer": " 1" } ] }
, JSON JSON-. , , IDE JSON , – JSON. , ( , , JSON- ), . / JSON .
, :
, , , ( ). , , , / :
, SELECT SQL. , , , ( , ).
, , , – .
, , , :
– ( ) . .
(SHOW, DIALOG)
:
- (WAIT) – , , , , .
- (NOWAIT) – .
.
, :
- (FLOAT) – .
- (DOCKED) – System.forms.
, – .
, , (DIALOG). (, , ), , , .
, , (INPUT), ( ), , , ( ), , , ( ).
(PRINT)
( ) , JasperReports : DOC, DOCX, XLS, XLSX, PDF, HTML, RTF , JasperReports. , , , , ( , ).
, - (PREVIEW), , / . , , .
(EXPORT, IMPORT)
, , , : XML, JSON, DBF, CSV, XLS, XLSX. .
, , , – . () , () , .
– , , « », :
- .
- ( , , , , , TRUE f(a) = b – f(a) b)
TRUE ( , , 0 , .., , , ).
, , . , , , . . ( ), .
- , ( ). , , ( ). .
. , — .
– , . , , . , , .

.

100x100 . , , . , «» . , ( ). , . , .
. , - , , .
:
- , – , , .
- – forms, log, status, root, toolbar, tree, (, root, , )
, – , , , , , ERP-. , , « », : ? Sério? ? , -, lsFusion language-based ( SQL ABAP), library-based ( Java 1C) / . , , – domain-specific , . -, , , , . : , , , . , , , ( ).
. – , :
, :
- . «» : , , / . , , , , , , .
- . control flow . , – .
- SQL ( ORM). , , , .
Conclusão
, , (, , , , tutorial, , , ). , , ( ) «», , lsFusion.
, , – . , . , , « . .», , ( - ).
. : « ». , . , , lsFusion SQL-. , , , – , - , . , SQL- (
). , . , , ( , ), , , . «?», « ...?» «?».
UPD:
.