Programando com brincadeira de criança

Programando com brincadeira de criança

A infância, normalmente, é uma das épocas que mais gostamos de nossas vidas. Nos preocupávamos muito mais em brincar – e muitas dessas brincadeiras ajudaram a desenvolver algumas de nossas habilidades físicas e mentais, habilidades essas que possuímos até hoje.
Uma dessas brincadeiras era a tal do “Mestre Mandou”, conhece? Ela funciona da seguinte forma: uma das crianças é o mestre e as demais são os seguidores. Então o mestre começa dizendo:
– O mestre mandou!
E os seguidores respondem:
– Fazer o quê?
E então o mestre dá uma ordem e os seguidores precisam cumprí-la.
Com base nessa brincadeira (para saber mais sobre ela, clique aqui) vamos conversar um pouco sobre o “Tell don’t ask“.  Se você nunca ouviu falar, o “Tell don’t ask”  segue a mesma lógica do Mestre Mandou.
Você possui um objeto e esse objeto faz várias coisas. E, algumas dessas coisas têm condições para que o objeto faça. Complicou? Vamos exemplificar.
Imagine o seguinte caso: uma loja online, em que para adicionar um item no carrinho de compras, ele deve estar em estoque, pois não é interessante para o lojista que ele deixe de vender produtos que não possa entregar de imediato.
Show me the code!
class Cart

has_many :products

def add_product(id)
product = Product.find(id)
raise ‘Product is not in stock’ unless product.stock?
product.add_product
end
end

class Product
STOCK_LIMIT = 10

def stock
quantity > STOCK_LIMIT
end

def add_product
# Add Product
end
end

Com base nesse exemplo nós aplicaremos o “Tell don’t ask“.
Perceba que a classe Cart tem um método add_product e, dentro desse método, fazemos uma validação e chamamos o método add_product do Product.
O “Tell don’t ask” fala justamente sobre isso. Caso você tenha que executar uma ação, não deve ficar perguntando a outro objeto se deve prosseguir ou não. Você deve agrupar esses comportamentos em um único lugar e, sempre que precisar executar a ação, chamar apenas o método.
Esse método se encarregará de fazer todas as verificações sem que o método que chamou fique se preocupando sobre como as coisas vão acontecer, como na brincadeira, em que
o “Tell don’t ask” apenas diz “Faça. Não importa como.”.
Aplicando o “Tell don’t ask” ficará nesse estilo:
class Cart
has_many :products

def add_product(id)
product = Product.find(id)
product .add_product!
end
end

class Product
STOCK_LIMIT = 10

def stock
quantity > STOCK_LIMIT
end

def add_product
# Add Product
end

def add_product!
raise ‘Product is not in stock’ unless stock?
add_product
end
end

Você pode perceber agora que o carrinho não pergunta se o produto está em estoque para adicioná-lo. Ele apenas diz para o produto se adicionar e a verificação, se tem estoque ou não, é feita pelo próprio produto.
É recomendável aplicar o “Tell don’t ask” porque quando você deixa a regra de negócio junto com o método que a executa, está evitando fazer alterações em vários lugares em dado momento em que você precise alterar a regra de negócio.
Por exemplo, agora além do produto estar no estoque, ele precisa estar ativo para compras, pois você pode deixar ele visível na loja, mas não pode disponibilizá-lo para compras e essa mesma regra deve refletir tanto no carrinho, como na lista de desejos.
No primeiro exemplo seria algo assim:
class Cart
has_many :products

def add_product(id)
product = Product.find(id)
raise ‘Product is not in stock’ unless product.stock?
raise ‘Product is not enabled’ unless product.enabled?
product.add_product
end
end

class Wishlist
has_many :products

def add_product(id)
product = Product.find(id)
raise ‘Product is not in stock’ unless product.stock?
raise ‘Product is not enabled’ unless product.enabled?
product.add_product
end
end

class Product
STOCK_LIMIT = 10

def stock
quantity > STOCK_LIMIT
end

def add_product
# Add Product
end
end

Aplicando o “Tell don’t ask” nosso exemplo ficará assim:
class Cart
has_many :products

def add_product(id)
product = Product.find(id)
product.add_product
end
end

class Wishlist
has_many :products

def add_product(id)
product = Product.find(id)
product.add_product
end
end

class Product
STOCK_LIMIT = 10

def stock
quantity > STOCK_LIMIT
end

def add_product
# Add Product
end

def add_product!
raise ‘Product is not in stock’ unless product.stock?
raise ‘Product is not enabled’ unless product.enabled?
add_product
end
end
Perceba que qualquer regra nova você aplica só dentro do método add_product! na classe Product e não mais em dois lugares, como seria no exemplo em que não é aplicado o “Tell don’t ask” que seria necessário trocar tanto na classe Cart como na Wishlist.
Gostou da dica? ficou com alguma dúvida? Deixe nos comentários.
O post Programando com brincadeira de criança apareceu primeiro em Blog Locaweb – Notícias sobre tecnologia, programação e muito mais..

Programando com brincadeira de criança
Fonte: Locaweb