Arquitetura Java: Uma Visão Pragmática Para Desenvolvedores

Arquitetura Java: Uma Visão Pragmática Para Desenvolvedores

(Palestra ministrada na UNIPÊ na abertura do MBA: ARQUITETURA E SOLUÇÕES DE TI em JUL-2017)

Quando se fala em arquitetura de sistemas Java é muito comum se pensar apenas em quais frameworks e tecnologias que serão utilizados, mas a verdade é que definir a arquitetura de sistemas vai muito além disso.

É preciso entender o contexto na qual o projeto e empresa estão inseridos, os pre-requisitos não-funcionais e até mesmo conhecer a equipe de perto. A partir daí devemos analisar os trade-offs de cada tecnologia ou ferramenta escolhida e ver se ela se adequa ao nosso sistema, sem nunca esquecer que aspectos como implementação e design de classes importam.

Por fim, discutiremos o verdadeiro papel de um arquiteto dentro das empresas.

F853760c988228c4a153333407e64f09?s=128

Rafael Ponte

July 05, 2017
Tweet

Transcript

  1. ARQUITETURA JAVA uma visão pragmática para desenvolvedores

  2. Quando eu só pensava em FRAMEWORKS!

  3. Estudava todos nos mais profundos detalhes…

  4. Decorava código e configurações

  5. Mas com o passar dos anos…

  6. Percebi que não eram frameworks o que mais me machucava

  7. Era manter código… dos outros!

  8. Era manter código… dos outros!

  9. e nessa palestra…

  10. @rponte

  11. None
  12. Fortaleza - Terra do Sol

  13. None
  14. None
  15. ARQUITETURA JAVA uma visão pragmática para desenvolvedores

  16. Antes de falarmos de arquitetura…

  17. O que é um arquiteto?

  18. Arquiteto é um papel

  19. Analisa as DESVANTAGENS

  20. Arquitetura, Design e Implementação

  21. Arquitetura tem a ver com pessoas

  22. e com tecnologias

  23. Tecnologias são: contextuais, temporais e pessoais

  24. mas apesar disso, elas importam…

  25. None
  26. mais especificamente…

  27. arquitetura de sistemas corporativos

  28. Sistemas Web

  29. quando falam em arquitetura as pessoas lembram…

  30. frameworks, tecnologias e linguagens

  31. mas há algo mais importante…

  32. MANUTENÇÃO

  33. o bom arquiteto pensa em manutenção a longo- prazo

  34. é a parte mais CARA de um software

  35. E isso está muito ligado a qualidade do código

  36. Passamos 70% do tempo LENDO código

  37. Codigo ruim 
 = 
 Dificil manter

  38. além disso arquitetura precisa ser SIMPLES de EVOLUIR

  39. Foco na Manutenção Sustentável

  40. MANUTENÇÃO SUSTENTÁVEL

  41. navegador

  42. navegador servidor

  43. navegador servidor

  44. navegador servidor requisição

  45. navegador servidor db requisição

  46. navegador servidor db requisição resposta

  47. navegador servidor db requisição resposta

  48. navegador servidor db requisição resposta

  49. servidor Aplicação

  50. servidor

  51. servidor Produto.java Venda.java BancoDeDados.java FinalizarCompra.java Pagamento.java carrinhoDeCompras.jsp index.jsp site.css app.js

    GravaProduto.java EnviaEmail.java GravaProdutoServlet.java finalizar-compra.jsp
  52. servidor

  53. servidor

  54. servidor

  55. Divisão de Camadas

  56. servidor

  57. servidor modelo

  58. servidor modelo telas

  59. servidor modelo acesso a dados telas

  60. servidor apresentação negócio persistência camadas

  61. servidor apresentação negócio persistência controle das telas camadas

  62. servidor apresentação negócio persistência controle das telas logica de negocio

    camadas
  63. servidor apresentação negócio persistência controle das telas logica de negocio

    acesso a banco e dados camadas
  64. servidor apresentação negócio persistência camadas

  65. servidor apresentação negócio persistência camadas

  66. servidor apresentação negócio persistência camadas

  67. servidor apresentação negócio persistência

  68. servidor apresentação negócio persistência qual framework?

  69. None
  70. Qual?

  71. .VRaptor JSF..

  72. Action-based Component-based.

  73. Action-based

  74. requisição resposta

  75. requisição C

  76. requisição C A

  77. requisição C A M

  78. requisição C A V M

  79. requisição C A V resposta M

  80. requisição C A V resposta M (empurra dados)

  81. requisição C A V resposta M (empurra dados) MVC Push

  82. requisição C A V resposta M (empurra dados) MVC Push

    Struts Spring MVC VRaptor Ruby On Rails Laravel .Net MVC
  83. Component-based

  84. requisição resposta

  85. requisição C

  86. requisição C V

  87. requisição C MB V

  88. requisição C MB V M

  89. requisição C MB V M

  90. requisição C MB V M

  91. requisição C MB V M

  92. requisição C MB V resposta M

  93. requisição C MB V resposta M (puxa dados)

  94. requisição C MB V resposta M (puxa dados) MVC Pull

  95. requisição C MB V resposta M (puxa dados) MVC Pull

    JSF Wicket GWT Tapestry
  96. Diferença?

  97. C A V C MB V (baixo acoplamento) (alto acoplamento)

    action-based component- based
  98. Qual o melhor?

  99. @Controller public class ProdutoController { @Post("/produtos/grava") public void grava(Produto produto)

    { // executa logica de negocio } } VRaptor
  100. @ManagedBean public class ProdutoBean { public void grava(Produto produto) {

    // executa logica de negocio } } JSF
  101. servidor apresentação negócio persistência

  102. servidor apresentação negócio persistência

  103. public class Produto { private Integer id; private String nome;

    private String descricao; private Double preco; private List<Categoria> categorias; }
  104. public class Produto { private Integer produtoId; private String produtoNome;

    private String produtoDescricao; private Double produtoPreco; private List<Categoria> categorias; }
  105. public class Produto { private Integer produtoId; private String produtoNome;

    private String produtoDescricao; private Double produtoPreco; private List<Categoria> categorias; }
  106. public class Produto { private Integer produtoId; private String produtoNome;

    private String produtoDescricao; private Double produtoPreco; private List<Categoria> categorias; }
  107. public class Produto { private Integer produtoId; private String produtoNome;

    private String produtoDescricao; private Double produtoPreco; private List<Categoria> categorias; }
  108. public class Produto { private Integer produtoId; private String produtoNome;

    private String produtoDescricao; private Double produtoPreco; private List<Categoria> categorias; }
  109. public class Produto { private Integer produtoId; private String produtoNome;

    private String produtoDescricao; private Double produtoPreco; private List<Categoria> categorias; }
  110. public class Produto { private Integer id; private String nome;

    private String descricao; private Double preco; private List<Categoria> tags; }
  111. public class Produto { private Integer id; private String nome;

    private String descricao; private Double preco; private List<Categoria> tags; }
  112. public class Produto { private Integer id; private String nome;

    private String descricao; private Double preco; private List<Categoria> tags; }
  113. public class Produto { private Integer id; private String nome;

    private String descricao; private Double preco; private List<Categoria> tags; }
  114. public class Produto { private Integer id; private String nome;

    private String descricao; private Double preco; private List<Categoria> categorias; }
  115. class Produto { ... } class Cliente { ... }

    class Venda { ... } class Pagamento { ... } class Parcela { ... } class Imposto { ... } class Frete { ... }
  116. public class FinalizaVenda { private void finaliza(Venda venda) { //

    grava venda no banco // baixa no estoque dos produtos // efetua pagamento // envia email para cliente } }
  117. Use nomenclatura e jargões do domínio do seu negócio

  118. servidor apresentação negócio persistência

  119. servidor apresentação negócio persistência

  120. public class ProdutoDao { void adiciona(Produto produto) { Connection c

    = // cria conexão com banco String sql = "INSERT INTO TB_PRODUTO(nome,desc,preco) VALUES (?,?,?)"; PreparedStatement ps = c.prepareStatment(sql); ps.setString(1, produto.getNome()); ps.setString(2, produto.getDescricao()); ps.setDouble(3, produto.getPreco()); ps.execute(); // executa sql c.close(); // fecha conexão } }
  121. public class ProdutoDao { void adiciona(Produto produto) { Connection c

    = // cria conexão com banco String sql = "INSERT INTO TB_PRODUTO(nome,desc,preco) VALUES (?,?,?)"; PreparedStatement ps = c.prepareStatment(sql); ps.setString(1, produto.getNome()); ps.setString(2, produto.getDescricao()); ps.setDouble(3, produto.getPreco()); ps.execute(); // executa sql c.close(); // fecha conexão } }
  122. public class ProdutoDao { void adiciona(Produto produto) { Connection c

    = // cria conexão com banco String sql = "INSERT INTO TB_PRODUTO(nome,desc,preco) VALUES (?,?,?)"; PreparedStatement ps = c.prepareStatment(sql); ps.setString(1, produto.getNome()); ps.setString(2, produto.getDescricao()); ps.setDouble(3, produto.getPreco()); ps.execute(); // executa sql c.close(); // fecha conexão } }
  123. public class ProdutoDao { void adiciona(Produto produto) { Connection c

    = // cria conexão com banco String sql = "INSERT INTO TB_PRODUTO(nome,desc,preco) VALUES (?,?,?)"; PreparedStatement ps = c.prepareStatment(sql); ps.setString(1, produto.getNome()); ps.setString(2, produto.getDescricao()); ps.setDouble(3, produto.getPreco()); ps.execute(); // executa sql c.close(); // fecha conexão } }
  124. public class ProdutoDao { void adiciona(Produto produto) { Connection c

    = // cria conexão com banco String sql = "INSERT INTO TB_PRODUTO(nome,desc,preco) VALUES (?,?,?)"; PreparedStatement ps = c.prepareStatment(sql); ps.setString(1, produto.getNome()); ps.setString(2, produto.getDescricao()); ps.setDouble(3, produto.getPreco()); ps.execute(); // executa sql c.close(); // fecha conexão } }
  125. public class ProdutoDao { void adiciona(Produto produto) { Connection c

    = // cria conexão com banco String sql = "INSERT INTO TB_PRODUTO(nome,desc,preco) VALUES (?,?,?)"; PreparedStatement ps = c.prepareStatment(sql); ps.setString(1, produto.getNome()); ps.setString(2, produto.getDescricao()); ps.setDouble(3, produto.getPreco()); ps.execute(); // executa sql c.close(); // fecha conexão } }
  126. public class ProdutoDao { void adiciona(Produto produto) { Connection c

    = // cria conexão com banco String sql = "INSERT INTO TB_PRODUTO(nome,desc,preco) VALUES (?,?,?)"; PreparedStatement ps = c.prepareStatment(sql); ps.setString(1, produto.getNome()); ps.setString(2, produto.getDescricao()); ps.setDouble(3, produto.getPreco()); ps.execute(); // executa sql c.close(); // fecha conexão } }
  127. public class ProdutoDao { void adiciona(Produto produto) { Connection c

    = // cria conexão com banco String sql = "INSERT INTO TB_PRODUTO(nome,desc,preco) VALUES (?,?,?)"; PreparedStatement ps = c.prepareStatment(sql); ps.setString(1, produto.getNome()); ps.setString(2, produto.getDescricao()); ps.setDouble(3, produto.getPreco()); ps.execute(); // executa sql c.close(); // fecha conexão } }
  128. public class ProdutoDao { void adiciona(Produto produto) { Connection c

    = // cria conexão com banco String sql = "INSERT INTO TB_PRODUTO(nome,desc,preco) VALUES (?,?,?)"; PreparedStatement ps = c.prepareStatment(sql); ps.setString(1, produto.getNome()); ps.setString(2, produto.getDescricao()); ps.setDouble(3, produto.getPreco()); ps.execute(); // executa sql c.close(); // fecha conexão } }
  129. Para outras entidades não é diferente…

  130. public class ClienteDao { void adiciona(Cliente cliente) { Connection c

    = // cria conexão com banco String sql = "INSERT INTO TB_CLIENTE(nome,cpf) VALUES (?,?)"; PreparedStatement ps = c.prepareStatment(sql); ps.setString(1, cliente.getNome()); ps.setString(2, cliente.getCpf()); ps.execute(); // executa sql c.close(); // fecha conexão } }
  131. public class ClienteDao { void adiciona(Cliente cliente) { Connection c

    = // cria conexão com banco String sql = "INSERT INTO TB_CLIENTE(nome,cpf) VALUES (?,?)"; PreparedStatement ps = c.prepareStatment(sql); ps.setString(1, cliente.getNome()); ps.setString(2, cliente.getCpf()); ps.execute(); // executa sql c.close(); // fecha conexão } }
  132. public class ClienteDao { void adiciona(Cliente cliente) { Connection c

    = // cria conexão com banco String sql = "INSERT INTO TB_CLIENTE(nome,cpf) VALUES (?,?)"; PreparedStatement ps = c.prepareStatment(sql); ps.setString(1, cliente.getNome()); ps.setString(2, cliente.getCpf()); ps.execute(); // executa sql c.close(); // fecha conexão } }
  133. public class ClienteDao { List<Cliente> lista() { List<Cliente> clientes =

    new ArrayList<>(); Connection c = // cria conexão com banco String sql = “select nome, cpf from TB_CLIENTE”; PreparedStatement ps = c.prepareStatment(sql); ResultSet rs = ps.executeQuery(); while (rs.next()) { Cliente cliente = new Cliente(); cliente.setNome(rs.getString(“nome”)); cliente.setcpf(rs.getString(“cpf”)); clientes.add(cliente);
 } return clientes; }
  134. public class ClienteDao { List<Cliente> lista() { List<Cliente> clientes =

    new ArrayList<>(); Connection c = // cria conexão com banco String sql = “select nome, cpf from TB_CLIENTE”; PreparedStatement ps = c.prepareStatment(sql); ResultSet rs = ps.executeQuery(); while (rs.next()) { Cliente cliente = new Cliente(); cliente.setNome(rs.getString(“nome”)); cliente.setcpf(rs.getString(“cpf”)); clientes.add(cliente);
 } return clientes; }
  135. public class ClienteDao { List<Cliente> lista() { List<Cliente> clientes =

    new ArrayList<>(); Connection c = // cria conexão com banco String sql = “select nome, cpf from TB_CLIENTE”; PreparedStatement ps = c.prepareStatment(sql); ResultSet rs = ps.executeQuery(); while (rs.next()) { Cliente cliente = new Cliente(); cliente.setNome(rs.getString(“nome”)); cliente.setcpf(rs.getString(“cpf”)); clientes.add(cliente);
 } return clientes; }
  136. public class ClienteDao { List<Cliente> lista() { List<Cliente> clientes =

    new ArrayList<>(); Connection c = // cria conexão com banco String sql = “select nome, cpf from TB_CLIENTE”; PreparedStatement ps = c.prepareStatment(sql); ResultSet rs = ps.executeQuery(); while (rs.next()) { Cliente cliente = new Cliente(); cliente.setNome(rs.getString(“nome”)); cliente.setcpf(rs.getString(“cpf”)); clientes.add(cliente);
 } return clientes; }
  137. Repare no que estamos fazendo…

  138. Paradigma Relacional Paradigma OO

  139. Paradigma Relacional Paradigma OO classes atributos objetos herança associação encapsulamento

    polimorfismo
  140. Paradigma Relacional Paradigma OO classes atributos objetos herança associação encapsulamento

    polimorfismo tabelas colunas tuplas primary keys foreign keys constraints joins
  141. Paradigma Relacional Paradigma OO classes atributos objetos herança associação encapsulamento

    polimorfismo tabelas colunas tuplas primary keys foreign keys constraints joins
  142. Paradigma Relacional Paradigma OO classes atributos objetos herança associação encapsulamento

    polimorfismo tabelas colunas tuplas primary keys foreign keys constraints joins
  143. Paradigma Relacional Paradigma OO classes atributos objetos herança associação encapsulamento

    polimorfismo tabelas colunas tuplas primary keys foreign keys constraints joins
  144. Paradigma Relacional Paradigma OO classes atributos objetos herança associação encapsulamento

    polimorfismo tabelas colunas tuplas primary keys foreign keys constraints joins
  145. Paradigma Relacional Paradigma OO classes atributos objetos herança associação encapsulamento

    polimorfismo tabelas colunas tuplas primary keys foreign keys constraints joins conexao.salva(produto)
  146. Paradigma Relacional Paradigma OO classes atributos objetos herança associação encapsulamento

    polimorfismo tabelas colunas tuplas primary keys foreign keys constraints joins conexao.salva(produto) ORM
 (Object Relational Mapping)
  147. Paradigma Relacional Paradigma OO classes atributos objetos herança associação encapsulamento

    polimorfismo tabelas colunas tuplas primary keys foreign keys constraints joins conexao.salva(produto)
  148. @Entity @Table(name="TB_PRODUTO") public class Produto { @Id private Integer id;

    private String nome; private String descricao; @Column(name="VALOR") private Double preco; }
  149. @Entity public class Produto { @Id @GeneratedValue private Integer id;

    private String nome; private String descricao; @Column(name="VALOR") private Double preco; }
  150. @Entity public class Produto { @Id private Integer id; private

    String nome; private String descricao; @Column(name="VALOR") private Double preco; }
  151. @Entity public class Produto { @Id @GeneratedValue private Integer id;

    private String nome; private String descricao; @Column(name="VALOR") private Double preco; }
  152. Mas o Padrão da empresa é diferente

  153. @Entity @Table(name="TB_PRODUTO") public class Produto { @Id @GeneratedValue private Integer

    id; private String nome; private String descricao; @Column(name="VALOR") private Double preco; }
  154. @Entity @Table(name="TB_PRODUTO") public class Produto { @Id @GeneratedValue private Integer

    id; private String nome; private String descricao; @Column(name=“VALOR") private Double preco; }
  155. E como grava?

  156. public class ProdutoDao { void adiciona(Produto produto) { EntityManager manager

    = // cria conexão manager.getTransaction().begin(); manager.persist(produto); manager.getTransaction().commit(); } }
  157. public class ProdutoDao { void adiciona(Produto produto) { EntityManager manager

    = // cria conexão manager.getTransaction().begin(); manager.persist(produto); manager.getTransaction().commit(); } }
  158. public class ProdutoDao { void adiciona(Produto produto) { EntityManager manager

    = // cria conexão manager.getTransaction().begin(); manager.persist(produto); manager.getTransaction().commit(); } }
  159. public class ProdutoDao { void adiciona(Produto produto) { EntityManager manager

    = // cria conexão manager.getTransaction().begin(); manager.persist(produto); manager.getTransaction().commit(); } }
  160. public class ProdutoDao { void adiciona(Produto produto) { EntityManager manager

    = // cria conexão manager.getTransaction().begin(); manager.persist(produto); manager.getTransaction().commit(); } }
  161. INSERT INTO TB_PRODUTO(nome, descricao, valor) VALUES (?, ?, ?); CONSOLE

  162. Relacionamentos?

  163. @Entity public class Produto { // outros atributos @ManyToMany private

    List<Categorias> categorias; }
  164. @Entity public class Produto { // outros atributos @ManyToMany private

    List<Categorias> categorias; }
  165. E se meu time é bom em SQL?

  166. None
  167. SELECT * FROM PRODUTO WHERE PRODUTO.PUBLICADO_EM = 2011 ORDER BY

    PRODUTO.NOME SQL
  168. jooq.selectFrom(PRODUTO) .where(PRODUTO.PUBLICADO_EM.eq(2011)) .orderBy(PRODUTO.NOME) jOOQ

  169. SELECT AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME, COUNT(*) FROM AUTHOR JOIN BOOK ON AUTHOR.ID

    = BOOK.AUTHOR_ID WHERE BOOK.LANGUAGE = 'DE' AND BOOK.PUBLISHED > DATE '2008-01-01' GROUP BY AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME HAVING COUNT(*) > 5 ORDER BY AUTHOR.LAST_NAME ASC NULLS FIRST LIMIT 2 OFFSET 1 SQL
  170. jooq.select(AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME, count()) .from(AUTHOR) .join(BOOK).on(AUTHOR.ID.equal(BOOK.AUTHOR_ID)) .where(BOOK.LANGUAGE.eq("DE")) .and(BOOK.PUBLISHED.gt(date("2008-01-01"))) .groupBy(AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME) .having(count().gt(5))

    .orderBy(AUTHOR.LAST_NAME.asc().nullsFirst()) .limit(2) .offset(1) jOOQ
  171. Qual o melhor?

  172. None
  173. diminuir acoplamento

  174. aumentar coesão

  175. public class ProdutoDao { void adiciona(Produto produto) { EntityManager manager

    = // cria conexão manager.getTransaction().begin(); manager.persist(produto); manager.getTransaction().commit(); } }
  176. public class ProdutoDao { void adiciona(Produto produto) { EntityManager em

    = new JpaUtil().getEntityManager(); EntityTransaction tx = em.getTransaction(); try { tx.begin(); // inicia transação em.persist(produto); tx.commit(); // comida transação } catch (Exception e) { if (tx != null && tx.isActive()) { tx.rollback(); // desfaz transação } throw new DaoException(e); } finally { if (em != null) { em.close(); } } } }
  177. Qual o problema dessa classe?

  178. public class ProdutoDao { void adiciona(Produto produto) { EntityManager em

    = new JpaUtil().getEntityManager(); EntityTransaction tx = em.getTransaction(); try { tx.begin(); // inicia transação em.persist(produto); tx.commit(); // comida transação } catch (Exception e) { if (tx != null && tx.isActive()) { tx.rollback(); // desfaz transação } throw new DaoException(e); } finally { if (em != null) { em.close(); } } } }
  179. public class ProdutoDao { void adiciona(Produto produto) { EntityManager em

    = new JpaUtil().getEntityManager(); EntityTransaction tx = em.getTransaction(); try { tx.begin(); // inicia transação em.persist(produto); tx.commit(); // comida transação } catch (Exception e) { if (tx != null && tx.isActive()) { tx.rollback(); // desfaz transação } throw new DaoException(e); } finally { if (em != null) { em.close(); } } } }
  180. public class ProdutoDao { void adiciona(Produto produto) { EntityManager em

    = new JpaUtil().getEntityManager(); EntityTransaction tx = em.getTransaction(); try { tx.begin(); // inicia transação em.persist(produto); tx.commit(); // comida transação } catch (Exception e) { if (tx != null && tx.isActive()) { tx.rollback(); // desfaz transação } throw new DaoException(e); } finally { if (em != null) { em.close(); } } } }
  181. public class ProdutoDao { void adiciona(Produto produto) { EntityManager em

    = new JpaUtil().getEntityManager(); EntityTransaction tx = em.getTransaction(); try { tx.begin(); // inicia transação em.persist(produto); tx.commit(); // comida transação } catch (Exception e) { if (tx != null && tx.isActive()) { tx.rollback(); // desfaz transação } throw new DaoException(e); } finally { if (em != null) { em.close(); } } } }
  182. MUITA responsabilidade

  183. SOLTEIRÃO

  184. public class ProdutoDao { void adiciona(Produto produto) { EntityManager em

    = new JpaUtil().getEntityManager(); EntityTransaction tx = em.getTransaction(); try { tx.begin(); // inicia transação em.persist(produto); tx.commit(); // comida transação } catch (Exception e) { if (tx != null && tx.isActive()) { tx.rollback(); // desfaz transação } throw new DaoException(e); } finally { if (em != null) { em.close(); } } } }
  185. public class ProdutoDao { void adiciona(Produto produto) { EntityManager em

    = new JpaUtil().getEntityManager(); EntityTransaction tx = em.getTransaction(); try { tx.begin(); // inicia transação em.persist(produto); tx.commit(); // comida transação } catch (Exception e) { if (tx != null && tx.isActive()) { tx.rollback(); // desfaz transação } throw new DaoException(e); } finally { if (em != null) { em.close(); } } } }
  186. public class ProdutoDao { void adiciona(Produto produto) { EntityManager em

    = new JpaUtil().getEntityManager(); EntityTransaction tx = em.getTransaction(); try { tx.begin(); // inicia transação em.persist(produto); tx.commit(); // comida transação } catch (Exception e) { if (tx != null && tx.isActive()) { tx.rollback(); // desfaz transação } throw new DaoException(e); } finally { if (em != null) { em.close(); } } } }
  187. public class ProdutoDao { void adiciona(Produto produto) { EntityManager em

    = new JpaUtil().getEntityManager(); EntityTransaction tx = em.getTransaction(); try { tx.begin(); // inicia transação em.persist(produto); tx.commit(); // comida transação } catch (Exception e) { if (tx != null && tx.isActive()) { tx.rollback(); // desfaz transação } throw new DaoException(e); } finally { if (em != null) { em.close(); } } } }
  188. public class ProdutoDao { void adiciona(Produto produto) { EntityManager em

    = new JpaUtil().getEntityManager(); EntityTransaction tx = em.getTransaction(); try { tx.begin(); // inicia transação em.persist(produto); tx.commit(); // comida transação } catch (Exception e) { if (tx != null && tx.isActive()) { tx.rollback(); // desfaz transação } throw new DaoException(e); } finally { if (em != null) { em.close(); } } } }
  189. public class ProdutoDao { private EntityManager em; public ProdutoDao(EntityManager em)

    { this.em = em; } void adiciona(Produto produto) { EntityTransaction tx = em.getTransaction(); try { tx.begin(); // inicia transação em.persist(produto); tx.commit(); // comida transação } catch (Exception e) { // restante do codigo } finally { if (em != null) { em.close(); } } }
  190. public class ProdutoDao { private EntityManager em; public ProdutoDao(EntityManager em)

    { this.em = em; } void adiciona(Produto produto) { EntityTransaction tx = em.getTransaction(); try { tx.begin(); // inicia transação em.persist(produto); tx.commit(); // comida transação } catch (Exception e) { // restante do codigo } finally { if (em != null) { em.close(); } } }
  191. public class ProdutoDao { private EntityManager em; public ProdutoDao(EntityManager em)

    { this.em = em; } void adiciona(Produto produto) { EntityTransaction tx = em.getTransaction(); try { tx.begin(); // inicia transação em.persist(produto); tx.commit(); // comida transação } catch (Exception e) { // restante do codigo } finally { if (em != null) { em.close(); } } }
  192. None
  193. Mas tem algo estranho…

  194. @ManagedBean public class ProdutoBean { public void grava(Produto produto) {

    ProdutoDao dao = new ProdutoDao(); dao.adiciona(produto); // restante do código } } JSF
  195. @ManagedBean public class ProdutoBean { public void grava(Produto produto) {

    ProdutoDao dao = new ProdutoDao(); dao.adiciona(produto); // restante do código } } JSF
  196. JSF @ManagedBean public class ProdutoBean { public void grava(Produto produto)

    { ProdutoDao dao = new ProdutoDao(); dao.adiciona(produto); // restante do código } } Não compila!
  197. @ManagedBean public class ProdutoBean { public void grava(Produto produto) {

    EntityManager em = new JpaUtil().getEM(); ProdutoDao dao = new ProdutoDao(em); dao.adiciona(produto); // restante do código } } JSF
  198. JSF @ManagedBean public class ProdutoBean { public void grava(Produto produto)

    { EntityManager em = new JpaUtil().getEM(); ProdutoDao dao = new ProdutoDao(em); dao.adiciona(produto); // restante do código } }
  199. JSF @ManagedBean public class ProdutoBean { public void grava(Produto produto)

    { EntityManager em = new JpaUtil().getEM(); ProdutoDao dao = new ProdutoDao(em); dao.adiciona(produto); // restante do código } }
  200. JSF @ManagedBean public class ProdutoBean { public void grava(Produto produto)

    { EntityManager em = new JpaUtil().getEM(); ProdutoDao dao = new ProdutoDao(em); dao.adiciona(produto); // restante do código } }
  201. Muitas dependências!

  202. Mudando o problema de lugar!

  203. ProdutoBean

  204. ProdutoBean ProdutoDao

  205. ProdutoBean ProdutoDao EntityManager

  206. ProdutoBean ProdutoDao EntityManager JpaUtil

  207. ProdutoBean ProdutoDao EntityManager JpaUtil ??

  208. Resolver esse grafo nao é difícil…

  209. None
  210. Spring

  211. Spring

  212. Spring DI (Injeção de Dependências)

  213. Spring IoC/DI (Inversão de Controle / Injeção de Dependências)

  214. Spring CORE

  215. Spring

  216. Spring

  217. Deixar o Spring gerenciar os objetos

  218. @ManagedBean public class ProdutoBean { public void grava(Produto produto) {

    EntityManager em = new JpaUtil().getEM(); ProdutoDao dao = new ProdutoDao(em); dao.adiciona(produto); // restante do código } } JSF
  219. @ManagedBean public class ProdutoBean { public void grava(Produto produto) {

    EntityManager em = new JpaUtil().getEM(); ProdutoDao dao = new ProdutoDao(em); dao.adiciona(produto); // restante do código } } JSF
  220. @ManagedBean public class ProdutoBean { private ProdutoDao dao public void

    grava(Produto produto) { dao.adiciona(produto); // restante do código } } JSF
  221. @ManagedBean public class ProdutoBean { private ProdutoDao dao public void

    grava(Produto produto) { dao.adiciona(produto); // restante do código } } JSF Injeta Spring!
  222. @ManagedBean public class ProdutoBean { private ProdutoDao dao public void

    grava(Produto produto) { dao.adiciona(produto); // restante do código } } JSF
  223. @Controller public class ProdutoBean { private ProdutoDao dao public void

    grava(Produto produto) { dao.adiciona(produto); // restante do código } } JSF
  224. @Controller public class ProdutoBean { @Autowired private ProdutoDao dao public

    void grava(Produto produto) { dao.adiciona(produto); // restante do código } } JSF
  225. @Controller public class ProdutoBean { @Autowired private ProdutoDao dao public

    void grava(Produto produto) { dao.adiciona(produto); // restante do código } } JSF Quem contrala?
  226. @Repository public class ProdutoDao { private EntityManager em; public ProdutoDao(EntityManager

    em) { this.em = em; } void adiciona(Produto produto) { // ... } }
  227. @Repository public class ProdutoDao { private EntityManager em; public ProdutoDao(EntityManager

    em) { this.em = em; } void adiciona(Produto produto) { // ... } }
  228. @Repository public class ProdutoDao { private EntityManager em; public ProdutoDao(EntityManager

    em) { this.em = em; } void adiciona(Produto produto) { // ... } } Injeta Spring!
  229. @Repository public class ProdutoDao { private EntityManager em; @Autowired public

    ProdutoDao(EntityManager em) { this.em = em; } void adiciona(Produto produto) { // ... } }
  230. @Repository public class ProdutoDao { private EntityManager em; @Autowired public

    ProdutoDao(EntityManager em) { this.em = em; } void adiciona(Produto produto) { // ... } } Quem controla?
  231. @Repository public class ProdutoDao { private EntityManager em; @Autowired public

    ProdutoDao(EntityManager em) { this.em = em; } void adiciona(Produto produto) { // ... } } JPA/Hibernate
  232. @Repository public class ProdutoDao { @PersistenceContext private EntityManager em; @Autowired

    public ProdutoDao(EntityManager em) { this.em = em; } void adiciona(Produto produto) { // ... } }
  233. @Repository public class ProdutoDao { @PersistenceContext private EntityManager em; @Autowired

    public ProdutoDao(EntityManager em) { this.em = em; } void adiciona(Produto produto) { // ... } }
  234. @Repository public class ProdutoDao { @PersistenceContext private EntityManager em; @Autowired

    public ProdutoDao(EntityManager em) { this.em = em; } void adiciona(Produto produto) { // ... } }
  235. @Repository public class ProdutoDao { @PersistenceContext private EntityManager em; void

    adiciona(Produto produto) { // ... } }
  236. ProdutoBean ProdutoDao EntityManager ...

  237. Se ele controla ele pode ir mais além…

  238. @Repository public class ProdutoDao { @PersistenceContext private EntityManager em; void

    adiciona(Produto produto) { try { tx.begin(); // inicia transação em.persist(produto); tx.commit(); // comida transação } catch (Exception e) { if (tx != null && tx.isActive()) { tx.rollback(); // desfaz transação } throw new DaoException(e); } finally { if (em != null) { em.close(); } } }
  239. @Repository public class ProdutoDao { @PersistenceContext private EntityManager em; void

    adiciona(Produto produto) { try { tx.begin(); // inicia transação em.persist(produto); tx.commit(); // comida transação } catch (Exception e) { if (tx != null && tx.isActive()) { tx.rollback(); // desfaz transação } throw new DaoException(e); } finally { if (em != null) { em.close(); } } }
  240. @Repository public class ProdutoDao { @PersistenceContext private EntityManager em; void

    adiciona(Produto produto) { try { tx.begin(); // inicia transação em.persist(produto); tx.commit(); // comida transação } catch (Exception e) { if (tx != null && tx.isActive()) { tx.rollback(); // desfaz transação } throw new DaoException(e); } finally { if (em != null) { em.close(); } } }
  241. @Repository public class ProdutoDao { @PersistenceContext private EntityManager em; void

    adiciona(Produto produto) { try { tx.begin(); // inicia transação em.persist(produto); tx.commit(); // comida transação } catch (Exception e) { if (tx != null && tx.isActive()) { tx.rollback(); // desfaz transação } throw new DaoException(e); } finally { if (em != null) { em.close(); } } } É a responsabilidade!
  242. @Repository public class ProdutoDao { @PersistenceContext private EntityManager em; void

    adiciona(Produto produto) { try { tx.begin(); // inicia transação em.persist(produto); tx.commit(); // comida transação } catch (Exception e) { if (tx != null && tx.isActive()) { tx.rollback(); // desfaz transação } throw new DaoException(e); } finally { if (em != null) { em.close(); } } } Controle 
 Transacional
  243. @Repository public class ProdutoDao { @PersistenceContext private EntityManager em; @Transactional

    void adiciona(Produto produto) { try { tx.begin(); // inicia transação em.persist(produto); tx.commit(); // comida transação } catch (Exception e) { if (tx != null && tx.isActive()) { tx.rollback(); // desfaz transação } throw new DaoException(e); } finally { if (em != null) { em.close(); } } }
  244. @Repository public class ProdutoDao { @PersistenceContext private EntityManager em; @Transactional

    void adiciona(Produto produto) { try { tx.begin(); // inicia transação em.persist(produto); tx.commit(); // comida transação } catch (Exception e) { if (tx != null && tx.isActive()) { tx.rollback(); // desfaz transação } throw new DaoException(e); } finally { if (em != null) { em.close(); } } }
  245. @Repository public class ProdutoDao { @PersistenceContext private EntityManager em; @Transactional

    void adiciona(Produto produto) { try { tx.begin(); // inicia transação em.persist(produto); tx.commit(); // comida transação } catch (Exception e) { if (tx != null && tx.isActive()) { tx.rollback(); // desfaz transação } throw new DaoException(e); } finally { if (em != null) { em.close(); } } }
  246. @Repository public class ProdutoDao { @PersistenceContext private EntityManager em; @Transactional

    void adiciona(Produto produto) { em.persist(produto); } }
  247. Qualquer mudança agora se torna mais simples

  248. Concluindo…

  249. Arquitetura tem a ver com: • longo prazo • pessoas

    • frameworks
  250. Arquitetura tem a ver com: • longo prazo • pessoas

    • frameworks
  251. Arquitetura tem a ver com: • longo prazo • pessoas

    • frameworks
  252. Arquitetura tem a ver com: • longo prazo • pessoas

    • frameworks
  253. E lembre-se…

  254. MANUTENÇÃO é a parte mais cara do desenvolvimento

  255. @rponte http://triadworks.com.br/ @triadworks