Post on 15-Jan-2015
description
1
O impacto do designna sua arquitetura
Paulo Silveirapaulo.silveira@caelum.com.br @paulo_caelum
de programador a designer a arquiteto?
Martin Fowler, Who needs an Architect?http://bit.ly/fowlerArchitect
Então você quer ser um arquiteto Java?http://bit.ly/arquitetoJava
Arquitetura
#1
Alguns padrões são arquiteturais, outros são de design, ajudando a arquitetura... eu não separo os dois já que o que
é arquitetural ou não é subjetivo.
Martin Fowler, Patterns of Enterprise Application Architecture
Design
#2
Você deve enfrentar suas batalhas de design no nível macro-arquitetural e no campo das instâncias.
Craig Larman, The importance of being Closed
Implementação
#3
...de manhã, o arquiteto programa com os desenvolvedores...
Martin Fowler, Who needs an Architect?
Afinal, pra você, o que é arquitetura?
Arquitetura são os principais elementos
do sistema, as peças que são difíceis de mudar.
Ralph Johnson (do GoF) e Martin FowlerWho needs an Architect?
Arquitetura são as decisões que gostaríamos de ter tomado no começo
do projeto.
Arquitetura são os principais elementos
do sistema, as peças que são difíceis de mudar.
“Martin Fowler não sabe nada”
meu artigo recebeu vários comentários, inclusive essas críticas:
“Você é poético, não sabe nada”
“Martin Fowler não sabe nada”
meu artigo recebeu vários comentários, inclusive essas críticas:
“Você é poético, não sabe nada”
“Martin Fowler não sabe nada”
“Ralph Johnson não sabe nada”
meu artigo recebeu vários comentários, inclusive essas críticas:
“Você é poético, não sabe nada”
“Martin Fowler não sabe nada”
“Ralph Johnson não sabe nada”
“CMU-SEI são professores, não sabem nada”
meu artigo recebeu vários comentários, inclusive essas críticas:
Resolvi então também dar minha opinião pessoal
Arquitetura é toda decisão que impactam em grandes trade-offs e que podem ou não
serem difíceis de mudar.
Resolvi então também dar minha opinião pessoal
Arquitetura é toda decisão que impactam em grandes trade-offs e que podem ou não
serem difíceis de mudar.
E ela pode ser evolutivaLast Responsible Moment
Resolvi então também dar minha opinião pessoal
E como tornar essas decisões “mais” possíveis
de mudar?
Arquiteturax
Arquitetura Java
Arquiteturax
Arquitetura Java
...você precisa de pelo menos um arquiteto com enorme experiência prática na plataforma
escolhida.
Joel Spoelsky, Language Wars
ImplementaçãoDesign
Arquitetura
Neal Gafter, Evolutionary Architecture
PIRÂMIDE?
ImplementaçãoDesign
Arquitetura
Neal Gafter, Evolutionary Architecture
Não acredito que implementação e design tenham “menos” importância
PIRÂMIDE?
Arquitetura
Design
Implementação
Design
Arquitetura
Implementação
Design
Arquitetura
Implementação
Dois exemplos dedesign facilitando a arquitetura
Site da Caelum
repository.adiciona(noticia);
qual é a implementação?
1. Hibernatepublic class NoticiaDao implements NoticiaRepository {
private final Session session;
public NoticiaDao(Session session) { this.session = session; } public void adiciona(Noticia noticia) { session.save(noticia); } @SuppressWarnings("unchecked") public List<Noticia> todasNoticias() { return session.createCriteria(Noticia.class) .addOrder(Order.desc("data")).list(); }
2. JPA/BigTable o que mudamos quandomigramos para o cloud
2. JPA/BigTablepublic class NoticiaDao implements NoticiaRepository {
private final EntityManager manager;
public NoticiaDao(EntityManager manager) { this.manager = manager; } public void adiciona(Noticia noticia) { manager.persist(noticia); } @SuppressWarnings("unchecked") public List<Noticia> todasNoticias() { return manager.createQuery("select n from Noticia n")).getResultList(); }
o que mudamos quandomigramos para o cloud
3. Objectify
3. Objectifypublic class NoticiaDao implements NoticiaRepository { private final Objectify objectify; public NoticiaDao(Objectify objectify) { this.objectify = objectify; } public void adiciona(Noticia noticia) { objectify.put(noticia); }
public List<Noticia> noticiasVisiveis() { return objectify.query(Noticia.class).filter("ordem >",0).order("ordem").list(); }
3. Objectifypublic class NoticiaDao implements NoticiaRepository { private final Objectify objectify; public NoticiaDao(Objectify objectify) { this.objectify = objectify; } public void adiciona(Noticia noticia) { objectify.put(noticia); }
public List<Noticia> noticiasVisiveis() { return objectify.query(Noticia.class).filter("ordem >",0).order("ordem").list(); }
lento e não muito disponível
4. Objectify + Memcache
4. Objectify + Memcachepublic class NoticiaDao implements NoticiaRepository { private final Cache cache; private final Objectify objectify; public NoticiaDao(Objectify objectify, Cache cache) { this.objectify = objectify; this.cache = cache; } public void adiciona(Noticia noticia) { objectify.put(noticia); cache.remove(CACHE_ROOT, NOTICIAS_VISIVEIS); } public List<Noticia> noticiasVisiveis() { List<Noticia> noticias = cache.get(CACHE_ROOT, NOTICIAS_VISIVEIS); if (cached == null) { noticias = objectify.query(Noticia.class).filter("ordem >",0).order("ordem").list(); cache.put(CACHE_ROOT, NOTICIAS_VISIVEIS, noticias); } return noticias; }
Relembrando IoC e DI
NoticiaRepository repository = new NoticiaRepository(???); repository.adiciona(noticia);
Relembrando IoC e DI
NoticiaRepository repository = new NoticiaRepository(???); repository.adiciona(noticia);
Ter feito o design com IoC e DI facilitoumudanças arquiteturais:
hibernate -> JPA no Cloud -> Objectify -> Memcached
WebChat Ajax
Mudando de Comet com long pollingpara Comet streaming com Servlets 3 AsyncContext
long polling
public class Agent { // ... private final Queue<Update> updates =
new ConcurrentLinkedQueue<Update>(); public Agent(RoomFactory roomFactory, ClientQueue queue, Tenant tenant) { this.roomFactory = roomFactory; this.queue = queue; this.tenant = tenant; } public void addUpdate(Update update) { updates.add(update); }
public Update updates() { createAndRemoveRooms(); return updates.poll(); }
como fazer blocante?
collections sem DI?
streaming segurando conexão
public class Agent { // ... private final BlockingQueue<Update> updates =
new LinkedBlockingQueue<Update>(); public Agent(RoomFactory roomFactory, ClientQueue queue, Tenant tenant) { this.roomFactory = roomFactory; this.queue = queue; this.tenant = tenant; } public void addUpdate(Update update) { updates.add(update); }
public Update updates() { createAndRemoveRooms(); return updates.take(); }
thread per request no comet = bad
streaming não blocante
private BlockingQueue<Update> updates = new LinkedBlockingQueue<Update>();// ...
while (true) { final Update update = updates.take();
for (final AsyncContext ctx : clients.get(update.getRoom())) {
PrintWriter writer = ctx.getResponse() .getWriter(); writer.println(update.getMessage()); writer.flush();
} }
para isso a fila de eventos precisaria ser única
public class Agent { // ... private final Queue<Update> updates;
Agent(RoomFactory roomFactory, ClientQueue queue, Tenant tenantQueue<Update> updates) {
this.roomFactory = roomFactory; this.queue = queue; this.tenant = tenant; this.updates = updates; }
public void addUpdate(Update update) { updates.add(update); }
public Update updates() { createAndRemoveRooms(); return updates.take(); }
queue tb por DI e dá para voltarpro long polling facilmente!
Exemplo bônus:
Nick Kallen, arquiteto do Twitter
no #qconsp com #Scala
FIFO/LIFOblocante/não blocante
usando IoC+DI
Nos 3 exemplos:
• IoC facilitou evolução arquitetural
• possibilita decisão no “last responsible moment”
• e com isso podemos trocar trade-offs
• código, design e arquitetura muito próximos
para obter isso (em JAVA!):
Boas práticas de OO (construtores)
para obter isso (em JAVA!):
IoC e DI (mesmo sem framework)
Boas práticas de OO (construtores)
para obter isso (em JAVA!):
Testes te “forçam” a DI
IoC e DI (mesmo sem framework)
Boas práticas de OO (construtores)
para obter isso (em JAVA!):
Testes te “forçam” a DI
IoC e DI (mesmo sem framework)
Boas práticas de OO (construtores)
Desacoplamento (generalização)
para obter isso (em JAVA!):
Obrigado!
Visite:www.tectura.com.br
www.agendatech.com.brwww.ProgramadorPoliglota.com.br