o que você nÃo aprendeu sobre programação orientada a objetos

147
O que você NÃO aprendeu sobre Orientação a Objetos Danilo Sato @dtsato

Upload: danilo-sato

Post on 24-May-2015

3.531 views

Category:

Technology


0 download

DESCRIPTION

Slides da minha palestra na RubyConf BR 2013 Ruby é uma linguagem orientada a objetos, porém a maneira como aprendemos orientação a objetos geralmente foca no "O que?" e pouco no "Por quê?". Aprendemos o que é herança, polimorfismo, as diferenças entre classes e objetos, mas não discutimos questões mais relevantes como: o que caracteriza um bom design OO? Quais as vantagens e desvantagens de usar herança? Como OO me ajuda a resolver problemas do dia a dia? Nesta palestra vamos abordar estas e outras questões de design e modelagem OO através de exemplos. Pretendo desbancar alguns mitos - como modelar OO é modelar o mundo real - assim como compartilhar alguns princípios para ajudar você e seu time a melhorar a qualidade do código da sua aplicação Ruby.

TRANSCRIPT

Page 1: O que você NÃO aprendeu sobre Programação Orientada a Objetos

O que você NÃO aprendeu sobre Orientação a ObjetosDanilo Sato@dtsato

Page 2: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Danilo Sato@dtsato - www.dtsato.com

Desenvolvedor, Arquiteto, Coach, DevOps, Treinador

Page 3: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Como aprendemos OO?

Page 4: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Orientação a Objetos é:Herança +

Polimorfismo +Encapsulamento

Page 5: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Orientação a Objetos é:Modelar o Mundo Real

Page 6: O que você NÃO aprendeu sobre Programação Orientada a Objetos
Page 7: O que você NÃO aprendeu sobre Programação Orientada a Objetos

“A execução de um programa é considerada um modelo físico, simulando o comportamento de

uma parte real ou imaginária do mundo."-- Kristen Nygaard

Page 8: O que você NÃO aprendeu sobre Programação Orientada a Objetos
Page 9: O que você NÃO aprendeu sobre Programação Orientada a Objetos

“Programação orientada a objetos é uma péssima ideia, que só poderia ter nascido na

Califórnia."-- Edsger W. Dijkstra

Page 10: O que você NÃO aprendeu sobre Programação Orientada a Objetos

“Programação orientada a objetos é uma péssima ideia, que só poderia ter nascido na

Califórnia."-- Edsger W. Dijkstra

Page 11: O que você NÃO aprendeu sobre Programação Orientada a Objetos
Page 12: O que você NÃO aprendeu sobre Programação Orientada a Objetos

“Na Ciência da Computação, arrogância é medida em nano-Dijkstras"

-- Alan Kay

Page 13: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Inventou o termo “Orientação a Objetos”

Page 14: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Inventou o termo “Orientação a Objetos”

Smalltalk

Page 15: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Células

Page 16: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Inventou o termo “Orientação a Objetos”

Page 17: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Inventou o termo “Orientação a Objetos”

“OO significa passagem de mensagem, retenção local, proteção e ocultação do estado

de um processo, e associação tardia de tudo"

Page 18: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Inventou o termo “Orientação a Objetos”

“OO significa passagem de mensagem, retenção local, proteção e ocultação do estado

de um processo, e associação tardia de tudo"

“A grande ideia é passagem de mensagem"

Page 19: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Inventou o termo “Orientação a Objetos”

“OO significa passagem de mensagem, retenção local, proteção e ocultação do estado

de um processo, e associação tardia de tudo"

“A grande ideia é passagem de mensagem"

“OO é um modelo computacional, não um paradigma de programação"

Page 20: O que você NÃO aprendeu sobre Programação Orientada a Objetos
Page 21: O que você NÃO aprendeu sobre Programação Orientada a Objetos
Page 22: O que você NÃO aprendeu sobre Programação Orientada a Objetos

“...(Erlang) é a única linguagem orientada a objetos e talvez eu tenha sido prematuro em

dizer o que era orientação a objetos"

-- Joe Armstrong

Page 23: O que você NÃO aprendeu sobre Programação Orientada a Objetos
Page 24: O que você NÃO aprendeu sobre Programação Orientada a Objetos
Page 25: O que você NÃO aprendeu sobre Programação Orientada a Objetos
Page 26: O que você NÃO aprendeu sobre Programação Orientada a Objetos
Page 27: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Orientação a Objetos:Programa?Linguagem?Paradigma?

Modelo Computacional?

Page 28: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Orientação a Objetos:Programa?Linguagem?Paradigma?

Modelo Computacional?

Ninguém Concorda

Page 29: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Esta palestraé sobre oo

Page 30: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Esta palestraNão é sobre oo

Page 31: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Esta palestraé sobre DESIGNDESIGN

Page 32: O que você NÃO aprendeu sobre Programação Orientada a Objetos

O que é ?DESIGN

Page 33: O que você NÃO aprendeu sobre Programação Orientada a Objetos

DESIGN Código==

Page 34: O que você NÃO aprendeu sobre Programação Orientada a Objetos

DESIGN Código==

Estrutura

Organização

FlexibilidadeTestabilidade

Legibilidade

Coesão

Acoplamento

Dependências

Page 35: O que você NÃO aprendeu sobre Programação Orientada a Objetos

BOM reduz ocusto da mudança

DESIGN

Page 36: O que você NÃO aprendeu sobre Programação Orientada a Objetos

DESIGN

Page 37: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Hipótese da stamina do DESIGN

Page 38: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Func

iona

lidad

es

Tempo

Page 39: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Func

iona

lidad

es

Tempo

Sem Design

Page 40: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Func

iona

lidad

es

Tempo

Bom Design

Sem Design

Page 41: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Func

iona

lidad

es

Tempo

Bom Design

Sem DesignOnde o design

se paga

Page 42: O que você NÃO aprendeu sobre Programação Orientada a Objetos
Page 43: O que você NÃO aprendeu sobre Programação Orientada a Objetos

2004!

Page 44: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Design foi esquecido

Rails

Page 45: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Design foi esquecido

RailsModelView

ControllerHelperMailer

...

Page 46: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Model

View

Controller

Page 47: O que você NÃO aprendeu sobre Programação Orientada a Objetos

ZeroDesign

DesignÁgil

Up-frontDesign

Page 48: O que você NÃO aprendeu sobre Programação Orientada a Objetos

DESIGN É BOM

Design “ativo”

Page 49: O que você NÃO aprendeu sobre Programação Orientada a Objetos

DESIGN É BOM

Design “passivo”

Page 50: O que você NÃO aprendeu sobre Programação Orientada a Objetos

DESIGN É BOM

Design ágil == Design evolutivo

Page 51: O que você NÃO aprendeu sobre Programação Orientada a Objetos

DESIGN É BOM

Design ágil == Design evolutivo

Page 52: O que você NÃO aprendeu sobre Programação Orientada a Objetos
Page 53: O que você NÃO aprendeu sobre Programação Orientada a Objetos
Page 54: O que você NÃO aprendeu sobre Programação Orientada a Objetos

TUDO É UM OBJETO!

Page 55: O que você NÃO aprendeu sobre Programação Orientada a Objetos

TUDO É UM OBJETO?

Page 56: O que você NÃO aprendeu sobre Programação Orientada a Objetos

TUDO É UM OBJETO?

class?

Page 57: O que você NÃO aprendeu sobre Programação Orientada a Objetos

TUDO É UM OBJETO?

if?

class?

Page 58: O que você NÃO aprendeu sobre Programação Orientada a Objetos

TUDO É UM OBJETO?

while?if?

class?

Page 59: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Smalltalk

Page 60: O que você NÃO aprendeu sobre Programação Orientada a Objetos

WARNING!

O código que você está prestes a ler foi escrito com o propósito educacional. Não faça isso em casa ou coloque código parecido em produção.

Page 61: O que você NÃO aprendeu sobre Programação Orientada a Objetos

class TrueClass def if_true(is_true, otherwise: -> {}) is_true.call end

def if_false(is_false, otherwise: -> {}) otherwise.call endend

class FalseClass def if_true(is_true, otherwise: -> {}) otherwise.call end

def if_false(is_false, otherwise: -> {}) is_false.call endend

Condições

Page 62: O que você NÃO aprendeu sobre Programação Orientada a Objetos

2.0.0 > (2 > 1).if_true -> {2.0.0?> puts "sim"2.0.0?> }, otherwise: -> {2.0.0?> puts "não"2.0.0?> }sim => nil

2.0.0 > (1 > 2).if_true -> {2.0.0?> puts "sim"2.0.0?> }, otherwise: -> {2.0.0?> puts "não"2.0.0?> }não => nil

Condições

Page 63: O que você NÃO aprendeu sobre Programação Orientada a Objetos

class Proc def while_true(&blk) self.call.if_true -> { blk.call while_true(&blk) } endend

2.0.0?> i = 02.0.0?> -> {i < 3}.while_true do2.0.0?> puts i2.0.0?> i += 12.0.0?> end012 => nil

Loops

Page 64: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Herança

Page 65: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Herança

“É um”

Page 66: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Ave

Pato Pinguim

+ voa()

+ voa() + voa()

Page 67: O que você NÃO aprendeu sobre Programação Orientada a Objetos

class Bird def fly puts "flap, flap, flap" endend

class Penguin < Bird def fly raise "I don't know how to fly" endend

flock = [Bird.new, Bird.new, Bird.new]flock.each { |bird| bird.fly }# >> flap, flap, flap# >> flap, flap, flap# >> flap, flap, flap

Page 68: O que você NÃO aprendeu sobre Programação Orientada a Objetos

class Bird def fly puts "flap, flap, flap" endend

class Penguin < Bird def fly raise "I don't know how to fly" endend

flock = [Penguin.new, Penguin.new, Penguin.new]flock.each { |bird| bird.fly }# ~> -:9:in `fly': I don't know how to fly (RuntimeError)# ~> from -:14:in `block in <main>'# ~> from -:14:in `each'

Page 69: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Princípio de Substituição de Liskov

Se S é um subtipo de T, então os objetos do tipo T podem ser

substituídos pelos objetos de tipo S em qualquer lugar do programa

Page 70: O que você NÃO aprendeu sobre Programação Orientada a Objetos
Page 71: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Isto não é uma ave.Isto não é uma ave.

Page 72: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Herança

“É um”

Page 73: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Herança

“É um”

Page 74: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Herança

Page 75: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Herança?

Page 76: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Herança

Page 77: O que você NÃO aprendeu sobre Programação Orientada a Objetos

class Book < ActiveRecord::Base def initialize(attributes = nil, options = {}) super @my_cache = {} end def number_of_pages @my_cache[:number_of_pages] ||= 10000 endend

Book.create( :title => "Lord of the Rings").number_of_pages # => 10000

Book.find_by( :title => "Lord of the Rings").number_of_pages # ~> -:8:in `number_of_pages': undefined method `[]' for nil:NilClass (NoMethodError)

Page 78: O que você NÃO aprendeu sobre Programação Orientada a Objetos

class Book < ActiveRecord::Base def after_initialize @my_cache = {} end def number_of_pages @my_cache[:number_of_pages] ||= 10000 endend

Book.create( :title => "Lord of the Rings").number_of_pages # => 10000

Book.find_by( :title => "Lord of the Rings").number_of_pages # => 10000

Page 79: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Herança:Preciso entender o que a(s) classe(s)

Pai faz(em)!

Page 80: O que você NÃO aprendeu sobre Programação Orientada a Objetos

class Deck < Array def initialize suits = %w(S H C D) indexes = %w(A 2 3 4 5 6 7 8 9 10 J Q K) cards = indexes.product(suits) super(cards) end

def draw(n) self.pop(n) endend

deck = Deck.newdeck.shuffle!.draw(5) # => [["6", "H"], ["Q", "H"], ["3", "C"], ["6", "S"], ["K", "C"]]

deck << ["A", "S"] << ["A", "S"]deck.count { |card| card[0] == "A"} # => 6 aces?

Page 81: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Não use herança se não usar todo o comportamento

do(s) pais(s)

Page 82: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Herança é perigoso

Page 83: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Herança é perigoso

Page 84: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Herança é perigoso

Page 85: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Herança é perigoso

Page 86: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Herança é perigoso

Page 87: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Use Herança quando há

especialização

Page 88: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Prefira hierarquias

rasas

Page 89: O que você NÃO aprendeu sobre Programação Orientada a Objetos

BigDecimal RationalComplexFloatInteger

Fixnum Bignum

Numeric

Page 90: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Agregação e composição

Page 91: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Agregação Composição

“Tem um”

Page 92: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Agregação

Page 93: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Agregação

Page 94: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Agregação

Page 95: O que você NÃO aprendeu sobre Programação Orientada a Objetos

composição

Page 96: O que você NÃO aprendeu sobre Programação Orientada a Objetos

composição

Page 97: O que você NÃO aprendeu sobre Programação Orientada a Objetos

composição

Page 98: O que você NÃO aprendeu sobre Programação Orientada a Objetos

class Deck def initialize suits = %w(S H C D) indexes = %w(A 2 3 4 5 6 7 8 9 10 J Q K) @cards = indexes.product(suits) end

def count(&blk); @cards.count(&blk) end def <<(card) @cards << card unless @cards.include?(card) self endend

deck = Deck.newdeck << ["A", "S"] << ["A", "S"]deck.count { |card| card[0] == "A"} # => 4

Page 99: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Prefira composição ao

invés de Herança

Page 100: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Delegação

Page 101: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Delegação

Page 102: O que você NÃO aprendeu sobre Programação Orientada a Objetos

require 'forwardable'class Deck extend Forwardable def_delegator :@cards, :pop, :draw def_delegators :@cards, :count

def initialize suits = %w(S H C D) indexes = %w(A 2 3 4 5 6 7 8 9 10 J Q K) @cards = indexes.product(suits) end

def <<(card) @cards << card unless @cards.include?(card) self endend

deck = Deck.newdeck.draw(5) # => [["Q", "D"], ["K", "S"], ["K", "H"], ["K", "C"], ["K", "D"]]

Page 103: O que você NÃO aprendeu sobre Programação Orientada a Objetos

polimorfismo

Page 104: O que você NÃO aprendeu sobre Programação Orientada a Objetos

polimorfismo

Page 105: O que você NÃO aprendeu sobre Programação Orientada a Objetos

polimorfismo

Page 106: O que você NÃO aprendeu sobre Programação Orientada a Objetos
Page 107: O que você NÃO aprendeu sobre Programação Orientada a Objetos

1. Herança

Page 108: O que você NÃO aprendeu sobre Programação Orientada a Objetos

1. Herança2. Duck Typing

Page 109: O que você NÃO aprendeu sobre Programação Orientada a Objetos

1. Herança2. Duck Typing3. Mixins

Page 110: O que você NÃO aprendeu sobre Programação Orientada a Objetos

permite separar abstração da concretização

Page 111: O que você NÃO aprendeu sobre Programação Orientada a Objetos

permite separar “O que” do

“Como”

Page 112: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Princípio “Open-Closed”

Entidades de software como classes, módulos e funções devem

ser abertas para extensão, mas fechadas para modificação

-- Bertrand Meyer

Page 113: O que você NÃO aprendeu sobre Programação Orientada a Objetos

MITO: Modelar OO é modelar o mundo real

Page 114: O que você NÃO aprendeu sobre Programação Orientada a Objetos
Page 115: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Actor

Ghost Pacman

center, direction+ collidesWith(Actor)+ advance(millis)+ getNextDirection()

Page 116: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Actor

GhostStrategy

PacmanStrategy

MovementStrategy+ getNextDirection()

Page 117: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Actor

RandomStrategy

UserControlStrategy

MovementStrategy+ getNextDirection()

Page 118: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Actor

RandomStrategy

UserControlStrategy

MovementStrategy+ getNextDirection()

TargetChasingStrategy

+ getTarget()

Page 119: O que você NÃO aprendeu sobre Programação Orientada a Objetos

o design evolui Conforme o

entendimento do domínio evolui

Page 120: O que você NÃO aprendeu sobre Programação Orientada a Objetos

[ ] Metallica (10)[ ] Iron Maiden (5)[ ] AC/DC (15)[ ] ...

[ ] Black Album (5)[ ] Master of Puppets (5)[ ] Killers (5)[ ] ...

[x] Rock (50)[ ] Clássico (100)[ ] Jazz (80)[ ] Blues

Filtros

Artista

Album

Estilo

Page 121: O que você NÃO aprendeu sobre Programação Orientada a Objetos

class Song < ActiveRecord::Base searchable do string :title string :album { album.title } string :artist { album.artist.name } ... end

def self.build_with_filters(p={}) search = Sunspot.new_search(Song) search.build do title = with(:title, p[:title]) if p[:title].present? artist = with(:artist, p[:artist]) if p[:artist].present? album = with(:album, p[:album]) if p[:album].present? ... facet :artist, exclude: artist facet :album, exclude: album end search endend

Page 122: O que você NÃO aprendeu sobre Programação Orientada a Objetos

class Song < ActiveRecord::Base ... def self.build_with_filters(p={}) search = Sunspot.new_search(Song)

if p[:artist] to_reject = p[:artist_album].map do |artist_album| JSON.parse(artist_album)['album'] end p[:album].reject! do |element| to_reject.include?(element) end p[:album] = [{}] if p[:album].empty? end

search.build do ... end search endend

Page 123: O que você NÃO aprendeu sobre Programação Orientada a Objetos

o domínionão é música

Page 124: O que você NÃO aprendeu sobre Programação Orientada a Objetos

o domínioé busca

Page 125: O que você NÃO aprendeu sobre Programação Orientada a Objetos

require 'forwadable'

module Search class SongDocument extend Forwardable def_delegators :@song, :title

def initialize(song) @song = song end

def album @song.album.title end

def artist @song.artist.name end ... endend

Page 126: O que você NÃO aprendeu sobre Programação Orientada a Objetos

module Search class SongDocument def self.search_filters(p={}) [ Search::OptionalFilter.new(:artist, p), Search::AlbumFilter.new(:artist, :artist_album, p), Search::OptionalFilter.new(:title, p) ] end def self.build_with_filters(filters, p={}) Sunspot.new_search(Song).tap do |search| filters.each do |filter| filter.apply_to(search) end Search::Faceter.new(filters, p).apply_to(search) end end endend

Page 127: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Busca

Música

DocumentFilter

Facet

Indexer

SongAlbum

Artist

Page 128: O que você NÃO aprendeu sobre Programação Orientada a Objetos

ContextosDelimitados

Busca

Música

DocumentFilter

Facet

Indexer

SongAlbum

Artist

Page 129: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Mapa de Contextos

Busca

Música

Page 130: O que você NÃO aprendeu sobre Programação Orientada a Objetos
Page 131: O que você NÃO aprendeu sobre Programação Orientada a Objetos

“Todos os modelos estão errados,alguns modelos são úteis"

-- George Box

Page 132: O que você NÃO aprendeu sobre Programação Orientada a Objetos

MITO: Modelar OO é modelar o mundo real

Page 133: O que você NÃO aprendeu sobre Programação Orientada a Objetos

MITO: Modelar OO é modelar o mundo real

Page 134: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Resumindo...

Page 135: O que você NÃO aprendeu sobre Programação Orientada a Objetos

OO é passagemde mensagem

Page 136: O que você NÃO aprendeu sobre Programação Orientada a Objetos

HerançaagregaçãoComposiçãodelegação

polimorfismo

Page 137: O que você NÃO aprendeu sobre Programação Orientada a Objetos

DESIGN É BOM

ZeroDesign

DesignÁgil

Up-frontDesign

Design ágil == Design evolutivo

Page 138: O que você NÃO aprendeu sobre Programação Orientada a Objetos

DESIGN É BOM

ZeroDesign

DesignÁgil

Up-frontDesign

Design ágil == Design evolutivo

Page 139: O que você NÃO aprendeu sobre Programação Orientada a Objetos
Page 140: O que você NÃO aprendeu sobre Programação Orientada a Objetos
Page 141: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Não modele o mundo real

Page 142: O que você NÃO aprendeu sobre Programação Orientada a Objetos

modele oseu domínio

Page 143: O que você NÃO aprendeu sobre Programação Orientada a Objetos

aprenda oseu domínio

Page 144: O que você NÃO aprendeu sobre Programação Orientada a Objetos

evolua oseu domínio

Page 145: O que você NÃO aprendeu sobre Programação Orientada a Objetos

se divirta!

Page 146: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Obrigado!

Danilo Sato@dtsato - www.dtsato.com

Desenvolvedor, Arquiteto, Coach, DevOps, Treinador

Page 147: O que você NÃO aprendeu sobre Programação Orientada a Objetos

Referências

• “Practical Object-Oriented Design in Ruby” Sandi Metz

• “Domain-Driven Design: Tackling Complexity in the Heart of Software” Eric Evans

• “Analysis Patterns: Reusable Object Models” Martin Fowler

• “Patterns of Enterprise Application Architecture” Martin Fowler

• “Design Patterns: Elements of Reusable Object-Oriented Software” Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides

• “Growing Object-Oriented Software, Guided by Tests” Steve Freeman , Nat Pryce

• “Object-Oriented Software Construction” Bertrand Meyer

Livros: