29
Arquitetando com Buzzwords Fabiano Guizellini Modos Arquiteto de Software na HBSIS @fmodos

Arquitetando com buzzwords

Embed Size (px)

Citation preview

Page 1: Arquitetando com buzzwords

Arquitetando com BuzzwordsFabiano Guizellini Modos

Arquiteto de Software na HBSIS

@fmodos

Page 2: Arquitetando com buzzwords

Por que Arquitetando com Buzzwords?

Page 3: Arquitetando com buzzwords

Contextualização

• Objetivo do sistemaInformatizar mais de 600 planilhas Excel

• Tamanho do sistema atualmente~200 tipos de entidades (tabela)~600 relacionamentos entre as tabelas~3000 colunas (~1500 colunas são fórmulas customizáveis)~1 tela de cadastro por entidade (~200 telas)

• Usuários podem Adicionar, Editar e Excluir registros

Page 4: Arquitetando com buzzwords

Cache

Qual a vantagem?

Acesso rápido a dados e economia de CPU

Qual a desvantagem?

Risco de acessar dados inconsistentes/desatualizados

Page 5: Arquitetando com buzzwords

Gânglio Basal – cache do cérebro

Page 6: Arquitetando com buzzwords

Local Cache Shared Cache

Como lidar com Cache em serviços distribuídos?

Menos concorrênciaCache menorRisco maior de dado desatualizado

Mais fácil para manter consistênciaDifícil identificar quem é o DONO da informação

Page 7: Arquitetando com buzzwords

Onde utilizamos Local Cache?

Fórmula modo edição:

Fórmula traduzida para o usuário:

Page 8: Arquitetando com buzzwords

Como mantemos dados consistentes usando Local Cache?

Publish Subscribe Message Pattern

Fonte: http://www.enterpriseintegrationpatterns.com/patterns/messaging/PublishSubscribeChannel.html

Page 9: Arquitetando com buzzwords

Como utilizamos PubSub para atualizar LocalCache?

Publisher

Subscriber

Subscriber

Page 10: Arquitetando com buzzwords

CRUD -> C(reate) R(ead) U(pdate) D(delete)@Path("/cadeira")public class CadeiraRest {

@InjectCadeiraService cadeiraService;

@POSTpublic Response novaCadeira(CadeiraVO cadeiraVo) {

return Response.status(Status.CREATED).entity(cadeiraService.save(cadeiraVo)).build(); }

@GETpublic Response buscarTodasCadeiras() {

return Response.status(Status.OK).entity(cadeiraService.findAll()).build();}

@PUTpublic Response alterarCadeira(CadeiraVO cadeiraVo) {

return Response.status(Status.OK).entity(cadeiraService.alterarCadeira(cadeiraVo)).build();}

@DELETE@Path("{id}")public Response excluirCadeira(@PathParam("id")Integer id) {

cadeiraService.excluirCadeira(id);return Response.status(204).build();

}}

@Servicepublic class CadeiraService {

@InjectCadeiraRepository cadeiraRepository;

public Cadeira novaCadeira(CadeiraVO cadeiraVo) {return cadeiraRepository.insert(Cadeira.of(cadeiraVo));

}

public List<Cadeira> findAll() {return cadeiraRepository.findAll();

}

public Cadeira alterarCadeira(CadeiraVO cadeiraVo) {return cadeiraRepository.save(Cadeira.of(cadeiraVo));

}

public void excluirCadeira(@PathParam("id")Integer id) {cadeiraRepository.delete(id);

}}

Page 11: Arquitetando com buzzwords

CQRS -> Command Query Resource SegregationA forma que tu grava o dado é diferente da forma que tu lê.

http://www.kennybastani.com/2017/01/building-event-driven-microservices.html

Page 12: Arquitetando com buzzwords

Pontos Ken Pontos Modos

100 50

Source Target Golpe

Ken Modos Haduken

Source Target Golpe Pontos Data/Hora

Ken Modos Haduken -50 03-05-2017 00:47:00

Command

Event

Snapshot

Command -> uma intenção

Event -> algo que ocorreu

Snapshot -> salva o valor atual do

agregado

Page 13: Arquitetando com buzzwords

CQRS - Exemplos de código

• https://github.com/sdaschner/scalable-coffee-shop

• https://github.com/cer/event-sourcing-examples

• https://github.com/gregoryyoung/m-r

Page 14: Arquitetando com buzzwords

To CRUD or to CQRS?

Page 15: Arquitetando com buzzwords

Como utilizamos CQRS

ChangeRequestCommand:

{

modelId : ‘123’,

table : ‘cadeira’,

field : ‘valor’,

value : ‘50’

}

Command

Event Publica

Calcula Fórmulas

Atualiza Valor Fórmulas

Page 16: Arquitetando com buzzwords

Event SourcingLog de todas operações executadas em um aggregate

public void testEventSourcing(){

long fightID = 123;

Fight fight = fightService.getById(fightID);

Fight tempFight = new Fight():

Assert.assertNotEquals(fight.getPointsPlayer1(), tempFight.getPointsPlayer1());

Assert.assertNotEquals(fight.getPointsPlayer2(), tempFight.getPointsPlayer2());

List<FightEvent> fightEvents = fightEventService.getEventsByFightID(fightID);

for(FightEvent event : fightEvents){

tempFight.apply(FightCommand.of(event));

}

Assert.assertEquals(fight.getPointsPlayer1(), tempFight.getPointsPlayer1());

Assert.assertEquals(fight.getPointsPlayer2(), tempFight.getPointsPlayer2());

}

Page 17: Arquitetando com buzzwords

SQL NOSQL

Page 18: Arquitetando com buzzwords

Diagrama Classe Diagrama Relacional Diagrama NoSQL

-Deve permitir cadastro de Dish informando nome, descrição e lista de ingredientes. -Deve permitir que usuários logados através do email e senha insiram comentários em um Dish.

Estudo de Caso

Page 19: Arquitetando com buzzwords

Consulta de Dados

SQL NoSQL

select d.name, d.description from dish d where id=1

select i.name from ingredient i where i.dish_id=1

select c.text, u.nickname, u.name from comment c, useru where c.user_id = u.id and c.dish_id = 1

db.getCollection(‘Dish’).find({_id : 1})

Page 20: Arquitetando com buzzwords

Inconsistência de DadosO que acontece se o usuário “JOSÉ” atualizar o nickname para “JOÃO”?

SQL NoSQL

update user set nickname = ‘JOÃO’ where id=1 db.getCollection(‘User’).update({_id : 1}, {$set : {nickname : ‘JOÃO’}})

{name: “Dish Test”

ingredients : [“arroz”],

comments : Array[

{

text : ‘Comentario do José’

user : {

nickname : ‘JOSÉ’

}

]

Como resolvemos?

-Utilizando o Visitor Design Pattern que veremos nos próximos capítulos

Page 21: Arquitetando com buzzwords

Concorrência de alteração

SQL NoSQL

public void addComment(Dish dish, User user, String text){Comment comment = Comment.of(dish, user, text);commentRepository.insert(dish);

}

public void addComment(Dish dish, User user, String text){Comment comment = Comment.of(user, text);

dish.addComment(comment);dishRepository.save(dish);

}

• Syncronized??? Please nosyncronized(dish.getId(){

Comment comment = Comment.of(user, text);dish.addComment(comment);dishRepository.save(dish);

}

Page 22: Arquitetando com buzzwords

• Codigo com update do mongodbmongoTemplate.updateFirst(queryId(dish.getId()), new Update().addToSet(comment), “Dish”)

• Fila de processamento

Como resolvemos?

-Devido uma regra de negócio toda alteração somente pode ser atualizada na planilha em datas pré definidas, dessa forma possuímos serviços agendados que atualizam os Snapshots(Planilha) de forma síncrona.

Concorrência de alteração

Page 23: Arquitetando com buzzwords

Controle Transação MongoDB???

“Aquilo que você conhece não pode te machucar” – Livro: A lógica do cisne negro

Como resolvemos?

-Agrupamos todas as informações em um registro

-Processos batch, temos um controle de execução que gera log de cada step e consegue continuar de onde parou

Page 24: Arquitetando com buzzwords

Como alterar registros de um agregado não estruturado?

Visitor Design Pattern

class ApplyChangeVisitor implements Visitor{ChangeRequestCommand change = ...

public void visit(Entidade e){if(e.getId().equals(change.getModelId()){

e.setFieldValue(change.getField(), change.getValue());}

}}

class abstract Entidade {public void accept(Visitor visitor){

visitor.visit(this);//busca associações e invoca accept

refEntidade.accept(visitor);}

}

Entidade planilha = ....ChangeRequestCommand change = ....planilha.accept(new ApplyChangeVisitor(change));

Page 25: Arquitetando com buzzwords

Editing/Publishing Pattern

https://martinfowler.com/articles/two-stack-cms/#edit-publish

Page 26: Arquitetando com buzzwords

Como utilizamos Editing/Publishing

• Criamos um conceito de View por cada usuário

• Comandos de alteração são armazenados no Editing da View do usuário

• Publishing é a versão aprovada compartilhada por todos usuários

View Usuário = Comandos Editing + Versão Publishing

Page 27: Arquitetando com buzzwords

"My feeling is that when we prepare a program, it can be like composing poetry or music; as Andrei Ershov has said [9], programming can give us both intellectual and emotional satisfaction, because it is a real achievement to master complexity and to establish a system of consistent rules." Computer Programming as an Art Donald Knuth, 1974

Page 28: Arquitetando com buzzwords

Obrigado!@fmodos

Page 29: Arquitetando com buzzwords

Referências

• http://www.kennybastani.com/2017/01/building-event-driven-microservices.html

• http://cqrs.nu/Faq

• http://www.enterpriseintegrationpatterns.com/ramblings/eip1_examples_updated.html

• https://martinfowler.com/articles/201701-event-driven.html

• https://pt.wikipedia.org/wiki/Visitor_Pattern

• https://twitter.com/gregyoung

• https://docs.mongodb.com/manual/

• https://martinfowler.com/articles/two-stack-cms/#edit-publish