Negócio Escrito em Código
O Caminho do Negócio ao Código
Fonte e Vice-versa
Douglas Siviotti Outubro
2018
Sobre esta Apresentação
2/59
1. Conteúdo: Expressividade no Código Fonte Refletindo o Negócio
2. Área/Foco: Engenharia de Software, Desenvolvimento Ágil
3. Público alvo: Gestores (parte 1) e Desenvolvedores
4. Conteúdo relacionado: Clean Code, Autodocumentação, DDD, SOLID, GRASP,
“DRY”, “Tell, don’t ask”, Lei de Demeter
Organização (+- 40 minutos)
Parte 1 – O Novo Caminho do Negócio ao Código (Ágil)
Parte 2 – O Caminho de Volta do Código ao Negócio
Material de apoio desta apresentação:
https://github.com/artesoftware/conteudo
Título do Slide (Arial 18)
3/59
O Novo Caminho doO Novo Caminho do
Negócio ao CódigoNegócio ao Código
Parte 1
Título do Slide (Arial 18)
4/59
O que éO que é
CódigoCódigo
Fonte?Fonte?
Título do Slide (Arial 18)
5/59
O que éO que é
Negócio?Negócio?
Negócio = Negação do Ócio = Atividade ou Ocupação
6/59
NEGÓCIONEGÓCIO
Objetivo, Meta, Finalidade, Dever, Missão, TarefaObjetivo, Meta, Finalidade, Dever, Missão, Tarefa
ProblemaProblema SoluçãoSolução
Enfrenta
Requer
Viabiliza
Caminho Genérico do Negócio até o Código
7/59
NEGÓCIONEGÓCIONEGÓCIONEGÓCIO
CÓDIGOCÓDIGOCÓDIGOCÓDIGO
ProblemaProblema
SoluçãoSolução
Caminho Tradicional do Negócio até o Código (Artefatos)
8/59
NEGÓCIONEGÓCIONEGÓCIONEGÓCIO
CÓDIGOCÓDIGOCÓDIGOCÓDIGOProjetoProjeto
RequisitoRequisito
AnáliseAnálise
Compras online
Vários Produtos
Pedido {
List<Item> itens
}
Item {
Produto produto
}
Caminho Tradicional do Negócio até o Código (Papéis)
9/59
NEGÓCIONEGÓCIONEGÓCIONEGÓCIO
CÓDIGOCÓDIGOCÓDIGOCÓDIGOProjetoProjeto
Analista / AD
Analista de
Requisitos
Programador
Cliente
Arquiteto / DBA
RequisitoRequisito
AnáliseAnálise
Caminho Ágil do Negócio até o Código
10/59
Cliente
Desenvolvedores
+ Interação
- processo e ferramentas
+ Software
Funcionando
- documentação abrangente
NEGÓCIONEGÓCIONEGÓCIONEGÓCIO
CÓDIGOCÓDIGOCÓDIGOCÓDIGO
Quem?
11/59
+ Time
- papéis fixos
- intermediários
Título do Slide (Arial 18)
12/59
Inception / Descoberta
Backlog / Planning Poker
História de Usuário
Critérios de Aceite
Simple Design / DDD
Clean Code
Padrões de Codificação
Integração Contínua
Refatoração / Revisão
Testes Unitários / TDD
Comunidades de Práticas
+ Práticas
- artefatos
Como?
Título do Slide (Arial 18)
13/59
+ Leve
- prescritivo
+ Entregas
- tempo e surpresas ruins
Título do Slide (Arial 18)
14/59
+ Entregas
- tempo e surpresas ruins
+ Leve
- prescritivo
+ Manutenção
Refatoração como parte do processo
Contrapartida
+ eficiência na definição do problema
+ maturidade e multidisciplinaridade
+ excelência técnica
+ tratamento da dívida técnica (refatoração)
+ automação de teste, build e entrega
+ controle de qualidade
Contrapartida Fundamental do Novo Caminho
15/59
+ Manutenção
o código de negócio é idiossincrático
novos devs. precisam ler e entender
é o que mais muda ao longo do tempo
O novo caminho requer um código que
possa ser lido e ter o negócio entendido
por outros além dos que o escreveram
agora, só rodar não basta!
Parte 2
O Caminho de Volta doO Caminho de Volta do
Código ao NegócioCódigo ao Negócio
Características do Código que Expressa Negócio
17/59
2 3 4 5
Independência1
2 Isolamento
3 Significado
4 Modularização
5 Simplicidade
1
Solução
Código
Problema
Negócio
Características do Código que Expressa Negócio
18/59
1. Independência de Artefatos Externos
O código fonte é a fonte mais confiável
Quando possível, o código fonte e não outro artefato é a
própria especificação do problema na sua forma definitiva
1 2 3 4 5
A FonteA Fonte
Documentação Ativa
20/59
1 2 3 4 5
documentação ativa é um elemento de requisito que além de
conter uma descrição compreensível de uma especificação de
software também é um artefato de código sintaticamente válido na
linguagem de origem do sistema especificado
100101
código
fonte
Formato
Amigável Cliente
Transformação
ou cópia
Documentação Ativa
21/59
1 2 3 4 5
● Mensagens do Sistema
● Perfis / Roles de Usuário
● ID de Regra de Negócio
● Constantes do Negócio
● Estados e Transições
● Layout de Integrações
Problema
Rastreabilidade
Vertical de Código
O quanto antes
melhor
Esquema de Mensagens/Const/Roles com Documentação Ativa
22/59
1 2 3 4 5
constantes
ABC=”ER001”
DEF=”ER002”
XPTO=”ER003”
properties
ER001=”abc”
ER002=”def”
ER003=”xyz”
cópia Solução
ALM
Cliente
funcionalidade
Msg =
load (XPTO)
Erro: xyz
Esquema de Regra de Negócio com Documentação Ativa
23/59
1 2 3 4 5
Anotação de
Rastreio
@Rule(RN)
Enum de Regras
RNG001 (“RN01”)
RNG001 (“RN02”)
RNG001 (“RN03”)
cópia Solução
ALM
Cliente
funcionalidade
@Rule(RNG001)
Erro em:
RNG001
Verificação de
Regras de Negócio
- Ausência
- Duplicidade
Especificações de Layouts de Integrações
24/59
1 2 3 4 5
Ponto A Ponto BXSDPPL
Estados e Transições
25/59
1 2 3 4 5
Descrevem bem o problema real
Viabilizam processos assíncronos
Encapsulam questões de negócio
Marcos importantes dos eventos
Centralizam regras de negócio
Enum Inteligente
Concentra as regras sobre
as transições dos estados
podeTransitarPara(E): boolean
1 2 3 4 5class Pedido(val numero: String, val criacao: LocalDate, val conclusao: LocalDate?) {
var estado = Estado.ABERTO
set (value) {
if (!estado.podeTransitarPara(value)) {
throw IllegalArgumentException("Transição não permitida de $estado para $value")
}
field = value
}
}
enum class Estado (val id: Int, val descricao: String,
val encerrado: Boolean){
ABERTO(1, "Aberto", false),
FINALIZADO(2, "Finalizado", false),
PAGO(3, "Pago", false),
EM_TRANSPORTE(4, "Em Transporte", false),
ENTREGUE(5, "Entregue", true),
CANCELADO(6, "Cancelado", true);
fun isEncerrado(): Boolean{
return encerrado
}
fun podeTransitarPara(proximo: Estado): Boolean{
// TODO implementar Finalizado -> Aberto
return id == proximo.id - 1
}
}
@Test fun devePassarDeAbertoParaFinalizado() {
val pedido = Pedido("123", LocalDate.now(), null)
assertTrue(pedido.estado == Estado.ABERTO);
pedido.estado = Estado.FINALIZADO
assertTrue(pedido.estado == Estado.FINALIZADO)
}
@Test(expected=IllegalArgumentException::class)
fun deveDarErroAoPassarDeAbertoParaEntregue() {
val pedido = Pedido("123", LocalDate.now(), null)
pedido.estado = Estado.ENTREGUE
}
Características do Código que Expressa Negócio
27/59
2. Isolamento
O requisito está no código, mas muito código não vem do requisito
O processo de refinamento Problema/Solução caminha por
muitas tecnologias, processos e paradigmas
1 2 3 4 5
Como Água e ÓleoComo Água e Óleo
Abordagens para Isolar o Negócio – DDD, MVC e Camadas
29/59
Modelo
Controle
Visão
Controle e Negócio
Apresentação / Serviço
Persistência
Domain
1 2 3 4 5
Empacotamento Modular de Aplicação Monolítica
30/59
1 2 3 4 5
Problema
Solução
Negócio Infraestrutura
spec
infra
core
service
Cliente
Tecnologia
Dependência
service
core infraspec
Service 1
Empacotamento de Microserviços
31/59
1 2 3 4 5
Infra 1Domain 1
Service 2
Infra 2Domain 2
Service 3
Infra 3Domain 3
Commons
InfraSpec
Abordagens para Isolar Infraestrutura e Código de Terceiros
32/59
1 2 3 4 5
Terceiros Infraestrutura
Infraestrutura
Aplicação
API de Terceiros
public class Client {
@Inject
private JsonParser jsonParser;
}
Características do Código que Expressa Negócio
33/59
3. Significado
Linguagem de programação não precisa de tradução
O código deve ser escrito para ser lido por outra pessoa além
de quem o escreveu: programação é comunicação
1 32 4 5
Mundo das IdeiasMundo das Ideias
Linguagem de Negócio - “Comunique, não Codifique”
35/59
1 32 4 5
Cliente
Vocabulário
de Negócio
Problema
Desenvolvedor 1
Desenvolvedor 2Problema
Solução
100101
código
100101
código
Linguagem de Onipresente
36/59
1 32 4 5
Cliente
Vocabulário
de Negócio
Problema
Desenvolvedor 1
Desenvolvedor 2Problema
Solução
100101
código
100101
código
Linguagem
Ubíqua
Todos usando
Mesmo vocabulário
Mesmos conceitos
Ruído na Comunicação: Nomes Ruins
37/59
1 32 4 5
Notação
Húngara e
seu bando
strNome = “Fulano”
intIdade = 15
IParser, TipoEnum
Não use “notação húngara” ou prefixação por tipos
Interfaces recebem os nomes do conceito: “Parser”
(BasicParser, GenericParser, ParserImpl etc)
Camel case “sem corcova”: CNPJDAO, SPEDREST
O tamanho de um nome é proporcional ao seu escopo
i, j e k somente em loops
Boa Comunicação: Nomes Significativos
38/59
1 32 4 5
Nomes a partir do domínio do problema (Pedido, Item etc)
Nomes a partir do domínio da solução (Controller, Delegate, DAO)
Classes = Substantivos, Métodos = Verbos
Nomes pronunciáveis e passíveis de busca
Comentários: Deixa eu Desenhar...
39/59
1 32 4 5
Regra Geral: Comentários são a última opção
Usamos comentários quando não conseguimos nos expressar no código
Bons Comentários
● Questões legais (copyright)
● TODO “de verdade”
● JavaDoc em APIs públicas
● Destaque de algo relevante
● Alerta sobre consequências
Maus Comentários
● Código Morto
● JavaDoc em código não público
● Ao lado de chave de fecho
● Controle de versão
● Redundantes ou ruidosos
Padrões de Codificação
Padrão Ruim é Melhor que Nenhum Padrão
40/59
1 32 4 5
Cliente
Vocabulário
de Negócio
Problema
Desenvolvedor 1
Desenvolvedor 2Problema
Solução
100101
código
100101
código
Testes de Unidade
41/59
1 32 4 5
class GsonJsonParserTest {
val parser = GsonJsonParser()
val json = "{"name":"Ladybug","age":15}"
val person = Person("Ladybug", 15)
@Test
fun deveConverterObjetoParaJson() {
val parsed = parser.toJson(person)
assertEquals(json, parsed)
}
@Test
fun deveConverterJsonParaObjeto() {
val parsed = parser.fromJson(json, Person::class.java)
assertEquals(person, parsed)
}
}
De quem é este teste?
O que ele testa?
Características do Código que Expressa Negócio
42/59
4. Modularização
Quantos livros nunca lerei?
Um sistema é um conjunto de partes que interagem por um
objetivo comum. Cada parte faz somente a sua parte.
1 42 3 5
EncanamentoEncanamento
https://www.google.com.au/about/datacenters/gallery/images/_2000/DLS_013.jpg
Qual Figura Representa a Solução de Busca do Google?
44/59
1 42 3 5
(A)
(B) COOBOL
Divisão de Negócio: Contexto Delimitado (Bounded Context)
45/59
1 42 3 5
https://martinfowler.com/bliki/BoundedContext.html
Abstrações
46/59
1 42 3 5
Version
GenericCustomer
Person
Pipeline
Version
Princípio DRY (Don’t Repeat Yourself - “Não se Repita”)
47/59
1 42 3 5
Regra de Negócio id = RNG001
Número de sócios <= 5
MAX_SOCIOS = 5Parâmetro de Negócio:
Máximo de Sócios = 5
@Rule(RNG001)
IF (socios.count > MAX_SOCIOS)
msg = format(ER-001,MAX_SOCIOS)
New BusinessException (msg)
ER-001=”Proibido mais que
{%} sócios”
Mensagem do Sistema(EMS):
ER-001 = “Proibido mais
que 5 sócios”
Não faça a mesma coisa em dois lugares
ProblemaProblema SoluçãoSolução
Princípio Single Responsability (Responsabilidade Única)
48/59
1 42 3 5
Não faça duas coisas no mesmo lugar
“Uma classe só deveria ter um único motivo para mudar”
Refatoração
Indireção (Delegação)
50/59
1 42 3 5
Indireção Indireção
Calculo de Frete Busca de Endereço
GRASP – Padrões para atribuição de responsabilidades em um projeto orientado a objetos:
Padrões Básicos: Information Expert, Creator , High Cohesion, Low Coupling, Controller
Padrões Avançados: Polymorphism, Pure Fabrication, Indirection, Protected Variations.
Efetuar Pedido
Características do Código que Expressa Negócio
51/59
5. Simplicidade
Menos é mais*
“A simplicidade é o último grau de sofisticação” Leonardo Da Vinci
Simples não é simplório!
1 52 3 4
* Ludwig Mies van der Rohe - Arquiteto
Título do Slide (Arial 18)
52/59
ExpressividadeExpressividade
Quatro Regras da Simplicidade de Kent Beck
53/59
1 52 3 4
● Todos os testes passam
● Claro, Expressivo e Consistente
● Nenhuma duplicação de
comportamento ou configuração
● Mínimo possível de métodos,
classes e módulos
http://wiki.c2.com/?XpSimplicityRules
Quatro Regras da Simplicidade de Kent Beck (por Martin Fowler)
54/59
1 52 3 4
● Os testes passam
● Revela intenção
● Nenhuma duplicação
● Mínimo de elementos
https://martinfowler.com/bliki/BeckDesignRules.html
Acoplamento e a Lei de Demeter
55/59
1 52 3 4
val pedido = Pedido("123", LocalDate.now(), null)
if (pedido.estado == Estado.CANCELADO || pedido.estado == Estado.ENTREGUE){
// faça algo se estiver encerrado
}
if (pedido.estado.isEncerrado()){
// faça algo se estiver encerrado
}
if (pedido.isEncerrado()){
// faça algo se estiver encerrado
}
1
2
3
Acoplado a 2 classes e 1 lista
Acoplado a 2 classes
Acoplado a 1 classe
intenção:
Fazer algo se o pedido estiver encerrado
23
isEncerrado()
1
Encapsulamento
56/59
1 52 3 4
https://martinfowler.com/bliki/TellDontAsk.html
class Pedido(val numero: String, val criacao: LocalDate,
val conclusao: LocalDate?) {
var estado = Estado.ABERTO
set (value) {
if (!estado.podeTransitarPara(value)) {
throw IllegalArgumentException
("Transição não permitida de $estado para $value")
}
field = value
}
fun isEncerrado(): Boolean{
return estado.isEncerrado() || isAntigoDemais()
}
fun isAntigoDemais()= LocalDate.now().isAfter(criacao.plusYears(1))
}
val pedido = Pedido("123", LocalDate.now(), null)
if (pedido.estado == Estado.CANCELADO || pedido.estado == Estado.ENTREGUE){
// faça algo se estiver encerrado
}
if (pedido.estado.isEncerrado()){
// faça algo se estiver encerrado
}
if (pedido.isEncerrado()){
// faça algo se estiver encerrado
}
1
2
3
3
Princípio “Tell, don’t ask”
+ simples
Independência1 Código feito como especificação do problema
2 Isolamento Código desenhado para destacar o negócio
4 Modularização Código bem dividido em partes especializadas
3 Significado Código escrito em uma linguagem onipresente
5 Simplicidade Código cuidadosamente otimizado para leitura
Referência
58/59
EVANS, E. Domain-Driven Design – Atacando as complexidades no coração do software.
2a edição, Rio de Janeiro, Alta Books, 2010.
FOWLER, Martin. BeckDesignRules, https://martinfowler.com/bliki/BeckDesignRules.html
FOWLER, Martin. BoundedContext, https://martinfowler.com/bliki/BoundedContext.html
FOWLER, Martin. TellDontAsk, https://martinfowler.com/bliki/TellDontAsk.html
HUNT, Andrew; THOMAS, David, O Programador Pragmático, Bookman, 2010
MARTIN, Robert, O Codificador Limpo, Alta Books, Rio de Janeiro 2012
MARTIN, Robert, Código Limpo, Alta Books, Rio de Janeiro 2011
Programação Funcional X Orientação a Objetos
59/59
1 42 3 5
Orientado a
Objetos
para encerrar...
Obrigado!
Douglas Siviotti
douglas.siviotti@gmail.com
github.com/siviotti
Funcional

Negócio Escrito em Código

  • 1.
    Negócio Escrito emCódigo O Caminho do Negócio ao Código Fonte e Vice-versa Douglas Siviotti Outubro 2018
  • 2.
    Sobre esta Apresentação 2/59 1.Conteúdo: Expressividade no Código Fonte Refletindo o Negócio 2. Área/Foco: Engenharia de Software, Desenvolvimento Ágil 3. Público alvo: Gestores (parte 1) e Desenvolvedores 4. Conteúdo relacionado: Clean Code, Autodocumentação, DDD, SOLID, GRASP, “DRY”, “Tell, don’t ask”, Lei de Demeter Organização (+- 40 minutos) Parte 1 – O Novo Caminho do Negócio ao Código (Ágil) Parte 2 – O Caminho de Volta do Código ao Negócio Material de apoio desta apresentação: https://github.com/artesoftware/conteudo
  • 3.
    Título do Slide(Arial 18) 3/59 O Novo Caminho doO Novo Caminho do Negócio ao CódigoNegócio ao Código Parte 1
  • 4.
    Título do Slide(Arial 18) 4/59 O que éO que é CódigoCódigo Fonte?Fonte?
  • 5.
    Título do Slide(Arial 18) 5/59 O que éO que é Negócio?Negócio?
  • 6.
    Negócio = Negaçãodo Ócio = Atividade ou Ocupação 6/59 NEGÓCIONEGÓCIO Objetivo, Meta, Finalidade, Dever, Missão, TarefaObjetivo, Meta, Finalidade, Dever, Missão, Tarefa ProblemaProblema SoluçãoSolução Enfrenta Requer Viabiliza
  • 7.
    Caminho Genérico doNegócio até o Código 7/59 NEGÓCIONEGÓCIONEGÓCIONEGÓCIO CÓDIGOCÓDIGOCÓDIGOCÓDIGO ProblemaProblema SoluçãoSolução
  • 8.
    Caminho Tradicional doNegócio até o Código (Artefatos) 8/59 NEGÓCIONEGÓCIONEGÓCIONEGÓCIO CÓDIGOCÓDIGOCÓDIGOCÓDIGOProjetoProjeto RequisitoRequisito AnáliseAnálise Compras online Vários Produtos Pedido { List<Item> itens } Item { Produto produto }
  • 9.
    Caminho Tradicional doNegócio até o Código (Papéis) 9/59 NEGÓCIONEGÓCIONEGÓCIONEGÓCIO CÓDIGOCÓDIGOCÓDIGOCÓDIGOProjetoProjeto Analista / AD Analista de Requisitos Programador Cliente Arquiteto / DBA RequisitoRequisito AnáliseAnálise
  • 10.
    Caminho Ágil doNegócio até o Código 10/59 Cliente Desenvolvedores + Interação - processo e ferramentas + Software Funcionando - documentação abrangente NEGÓCIONEGÓCIONEGÓCIONEGÓCIO CÓDIGOCÓDIGOCÓDIGOCÓDIGO
  • 11.
    Quem? 11/59 + Time - papéisfixos - intermediários
  • 12.
    Título do Slide(Arial 18) 12/59 Inception / Descoberta Backlog / Planning Poker História de Usuário Critérios de Aceite Simple Design / DDD Clean Code Padrões de Codificação Integração Contínua Refatoração / Revisão Testes Unitários / TDD Comunidades de Práticas + Práticas - artefatos Como?
  • 13.
    Título do Slide(Arial 18) 13/59 + Leve - prescritivo + Entregas - tempo e surpresas ruins
  • 14.
    Título do Slide(Arial 18) 14/59 + Entregas - tempo e surpresas ruins + Leve - prescritivo + Manutenção Refatoração como parte do processo Contrapartida + eficiência na definição do problema + maturidade e multidisciplinaridade + excelência técnica + tratamento da dívida técnica (refatoração) + automação de teste, build e entrega + controle de qualidade
  • 15.
    Contrapartida Fundamental doNovo Caminho 15/59 + Manutenção o código de negócio é idiossincrático novos devs. precisam ler e entender é o que mais muda ao longo do tempo O novo caminho requer um código que possa ser lido e ter o negócio entendido por outros além dos que o escreveram agora, só rodar não basta!
  • 16.
    Parte 2 O Caminhode Volta doO Caminho de Volta do Código ao NegócioCódigo ao Negócio
  • 17.
    Características do Códigoque Expressa Negócio 17/59 2 3 4 5 Independência1 2 Isolamento 3 Significado 4 Modularização 5 Simplicidade 1 Solução Código Problema Negócio
  • 18.
    Características do Códigoque Expressa Negócio 18/59 1. Independência de Artefatos Externos O código fonte é a fonte mais confiável Quando possível, o código fonte e não outro artefato é a própria especificação do problema na sua forma definitiva 1 2 3 4 5
  • 19.
  • 20.
    Documentação Ativa 20/59 1 23 4 5 documentação ativa é um elemento de requisito que além de conter uma descrição compreensível de uma especificação de software também é um artefato de código sintaticamente válido na linguagem de origem do sistema especificado 100101 código fonte Formato Amigável Cliente Transformação ou cópia
  • 21.
    Documentação Ativa 21/59 1 23 4 5 ● Mensagens do Sistema ● Perfis / Roles de Usuário ● ID de Regra de Negócio ● Constantes do Negócio ● Estados e Transições ● Layout de Integrações Problema Rastreabilidade Vertical de Código O quanto antes melhor
  • 22.
    Esquema de Mensagens/Const/Rolescom Documentação Ativa 22/59 1 2 3 4 5 constantes ABC=”ER001” DEF=”ER002” XPTO=”ER003” properties ER001=”abc” ER002=”def” ER003=”xyz” cópia Solução ALM Cliente funcionalidade Msg = load (XPTO) Erro: xyz
  • 23.
    Esquema de Regrade Negócio com Documentação Ativa 23/59 1 2 3 4 5 Anotação de Rastreio @Rule(RN) Enum de Regras RNG001 (“RN01”) RNG001 (“RN02”) RNG001 (“RN03”) cópia Solução ALM Cliente funcionalidade @Rule(RNG001) Erro em: RNG001 Verificação de Regras de Negócio - Ausência - Duplicidade
  • 24.
    Especificações de Layoutsde Integrações 24/59 1 2 3 4 5 Ponto A Ponto BXSDPPL
  • 25.
    Estados e Transições 25/59 12 3 4 5 Descrevem bem o problema real Viabilizam processos assíncronos Encapsulam questões de negócio Marcos importantes dos eventos Centralizam regras de negócio Enum Inteligente Concentra as regras sobre as transições dos estados podeTransitarPara(E): boolean
  • 26.
    1 2 34 5class Pedido(val numero: String, val criacao: LocalDate, val conclusao: LocalDate?) { var estado = Estado.ABERTO set (value) { if (!estado.podeTransitarPara(value)) { throw IllegalArgumentException("Transição não permitida de $estado para $value") } field = value } } enum class Estado (val id: Int, val descricao: String, val encerrado: Boolean){ ABERTO(1, "Aberto", false), FINALIZADO(2, "Finalizado", false), PAGO(3, "Pago", false), EM_TRANSPORTE(4, "Em Transporte", false), ENTREGUE(5, "Entregue", true), CANCELADO(6, "Cancelado", true); fun isEncerrado(): Boolean{ return encerrado } fun podeTransitarPara(proximo: Estado): Boolean{ // TODO implementar Finalizado -> Aberto return id == proximo.id - 1 } } @Test fun devePassarDeAbertoParaFinalizado() { val pedido = Pedido("123", LocalDate.now(), null) assertTrue(pedido.estado == Estado.ABERTO); pedido.estado = Estado.FINALIZADO assertTrue(pedido.estado == Estado.FINALIZADO) } @Test(expected=IllegalArgumentException::class) fun deveDarErroAoPassarDeAbertoParaEntregue() { val pedido = Pedido("123", LocalDate.now(), null) pedido.estado = Estado.ENTREGUE }
  • 27.
    Características do Códigoque Expressa Negócio 27/59 2. Isolamento O requisito está no código, mas muito código não vem do requisito O processo de refinamento Problema/Solução caminha por muitas tecnologias, processos e paradigmas 1 2 3 4 5
  • 28.
    Como Água eÓleoComo Água e Óleo
  • 29.
    Abordagens para Isolaro Negócio – DDD, MVC e Camadas 29/59 Modelo Controle Visão Controle e Negócio Apresentação / Serviço Persistência Domain 1 2 3 4 5
  • 30.
    Empacotamento Modular deAplicação Monolítica 30/59 1 2 3 4 5 Problema Solução Negócio Infraestrutura spec infra core service Cliente Tecnologia Dependência service core infraspec
  • 31.
    Service 1 Empacotamento deMicroserviços 31/59 1 2 3 4 5 Infra 1Domain 1 Service 2 Infra 2Domain 2 Service 3 Infra 3Domain 3 Commons InfraSpec
  • 32.
    Abordagens para IsolarInfraestrutura e Código de Terceiros 32/59 1 2 3 4 5 Terceiros Infraestrutura Infraestrutura Aplicação API de Terceiros public class Client { @Inject private JsonParser jsonParser; }
  • 33.
    Características do Códigoque Expressa Negócio 33/59 3. Significado Linguagem de programação não precisa de tradução O código deve ser escrito para ser lido por outra pessoa além de quem o escreveu: programação é comunicação 1 32 4 5
  • 34.
  • 35.
    Linguagem de Negócio- “Comunique, não Codifique” 35/59 1 32 4 5 Cliente Vocabulário de Negócio Problema Desenvolvedor 1 Desenvolvedor 2Problema Solução 100101 código 100101 código
  • 36.
    Linguagem de Onipresente 36/59 132 4 5 Cliente Vocabulário de Negócio Problema Desenvolvedor 1 Desenvolvedor 2Problema Solução 100101 código 100101 código Linguagem Ubíqua Todos usando Mesmo vocabulário Mesmos conceitos
  • 37.
    Ruído na Comunicação:Nomes Ruins 37/59 1 32 4 5 Notação Húngara e seu bando strNome = “Fulano” intIdade = 15 IParser, TipoEnum Não use “notação húngara” ou prefixação por tipos Interfaces recebem os nomes do conceito: “Parser” (BasicParser, GenericParser, ParserImpl etc) Camel case “sem corcova”: CNPJDAO, SPEDREST O tamanho de um nome é proporcional ao seu escopo i, j e k somente em loops
  • 38.
    Boa Comunicação: NomesSignificativos 38/59 1 32 4 5 Nomes a partir do domínio do problema (Pedido, Item etc) Nomes a partir do domínio da solução (Controller, Delegate, DAO) Classes = Substantivos, Métodos = Verbos Nomes pronunciáveis e passíveis de busca
  • 39.
    Comentários: Deixa euDesenhar... 39/59 1 32 4 5 Regra Geral: Comentários são a última opção Usamos comentários quando não conseguimos nos expressar no código Bons Comentários ● Questões legais (copyright) ● TODO “de verdade” ● JavaDoc em APIs públicas ● Destaque de algo relevante ● Alerta sobre consequências Maus Comentários ● Código Morto ● JavaDoc em código não público ● Ao lado de chave de fecho ● Controle de versão ● Redundantes ou ruidosos
  • 40.
    Padrões de Codificação PadrãoRuim é Melhor que Nenhum Padrão 40/59 1 32 4 5 Cliente Vocabulário de Negócio Problema Desenvolvedor 1 Desenvolvedor 2Problema Solução 100101 código 100101 código
  • 41.
    Testes de Unidade 41/59 132 4 5 class GsonJsonParserTest { val parser = GsonJsonParser() val json = "{"name":"Ladybug","age":15}" val person = Person("Ladybug", 15) @Test fun deveConverterObjetoParaJson() { val parsed = parser.toJson(person) assertEquals(json, parsed) } @Test fun deveConverterJsonParaObjeto() { val parsed = parser.fromJson(json, Person::class.java) assertEquals(person, parsed) } } De quem é este teste? O que ele testa?
  • 42.
    Características do Códigoque Expressa Negócio 42/59 4. Modularização Quantos livros nunca lerei? Um sistema é um conjunto de partes que interagem por um objetivo comum. Cada parte faz somente a sua parte. 1 42 3 5
  • 43.
  • 44.
    Qual Figura Representaa Solução de Busca do Google? 44/59 1 42 3 5 (A) (B) COOBOL
  • 45.
    Divisão de Negócio:Contexto Delimitado (Bounded Context) 45/59 1 42 3 5 https://martinfowler.com/bliki/BoundedContext.html
  • 46.
    Abstrações 46/59 1 42 35 Version GenericCustomer Person Pipeline Version
  • 47.
    Princípio DRY (Don’tRepeat Yourself - “Não se Repita”) 47/59 1 42 3 5 Regra de Negócio id = RNG001 Número de sócios <= 5 MAX_SOCIOS = 5Parâmetro de Negócio: Máximo de Sócios = 5 @Rule(RNG001) IF (socios.count > MAX_SOCIOS) msg = format(ER-001,MAX_SOCIOS) New BusinessException (msg) ER-001=”Proibido mais que {%} sócios” Mensagem do Sistema(EMS): ER-001 = “Proibido mais que 5 sócios” Não faça a mesma coisa em dois lugares ProblemaProblema SoluçãoSolução
  • 48.
    Princípio Single Responsability(Responsabilidade Única) 48/59 1 42 3 5 Não faça duas coisas no mesmo lugar “Uma classe só deveria ter um único motivo para mudar”
  • 49.
  • 50.
    Indireção (Delegação) 50/59 1 423 5 Indireção Indireção Calculo de Frete Busca de Endereço GRASP – Padrões para atribuição de responsabilidades em um projeto orientado a objetos: Padrões Básicos: Information Expert, Creator , High Cohesion, Low Coupling, Controller Padrões Avançados: Polymorphism, Pure Fabrication, Indirection, Protected Variations. Efetuar Pedido
  • 51.
    Características do Códigoque Expressa Negócio 51/59 5. Simplicidade Menos é mais* “A simplicidade é o último grau de sofisticação” Leonardo Da Vinci Simples não é simplório! 1 52 3 4 * Ludwig Mies van der Rohe - Arquiteto
  • 52.
    Título do Slide(Arial 18) 52/59 ExpressividadeExpressividade
  • 53.
    Quatro Regras daSimplicidade de Kent Beck 53/59 1 52 3 4 ● Todos os testes passam ● Claro, Expressivo e Consistente ● Nenhuma duplicação de comportamento ou configuração ● Mínimo possível de métodos, classes e módulos http://wiki.c2.com/?XpSimplicityRules
  • 54.
    Quatro Regras daSimplicidade de Kent Beck (por Martin Fowler) 54/59 1 52 3 4 ● Os testes passam ● Revela intenção ● Nenhuma duplicação ● Mínimo de elementos https://martinfowler.com/bliki/BeckDesignRules.html
  • 55.
    Acoplamento e aLei de Demeter 55/59 1 52 3 4 val pedido = Pedido("123", LocalDate.now(), null) if (pedido.estado == Estado.CANCELADO || pedido.estado == Estado.ENTREGUE){ // faça algo se estiver encerrado } if (pedido.estado.isEncerrado()){ // faça algo se estiver encerrado } if (pedido.isEncerrado()){ // faça algo se estiver encerrado } 1 2 3 Acoplado a 2 classes e 1 lista Acoplado a 2 classes Acoplado a 1 classe intenção: Fazer algo se o pedido estiver encerrado 23 isEncerrado() 1
  • 56.
    Encapsulamento 56/59 1 52 34 https://martinfowler.com/bliki/TellDontAsk.html class Pedido(val numero: String, val criacao: LocalDate, val conclusao: LocalDate?) { var estado = Estado.ABERTO set (value) { if (!estado.podeTransitarPara(value)) { throw IllegalArgumentException ("Transição não permitida de $estado para $value") } field = value } fun isEncerrado(): Boolean{ return estado.isEncerrado() || isAntigoDemais() } fun isAntigoDemais()= LocalDate.now().isAfter(criacao.plusYears(1)) } val pedido = Pedido("123", LocalDate.now(), null) if (pedido.estado == Estado.CANCELADO || pedido.estado == Estado.ENTREGUE){ // faça algo se estiver encerrado } if (pedido.estado.isEncerrado()){ // faça algo se estiver encerrado } if (pedido.isEncerrado()){ // faça algo se estiver encerrado } 1 2 3 3 Princípio “Tell, don’t ask” + simples
  • 57.
    Independência1 Código feitocomo especificação do problema 2 Isolamento Código desenhado para destacar o negócio 4 Modularização Código bem dividido em partes especializadas 3 Significado Código escrito em uma linguagem onipresente 5 Simplicidade Código cuidadosamente otimizado para leitura
  • 58.
    Referência 58/59 EVANS, E. Domain-DrivenDesign – Atacando as complexidades no coração do software. 2a edição, Rio de Janeiro, Alta Books, 2010. FOWLER, Martin. BeckDesignRules, https://martinfowler.com/bliki/BeckDesignRules.html FOWLER, Martin. BoundedContext, https://martinfowler.com/bliki/BoundedContext.html FOWLER, Martin. TellDontAsk, https://martinfowler.com/bliki/TellDontAsk.html HUNT, Andrew; THOMAS, David, O Programador Pragmático, Bookman, 2010 MARTIN, Robert, O Codificador Limpo, Alta Books, Rio de Janeiro 2012 MARTIN, Robert, Código Limpo, Alta Books, Rio de Janeiro 2011
  • 59.
    Programação Funcional XOrientação a Objetos 59/59 1 42 3 5 Orientado a Objetos para encerrar... Obrigado! Douglas Siviotti douglas.siviotti@gmail.com github.com/siviotti Funcional