1. Negócio Escrito em Có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?
7. 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
8. 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
}
9. 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
10. 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
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 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!
16. Parte 2
O Caminho de Volta doO Caminho de Volta do
Código ao NegócioCódigo ao Negócio
17. 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
18. 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
20. 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
21. 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
25. 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
26. 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
}
27. 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
29. 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
30. 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
31. 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
32. 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;
}
33. 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
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
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
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: 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
39. 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
40. 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
41. 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?
42. 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
47. 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
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”
50. 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
51. 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
52. Título do Slide (Arial 18)
52/59
ExpressividadeExpressividade
53. 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
54. 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
55. 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
56. 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
57. 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
58. 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
59. 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