lectures.alex.balgavy.eu

Lecture notes from university.
git clone git://git.alex.balgavy.eu/lectures.alex.balgavy.eu.git
Log | Files | Refs | Submodules

index.md (9092B)


      1 +++
      2 title = 'Object-oriented design patterns in UML'
      3 +++
      4 ## Object-oriented design patterns in UML
      5 design pattern: a reusable form of solution to a common design problem (like a 'template')
      6 
      7 not a finished design, cannot be transformed directly into source code
      8 
      9 not prescriptive, so don't memorize them. it's important to understand when and why they're needed.
     10 
     11 speaking of, they're not always needed. don't over-complicate shit, you'll end up with a dumpster fire that nobody can maintain.
     12 
     13 essential parts of a design pattern
     14 * Pattern name
     15     * provides common vocab for software designers
     16 * Intent
     17     * What does the design pattern do?
     18     * What is its rationale and intent?
     19     * What design issue/problem does it address?
     20 * Solution
     21     * the basic elements providing solution to the problem (structure, participants, collaborations)
     22 * Consequences
     23     * results and trade offs by applying the pattern
     24 
     25 ### Creational
     26 how objects can be created (maintainability, control, extensibility)
     27 
     28 we study the singleton and factory method. then there are also abstract factory, object pool, and prototype.
     29 
     30 #### Singleton
     31 <table>
     32 <tr><th>Name</th><th>Singleton</th></tr>
     33 <tr><td>Intent</td><td>To ensure that only one instance of a class is allowed in a system. <br>Controlled access to a single object is needed</td></tr>
     34 <tr><td>Solution</td><td><img src="./singleton-solution-diagram.png">Singleton solution diagram</td></tr>
     35 <tr><td>Consequences</td><td>Controlled access to sole instance <br> Reduced name space (fewer 'global' variables) <br> permits variable number of instances</td></tr>
     36 </table>
     37 
     38 Implementation
     39 
     40 ```java
     41 public class SingleObject {
     42     // private constructor, cannot be instantiated from outside
     43     private SingleObject(){}
     44 
     45     // create the one single instance
     46     private static SingleObject instance = new SingleObject();
     47 
     48     // get the only instance
     49     public static SingleObject getInstance() {
     50         return instance;
     51     }
     52 
     53     public void showMessage() {
     54         System.out.println("Hello world!");
     55     }
     56 ```
     57 
     58 #### Factory method
     59 <table>
     60 <tr><th>Name</th><th>Factory method</th></tr>
     61 <tr><td>Intent</td><td>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 `new` operator because you don't want to hard code the class to be instantiated</td></tr>
     62 <tr><td>Solution</td><td><img src="factory-method-diagram.png">Factory method diagram</td></tr>
     63 <tr><td>Consequences</td><td>end up with dedicated class to create instances of objects <br> can pass arguments to the class to control the features of the objects</td></tr>
     64 </table>
     65 
     66 Implementation
     67 
     68 ```java
     69 public class ShapeFactory {
     70     public Shape getShape(String shapeTYpe) {
     71         if (shapeType == null) {
     72             return null;
     73         }
     74         if (shapeType.equalsIgnoreCase("CIRCLE")) {
     75             return new Circle();
     76         }
     77         else if (shapeType.equalsIgnoreCase("RECTANGLE")) {
     78             return new Rectangle();
     79         }
     80         else if (shapeType.equalsIgnoreCase("SQUARE")) {
     81             return new Square();
     82         }
     83 
     84         return null;
     85     }
     86 }
     87 ```
     88 
     89 ### Structural
     90 how to form larger structures (management of complexity, efficiency)
     91 
     92 adapter is studied in this course. also have proxy, bridge, decorator, facade, flyweight, composite, private class data.
     93 
     94 #### Adapter
     95 <table>
     96 <tr><th>Name</th><th>Adapter</th></tr>
     97 <tr><td>Intent</td><td>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</td></tr>
     98 <tr><td>Solution</td><td><img src="adapter-diagram-1.png">Adapter diagram 1 <img src="adapter-diagram-2.png">Adapter diagram 2</td></tr>
     99 <tr><td>Consequences</td><td>single class is responsible to join functionalities of independent/incompatible classes</td></tr>
    100 </table>
    101 
    102 Implementation
    103 
    104 ```java
    105 public class Wrapper {
    106     // the wrapped object
    107     private LegacyComponent legacyComponent;
    108 
    109     // constructor
    110     public Wrapper (LegacyComponent instance) {
    111         this.legacyComponent = instance;
    112     }
    113 
    114     // call to wrapped method
    115     public int doThis() {
    116         int result = 0;
    117         float value = this.legacyComponent.doThat();
    118         // magic the value into an integer somehow, then
    119         return result;
    120     }
    121 }
    122 ```
    123 
    124 ### Behavioral
    125 how responsibilities can be assigned to objects (objects decoupling, flexibility, better communication)
    126 
    127 we study observer and chain of responsibility. there are also command, interpreter, iterator, mediator, memento, null object, state, strategy, template method, and visitor.
    128 
    129 #### Observer
    130 <table>
    131 <tr><th>Name</th><th>Observer</th></tr>
    132 <tr><td>Intent</td><td>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</td></tr>
    133 <tr><td>Solution</td><td><img src="observer-diagram.png">Observer diagram</td></tr>
    134 <tr><td>Consequences</td><td>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</td></tr>
    135 </table>
    136 
    137 Implementation
    138 
    139 ```java
    140 public abstract class Observer {
    141     protected Subject subject;
    142     public abstract void update();
    143 }
    144 
    145 class MappingRover extends Observer {
    146     // specify observed subject in constructor
    147     public MappingRover(Subject subject) P
    148         this.subject = subject;
    149         subject.attach(this);
    150     }
    151 
    152     // observers "pull" information
    153     public void update() {
    154         if (this.subject.getState() == 0) {
    155             // map the environment
    156         }
    157         else {
    158             // "come back home", whatever that means
    159         }
    160     }
    161 }
    162 public abstract class Subject {
    163     private List<Observer> observers = new ArrayList<Observer>();
    164     private int state;
    165 
    166     public int getState() { ... }
    167     public void setState(int state) { ... } // and notify all observers
    168     public void attach(Observer observer) { ... } // add to observers list
    169     public void detach(Observer observer) { ... } //remove from observers list
    170 
    171     public void notifyAllObservers() { ... } // run the update function for each observer in list
    172 }
    173 
    174 public static void main(String[] args) {
    175     CentralStation cs = new CentralStation();
    176     cs.setState(0);
    177 
    178     MappingRover rover1 = new MappingRover(cs);
    179     CameraRover rover2 = new CameraRover(cs);
    180     CameraRover rover3 = new CameraRover(cs);
    181 
    182     cs.setState(1);
    183 }
    184 ```
    185 
    186 #### Chain of responsibility
    187 <table>
    188 </tr><th>Name</th><th>Chain of responsibility</th></tr>
    189 </tr><td>Intent</td><td>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)</td></tr>
    190 </tr><td>Solution</td><td><img src="chain-of-responsibility-diagram.png">Chain of responsibility diagram</td></tr>
    191 </tr><td>Consequences</td><td>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</td></tr>
    192 </table>
    193 
    194 Implementation
    195 
    196 ```java
    197 public class Task {
    198     private Coordinate coords;
    199     private RequestEnum request;
    200 
    201     // basic getters and setters
    202     public Coordinate getcoords() { ... }
    203     public setCoords(Coordinate coords) { ... }
    204 
    205     public RequestEnum getRequest() { ... }
    206     public setRequest(RequestEnum request) { ... }
    207 }
    208 
    209 public enum RequestEnum {
    210     PICTURE, MAP;
    211 }
    212 
    213 public class Coordinate {
    214     private float lat, lon;
    215 
    216     // basic getters and setters
    217     public float getLat() { ... };
    218     public setLat(float lat) { ... };
    219     public float getLon() { ... };
    220     public setLon(float lon) { ... };
    221 }
    222 
    223 public abstract class TaskHandler {
    224     TaskHandler successor;
    225     publicc void setSuccessor(TaskHandler successor) {
    226         this.successor = successor;
    227     }
    228     public abstract void handleRequest(Task task);
    229 }
    230 
    231 public class CameraRover extends TaskHandler {
    232     public void handleRequest(Task task) {
    233         if (task.request == RequestEnum.PICTURE) {
    234             // take a picture
    235         }
    236         else {
    237             // pass on to successor
    238             if (successor != null) {
    239                 successor.handleRequest(request);
    240             }
    241         }
    242     }
    243 }
    244 
    245 public class Main {
    246     public static TaskHandler setUpChain() {
    247         MapRover mapper = new MapRover();
    248         CameraRover photographer1 = new CameraRover();
    249         CameraRover photographer2 = new CameraRover();
    250         CameraRover photographer3 = new CameraRover();
    251 
    252         return mapper;
    253     }
    254     public static void main(Striing[] args) {
    255         TaskHandler chain = setUpChain;
    256 
    257         chain.handleRequest(...);
    258     }
    259 }
    260 ```
    261