O documento discute estratégias para evolução de sistemas de forma pacífica, apresentando: 1) Como evitar problemas ao alterar código e bancos de dados, explicitando mudanças; 2) Técnicas como avisar usuários, duplicar funcionalidade e descontinuar métodos antigos gradativamente; 3) Abordagens para manter compatibilidade com sistemas externos ao longo do tempo.
2. Agenda
Anatomia de uma mudança
Mudança de código
Mudança de banco de dados
Sistemas externos
Retro-compatibilidade e Compatibilidade futura
2Wednesday, July 3, 13
3. Anatomia de uma mudança
167 insertions(+),
119 files changed,
153 deletions(-)
3Wednesday, July 3, 13
4. Dissecando uma mudança
class Exemplo
def nome_velho
return 42
end
end
class Exemplo
def nome_novo
return 42
end
end
- def nome_velho
+ def nome_novo
4Wednesday, July 3, 13
5. Dissecando uma mudança
class Exemplo
def nome_velho
return 42
end
end
class Exemplo
def nome_novo
return 42
end
end
class Resposta
def resposta(pergunta)
e = Exemplo.new
return e.nome_velho
end
end
5Wednesday, July 3, 13
6. class Resposta
def resposta(pergunta)
e = Exemplo.new
return e.nome_velho
end
end
Dissecando uma mudança
class Exemplo
def nome_velho
return 42
end
end
class Exemplo
def nome_novo
return 42
end
end
6Wednesday, July 3, 13
7. Evitando o problema
class Exemplo
def nome_velho
return 42
end
end
class Resposta
def answer(pergunta)
e = Exemplo.new
return e.nome_velho
end
end
7Wednesday, July 3, 13
8. Evitando o problema
class Exemplo
def nome_velho
return 42
end
end
class Resposta
def answer(pergunta)
e = Exemplo.new
return e.nome_velho
end
end
class Exemplo
def nome_velho
puts "Esse método
foi deperequetado.
Favor usar nome_novo"
return nome_novo
end
def nome_novo
return 42
end
end
8Wednesday, July 3, 13
17. Lá no código
class Session
def experience
return execute("select experience from
sessions where id = ?", id)
end
end
17Wednesday, July 3, 13
18. Lá no código
> session.experience
ColumnNotFoundException: no column named
experience
18Wednesday, July 3, 13
19. Lá no código
> session.experience
ColumnNotFoundException: no column named
experience
E agora José?
19Wednesday, July 3, 13
20. Como evitar?
V1
Código usa experience
BD tem experience
V2
Código não usa experience
BD não tem experience
20Wednesday, July 3, 13
21. Como evitar?
V1
Código usa experience
BD tem experience
V2
Código não usa experience
BD não tem experience
21Wednesday, July 3, 13
22. Como evitar?
V1
Código usa experience
BD tem experience
V2
Código não usa experience
BD não tem experience
V1.5
Código não usa experience
BD tem experience
22Wednesday, July 3, 13
23. Como evitar?
V1
Código usa experience
BD tem experience
V2
Código não usa experience
BD não tem experience
V1.5
Código não usa experience
BD tem experience
23Wednesday, July 3, 13
24. E a adição?
V1
Código não usa limit
BD não tem limit
V2
Código usa limit
BD tem limit
24Wednesday, July 3, 13
25. E a adição?
V1
Código não usa limit
BD não tem limit
V2
Código usa limit
BD tem limit
25Wednesday, July 3, 13
26. E adição?
V1
Código não usa limit
BD não tem limit
V2
Código usa limit
BD tem limit
V1.5
Código não usa limit
BD tem limit
26Wednesday, July 3, 13
27. E adição?
V1
Código não usa limit
BD não tem limit
V2
Código usa limit
BD tem limit
V1.5
Código não usa limit
BD tem limit
27Wednesday, July 3, 13
29. Explicitar
class Subclasse < Superclasse
end
> implementacao = Subclasse.new
> implementacao.metodo_da_super_classe
29Wednesday, July 3, 13
30. Explicitar
class Subclasse < Superclasse
end
> implementacao = Subclasse.new
> implementacao.metodo_da_super_classe
class Subclasse < Superclasse
def metodo_da_super_classe
super
end
end
30Wednesday, July 3, 13
31. Avisar
class Subclasse < Superclasse
def metodo_da_super_classe
puts "Esse método está sendo
deperequetado. Favor não usar mais"
super
end
end
31Wednesday, July 3, 13
32. Avisar
class Subclasse < Superclasse
def metodo_da_super_classe
puts "Esse método está sendo
deperequetado. Favor não usar mais"
super
end
end
> implementacao = Subclasse.new
> implementacao.metodo_da_super_classe
Esse método está sendo deperequetado.
Favor não usar mais
32Wednesday, July 3, 13
33. Duplicar
class Subclasse < Superclasse
def metodo_da_super_classe
puts "Esse método está sendo
deperequetado. Favor usar novo_metodo"
super
end
def novo_metodo
42
end
end
33Wednesday, July 3, 13
34. Duplicar
class Subclasse < Superclasse
def metodo_da_super_classe
puts "Esse método está sendo
deperequetado. Favor usar novo_metodo"
super
return novo_metodo
end
def novo_metodo
42
end
end
34Wednesday, July 3, 13
35. Descontinuar
class Subclasse < Superclasse
def metodo_da_super_classe
puts "Esse método está sendo
deperequetado. Favor usar novo_metodo"
return novo_metodo
end
def novo_metodo
42
end
end
35Wednesday, July 3, 13
36. Proteger
class Subclasse < Superclasse
def metodo_da_super_classe
raise "Esse método está
deperequetado. Use novo_metodo"
end
def novo_metodo
42
end
end
36Wednesday, July 3, 13
40. Mesmo padrão
Sistema com contrato velho
Externo com contrato velho
Sistema com contrato velho e novo
Externo com contrato velho
40Wednesday, July 3, 13
41. Mesmo padrão
Sistema com contrato velho
Externo com contrato velho
Sistema com contrato velho e novo
Externo com contrato novo
Sistema com contrato velho e novo
Externo com contrato velho
41Wednesday, July 3, 13
42. Mesmo padrão
Sistema com contrato velho
Externo com contrato velho
Sistema com contrato velho e novo
Externo com contrato novo
Sistema com contrato velho e novo
Externo com contrato velho
Sistema com contrato novo
Externo com contrato novo
42Wednesday, July 3, 13
43. Troca de mensagens
{ nome: “Hugo
Corbucci”,
nascimento:
“1983-12-26”
}
43Wednesday, July 3, 13
51. Código Velho + Dado Novo
•Não remover dado usado pelo código velho
51Wednesday, July 3, 13
52. Código Velho + Dado Novo
•Não remover dado usado pelo código velho
•Não mudar acesso de dados
52Wednesday, July 3, 13
53. Código Velho + Dado Novo
•Não remover dado usado pelo código velho
•Não mudar acesso de dados
•Não mudar semântica de dados
53Wednesday, July 3, 13
55. Código Novo + Dado Velho
• Ler novo dado se presente – usar o velho
se ausente
55Wednesday, July 3, 13
56. Código Novo + Dado Velho
• Ler novo dado se presente – usar o velho
se ausente
• Escrever novo dado se possível – escrever
dado velho se não der
56Wednesday, July 3, 13
57. Código Novo + Dado Velho
• Ler novo dado se presente – usar o velho
se ausente
• Escrever novo dado se possível – escrever
dado velho se não der
• Adicionar logs para acompanhar migração
de dados
57Wednesday, July 3, 13
58. Código atual + Dado atual
Código atual + Dado futuro
Código futuro + Dado atual
Código futuro + Dado futuro
Compatibilidade futura
58Wednesday, July 3, 13
59. Código atual + Dado atual
Código atual + Dado futuro
Código futuro + Dado atual
Código futuro + Dado futuro
Compatibilidade futura
59Wednesday, July 3, 13
61. Código atual + Dado futuro
• Não depender de ‘dado não existir’
61Wednesday, July 3, 13
62. Código atual + Dado futuro
• Não depender de ‘dado não existir’
• Não depender de validações no BD
(unicidade, tipo, etc)
62Wednesday, July 3, 13
63. Código atual + Dado futuro
• Não depender de ‘dado não existir’
• Não depender de validações no BD
(unicidade, tipo, etc)
• Você vai falhar!
Não tem problema com isso
63Wednesday, July 3, 13
65. Código atual + Dado futuro
• Mantenha seus dados limpos - corrija
dados antigos se estiverem sujos
65Wednesday, July 3, 13
66. Código atual + Dado futuro
• Mantenha seus dados limpos - corrija
dados antigos se estiverem sujos
• Limpe/remova dados obsoletos (ou
deperequetados) e dados não utilizados
66Wednesday, July 3, 13
67. Código atual + Dado futuro
• Mantenha seus dados limpos - corrija
dados antigos se estiverem sujos
• Limpe/remova dados obsoletos (ou
deperequetados) e dados não utilizados
• Você vai falhar!
Não tem problema com isso
67Wednesday, July 3, 13
71. Resumindo
• Avise ao invés de remover
• Desacople migrações/sistemas externos de
mudanças de código
71Wednesday, July 3, 13
72. Resumindo
• Avise ao invés de remover
• Desacople migrações/sistemas externos de
mudanças de código
• Retrocompatibilidade é difícil mas seguro
72Wednesday, July 3, 13
73. Resumindo
• Avise ao invés de remover
• Desacople migrações/sistemas externos de
mudanças de código
• Retrocompatibilidade é difícil mas seguro
• Compatibilidade futura é quase impossível
mas tudo bem com isso
73Wednesday, July 3, 13
74. Resumindo
• Avise ao invés de remover
• Desacople migrações/sistemas externos de
mudanças de código
• Retrocompatibilidade é difícil mas seguro
• Compatibilidade futura é quase impossível
mas tudo bem com isso
• Isso é necessário para Entrega Contínua
74Wednesday, July 3, 13
75. Resumindo
• Avise ao invés de remover
• Desacople migrações/sistemas externos de
mudanças de código
• Retrocompatibilidade é difícil mas seguro
• Compatibilidade futura é quase impossível
mas tudo bem com isso
• Isso é necessário para Entrega Contínua
• Existem ferramentas que ajudam a lidar
com isso. Procure-as!
75Wednesday, July 3, 13