oo-design-patterns.html (10828B)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <script type="text/javascript" async src="https://cdn.jsdelivr.net/gh/mathjax/MathJax@2.7.5/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script> 5 <link rel="Stylesheet" type="text/css" href="style.css"> 6 <title>oo-design-patterns</title> 7 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 8 </head> 9 <body> 10 11 <div id="Object-oriented design patterns in UML"><h2 id="Object-oriented design patterns in UML">Object-oriented design patterns in UML</h2></div> 12 <p> 13 design pattern: a reusable form of solution to a common design problem (like a 'template') 14 </p> 15 16 <p> 17 not a finished design, cannot be transformed directly into source code 18 </p> 19 20 <p> 21 not prescriptive, so don't memorize them. it's important to understand when and why they're needed. 22 </p> 23 24 <p> 25 speaking of, they're not always needed. don't over-complicate shit, you'll end up with a dumpster fire that nobody can maintain. 26 </p> 27 28 <p> 29 essential parts of a design pattern 30 </p> 31 <ul> 32 <li> 33 Pattern name 34 35 <ul> 36 <li> 37 provides common vocab for software designers 38 39 </ul> 40 <li> 41 Intent 42 43 <ul> 44 <li> 45 What does the design pattern do? 46 47 <li> 48 What is its rationale and intent? 49 50 <li> 51 What design issue/problem does it address? 52 53 </ul> 54 <li> 55 Solution 56 57 <ul> 58 <li> 59 the basic elements providing solution to the problem (structure, participants, collaborations) 60 61 </ul> 62 <li> 63 Consequences 64 65 <ul> 66 <li> 67 results and trade offs by applying the pattern 68 69 </ul> 70 </ul> 71 72 <div id="Object-oriented design patterns in UML-Creational"><h3 id="Creational">Creational</h3></div> 73 <p> 74 how objects can be created (maintainability, control, extensibility) 75 </p> 76 77 <p> 78 we study the singleton and factory method. then there are also abstract factory, object pool, and prototype. 79 </p> 80 81 <div id="Object-oriented design patterns in UML-Creational-Singleton"><h4 id="Singleton">Singleton</h4></div> 82 <table> 83 <tr> 84 <th> 85 Name 86 </th> 87 <th> 88 Singleton 89 </th> 90 </tr> 91 <tr> 92 <td> 93 Intent 94 </td> 95 <td> 96 To ensure that only one instance of a class is allowed in a system. <br>Controlled access to a single object is needed 97 </td> 98 </tr> 99 <tr> 100 <td> 101 Solution 102 </td> 103 <td> 104 <img src="img/singleton-solution-diagram.png" alt="Singleton solution diagram" /> 105 </td> 106 </tr> 107 <tr> 108 <td> 109 Consequences 110 </td> 111 <td> 112 Controlled access to sole instance <br> Reduced name space (fewer 'global' variables) <br> permits variable number of instances 113 </td> 114 </tr> 115 </table> 116 117 <p> 118 Implementation 119 </p> 120 121 <pre java> 122 public class SingleObject { 123 // private constructor, cannot be instantiated from outside 124 private SingleObject(){} 125 126 // create the one single instance 127 private static SingleObject instance = new SingleObject(); 128 129 // get the only instance 130 public static SingleObject getInstance() { 131 return instance; 132 } 133 134 public void showMessage() { 135 System.out.println("Hello world!"); 136 } 137 </pre> 138 139 <div id="Object-oriented design patterns in UML-Creational-Factory method"><h4 id="Factory method">Factory method</h4></div> 140 <table> 141 <tr> 142 <th> 143 Name 144 </th> 145 <th> 146 Factory method 147 </th> 148 </tr> 149 <tr> 150 <td> 151 Intent 152 </td> 153 <td> 154 to abstract process of object creation so that type of created object can be determined at run time <br> to make design more customizable in terms of which objects can be created <br> avoiding the <code>new</code> operator because you don't want to hard code the class to be instantiated 155 </td> 156 </tr> 157 <tr> 158 <td> 159 Solution 160 </td> 161 <td> 162 <img src="img/factory-method-diagram.png" alt="Factory method diagram" /> 163 </td> 164 </tr> 165 <tr> 166 <td> 167 Consequences 168 </td> 169 <td> 170 end up with dedicated class to create instances of objects <br> can pass arguments to the class to control the features of the objects 171 </td> 172 </tr> 173 </table> 174 175 <p> 176 Implementation 177 </p> 178 179 <pre java> 180 public class ShapeFactory { 181 public Shape getShape(String shapeTYpe) { 182 if (shapeType == null) { 183 return null; 184 } 185 if (shapeType.equalsIgnoreCase("CIRCLE")) { 186 return new Circle(); 187 } 188 else if (shapeType.equalsIgnoreCase("RECTANGLE")) { 189 return new Rectangle(); 190 } 191 else if (shapeType.equalsIgnoreCase("SQUARE")) { 192 return new Square(); 193 } 194 195 return null; 196 } 197 } 198 </pre> 199 200 <div id="Object-oriented design patterns in UML-Structural"><h3 id="Structural">Structural</h3></div> 201 <p> 202 how to form larger structures (management of complexity, efficiency) 203 </p> 204 205 <p> 206 adapter is studied in this course. also have proxy, bridge, decorator, facade, flyweight, composite, private class data. 207 </p> 208 209 <div id="Object-oriented design patterns in UML-Structural-Adapter"><h4 id="Adapter">Adapter</h4></div> 210 <table> 211 <tr> 212 <th> 213 Name 214 </th> 215 <th> 216 Adapter 217 </th> 218 </tr> 219 <tr> 220 <td> 221 Intent 222 </td> 223 <td> 224 to convert interface of class into another interface <br> to let two or more classes with incompatible interfaces work together <br> to wrap an existing class with a new one <br> to have a kinda homogeneous interface that masks diversity of some set of various objects 225 </td> 226 </tr> 227 <tr> 228 <td> 229 Solution 230 </td> 231 <td> 232 <img src="img/adapter-diagram-1.png" alt="Adapter diagram 1" /> <img src="img/adapter-diagram-2.png" alt="Adapter diagram 2" /> 233 </td> 234 </tr> 235 <tr> 236 <td> 237 Consequences 238 </td> 239 <td> 240 single class is responsible to join functionalities of independent/incompatible classes 241 </td> 242 </tr> 243 </table> 244 245 <p> 246 Implementation 247 </p> 248 249 <pre java> 250 public class Wrapper { 251 // the wrapped object 252 private LegacyComponent legacyComponent; 253 254 // constructor 255 public Wrapper (LegacyComponent instance) { 256 this.legacyComponent = instance; 257 } 258 259 // call to wrapped method 260 public int doThis() { 261 int result = 0; 262 float value = this.legacyComponent.doThat(); 263 // magic the value into an integer somehow, then 264 return result; 265 } 266 } 267 </pre> 268 269 <div id="Object-oriented design patterns in UML-Behavioral"><h3 id="Behavioral">Behavioral</h3></div> 270 <p> 271 how responsibilities can be assigned to objects (objects decoupling, flexibility, better communication) 272 </p> 273 274 <p> 275 we study observer and chain of responsibility. there are also command, interpreter, iterator, mediator, memento, null object, state, strategy, template method, and visitor. 276 </p> 277 278 <div id="Object-oriented design patterns in UML-Behavioral-Observer"><h4 id="Observer">Observer</h4></div> 279 <table> 280 <tr> 281 <th> 282 Name 283 </th> 284 <th> 285 Observer 286 </th> 287 </tr> 288 <tr> 289 <td> 290 Intent 291 </td> 292 <td> 293 to let some object(s) be notified of state changes in other objects in the system <br> when on object changes state, all dependents are notified and updated automatically 294 </td> 295 </tr> 296 <tr> 297 <td> 298 Solution 299 </td> 300 <td> 301 <img src="img/observer-diagram.png" alt="Observer diagram" /> 302 </td> 303 </tr> 304 <tr> 305 <td> 306 Consequences 307 </td> 308 <td> 309 supports broadcast communication <br> state changes in object(s) should trigger behavior in other objects <br> you can reuse objects without reusing their observers and v-v. <br> you can remove observers without changing the subjects 310 </td> 311 </tr> 312 </table> 313 314 <p> 315 Implementation 316 </p> 317 318 <pre java> 319 public abstract class Observer { 320 protected Subject subject; 321 public abstract void update(); 322 } 323 324 class MappingRover extends Observer { 325 // specify observed subject in constructor 326 public MappingRover(Subject subject) P 327 this.subject = subject; 328 subject.attach(this); 329 } 330 331 // observers "pull" information 332 public void update() { 333 if (this.subject.getState() == 0) { 334 // map the environment 335 } 336 else { 337 // "come back home", whatever that means 338 } 339 } 340 } 341 public abstract class Subject { 342 private List<Observer> observers = new ArrayList<Observer>(); 343 private int state; 344 345 public int getState() { ... } 346 public void setState(int state) { ... } // and notify all observers 347 public void attach(Observer observer) { ... } // add to observers list 348 public void detach(Observer observer) { ... } //remove from observers list 349 350 public void notifyAllObservers() { ... } // run the update function for each observer in list 351 } 352 353 public static void main(String[] args) { 354 CentralStation cs = new CentralStation(); 355 cs.setState(0); 356 357 MappingRover rover1 = new MappingRover(cs); 358 CameraRover rover2 = new CameraRover(cs); 359 CameraRover rover3 = new CameraRover(cs); 360 361 cs.setState(1); 362 } 363 </pre> 364 365 <div id="Object-oriented design patterns in UML-Behavioral-Chain of responsibility"><h4 id="Chain of responsibility">Chain of responsibility</h4></div> 366 <table> 367 <tr> 368 <th> 369 Name 370 </th> 371 <th> 372 Chain of responsibility 373 </th> 374 </tr> 375 <tr> 376 <td> 377 Intent 378 </td> 379 <td> 380 avoid coupling sender of request to receiver by giving more than one object a chance to handle request <br> chain receiving objects and pass request along chain until an object handles it (sequential) 381 </td> 382 </tr> 383 <tr> 384 <td> 385 Solution 386 </td> 387 <td> 388 <img src="img/chain-of-responsibility-diagram.png" alt="Chain of responsibility diagram" /> 389 </td> 390 </tr> 391 <tr> 392 <td> 393 Consequences 394 </td> 395 <td> 396 Reduced coupling between objects (every object needs to know its successor) <br> handler(s) are not known a priori and a request might be unhandled <br> you can change responsibilities by changing chain at runtime 397 </td> 398 </tr> 399 </table> 400 401 <p> 402 Implementation 403 </p> 404 405 <pre java> 406 public class Task { 407 private Coordinate coords; 408 private RequestEnum request; 409 410 // basic getters and setters 411 public Coordinate getcoords() { ... } 412 public setCoords(Coordinate coords) { ... } 413 414 public RequestEnum getRequest() { ... } 415 public setRequest(RequestEnum request) { ... } 416 } 417 418 public enum RequestEnum { 419 PICTURE, MAP; 420 } 421 422 public class Coordinate { 423 private float lat, lon; 424 425 // basic getters and setters 426 public float getLat() { ... }; 427 public setLat(float lat) { ... }; 428 public float getLon() { ... }; 429 public setLon(float lon) { ... }; 430 } 431 432 public abstract class TaskHandler { 433 TaskHandler successor; 434 publicc void setSuccessor(TaskHandler successor) { 435 this.successor = successor; 436 } 437 public abstract void handleRequest(Task task); 438 } 439 440 public class CameraRover extends TaskHandler { 441 public void handleRequest(Task task) { 442 if (task.request == RequestEnum.PICTURE) { 443 // take a picture 444 } 445 else { 446 // pass on to successor 447 if (successor != null) { 448 successor.handleRequest(request); 449 } 450 } 451 } 452 } 453 454 public class Main { 455 public static TaskHandler setUpChain() { 456 MapRover mapper = new MapRover(); 457 CameraRover photographer1 = new CameraRover(); 458 CameraRover photographer2 = new CameraRover(); 459 CameraRover photographer3 = new CameraRover(); 460 461 return mapper; 462 } 463 public static void main(Striing[] args) { 464 TaskHandler chain = setUpChain; 465 466 chain.handleRequest(...); 467 } 468 } 469 </pre> 470 471 </body> 472 </html>