-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathQUIZ#1-Study
274 lines (237 loc) · 16.1 KB
/
QUIZ#1-Study
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
Design Patterns
SINGLETON:
\-> simplest of all the paterns and one of the most subtle
\-> Instantiates one and only one object.
\-> some objects we need only one of
\-> it is a convention for ensuring one and only one object is instantiated
\-> and it does not have many of the downsides of plain globals
public class Singleton {
private static Singleton uniqueInstance;
private Singleton() { }
public static Singleton getInstance () {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}
___________________________
| |
|_________Class_____________|
| private constructor |
| static unique instance |
| static getInstance() |
|___________________________|
DECORATOR:
\-> has the same supertype as the objects they decorate
\-> can use one or multiple decorators to wrap and object
\-> possible to pass around a decorated object in place of the original (ie. wrapped) object
\-> Objects can be decorated at any time.
\-> add its own behavior before or after (or both!), and delegates to the object it decorates
the rest of the job
\-> attaches additional responsibilities to an object dynamically.
\-> provides a flexible alternative to subclassing for extending functionality
Definition:
\-> each component can be used on its own or wrapped by a decorator
\-> each decorator HAS-A (wraps) a component, which means the secorator has an instance variable
that holds a reference to the component
\-> decorators implement the interface or abstract class as the component they will decorate.
\-> decorators can extend the state of the component
\-> concrete decorator has an instance variable for the thing it decorates (the component the decorator
wraps)
\-> decorators can add new methods; however, new behavior is typically added by doing computation
before or after an exiting method in the component.
___________________________
|------->| Abstract Component |<-------|
| |___________________________| |
| |
___________|_______________ __________________|________
| Concrete Component | | Component decorator |
| extends | | Abstract/extends |
|___________________________| |___________________________|
|
|
____________|______________
| ConcreteDecorator |
|___________________________|
| |
|___________________________|
Consequences:
\-> BENEFIT: MOre flexible than static inheritance
\-> BENEFIT: Avoids feature-laden classes high up in the class hierarchy
\-> LIABILITY: A decorator and its component are not identical
\-> LIABILITY: Lots of little objects
Summary:
\-> Inheritance: one form of extension, but not necessarily the best
\-> Principle: Favour composition over inheritance
\-> Principle: CLasses should be open for extension but closed for modification
\-> decorator Pattern prives an alternative to subclassing for extending behaviour
\-> Components can be wrapped with any number of decorators
\-> can result in many small objects in our design; overuse can result in complexity
TEMPLATE METHOD:
\-> defines the skeleton of an algorithm in a method, deferring some stpes to subclasses.
\-> lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure
___________________________ ___________________________
| abstract | | |
|_________Class_____________| | primitiveOperation1() |
| templateMethod() ---------|----------| primitiveOperation2() |
| primitiveOperation1()(abs)| | |
| primitiveOperation2()(abs)| |___________________________|
|___________________________|
^
|
____________|______________
| ConcreteClass |
|___________________________|
| primitiveOperation1() |
| primitiveOperation2() |
|___________________________|
\-> abstract class contains the template method... and abstract versions of the operations used by
the template method.
\-> can be many concrete classes each implementing the full set of operations required by the template
method.
\-> the template method makes use of the primitiveOPerations to implement an algorithm. it is decoupled
from the actual implementation of these operations
Hooks: (overrides)
\-> extra condition statement that bases its success on a concrete method.
\-> the subclass can override specific methods but does not have to.
Examples:
\-> Java Arrays Class: sort()
\-> swing JFrames
\-> java.awt.Component
\-> update()
FACADE:
\-> Reduces the number of objects a client interacts with
___________________________ ___________________________
| | | |
| Client A | | Client B |
|___________________________| |___________________________|
| |
| |
____V______________V_______
|--------| Facade |--------|
| |___________________________| |
| |
___________V_______________ __________________V________
| | | |
| Class | | Class |
|___________________________| |___________________________|
OBSERVER:
\-> Defines a one-to-many relationship so that when one object cahnges state, the others are
notified and updated automatically
___________________________ ___________________________
| <<interface>> | 0..* | <<interface>> |
|_________Subject___________|----------|__________Observer_________|
| addlistener() | observers| update() |
| removelistener() | | |
| notifylisteners() | | |
|___________________________| |___________________________|
^ ^
| |
| |
____________|______________ _____________|_____________
| Concrete Subject | 1 | Concrete observer |
|_________Subject___________|----------|________Observer___________|
| addlistener() {...} | | update() {...} |
| removelistener(){...} | | |
| notifylisteners(){...} | | |
|___________________________| subject|___________________________|
Summary:
\-> Allows different kinds of objects to react in their own way to an event
\-> The power of loose coupling
\-> the only thing the subject knows about an observer is that it implements a certain interface
\-> observers can be added at any time (they register themselves with the subject)
\-> No need to modify the subject to add new types of observers (the subject is
coupled only to the observer base class)
\-> The subject broadcasts events to all registered observers
\-> changes to either the subjects or observers will not affect the other (clients configures the
number and type of observers)
When to use the observer pattern:
\-> an abstraction has two aspects, one dependent on the other. Encapsulatiing theses aspects in
seperate objects lets you vary and reuse them independently
\-> a change to one object requires changing others, and you dont know how many objects need to be
changed.
\-> an bject should be able to notify other objects without making assumptions about who these objects
are. you dont want these objects tightly coupled.
ADAPTER:
Intent:
\-> Convert the interface of a class into another interface clients expect. Adapter lets classes work
together that couldn't otherwise because of incompatible interfaces.
\-> Wrap existuing class with a new interface.
\-> impedance match
Problem:
\-> An "Off the shelf" component offers compelling functionality that you would like to reuse, but its
"view of the world" is not compatible with the philosophy and architecture of the system currently being
developed.
Discussion:
\-> is about creating an intermediary abstraction that translates, or maps, the old component with the new system.
\-> implemented with either inheritance or with aggregation.
Structure:
_____________ ______________________________
| Client |--->| <<interface>> |
|_____________| |_____________Shape____________|
| +display(x1, y1, x2, y2) |
|______________________________|
^
|
______________|______________ ____________________________
|___________Rectangle_________| | <<adaptee>> |
| +display(x1, y1, x2, y2) |------->|________LegacyRectangle_____|
|_____________________________| | +display(x1, y1, w, h) |
: |____________________________| :
______________:_______________
|Delegate and map to adaptee |
|______________________________|
Example:
Ratchet ---> Adapter ----> socket
COMPOSITE:
Intent:
\-> Compose objects into tree structures to represent whole-part hierarchies. Composite lets clients
treat individual objects and compositions of objects uniformly.
\-> Recursive Composition.
\-> "directories contain entries, each of wich could be a directory".
\-> 1-to-many "has a" up the "is a" hierarchy.
Problem:
\-> Application needs to manuipulate a hierarchical collection of "primitive" and composite" objects.
\-> Processing of primitive object is handled one way, and processing of a composite ibject is handled differently.
\-> having to query the "type" of each object before attempting to process it is not desirable.
Discussion:
\-> use this pattern whenever you have "composites that contain components, each of which could be composite".
\-> Define an abstract base class(Component) that specifies the behavior that needs to be exercised uniformly
across all primitive and composite classes off of the component class. Each composite object "couples" itself
only to the abstract type component as it manages its "children".
Structure:
________________
| <<interface>> |
|____Component___|<------------------------------------------------\
| +doThis() | |
|________________| child |
^ |
______________|___________________ |
________|_________ ____________|____________ |
|_______Leaf_______| |________Composite________| -elements |
| +doThis() | | -childs |<>----------------------/
|__________________| |-------------------------| parent
| +addchild() |
| +removechild() |
| +getchild() |
| +doThis() |
|_________________________|----:
:
___________:________________
| //Container functionality |
| // for each child |
| child[i].doThis(); |
|____________________________|
Rules of Thumb:
\-> Composite and decorator have similar structure diagrams, reflecting the fact that both rely on
recursive composition to organize an open ended number of objects.
\-> Composite can be traversed with iterator. Vistor can apply an operation over a composite. Composite
could use chaing of responsibility to let components access global properties through their parent.
It could use observer to tie on object structure to another and state to let a component change its
behavior as its state changes.
\-> Composite can let you comnpose a mediator out of smaller pieces through recursive composition.
\-> decorator is designed to let you add responsibilities to objects without subclassing.
Composite's focus is not on embelishment but on representation. These intents are distinct but complementary.
Consequently, Composite and Decorator are often used in concert
\-> Flyweight is often combined with Composite to implement shared leaf nodes.