SlideShare uma empresa Scribd logo
1 de 172
Baixar para ler offline
sobre code smells,
refactoring e design
como SOLID pode te ajudar no dia a dia
hello
1996
Elaine Naomi Watanabe
Desenvolvedora de Software (Plataformatec)
Mestre em Ciência da Computação (USP)
twitter.com/elaine_nw
speakerdeck.com/elainenaomi
2019
http://careers.plataformatec.com.br
analisar os conceitos básicos de orientação a objeto
como identificar problemas na nossa base de código
como melhorar o design do nosso código
o que vamos ver?
orientação a objeto
uma versão super resumida
Objeto
Classe
class Pessoa
def initialize(nome_recebido, email_recebido)
@nome = nome_recebido
@email = email_recebido
end
def contato
@email
end
end exemplo de uma classe
p1 = Pessoa.new("Ana", "ana@email.com")
p1.contato
=> "ana@email.com"
p1 = Pessoa.new("Ana", "ana@email.com")
p1.contato
=> "ana@email.com"
exemplo de um objeto
p2 = Pessoa.new("Bia", "beatriz@email.com")
p2.contato
=> "beatriz@email.com"
exemplo de outro objeto
Herança
Polimorfismo
Composição
exemplo de herança
class PessoaFisica < Pessoa
def diga_oi
'olar'
end
end
p1 = PessoaFisica.new("Ana", "ana@email.com")
p1.contato
=> "ana@email.com"
método herdado
p1 = PessoaFisica.new("Ana", "ana@email.com")
p1.contato
=> "ana@email.com"
p1.diga_oi
=> "olar"
p1 = Pessoa.new("Ana", "ana@email.com")
p1.contato
=> "ana@email.com"
p1.diga_oi
=> NoMethodError (undefined method `diga_oi'
for #<Pessoa:0x00007fd9cb0f0760 @nome="Ana",
@email="ana@email.com">)
p1 = Pessoa.new("Ana", "ana@email.com")
p1.contato
=> "ana@email.com"
p1.diga_oi
=> NoMethodError (undefined method `diga_oi'
for #<Pessoa:0x00007fd9cb0f0760 @nome="Ana",
@email="ana@email.com">)
class PessoaJuridica < Pessoa
def contato
@nome
end
end
exemplo de polimorfismo
class PessoaJuridica < Pessoa
def contato
@nome
end
end
método redefinido
p1 = PessoaFisica.new("Ana", "ana@email.com")
p1.contato
=> "ana@email.com"
p2 = PessoaJuridica.new("Umbrella Academy",
"contato@email.com")
p2.contato
=> "Umbrella Academy"
[p1, p2].each do |pessoa|
puts pessoa.contato
end
não importa qual pessoa estou
chamando
class PessoaAnonima < Pessoa
def contato
'...'
end
end
homenagem a talk da Cybelle
class Pessoa
def initialize(nome_recebido, forma_de_contato_recebida)
@nome = nome_recebido
@contato_favorito = forma_de_contato_recebida
end
def contato
@contato_favorito.identificador
end
end exemplo de composição
class Twitter
def initialize(nome_do_usuario)
@nome = nome_do_usuario
end
def identificador
@nome
end
end
exemplo de composição
twitter = Twitter.new("@ana")
pessoa = Pessoa.new("Ana", twitter)
pessoa.contato
=> "@ana"
class WhatsApp
def initialize(numero_telefone_recebido)
@numero_telefone = numero_telefone_recebido
end
def identificador
@numero_telefone
end
end
zapzap = WhastApp.new(5511999999999)
pessoa = Pessoa.new("Ana", zapzap)
pessoa.contato
=> 5511999999999
Reúso
Coesão
Acoplamento
Encapsulamento
class MeuChatBot
def contato
oi
end
private
def oi
'olar'
end
end
exemplo de encapsulamento
class MeuChatBot
def contato
oi
end
private
def oi
'olar'
end
end
bot = MeuChatBot.new
bot.contato
=> "olar"
bot.oi
=> NoMethodError (undefined method `olar` for
#<MeuChatBot:0x00007fd9cb0f0760>)
método oi está encapsulado/oculto
objetos + mensagens = app
e no dia a dia?
Frameworks MVC
ViewModel
Controller
apresentação
intermediador
dados +
lógica de negócio
+ Funcionalidades
+ Funcionalidades
+ Modificações
+ Funcionalidades
+ Modificações
+ Bugs
Tamanho da base de código
Tempodeentregas
Nota: gráfico ilustrativo, mas baseado em fatos reais
"Esse código é difícil de entender"
"Joga isso fora e começa do zero"
Quando reescrever um sistema?
Uso de tecnologia desatualizada
Contratação de pessoas está difícil
Existência de tecnologias mais vantajosas
Fonte: http://blog.plataformatec.com.br/2016/07/key-points-to-consider-when-doing-a-software-rewrite/
que tal refatorar o código?
Refatoração
processo de melhorar o design do código existente,
alterando o software sem alterar o seu comportamento
Por que refatorar?
Código fácil de ler
Código fácil de entender
Código fácil de manter
Código limpo
precisamos mesmo refatorar?
Dívida Técnica
Custodamudança
Tempo
Fonte: How to Monetize Application Technical Debt, Gartner, 2011
Dívida Técnica
Valor de negócio
Custodamudança
Tempo
Fonte: How to Monetize Application Technical Debt, Gartner, 2011
e como evitar isso?
Custodamudança
Tempo
dívida técnica
refatoração
caso ótimo
Fonte: An Empirical Model of Technical Debt and Interest, MTD' 11, Ariadni Nugroho et al.
Como medir a necessidade de refatoração?
Quantidade de código duplicado
Dificuldade para escrever testes
Desempenho da suíte de testes
Identificação dos code smells
Code smells
Sintomas no código que indicam possíveis
problemas de design em sistemas orientados a objeto
Code smells
Indícios de que o código precisa ser refatorado
exemplos de code smells
Duplicated Code
Código duplicado
Regras de negócio duplicadas
Regra de negócio duplicada != Texto duplicado
Mesma alteração em vários arquivos,
Buscas globais para toda alteração
Shotgun Surgery
Vários comentários explicando o
funcionamento do código
Comments
# a é o valor total a ser cobrado
def charge(a)
# cartão com status = 3 é o cartão ativo
if credit_card.status == 3
payment_gateway.charge(a)
end
end
def charge(total)
# cartão com status = 3 é o cartão ativo
if credit_card.status == 3
payment_gateway.charge(total)
end
end segundos de vida economizados! o/
def charge(total)
# cartão com status = 3 é o cartão ativo
if credit_card.status == 3
payment_gateway.charge(total)
end
end
def charge(total)
# cartão com status = 3 é o cartão ativo
if credit_card.status == 3
payment_gateway.charge(total)
end
end
def charge(total)
# cartão com status = 3 é o cartão ativo
if credit_card.active?
payment_gateway.charge(total)
end
end
def charge(total)
if credit_card.active?
payment_gateway.charge(total)
end
end
def active?
status == 3
end
mais segundos de vida economizados!
o/
comentário != documentação
SECONDS_FOR_CONNECTION_TIMEOUT_IN_INTEGER = 60
# Public: Integer number of seconds to wait
# before connection timeout.
CONNECTION_TIMEOUT = 60
# Public: A summary of how much some user has consumed in a
certain plan.
#
# Examples
# plan_consumption_summary(contracted_plan)
# # => '2.44% (500 MB of 20 GB)'
#
# Returns a String.
def plan_consumption_summary(contracted_plan)
total_contracted = contracted_plan.plan_storage_limit
total_consumed = contracted_plan.total_consumed
# ...
Fonte: http://blog.plataformatec.com.br/2018/06/the-anatomy-of-code-documentation/
Mysterious Name
Long Function
Long Parameter List
Global Data
Mutable Data
Divergent Change
Outros code smells 2019
Feature Envy
Data Clumps
Primitive Obsession
Repeated Switches
Loops
Lazy Element
Speculative Generality
Temporary Field
2019
Message Chains
Middle Man
Insider Trading
Large Class
Alternative Classes with Different Interfaces
Data Class
Refused Bequest
2019
e como evitar os code smells?
reduzir
reconheça esses sintomas
Muitas regras de negócio nos controllers
Métodos muito longos
Classes muito grandes
Excesso de indireção/callbacks
Dificuldade para escrever testes
Classes de difícil manutenção
Ctrl + F / ⌘ + F para qualquer alteração
Arquivos constantemente alterados
reconheci, e agora?
Para cada code smell, existe
um conjunto de refatorações sugeridas
Martin Fowler e
Kent Beck listam
22 code smells e
sugerem como
refatorá-los
1999
Martin Fowler e
Kent Beck listam
22 code smells e
sugerem como
refatorá-los
2019
24
Refatoraram?
Mas vamos tentar olhar
para o design do código
Finalmente, SOLID o/
Single Responsibility Principle
Open/Closed Principle
Liskov Substitution Principle
Interface Segregation Principle
Dependency Inversion Principle
Single Responsibility Principle
O que a minha classe faz?
Indicativo de problemas: usar "e" ou "ou" na explicação
Métodos relacionados?
Uma única razão para mudar?
Alterações com efeitos previsíveis?
class BooksUser < ApplicationRecord
belongs_to: :book
belongs_to: :user
after_commit :send_notification_reservation_completed
def send_notification_reservation_completed
NotificationService.reservation_completed(user, book)
end
end
class BooksUser < ApplicationRecord
belongs_to: :book
belongs_to: :user
after_commit :send_notification_reservation_completed
def send_notification_reservation_completed
NotificationService.reservation_completed(user, book)
end
end
Uma classe de persistência não deveria saber sobre
notificações a um usuário, por ex.
Que tal um Service Object para isso?
Mais exemplos em: codeclimate.com/blog/7-ways-to-decompose-fat-activerecord-models/
class ReserveBookService
attr_reader :user, :book, :notification_service
def initialize(user, book, notification_service)
@user = user
@book = book
@notification_service = notification_service
end
def confirm!
user.books << book
notification_service.reservation_completed(user, book)
end
end
class ReserveBookService
attr_reader :user, :book, :notification_service
def initialize(user, book, notification_service)
@user = user
@book = book
@notification_service = notification_service
end
def confirm!
user.books << book
notification_service.reservation_completed(user, book)
end
end
Open/Closed Principle
Adicionar nova regra = modificar uma ou mais classes?
Se sim, é um indicativo de problema
Aberto para extensão, fechado para modificação
Defina interfaces/super classes
Reduza o acoplamento
class FinancialReport
def generate(account, file_format)
case file_format
when :csv
file = FormatCSV.generate_file(account.transactions)
when :xml
file = XML.parse_list(account.transactions)
end
Mailer.send(account.email, file)
end
end
class FinancialReport
def generate(account, file_format)
case file_format
when :csv
file = FormatCSV.generate_file(account.transactions)
when :xml
file = XML.parse_list(account.transactions)
when :pdf
file = PDFGenerator.create(account.transactions)
end
Mailer.send(account.email, file)
end
end edição
class FinancialReport
def generate(account, file_format)
case file_format
when :csv
file = FormatCSV.generate_file(account.transactions)
when :xml
file = XML.parse_list(account.transactions)
when :pdf
file = PDFGenerator.create(account.transactions)
end
Mailer.send(account.email, file)
end
end
class FinancialReport
def generate(account, file_creator)
file = file_creator.create(account.transactions)
Mailer.send(account.email, file)
end
end
class FileCreator
def create(items)
raise NotImplementedError
end
end
contrato
class FileCreatorXML < FileCreator
def create(items)
XML.parse(items)
end
end
class FileCreatorCSV < FileCreator
def create(items)
FormatCSV.generate_file(items)
end
end
class FileCreatorPDF < FileCreator
def create(items)
PDFGenerator.generate(items)
end
end
adição
class FinancialReport
def generate(account, file_creator)
file = file_creator.create(account.transactions)
Mailer.send(account.email, file)
end
end
FinancialReport.new.generate(account, FileCreatorPDF.new)
Liskov Substitution Principle
Barbara Liskov
Institute Professor from MIT
The 2008 Turing Award winner
liskov at csail.mit.edu
Liskov Substitution Principle (1987)
Let φ(x) be a property provable about objects x
of type T. Then φ(y) should be true for objects y
of type S where S is a subtype of T.
Tradução em: https://speakerdeck.com/elainenaomi/hacking-evening-liskov-substitution-principle
Eita!
Design by contract
respeitar os contratos definidos pela classe base
Pré-condições: dados de entrada
classes derivadas só podem ser mais permissivas
Pós-condições: dados de saída
classes derivadas só podem ser mais restritivas
Não podemos criar comportamentos inesperados ou incorretos!
O comportamento da super classe precisa ser mantido
class CheckingAccount
# ...
def deposit(value)
raise InvalidValueError if value <= 0
self.balance = self.balance + value
end
def compute_bonus
self.balance = self.balance * 1.01
end
end
class PayrollAccount < CheckingAccount
class OperationNotAllowed < StandardError; end
# ...
def compute_bonus
raise OperationNotAllowed
end
end
CheckingAccount.all.each do |account|
account.compute_bonus
end
CheckingAccount.all.each do |account|
begin
account.compute_bonus
rescue PayrollAccount::OperationNotAllowed
false
end
end
CheckingAccount.all.each do |account|
begin
account.compute_bonus
rescue PayrollAccount::OperationNotAllowed
false
end
end contrato quebrado
class PayrollAccount < CheckingAccount
# ...
def deposit(value)
raise InvalidValueError if value <= 100
self.balance = self.balance + value
end
def compute_bonus
self.balance = self.balance * 1.01
end
end
class PayrollAccount < CheckingAccount
# ...
def deposit(value)
raise InvalidValueError if value <= 100
self.balance = self.balance + value
end
def compute_bonus
self.balance = self.balance * 1.01
end
end
contrato quebrado
Deveriam ser classes diferentes!
Interface Segregation Principle
Uma classe derivada não deveria ser obrigada
a implementar métodos que ela não usa
class CoffeeMachine
def brew_coffee
# brew coffee logic
end
def fill_coffee_beans
# fill coffee beans
end
end
class Person
attr_reader :coffee_machine
def initialize
@coffee_machine = CoffeeMachine.new
End
def quero_cafe
coffee_machine.brew_coffee
end
end
class Staff
attr_reader :coffee_machine
def initialize
@coffee_machine = CoffeeMachine.new
end
def fill_coffee_beans
coffee_machine.fill_coffee_beans
end
end
Várias interfaces específicas é melhor do
que uma interface generalizada
class CoffeeMachineUserInterface
def brew_coffee
# brew coffee logic
end
end
class CoffeeMachineServiceInterface
def fill_coffee_beans
# fill coffee beans
end
end
class CoffeeMachineUserInterface
def brew_coffee
# brew coffee logic
end
end
class CoffeeMachineServiceInterface
def fill_coffee_beans
# fill coffee beans
end
end
class Person
attr_reader :coffee_machine
def initialize
@coffee_machine = CoffeeMachineUserInterface.new
end
def quero_cafe
coffee_machine.brew_coffee
end
end
class Person
attr_reader :coffee_machine
def initialize
@coffee_machine = CoffeeMachineUserInterface.new
end
def quero_cafe
coffee_machine.brew_coffee
end
end
class Staff
attr_reader :coffee_machine
def initialize
@coffee_machine = CoffeeMachineServiceInterface.new
end
def fill_coffee_beans
coffee_machine.fill_coffee_beans
end
end
class Staff
attr_reader :coffee_machine
def initialize
@coffee_machine = CoffeeMachineServiceInterface.new
end
def fill_coffee_beans
coffee_machine.fill_coffee_beans
end
end
Dependency Inversion Principle
Dependa de abstrações,
não de implementações
class FinancialReport
def generate(account, file_creator)
file = file_creator.create(account.transactions)
Mailer.send(account.email, file)
end
end
class FileCreatorCSV < FileCreator
def create(items)
FormatCSV.generate_file(items)
end
End
FinancialReport.new.generate(account, FileCreatorCSV.new)
class FileCreatorCSV < FileCreator
def create(items)
FormatCSV.generate_file(items)
NewCSVGenerator.parse(items, header: false)
end
End
FinancialReport.new.generate(account, FileCreatorCSV.new)
use o encapsulamento e polimorfismo a seu favor
TL;DR
Princípios para a criação de um código
mais flexível e adaptável a mudanças
SOLID
No fundo, o que queremos?
Alta coesão
Baixo acoplamento
Encapsulamento
vamos refatorar tudo?
esses conceitos nos ajudam a criar
aplicações mais flexíveis
converse com seu time
analisem juntos os trade-offs
verifique a cobertura de testes
testes automatizados são essenciais
para garantir a evolução do seu sistema
refatoração != revolução
cuidado com big design up front
e overengineering
e não esqueçam:
codar é um processo de comunicação
Donald Knuth. "Literate Programming (1984)" in Literate Programming. CSLI, 1992, pg. 99.
Mais sobre design?
Padrões de projeto
TDD, DDD
minhas referências
guidelines.plataformatec.com.br
thoughtbot.com/upcase/clean-code
refactoring.guru
mundopodcast.com.br/podprogramar
Mais referências:
Refactoring rails apps - Flavia Fortes
http://bit.ly/2zDADhe
Evitando o Jenga Driven Development - João Britto
http://bit.ly/2DFvB3v
Mais referências:
Por que (às vezes) você deve reinventar a roda -
Paulo Silva
https://youtu.be/kdNf2abcP5E?t=11640
Callbacks do ActiveRecord: o mal secreto ou
apenas mal compreendidos? - Rondy
https://youtu.be/kdNf2abcP5E?t=13214
Mais referências:
Sororidade
Empatia, solidariedade,
companheirismo, respeito
Juntas somos mais fortes
Até a próxima!
muito obrigada
speakerdeck.com/elainenaomi

Mais conteúdo relacionado

Mais procurados

Programando em C++ // Estrutura Básica
Programando em C++ // Estrutura Básica Programando em C++ // Estrutura Básica
Programando em C++ // Estrutura Básica Yuri Camelo
 
7. Arrays multidimensionais; Estratégias de resolução de problemas – Fundamen...
7. Arrays multidimensionais; Estratégias de resolução de problemas – Fundamen...7. Arrays multidimensionais; Estratégias de resolução de problemas – Fundamen...
7. Arrays multidimensionais; Estratégias de resolução de problemas – Fundamen...Manuel Menezes de Sequeira
 
Serversidephp pptx2-120418140114-phpapp01
Serversidephp pptx2-120418140114-phpapp01Serversidephp pptx2-120418140114-phpapp01
Serversidephp pptx2-120418140114-phpapp01joaocarlobarros
 
C#4 - Parte 2 - COM interop e variância
C#4 - Parte 2 - COM interop e variânciaC#4 - Parte 2 - COM interop e variância
C#4 - Parte 2 - COM interop e variânciaGiovanni Bassi
 
Programação Estruturada 2 - Aula 01 - Código Fonte
Programação Estruturada 2 - Aula 01 - Código FonteProgramação Estruturada 2 - Aula 01 - Código Fonte
Programação Estruturada 2 - Aula 01 - Código Fontethomasdacosta
 
Curso Linguagem de Programação I - PHP Básico
Curso Linguagem de Programação I - PHP BásicoCurso Linguagem de Programação I - PHP Básico
Curso Linguagem de Programação I - PHP BásicoNorton Guimarães
 
Spring framework 2.5
Spring framework 2.5Spring framework 2.5
Spring framework 2.5Diego Pacheco
 

Mais procurados (10)

Programando em C++ // Estrutura Básica
Programando em C++ // Estrutura Básica Programando em C++ // Estrutura Básica
Programando em C++ // Estrutura Básica
 
Aula1 c++ builder
Aula1   c++ builderAula1   c++ builder
Aula1 c++ builder
 
7. Arrays multidimensionais; Estratégias de resolução de problemas – Fundamen...
7. Arrays multidimensionais; Estratégias de resolução de problemas – Fundamen...7. Arrays multidimensionais; Estratégias de resolução de problemas – Fundamen...
7. Arrays multidimensionais; Estratégias de resolução de problemas – Fundamen...
 
Módulo de php
Módulo de phpMódulo de php
Módulo de php
 
Serversidephp pptx2-120418140114-phpapp01
Serversidephp pptx2-120418140114-phpapp01Serversidephp pptx2-120418140114-phpapp01
Serversidephp pptx2-120418140114-phpapp01
 
C#4 - Parte 2 - COM interop e variância
C#4 - Parte 2 - COM interop e variânciaC#4 - Parte 2 - COM interop e variância
C#4 - Parte 2 - COM interop e variância
 
Programação Estruturada 2 - Aula 01 - Código Fonte
Programação Estruturada 2 - Aula 01 - Código FonteProgramação Estruturada 2 - Aula 01 - Código Fonte
Programação Estruturada 2 - Aula 01 - Código Fonte
 
Curso Linguagem de Programação I - PHP Básico
Curso Linguagem de Programação I - PHP BásicoCurso Linguagem de Programação I - PHP Básico
Curso Linguagem de Programação I - PHP Básico
 
Spring framework 2.5
Spring framework 2.5Spring framework 2.5
Spring framework 2.5
 
Aula 1 | Introdução a C++
Aula 1 | Introdução a C++Aula 1 | Introdução a C++
Aula 1 | Introdução a C++
 

Semelhante a Como SOLID pode te ajudar no dia a dia

Code Smells: o que eles dizem sobre seu código?
Code Smells: o que eles dizem sobre seu código?Code Smells: o que eles dizem sobre seu código?
Code Smells: o que eles dizem sobre seu código?Elaine Naomi
 
Design de aplicações orientadas a objeto
Design de aplicações orientadas a objetoDesign de aplicações orientadas a objeto
Design de aplicações orientadas a objetoElaine Naomi
 
TDC2018SP | Trilha Ruby - Design de aplicacoes orientadas a objeto: uma visao...
TDC2018SP | Trilha Ruby - Design de aplicacoes orientadas a objeto: uma visao...TDC2018SP | Trilha Ruby - Design de aplicacoes orientadas a objeto: uma visao...
TDC2018SP | Trilha Ruby - Design de aplicacoes orientadas a objeto: uma visao...tdc-globalcode
 
Programação Orientada a Testes
Programação Orientada a TestesProgramação Orientada a Testes
Programação Orientada a TestesGregorio Melo
 
Exemplos de Design Patterns em Java
Exemplos de Design Patterns em JavaExemplos de Design Patterns em Java
Exemplos de Design Patterns em Javaalexmacedo
 
Clean code @rogeriofontes-techfriday-everis
Clean code @rogeriofontes-techfriday-everisClean code @rogeriofontes-techfriday-everis
Clean code @rogeriofontes-techfriday-everisRogerio Fontes
 
GURU SP - Design de aplicações orientadas a objeto
GURU SP - Design de aplicações orientadas a objetoGURU SP - Design de aplicações orientadas a objeto
GURU SP - Design de aplicações orientadas a objetoElaine Naomi
 
Vamos falar de Clean Code, Refatoração e TDD
Vamos falar de Clean Code, Refatoração e TDDVamos falar de Clean Code, Refatoração e TDD
Vamos falar de Clean Code, Refatoração e TDDDomingos Teruel
 
Padrões de projeto - Adapter, Proxy, Composite e Bridge
Padrões de projeto - Adapter, Proxy, Composite e BridgePadrões de projeto - Adapter, Proxy, Composite e Bridge
Padrões de projeto - Adapter, Proxy, Composite e BridgeLorran Pegoretti
 
Refactory Worshop
Refactory WorshopRefactory Worshop
Refactory Worshopguestd37c23
 
Transição - Orientação a objeto para Funcional
Transição - Orientação a objeto para FuncionalTransição - Orientação a objeto para Funcional
Transição - Orientação a objeto para FuncionalIsmael Velten
 

Semelhante a Como SOLID pode te ajudar no dia a dia (20)

Code Smells: o que eles dizem sobre seu código?
Code Smells: o que eles dizem sobre seu código?Code Smells: o que eles dizem sobre seu código?
Code Smells: o que eles dizem sobre seu código?
 
Design de aplicações orientadas a objeto
Design de aplicações orientadas a objetoDesign de aplicações orientadas a objeto
Design de aplicações orientadas a objeto
 
TDC2018SP | Trilha Ruby - Design de aplicacoes orientadas a objeto: uma visao...
TDC2018SP | Trilha Ruby - Design de aplicacoes orientadas a objeto: uma visao...TDC2018SP | Trilha Ruby - Design de aplicacoes orientadas a objeto: uma visao...
TDC2018SP | Trilha Ruby - Design de aplicacoes orientadas a objeto: uma visao...
 
Programação Orientada a Testes
Programação Orientada a TestesProgramação Orientada a Testes
Programação Orientada a Testes
 
Exemplos de Design Patterns em Java
Exemplos de Design Patterns em JavaExemplos de Design Patterns em Java
Exemplos de Design Patterns em Java
 
Clean code @rogeriofontes-techfriday-everis
Clean code @rogeriofontes-techfriday-everisClean code @rogeriofontes-techfriday-everis
Clean code @rogeriofontes-techfriday-everis
 
Refactoring - Design no Código
Refactoring - Design no CódigoRefactoring - Design no Código
Refactoring - Design no Código
 
GURU SP - Design de aplicações orientadas a objeto
GURU SP - Design de aplicações orientadas a objetoGURU SP - Design de aplicações orientadas a objeto
GURU SP - Design de aplicações orientadas a objeto
 
Vamos falar de Clean Code, Refatoração e TDD
Vamos falar de Clean Code, Refatoração e TDDVamos falar de Clean Code, Refatoração e TDD
Vamos falar de Clean Code, Refatoração e TDD
 
Código limpo
Código limpoCódigo limpo
Código limpo
 
Padrões de projeto - Adapter, Proxy, Composite e Bridge
Padrões de projeto - Adapter, Proxy, Composite e BridgePadrões de projeto - Adapter, Proxy, Composite e Bridge
Padrões de projeto - Adapter, Proxy, Composite e Bridge
 
Programando php com excelência
Programando php com excelênciaProgramando php com excelência
Programando php com excelência
 
Solid
SolidSolid
Solid
 
Revista programar 20
Revista programar 20Revista programar 20
Revista programar 20
 
Aula1
Aula1Aula1
Aula1
 
Refactory Worshop
Refactory WorshopRefactory Worshop
Refactory Worshop
 
PHPZEIRO: Adote um framework
PHPZEIRO: Adote um frameworkPHPZEIRO: Adote um framework
PHPZEIRO: Adote um framework
 
Transição - Orientação a objeto para Funcional
Transição - Orientação a objeto para FuncionalTransição - Orientação a objeto para Funcional
Transição - Orientação a objeto para Funcional
 
O que é ser um bom programador?
O que é ser um bom programador?O que é ser um bom programador?
O que é ser um bom programador?
 
Java - Primeiros passos
Java - Primeiros passosJava - Primeiros passos
Java - Primeiros passos
 

Mais de Elaine Naomi

Hacking Evening - Liskov Substitution Principle
Hacking Evening - Liskov Substitution PrincipleHacking Evening - Liskov Substitution Principle
Hacking Evening - Liskov Substitution PrincipleElaine Naomi
 
Guru SP: Decodificando o code review
Guru SP: Decodificando o code reviewGuru SP: Decodificando o code review
Guru SP: Decodificando o code reviewElaine Naomi
 
Bootcamp de Rails - CaquiCoders Meetup
Bootcamp de Rails - CaquiCoders MeetupBootcamp de Rails - CaquiCoders Meetup
Bootcamp de Rails - CaquiCoders MeetupElaine Naomi
 
TDC SP 2019 - Decodificando o code review
TDC SP 2019 - Decodificando o code reviewTDC SP 2019 - Decodificando o code review
TDC SP 2019 - Decodificando o code reviewElaine Naomi
 
Além da programação funcional com Elixir e Erlang
Além da programação funcional com Elixir e ErlangAlém da programação funcional com Elixir e Erlang
Além da programação funcional com Elixir e ErlangElaine Naomi
 
Code review: o que isso diz sobre a cultura dos times de desenvolvimento?
Code review: o que isso diz sobre a cultura dos times de desenvolvimento?Code review: o que isso diz sobre a cultura dos times de desenvolvimento?
Code review: o que isso diz sobre a cultura dos times de desenvolvimento?Elaine Naomi
 
Explorando o Paralelismo em Workflows Intensivos em Dados com o Uso de Anotaç...
Explorando o Paralelismo em Workflows Intensivos em Dados com o Uso de Anotaç...Explorando o Paralelismo em Workflows Intensivos em Dados com o Uso de Anotaç...
Explorando o Paralelismo em Workflows Intensivos em Dados com o Uso de Anotaç...Elaine Naomi
 
Uso de Anotações Semânticas para Exploração de Paralelismo em Workflows Inten...
Uso de Anotações Semânticas para Exploração de Paralelismo em Workflows Inten...Uso de Anotações Semânticas para Exploração de Paralelismo em Workflows Inten...
Uso de Anotações Semânticas para Exploração de Paralelismo em Workflows Inten...Elaine Naomi
 
Dealing with a search engine in your application - a Solr approach for beginners
Dealing with a search engine in your application - a Solr approach for beginnersDealing with a search engine in your application - a Solr approach for beginners
Dealing with a search engine in your application - a Solr approach for beginnersElaine Naomi
 
Um Método para Paralelização Automática de Workflows Intensivos em Dados
Um Método para Paralelização Automática de Workflows Intensivos em DadosUm Método para Paralelização Automática de Workflows Intensivos em Dados
Um Método para Paralelização Automática de Workflows Intensivos em DadosElaine Naomi
 
O que é BIG DATA e como pode influenciar nossas vidas
O que é BIG DATA e como pode influenciar nossas vidasO que é BIG DATA e como pode influenciar nossas vidas
O que é BIG DATA e como pode influenciar nossas vidasElaine Naomi
 
Introdução ao MongoDB
Introdução ao MongoDBIntrodução ao MongoDB
Introdução ao MongoDBElaine Naomi
 
Workflows científicos
Workflows científicosWorkflows científicos
Workflows científicosElaine Naomi
 
Algoritmos para economia de energia no escalonamento de workflows em nuvens c...
Algoritmos para economia de energia no escalonamento de workflows em nuvens c...Algoritmos para economia de energia no escalonamento de workflows em nuvens c...
Algoritmos para economia de energia no escalonamento de workflows em nuvens c...Elaine Naomi
 

Mais de Elaine Naomi (15)

Hacking Evening - Liskov Substitution Principle
Hacking Evening - Liskov Substitution PrincipleHacking Evening - Liskov Substitution Principle
Hacking Evening - Liskov Substitution Principle
 
Guru SP: Decodificando o code review
Guru SP: Decodificando o code reviewGuru SP: Decodificando o code review
Guru SP: Decodificando o code review
 
Bootcamp de Rails - CaquiCoders Meetup
Bootcamp de Rails - CaquiCoders MeetupBootcamp de Rails - CaquiCoders Meetup
Bootcamp de Rails - CaquiCoders Meetup
 
TDC SP 2019 - Decodificando o code review
TDC SP 2019 - Decodificando o code reviewTDC SP 2019 - Decodificando o code review
TDC SP 2019 - Decodificando o code review
 
Além da programação funcional com Elixir e Erlang
Além da programação funcional com Elixir e ErlangAlém da programação funcional com Elixir e Erlang
Além da programação funcional com Elixir e Erlang
 
Code review: o que isso diz sobre a cultura dos times de desenvolvimento?
Code review: o que isso diz sobre a cultura dos times de desenvolvimento?Code review: o que isso diz sobre a cultura dos times de desenvolvimento?
Code review: o que isso diz sobre a cultura dos times de desenvolvimento?
 
Explorando o Paralelismo em Workflows Intensivos em Dados com o Uso de Anotaç...
Explorando o Paralelismo em Workflows Intensivos em Dados com o Uso de Anotaç...Explorando o Paralelismo em Workflows Intensivos em Dados com o Uso de Anotaç...
Explorando o Paralelismo em Workflows Intensivos em Dados com o Uso de Anotaç...
 
Uso de Anotações Semânticas para Exploração de Paralelismo em Workflows Inten...
Uso de Anotações Semânticas para Exploração de Paralelismo em Workflows Inten...Uso de Anotações Semânticas para Exploração de Paralelismo em Workflows Inten...
Uso de Anotações Semânticas para Exploração de Paralelismo em Workflows Inten...
 
Dealing with a search engine in your application - a Solr approach for beginners
Dealing with a search engine in your application - a Solr approach for beginnersDealing with a search engine in your application - a Solr approach for beginners
Dealing with a search engine in your application - a Solr approach for beginners
 
Um Método para Paralelização Automática de Workflows Intensivos em Dados
Um Método para Paralelização Automática de Workflows Intensivos em DadosUm Método para Paralelização Automática de Workflows Intensivos em Dados
Um Método para Paralelização Automática de Workflows Intensivos em Dados
 
O que é BIG DATA e como pode influenciar nossas vidas
O que é BIG DATA e como pode influenciar nossas vidasO que é BIG DATA e como pode influenciar nossas vidas
O que é BIG DATA e como pode influenciar nossas vidas
 
Introdução ao MongoDB
Introdução ao MongoDBIntrodução ao MongoDB
Introdução ao MongoDB
 
Workflows científicos
Workflows científicosWorkflows científicos
Workflows científicos
 
Algoritmos para economia de energia no escalonamento de workflows em nuvens c...
Algoritmos para economia de energia no escalonamento de workflows em nuvens c...Algoritmos para economia de energia no escalonamento de workflows em nuvens c...
Algoritmos para economia de energia no escalonamento de workflows em nuvens c...
 
Qt Apresentação
Qt ApresentaçãoQt Apresentação
Qt Apresentação
 

Como SOLID pode te ajudar no dia a dia