Blog
User blogs
| Romain GEORGES |
Tag cloud
POST #20 : Ruby : Design patterns : Décorateur
le design pattern décorateur en Ruby
On veut vendre des boites aux lettres aujourd'hui.
Alors on modélise ses produits comme des objets, on va donc créer un objet Bal, avec un prix à l'unité
1 class Bal
2 def prix
3 0.2
4 end
5 end
Par la suite on va vendre des boites avec Anti-virus, comme un produit supplémentaire, l'antivirus change le prix.
1 class BalAV
2 def prix
3 0.3
4 end
5 end
Oui, mais en fait une bal AV c'est une Bal avec une option anti-virus, mais ça reste une boite aux lettres.
Certain me dirons pourquoi on hérite pas avec une surcharge de prix
1 class BalAV< Bal
2 def prix
3 0.3
4 end
5 end
Je dis, "oui mais ça reste une boite aux lettres!"
d'où le décorateur, voila l'outil :
1 module Decorateur
2 def initialize(article)
3 @article = article
4 end
5 def method_missing(method, *args)
6 args.empty? ? @article.send(method) : @article.send(method, args)
7 end
8 end
je définit mes produits supplémentaires comme des Décorateurs, des options sur le produit principale, si vous préféré
1 class AV
2 include Decorateur
3 def prix
4 @article.prix + 0.1
5 end
6 end
7
8 class Webmail
9 include Decorateur
10 def prix
11 @article.prix + 0.1
12 end
13 end
14
15 class IMAP
16 include Decorateur
17
18 def prix
19 @article.prix + 0.1
20 end
21 end
22
On va donc facilement créer une boite avec AV, tel que :
1 aBalIMAP = IMAP.new(Bal.new)
2 p aBalIMAP .prix
On peut même imaginer un Pricer :
1 class MarketPlacePricer
2 def self.premium
3 IMAP.new(Webmail.new(AV.new(Bal.new)))
4 end
5 end
6
7 p produitpremium = MarketPlacePricer.premium
8 p produitpremium .prix
Encore plus Ruby, on reprend notre class Bal
1 class Bal
2 def prix
3 0.2
4 end
5 end
Mais cette fois-ci on va utiliser des modules :
1
2 module AV
3 def prix
4 super + 0.1
5 end
6 end
7
8 module Anti-spam
9 def prix
10 super + 0.1
11 end
12 end
13
14 module IMAP
15 def prix
16 super + 0.1
17 end
18 end
19
20 module Webmail
21 def prix
22 super + 0.1
23 end
24 end
Et donc, simplement :
1
2 x = Bal.new
3 x.extend AV
4 x.extend Webmail
5 x.extend Anti-spam
6 x.extend Imap
7 p x.prix
8 p x
Also available in: Atom