Descreva a arquitetura que você usa para aplicativos da web Java? [fechadas]

146

Vamos compartilhar arquiteturas de aplicativos da Web baseadas em Java!

Existem muitas arquiteturas diferentes para aplicativos da web que devem ser implementadas usando Java. As respostas a essa pergunta podem servir como uma biblioteca de vários designs de aplicativos da Web com seus prós e contras. Embora eu perceba que as respostas serão subjetivas, vamos tentar ser o mais objetivos possível e motivar os prós e os contras que listamos.

Use o nível de detalhe que você preferir para descrever sua arquitetura. Para que sua resposta seja de qualquer valor, você precisará pelo menos descrever as principais tecnologias e idéias usadas na arquitetura que descreve. E por último mas não menos importante, quando devemos usar sua arquitetura?

Vou começar...


Visão geral da arquitetura

Utilizamos uma arquitetura de três camadas com base nos padrões abertos da Sun, como Java EE, Java Persistence API, Servlet e Java Server Pages.

  • Persistência
  • O negócio
  • Apresentação

Os possíveis fluxos de comunicação entre as camadas são representados por:

Persistence <-> Business <-> Presentation

O que, por exemplo, significa que a camada de apresentação nunca chama ou executa operações de persistência, mas sempre através da camada de negócios. Essa arquitetura destina-se a atender às demandas de um aplicativo da web de alta disponibilidade.

Persistência

Executa operações de persistência de criação, leitura, atualização e exclusão ( CRUD ). No nosso caso, estamos usando o JPA ( Java Persistence API ) e atualmente usamos o Hibernate como nosso provedor de persistência e usamos seu EntityManager .

Essa camada é dividida em várias classes, onde cada classe lida com um certo tipo de entidades (ou seja, entidades relacionadas a um carrinho de compras podem ser tratadas por uma única classe de persistência) e é usada por um e apenas um gerente .

Além disso, essa camada também armazena entidades JPAAccount , como coisas ShoppingCartetc.

O negócio

Toda a lógica vinculada à funcionalidade do aplicativo da web está localizada nessa camada. Essa funcionalidade pode estar iniciando uma transferência de dinheiro para um cliente que deseja pagar por um produto on-line usando seu cartão de crédito. Também poderia estar criando um novo usuário, excluindo um usuário ou calculando o resultado de uma batalha em um jogo baseado na Web.

Essa camada é dividida em várias classes e cada uma dessas classes é anotada @Statelesspara se tornar um SLSB ( Stateless Session Bean ). Cada SLSB é chamado de gerente e, por exemplo, um gerente pode ser uma classe anotada como mencionado AccountManager.

Quando é AccountManagernecessário executar operações CRUD, ele faz as chamadas apropriadas para uma instância de AccountManagerPersistence, que é uma classe na camada de persistência. Um esboço aproximado de dois métodos em AccountManagerpoderia ser:

...
public void makeExpiredAccountsInactive() {
    AccountManagerPersistence amp = new AccountManagerPersistence(...)
    // Calls persistence layer
    List<Account> expiredAccounts = amp.getAllExpiredAccounts();
    for(Account account : expiredAccounts) {
        this.makeAccountInactive(account)
    }
}
public void makeAccountInactive(Account account) {
    AccountManagerPersistence amp = new AccountManagerPersistence(...)
    account.deactivate();
    amp.storeUpdatedAccount(account); // Calls persistence layer
}

Usamos transações de gerenciador de contêineres, para que não tenhamos que fazer a demarcação de transações. O que basicamente acontece sob o capô é que iniciamos uma transação ao entrar no método SLSB e a confirmamos (ou reverte-a) imediatamente antes de sair do método. É um exemplo de convenção sobre configuração, mas ainda não precisamos de nada além do padrão Obrigatório.

Aqui está como o Tutorial do Java EE 5 da Sun explica o atributo de transação Requerido para Enterprise JavaBeans (EJB's):

Se o cliente estiver executando dentro de uma transação e chamar o método do bean corporativo, o método será executado dentro da transação do cliente. Se o cliente não estiver associado a uma transação, o contêiner iniciará uma nova transação antes de executar o método.

O atributo Requerido é o atributo de transação implícita para todos os métodos de enterprise bean em execução com demarcação de transação gerenciada por contêiner. Normalmente, você não define o atributo Requerido, a menos que precise substituir outro atributo de transação. Como os atributos da transação são declarativos, você pode alterá-los facilmente mais tarde.

Apresentação

Nossa camada de apresentação é responsável por ... apresentação! Ele é responsável pela interface do usuário e mostra informações ao usuário criando páginas HTML e recebendo entrada do usuário por meio de solicitações GET e POST. Atualmente, estamos usando a antiga combinação Servlet + Java Server Pages ( JSP ).

A camada chama métodos nos gerentes da camada de negócios para executar operações solicitadas pelo usuário e receber informações para mostrar na página da web. Às vezes, as informações recebidas da camada de negócios são de tipos menos complexos como String's' e ' integers ' e , outras vezes, entidades JPA .

Prós e contras da arquitetura

Prós

  • Ter tudo relacionado a uma maneira específica de persistência nessa camada significa apenas que podemos mudar do JPA para outra coisa, sem precisar reescrever nada na camada de negócios.
  • É fácil trocarmos nossa camada de apresentação por outra e é provável que o façamos se encontrarmos algo melhor.
  • É bom deixar o contêiner EJB gerenciar limites de transação.
  • O uso do Servlet + JPA é fácil (para começar) e as tecnologias são amplamente usadas e implementadas em muitos servidores.
  • O uso do Java EE deve facilitar a criação de um sistema de alta disponibilidade com balanceamento de carga e failover . Ambos sentimos que devemos ter.

Contras

  • Usando o JPA, você pode armazenar consultas frequentemente usadas como consultas nomeadas, usando a @NamedQueryanotação na classe de entidade JPA. Se você tiver o máximo possível de persistência nas classes de persistência, como em nossa arquitetura, isso espalhará os locais onde você poderá encontrar consultas para incluir também as entidades JPA. Será mais difícil visualizar as operações de persistência e, portanto, mais difíceis de manter.
  • Temos entidades JPA como parte de nossa camada de persistência. Mas Accounte ShoppingCarteles não são realmente objetos de negócios? Isso é feito assim que você precisa tocar nessas classes e transformá-las em entidades com as quais a JPA sabe lidar.
  • As entidades JPA, que também são nossos objetos de negócios, são criadas como objetos de transferência de dados ( DTOs ), também conhecidos como objetos de valor (VOs). Isso resulta em um modelo de domínio anêmico, pois os objetos de negócios não têm lógica própria, exceto métodos de acessador. Toda a lógica é feita por nossos gerentes na camada de negócios, o que resulta em um estilo de programação mais processual. Não é um bom design orientado a objetos, mas talvez isso não seja um problema? (Afinal, a orientação a objetos não é o único paradigma de programação que produziu resultados.)
  • O uso de EJB e Java EE apresenta um pouco de complexidade. E não podemos usar o Tomcat puramente (adicionar um micro-contêiner EJB não é puramente o Tomcat).
  • Existem muitos problemas com o uso do Servlet + JPA. Use o Google para obter mais informações sobre esses problemas.
  • Como as transações são fechadas ao sair da camada de negócios, não podemos carregar nenhuma informação das entidades JPA configuradas para serem carregadas do banco de dados quando necessário (usando fetch=FetchType.LAZY) de dentro da camada de apresentação. Isso acionará uma exceção. Antes de retornar uma entidade que contém esses tipos de campos, precisamos chamar os getter relevantes. Outra opção é usar o Java Persistence Query Language ( JPQL ) e executar um FETCH JOIN. No entanto, essas duas opções são um pouco complicadas.
user14070
fonte
1
Parece que você colocou a fasquia muito alta com sua própria resposta - ele pode ter outros desanimados :)
Jonik
5
Além disso, talvez sua opinião seja uma resposta normal, não faça parte da pergunta, para que possa ser votada juntamente com outras respostas.
Jonik
Esta pergunta foi referenciada na meta.
D4V1D

Respostas:

20

Ok, eu vou fazer um (mais curto):

  • Frontend: Tapeçaria (3 para projetos mais antigos, 5 para projetos mais recentes)
  • Camada de negócios: Primavera
  • DAO: Ibatis
  • Banco de Dados: Oracle

Utilizamos o suporte a transações Sping e iniciamos transações ao entrar na camada de serviço, propagando-se para as chamadas do DAO. A camada de Serviço possui o maior conhecimento do modelo de negócios, e os DAO fazem trabalhos CRUD relativamente simples.

Algumas coisas de consulta mais complicadas são tratadas por consultas mais complicadas no back-end por razões de desempenho.

As vantagens de usar o Spring no nosso caso é que podemos ter instâncias dependentes do país / idioma, que estão por trás de uma classe Spring Proxy. Com base no usuário da sessão, a implementação correta do país / idioma é usada ao fazer uma chamada.

O gerenciamento de transações é quase transparente, com reversão nas exceções de tempo de execução. Usamos exceções não verificadas o máximo possível. Costumávamos fazer exceções verificadas, mas com a introdução do Spring, vejo os benefícios de exceções não verificadas, lidando apenas com exceções quando é possível. Evita muitas coisas clichê de "pegar / reler" ou "joga".

Desculpe, é mais curto que o seu post, espero que você ache isso interessante ...

Rolf
fonte
Boa resposta! Esse segmento parece atrair algum tráfego, uma pena que outras pessoas não sintam que têm tempo para descrever suas arquiteturas ou que tenham outros motivos para não participar.
19

Hoje, as tecnologias ideais de desenvolvimento da Web baseadas em Java.

Camada da Web:

HTML + CSS + Ajax + JQuery

Controlador da Web RESTFul / Camada de processamento de ação / solicitação:

Play Framework

Lógica comercial / camada de serviço:

Use o código Java puro o maior tempo possível. Pode-se fazer a fusão de serviços da web aqui.

Camada de transformação de dados XML / JSon:

XMLTool (pesquisar no código do Google), JSoup, Google GSon, XStream, JOOX (pesquisar no código do Google)

Camada de persistência:

CRUD: JPA ou SienaProject ou QueryDSL / consultas complexas: JOOQ, QueryDSL

Rakesh Waghela
fonte
9

Aqui estão os meus 5 centavos

Apresentação

Android, Angular.JS WebClient, OAUTHv2

API

REST, Jersey (JAX-RS), Jackson (descriptografia / serialização JSON), objetos DTO (diferentes dos modelos de lógica de negócios)

Logíca de negócios

Mola para DI e manipulação de eventos. Abordagem DDD-ish de objetos de modelo. Os trabalhos em execução mais longos são transferidos com o SQS nos módulos de trabalho.

DAO

Modelo de repositório com modelos JDBC do Spring para armazenar Entidades. Redis (JEDIS) para tabelas de classificação, usando listas ordenadas. Memcache para Token Store.

Base de dados

MySQL, Memcached, Redis

Pepster
fonte
Isso é algo semelhante ao que seguimos em nossos projetos também! Além disso, o JBPM para fluxo de trabalho comercial. Por que não há primavera?
ininprsr
Devo fazer uma atualização com nosso arco atual: Atualmente, usamos Spring DI e JDBC-templates para a camada de acesso a dados.
Pepster 23/08/15
6

O que seguimos em nosso projeto é:

Tecnologia de front-end

  • AngularJS
  • HTML5
  • css3
  • Javascript
  • Bootstrap 3

API

  1. DESCANSAR
  2. JERSEY (JAX-RS)
  3. TENHA CERTEZA
  4. BOTA DE MOLA
  5. Jackson
  6. segurança de primavera

Logíca de negócios

  • DADOS DA PRIMAVERA

  • Dados do SPRING MongoDB

Base de dados

  • MongoDB

Servidor (para armazenamento em cache)

  • redis
CandleCoder
fonte
4

Ainda estamos usando a pilha Struts-Spring-Hibernate usual.

Para aplicativos futuros, analisamos o Spring Web Flow + Spring MVC + Hibernate ou Spring + Hibernate + Web Services com o front end Flex.

Uma característica distinta da nossa arquitetura é a modularização. Temos vários módulos, alguns começando com 3 a no máximo 30 tabelas no banco de dados. A maioria dos módulos consiste em negócios e projeto web. Projeto de negócios mantém lógica de negócios e persistência, enquanto a web mantém lógica de apresentação.
No nível lógico, existem três camadas: Negócios, Persistência e Apresentação.
Dependências: A
apresentação depende dos negócios e da persistência.
A persistência depende dos negócios.
Os negócios não dependem de outras camadas.

A maioria dos projetos de negócios possui três tipos de interfaces (nota: não GUI, é uma camada de interface java programática).

  1. Interface que a apresentação está usando como cliente
  2. Interface que outros módulos estão usando quando são o cliente do módulo.
  3. Interface que pode ser usada para fins administrativos do módulo.

Freqüentemente, 1 estende 2. Dessa forma, é fácil substituir uma implementação do módulo por outra. Isso nos ajuda a adotar diferentes clientes e a integrar mais facilmente. Alguns clientes compram apenas determinados módulos e precisamos integrar a funcionalidade que eles já possuem. Como a interface e a camada de implementação são separadas, é fácil implementar a implementação do módulo ad-hock para esse cliente específico sem afetar os módulos dependentes. E o Spring Framework facilita a injeção de diferentes implementações.

Nossa camada de negócios é baseada em POJOs. Uma tendência que estou observando é que esses POJOs se parecem com DTOs. Sofremos com o modelo de domínio anêmico . Não sei ao certo por que isso está acontecendo, mas pode ser devido à simplicidade do domínio do problema de muitos de nossos módulos, a maior parte do trabalho é CRUD ou porque os desenvolvedores preferem colocar a lógica em outro lugar.

Dan
fonte
3

Aqui está mais uma arquitetura da web em que trabalhei:

Um requisito importante era que o aplicativo deveria suportar celulares / outros dispositivos. O aplicativo também deve ser extensível ou flexível a mudanças nas opções de tecnologia.

Camada de apresentação:

  • JSP / JQuery (MVC do lado do cliente)
  • Android nativo
  • IPhone nativo
  • Web para dispositivos móveis (HTML5 / CSS3 / design responsivo)

  • Controladores REST de mola (pode mudar para JAX-RS)

Nível de serviço comercial:

Spring @Service (pode mudar para EJB sem estado)

Camada de acesso a dados:

Spring @Repository (pode mudar para EJB sem estado)

Camada de Recursos:

Entidades de hibernação (JPA) (podem mudar para qualquer ORM)

Você pode encontrar mais informações no livro que segue essa arquitetura aqui .

Amritendu De
fonte
2

IMHO, a maioria de nós tem um denominador comum. Pelo menos no back-end, temos alguma forma de contêiner IOC / DI e uma estrutura de persistência. Pessoalmente, uso Guice e Mybatis para isso. As diferenças estão em como implementamos a camada de visualização / interface do usuário / apresentação. Existem 2 opções principais aqui (podem ser mais). Baseado em ação (URLs mapeados para controladores) e baseado em componente. Atualmente, estou usando a camada de apresentação baseada em componentes (usando o wicket). Imita perfeitamente um ambiente de área de trabalho onde eu uso componentes e eventos em vez de URLs e controladores. Atualmente, estou procurando um motivo para migrar para esse tipo de arquitetura de controlador de URL (foi assim que acabei nesta página). Por que o hype sobre as arquiteturas RESTful e Stateless.

Para responder a essa pergunta em resumo: escrevo aplicativos da Web com estado usando uma estrutura orientada a componentes em cima do contêiner do Guice IOC e coloco dados no banco de dados relacional usando Mybatis.

joshua
fonte
1

Um pouco diferente, e eu reivindicaria uma arquitetura java mais modular aqui. Nós temos:

  1. Front-end do WS / Rest / JSP do Spring
  2. Spring MVC para lógica de serviço comercial, contendo lógica da camada de apresentação, bem como transações Spring
  3. Interface de comunicação de serviço de componente, consultada pelo EJB por serviços de negócios. Os EJBs definem seus próprios limites de transação que podem ingressar nas transações Spring.
  4. Implementações de serviço de componentes, novamente componentes Spring
  5. Camada de integração, MyBatis para integrações de banco de dados, Spring WS para integrações de serviços da web, outras tecnologias de integração para outros serviços
  6. Mainframes, bancos de dados, outros serviços em outros servidores ...

Além do acima, temos os módulos de biblioteca compartilhada, que é um provedor de funcionalidade comum para todos os serviços.

O uso de diferentes camadas nos permite dissociar completamente e a modularidade de que precisamos. Também podemos utilizar totalmente o poder do Java EE e do Spring. Nada nos impede de usar o JSF, por exemplo, para o front end, se necessário.

Comparado ao exemplo de arquitetura do OP, acho que isso pode ser descrito como tendo quatro camadas principais em vez de três, embora com um toque.

eis
fonte
0

Eu trabalhei em projetos que usam esse padrão rígido de gerente. Historicamente, eu era um grande defensor da hierarquia rígida, onde tudo se encaixava em uma caixa organizada. À medida que progrido na minha carreira, acho que isso é forçado em muitos casos. Acredito que adotar uma mentalidade mais ágil em relação ao design de aplicativos leva a um produto melhor. O que quero dizer com isso é criar um conjunto de classes que resolva o problema em questão. Em vez de dizer "Você criou um gerente para isso e aquilo?"

O projeto atual em que estou trabalhando é um aplicativo Web com uma combinação de chamadas Spring MVC e RestEasy JSON / Ajax. No lado do servidor incorporado em nossos controladores, há uma camada de dados sensível à fachada com JPA / Hibernate para acesso direto ao banco de dados, algum acesso EJB e algumas chamadas de serviço da Web baseadas em SOAP. Juntando tudo isso, há um código de controlador java personalizado que determina o que serializar como JSON e retornar ao cliente.

Nós gastamos quase nenhum tempo tentando criar algum padrão unificado, optando por adotar a idéia "Pior é Melhor" da Filosofia do Design Unix. Sendo muito melhor colorir fora das linhas e criar algo sensível, mais rápido do que criar algo que atenda a vários requisitos estritos de design.

nsfyn55
fonte
0

Os componentes na arquitetura de aplicativos da Web incluem:

1: Navegador: interação com o cliente

        HTML
        JavaScript
        Stylesheet

2: Internet

3: servidor da Web

        CSS
        Image
        Pages(Java render )

4: Servidor de Aplicativos

        App Webapp (Java interaction)
        Others WebApps

5: servidor de banco de dados

        Oracle, SQL, MySQL

6: Dados

iCrazybest
fonte