DesignPattern » Cronologia » Versione 9
Amministratore Truelite, 27-02-2007 16:14
1 | 9 | Amministratore Truelite | |
---|---|---|---|
2 | h2. Singleton Pattern |
||
3 | |||
4 | 5 | Amministratore Truelite | Il pattern singleton viene utilizzato quando si vuole creare una sola instanza di una classe. |
5 | |||
6 | Proviamo a pensare al caso di parsing di dati; essendo questa una operazione lunga e dispendiosa in termini di calcolo vogliamo poter riutilizzare i risultati della prima "esecuzione". |
||
7 | 1 | Amministratore Truelite | |
8 | Ecco un esempio: |
||
9 | 9 | Amministratore Truelite | <pre> |
10 | 5 | Amministratore Truelite | # Singleton class |
11 | 9 | Amministratore Truelite | # If instance is null creates an instance calling +new+ from object |
12 | 1 | Amministratore Truelite | class Singleton(object): |
13 | 5 | Amministratore Truelite | instance = None |
14 | |||
15 | 9 | Amministratore Truelite | def +new+(cls): |
16 | 5 | Amministratore Truelite | if cls.instance == None: |
17 | 9 | Amministratore Truelite | cls.instance = super(Singleton, cls).+new+(cls) |
18 | 5 | Amministratore Truelite | return cls.instance |
19 | |||
20 | a = Singleton() |
||
21 | |||
22 | print type(a) |
||
23 | 1 | Amministratore Truelite | print id(a) |
24 | 5 | Amministratore Truelite | |
25 | |||
26 | 1 | Amministratore Truelite | b = Singleton() |
27 | 5 | Amministratore Truelite | print type(b) |
28 | print id(b) |
||
29 | 9 | Amministratore Truelite | </pre> |
30 | 5 | Amministratore Truelite | |
31 | Risultato esecuzione: |
||
32 | |||
33 | 9 | Amministratore Truelite | <class '+main+.Singleton'> |
34 | 1 | Amministratore Truelite | |
35 | -1211002548 |
||
36 | |||
37 | 9 | Amministratore Truelite | <class '+main+.Singleton'> |
38 | 5 | Amministratore Truelite | |
39 | -1211002548 |
||
40 | |||
41 | 1 | Amministratore Truelite | |
42 | |||
43 | 9 | Amministratore Truelite | h2. Flyweight Pattern |
44 | |||
45 | |||
46 | 1 | Amministratore Truelite | Il pattern flyweight viene utilizzato quando si ha a che fare con un gran numero di oggetti con alcune caratteristiche comuni (che variano raramente) ed altre non comuni di cui ogni oggetto si fa carico per se. |
47 | |||
48 | Questo pattern può essere molto utile quando si vuole alleggerire il carico in ram di un grande numero di oggetti, facendo in modo di riutilizzare oggetti con "lo stesso stato". |
||
49 | |||
50 | Ecco un esempio di codice: |
||
51 | 9 | Amministratore Truelite | <pre> |
52 | 2 | Amministratore Truelite | # Flyweight pattern |
53 | 1 | Amministratore Truelite | # La classe "TipoOggetto" mantiene informazione delle caratteristiche intrinseche degli oggetti (in comune) |
54 | 9 | Amministratore Truelite | class [[TipoOggetto]](object): |
55 | 1 | Amministratore Truelite | _listaOggetti = {} |
56 | |||
57 | 9 | Amministratore Truelite | def +new+(cls, name): |
58 | oggetto = [[TipoOggetto]]._listaOggetti.get(name,None) |
||
59 | 1 | Amministratore Truelite | |
60 | if not oggetto: |
||
61 | 9 | Amministratore Truelite | oggetto = object.+new+(cls) |
62 | [[TipoOggetto]]._listaOggetti[name] = oggetto |
||
63 | 1 | Amministratore Truelite | return oggetto |
64 | |||
65 | |||
66 | 9 | Amministratore Truelite | def +init+(self, name): |
67 | 2 | Amministratore Truelite | self.name = name |
68 | print id(self), name |
||
69 | |||
70 | # Per mostrare come un oggetto può avere delle caratteristiche estrinseche si deve creare |
||
71 | 1 | Amministratore Truelite | # un'altra classe che utilizzi due oggetti di cui uno di tipo "TipoOggetto" |
72 | |||
73 | 9 | Amministratore Truelite | class [[ProvaFlyweight]]: |
74 | 2 | Amministratore Truelite | |
75 | 9 | Amministratore Truelite | def +init+(self, name, altro): |
76 | self.name = [[TipoOggetto]](name) |
||
77 | 2 | Amministratore Truelite | self.altro = altro |
78 | |||
79 | |||
80 | 9 | Amministratore Truelite | a = [[ProvaFlyweight]]("obj1", "1") |
81 | b = [[ProvaFlyweight]]("obj2", "2") |
||
82 | c = [[ProvaFlyweight]]("obj3", "3") |
||
83 | d = [[ProvaFlyweight]]("obj1", "4") |
||
84 | 2 | Amministratore Truelite | |
85 | print id(a.name) |
||
86 | print id(b.name) |
||
87 | print id(c.name) |
||
88 | print id(d.name) |
||
89 | |||
90 | |||
91 | print id(a.altro) |
||
92 | print id(b.altro) |
||
93 | print id(c.altro) |
||
94 | 1 | Amministratore Truelite | print id(d.altro) |
95 | |||
96 | 9 | Amministratore Truelite | </pre> |
97 | 1 | Amministratore Truelite | -1210465204 obj1 |
98 | 3 | Amministratore Truelite | |
99 | 1 | Amministratore Truelite | -1210465140 obj2 |
100 | |||
101 | -1210465076 obj3 |
||
102 | |||
103 | -1210465204 obj1 |
||
104 | 3 | Amministratore Truelite | |
105 | -1210465204 |
||
106 | |||
107 | 1 | Amministratore Truelite | -1210465140 |
108 | |||
109 | 3 | Amministratore Truelite | -1210465076 |
110 | 1 | Amministratore Truelite | |
111 | -1210465204 |
||
112 | 3 | Amministratore Truelite | |
113 | -1210102464 |
||
114 | 1 | Amministratore Truelite | |
115 | 3 | Amministratore Truelite | -1210465600 |
116 | |||
117 | 1 | Amministratore Truelite | -1210465536 |
118 | 3 | Amministratore Truelite | |
119 | 1 | Amministratore Truelite | -1210465440 |
120 | 4 | Amministratore Truelite | |
121 | 6 | Amministratore Truelite | Come si può vedere dal risultato dell'esecuzione l'attributo "name" dell'instanza "a" e "d" sono un unico oggetto. |
122 | |||
123 | |||
124 | 9 | Amministratore Truelite | h2. Observer Pattern |
125 | |||
126 | |||
127 | 6 | Amministratore Truelite | Il pattern Observer definisce una dipendenza "uno a molti" tra oggetti. In questo pattern gli oggetti rivestono due ruoli: |
128 | |||
129 | 9 | Amministratore Truelite | * Subject (il soggetto) |
130 | * Listeners (gli oggetti che ascoltano il soggetto) |
||
131 | 6 | Amministratore Truelite | |
132 | I listeners (o observer) si mettono in ascolto del soggetto; quando il soggetto "cambia stato" allora aggiorna tutti i listener in ascolto (registrati) su di lui. Questo paradigma di programmazione è quello che in alcuni linguaggi si trova nativo, ed è chiamato programmazione ad eventi. |
||
133 | |||
134 | Ecco un esempio: |
||
135 | 9 | Amministratore Truelite | <pre> |
136 | 6 | Amministratore Truelite | class Subject: |
137 | 9 | Amministratore Truelite | +listeners = [] |
138 | 6 | Amministratore Truelite | |
139 | 1 | Amministratore Truelite | def register(self, listener): |
140 | 9 | Amministratore Truelite | self.+listeners.append(listener) |
141 | 1 | Amministratore Truelite | |
142 | 9 | Amministratore Truelite | def +notifyAll(self): |
143 | for entry in self.+listeners: |
||
144 | 6 | Amministratore Truelite | entry.notify() |
145 | |||
146 | 1 | Amministratore Truelite | def statusChanged(self): |
147 | 9 | Amministratore Truelite | self.+notifyAll() |
148 | 6 | Amministratore Truelite | |
149 | class Listener: |
||
150 | 1 | Amministratore Truelite | |
151 | 9 | Amministratore Truelite | def +init+(self, listenerName): |
152 | 6 | Amministratore Truelite | self.name = listenerName |
153 | |||
154 | def notify(self): |
||
155 | print "Notify on listener ", self.name |
||
156 | 1 | Amministratore Truelite | |
157 | s = Subject() |
||
158 | 6 | Amministratore Truelite | |
159 | l1 = Listener("1") |
||
160 | l2 = Listener("2") |
||
161 | l3 = Listener("3") |
||
162 | l4 = Listener("4") |
||
163 | l5 = Listener("5") |
||
164 | |||
165 | |||
166 | s.register(l1) |
||
167 | s.register(l2) |
||
168 | s.register(l3) |
||
169 | s.register(l4) |
||
170 | s.register(l5) |
||
171 | |||
172 | s.statusChanged() |
||
173 | |||
174 | 9 | Amministratore Truelite | </pre> |
175 | 7 | Amministratore Truelite | |
176 | 8 | Amministratore Truelite | |
177 | 9 | Amministratore Truelite | h2. Decorator Pattern |
178 | |||
179 | |||
180 | 8 | Amministratore Truelite | E' un pattern abbastanza semplice che è parte fondamentale dell'OOP. Serve per aggiungere funzionalità agli oggetti. |
181 | |||
182 | Vediamo un esempio: |
||
183 | 9 | Amministratore Truelite | <pre> |
184 | 8 | Amministratore Truelite | class A: |
185 | 9 | Amministratore Truelite | def +init+(self, b): |
186 | 8 | Amministratore Truelite | """ b è una istanza della classe B""" |
187 | self.b = b |
||
188 | |||
189 | 9 | Amministratore Truelite | def +getattr+(self, name): |
190 | 8 | Amministratore Truelite | """ I metodi/attributi di A non devono conoscere come sono delegati a b """ |
191 | return getattr(self.b, name) |
||
192 | |||
193 | |||
194 | b = B() |
||
195 | a = A(b) |
||
196 | 9 | Amministratore Truelite | </pre> |
197 | 1 | Amministratore Truelite | |
198 | 9 | Amministratore Truelite | Il metodo +getaddr+ viene chiamato quando non vengono trovati gli attributi, quindi in automatico si vanno a ricercare nella |
199 | 1 | Amministratore Truelite | classe B, senza dovere distinguere le cose. |