21. FAT MODELS
THIN CONTROLLERS
sábado, 12 de maio de 12
22. DDD ERIC EVANS
DOMAIN DRIVEN DESIGN
sábado, 12 de maio de 12
23. As vezes, lidamos com
“coisas” que não se
encaixam em
determinados objetos
sábado, 12 de maio de 12
24. APPLICATION SERVICE
DOMAIN SERVICE
INFRASTRUCTURE SERVICE
sábado, 12 de maio de 12
25. Application Service
class AccountCSVExporter
def self.to_csv(account)
CSV.generate do |csv|
account.transactions.each do |transaction|
csv << [transaction.amount, transaction.created_on]
end
end
end
end
sábado, 12 de maio de 12
26. Domain Service
class FundsTransferService
def self.transfer(from, to, amount)
Account.transaction do
from.debit amount
to.credit amount
end
end
end
sábado, 12 de maio de 12
27. Infrastructure Service
class MessagingService
def self.overdrawn_account_sms(account)
Rails.queue.push SmsJob, "#{account.number}!"
end
end
sábado, 12 de maio de 12
28. DICA 2
ENTITIES AND
VALUE OBJECTS
sábado, 12 de maio de 12
29. ENTITIES
Objetos identificáveis por suas identidades
São mutáveis(mantendo a identidade)
Possuem um ciclo de vida na aplicação
sábado, 12 de maio de 12
30. class Order < ActiveRecord::Base
belongs_to :user
has_one :address
end
class Address < ActiveRecord::Base
belongs_to :order
end
sábado, 12 de maio de 12
31. VALUE OBJECTS
Objetos identificáveis por seu valores
São imutáveis
Descrevem “coisas”
sábado, 12 de maio de 12
32. class Address
attr_reader :street, :city
def initialize(street, city)
@street, @city = street, city
end
end
sábado, 12 de maio de 12
33. class Order < ActiveRecord::Base
belongs_to :user
composed_of :address,
:mapping => [%w(address_street street),
%w(address_city city)]
end
sábado, 12 de maio de 12
35. *PRESENTERS
*EXHIBTI OBJECTS
DECORATORS
Attach additional responsibilities to an object dynamically.
Decorators provide a flexible alternative to subclassing for
extending functionality. / Gang of Four
sábado, 12 de maio de 12
36. Lógica na View
<% if user_signed_in? %>
<%= product.name %>
<% else %>
<%= link_to product.name, product_path(product) %>
<% end %>
sábado, 12 de maio de 12
37. BasePresenter
require “delegate”
class BasePresenter < SimpleDelegator
attr_accessor :context
def initialize(model, context = nil, objects = [])
objects.each do |key, value|
self.class.send :define_method, key do
value
end
end
@context = context
super model
end
end
sábado, 12 de maio de 12
38. BasePresenter
class ProductPresenter < BasePresenter
def display_name
if user
name
else
context.link_to name, context.product_path(self)
end
end
def display_description
context.render “products/description”, :product => self
end
end
sábado, 12 de maio de 12
39. PresenterHelper
module PresenterHelper
def present(presenter_class, model, objects)
presenter = presenter_class.new(model, self, objects)
yield presenter if block_given?
presenter
end
end
sábado, 12 de maio de 12
40. Utilização
<% present ProductPresenter, @product, :user =>
current_user do |presenter| %>
<%= presenter.display_name %>
<%= presenter.display_description %>
<% end %>
sábado, 12 de maio de 12
43. DEPENDÊNCIAS
EXTERNAS
GRANDES CHANCES DE
MUDAR
sábado, 12 de maio de 12
44. Exemplo:
Gem Koala
github.com/arsduo/koala
@graph = Koala::Facebook::API.new(oauth_access_token)
@friends = @graph.get_connections("me", "friends")
sábado, 12 de maio de 12
45. Criando um Adapter
class FacebookAdapter
attr_accessor :access_token, :adapter
def initialize(access_token, adapter = Koala::Facebook::API)
@access_token = access_token
@adapter = adapter.new(access_token)
end
def friends
adapter.get_connections("me", "friends", :fields => "name")
end
end
sábado, 12 de maio de 12
46. FINALIZANDO...
Ao codificar, vamos
pensar no DESIGN
sábado, 12 de maio de 12