480 likes | 523 Views
Lec 07. David: Hateos Jahna: Design Patterns Build SportsVans application in class Design Patterns Assignments: proThreaded $git fetch –all $git checkout -fb lec07 gerber/updates. Design Patterns. “Gang of Four” (GoF) Book.
E N D
Lec 07 • David: Hateos • Jahna: Design Patterns • Build SportsVans application in class • Design Patterns • Assignments: proThreaded $git fetch –all $git checkout -fb lec07 gerber/updates
“Gang of Four” (GoF) Book • Design Patterns: Elements of Reusable Object-Oriented Software, Addison-Wesley Publishing Company, 1994 • Written by this "gang of four" • Dr. Erich Gamma, then Software Engineer, Taligent, Inc. • Dr. Richard Helm, then Senior Technology Consultant, DMR Group • Dr. Ralph Johnson, then and now at University of Illinois, Computer Science Department • Dr. John Vlissides, then a researcher at IBM • Thomas J. Watson Research Center • See John's WikiWiki tribute page http://c2.com/cgi/wiki?JohnVlissides
Head First Design Patterns • by Eric Freeman, Elisabeth Robson, Bert Bates, Kathy Sierra · O'Reilly Media · Ebook · 694 pages · ISBN 1449331491
Why Study Patterns? • Reuse tried, proven solutions • Provides a head start • Avoids gotchas later (unanticipated things) • No need to reinvent the wheel • Establish common terminology • Design patterns provide a common point of reference • Easier to say, “We could use Strategy here.” • Provide a higher level prospective • Frees us from dealing with the details too early
Other advantages • Most design patterns make software more modifiable, less brittle • we are using time tested solutions • Using design patterns makes software systems easier to change—more maintainable • Helps increase the understanding of basic object-oriented design principles • encapsulation, inheritance, interfaces, polymorphism
The Open-Close Design Principle Software entities like classes, modules and functions should be open for extension but closed for modifications. Adding new functionality should involve minimal changes to existing code. => adding new functionality will not break the old functionality => old functionality need not be re-tested Most changes will be handled as new methods and new classes. Designs following this principle would result in resilient code which does not break on addition of new functionality.
GoF Patterns Creational Patterns Abstract Factory Builder Factory Method Prototype Singleton Structural Patterns Adapter Bridge Composite Decorator Façade Flyweight Proxy Behavioral Patterns Chain of Responsibility Command Interpreter Iterator Mediator Memento Observer State Strategy Template Method Visitor
Jahna's Design Patterns Builder Factory Singleton Adapter Facade Command Iterator
More Design Patterns Prototype Composite Decorator Flyweight Proxy ChainOfResponse Visitor • Interpreter • Mediator • Mememto • Observer • State • Strategy Many examples taken from: https://github.com/iluwatar/java-design-patterns
Prototype The Prototype pattern is a creational design pattern in software development. It is used when the type of objects to create is determined by a prototypical instance, which is cloned to produce new objects. This pattern is used to: (1) avoid subclasses of a factory in the client application, and (2) avoid the inherent cost of creating a new object in the standard way (e.g., using the 'new' keyword)
Composite The Composite pattern describes that a group of objects is to be treated in the same way as a single instance of an object. The intent of a composite is to "compose" objects into tree structures to represent part-whole hierarchies. Implementing the Composite pattern lets clients treat individual objects and compositions uniformly. In this example we have sentences composed of words composed of letters. All of the objects can be treated through the same interface.
Decorator The Decorator pattern is a more flexible alternative to subclassing. The Decorator class implements the same interface as the target and uses composition to "decorate" calls to the target. Using the Decorator pattern it is possible to change the behavior of the class during Runtime. In this example we show how the simple Troll first attacks and then flees the battle. Then we decorate the Troll with a SmartHostile and perform the attack again. You can see how the behavior changes after the decoration.
Flyweight Flyweight pattern is useful when the program needs a huge amount of objects. It provides means to decrease resource usage by sharing object instances on an enumerated Map. In this example AlchemistShop has great amount of potions on its shelves. To fill the shelves AlchemistShop uses PotionFactory (which represents the Flyweight in this example). Internally, PotionFactory holds a map of the potions and lazily creates new Potions when requested. To enable safe sharing, between clients and threads, Flyweight objects must be immutable. Flyweight objects are by definition value objects.
Proxy A proxy, in its most general form, is a class functioning as an interface to something else. The proxy could interface to anything: a network connection, a large object in memory, a file, or some other resource that is expensive or impossible to duplicate. In short, a proxy is a wrapper or agent object that is being called by the client to access the real serving object behind the The Proxy design pattern allows you to provide an interface to other objects by creating a wrapper class as the proxy. The wrapper class, which is the proxy, can add additional functionality to the object of interest without changing the object's code.
Chain Of Responsibility The Chain of Responsibility pattern is a design pattern consisting of command objects and a series of processing objects. Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain. A mechanism also exists for adding new processing objects to the end of this chain. <p> In this example we organize the request handlers ({@link RequestHandler}) into a chain where each handler has a chance to act on the request on its turn. Here the king ({@link OrcKing}) makes requests and the military orcs ({@link OrcCommander}, {@link OrcOfficer}, {@link OrcSoldier}) form the handler chain.
Interpreter The Interpreter pattern is a design pattern that specifies how to evaluate sentences in a language. The basic idea is to have a class for each symbol (terminal or nonterminal) in a specialized computer language. The syntax tree of a sentence in the language is an instance of the composite pattern and is used to evaluate (interpret) the sentence for a client. <p> In this example we use the Interpreter pattern to break sentences into expressions ( {@link Expression}) that can be evaluated and as a whole form the result.
Mediator The Mediator pattern defines an object that encapsulates how a set of objects interact. This pattern is considered to be a behavioral pattern due to the way it can alter the program's running behavior. <p> Usually a program is made up of a large number of classes. So the logic and computation is distributed among these classes. However, as more classes are developed in a program, especially during maintenance and/or refactoring, the problem of communication between these classes may become more complex. This makes the program harder to read and maintain. Furthermore, it can become difficult to change the program, since any change may affect code in several other classes. <p> With the Mediator pattern, communication between objects is encapsulated with a mediator object. Objects no longer communicate directly with each other, but instead communicate through the mediator. This reduces the dependencies between communicating objects, thereby lowering the coupling. <p> In this example the mediator encapsulates how a set of objects ({@link PartyMember}) interact. Instead of referring to each other directly they use the mediator ({@link Party}) interface
Mediator (behavioral) • define an object that encapsulates how a set of objects interacts • mediator promotes loose coupling by keeping objects from refering to each other explicitly • it lets you vary their interactions independently Mediator
Memento The Memento pattern is a software design pattern that provides the ability to restore an object to its previous state (undo via rollback). The Memento pattern is implemented with three objects: the originator, a caretaker and a memento. The originator is some object that has an internal state. The caretaker is going to do something to the originator, but wants to be able to undo the change. The caretaker first asks the originator for a memento object. Then it does whatever operation (or sequence of operations) it was going to do. To roll back to the state before the operations, it returns the memento object to the originator. The memento object itself is an opaque object (one which the caretaker cannot, or should not, change). When using this pattern, care should be taken if the originator may change other objects or resources - the memento pattern operates on a single object. <p> In this example the object ({@link Star}) gives out a "memento" ({@link StarMemento}) that contains the state of the object. Later on the memento can be set back to the object restoring the state. In this example the mediator encapsulates how a set of objects ({@link PartyMember}) interact. Instead of referring to each other directly they use the mediator ({@link Party}) interface.
Observer The Observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. It is mainly used to implement distributed event handling systems. The Observer pattern is also a key part in the familiar model–view–controller (MVC) architectural pattern. The Observer pattern is implemented in numerous programming libraries and systems, including almost all GUI toolkits. <p> In this example {@link Weather} has a state that can be observed. The {@link Orcs} and {@link Hobbits} register as observers and receive notifications when the {@link Weather} changes. use the mediator ({@link Party}) interface.
Observer (behavioral) Observer1 notify() Subject notify() Observer2 An object holding a state and notifying its observers about state’s change. notify() Observer3 The aim is to make subject independent on observers - loose coupling.
State In State pattern the container object has an internal state object that defines the current behavior. The state object can be changed to alter the behavior. <p> This can be a cleaner way for an object to change its behavior at runtime without resorting to large monolithic conditional statements and thus improves maintainability. <p> In this example the {@link Mammoth} changes its behavior as time passes by.
State (behavioral) State Pattern allows an object to alter its behavior when its internal state changes.
Strategy The Strategy pattern (also known as the policy pattern) is a software design pattern that enables an algorithm's behavior to be selected at runtime. <p> Before Java 8 the Strategies needed to be separate classes forcing the developer to write lots of boilerplate code. With modern Java it is easy to pass behavior with method references and lambdas making the code shorter and more readable. <p> In this example ({@link DragonSlayingStrategy}) encapsulates an algorithm. The containing object ({@link DragonSlayer}) can alter its behavior by changing its strategy.
Visitor Visitor pattern defines mechanism to apply operations on nodes in hierarchy. New operations can be added without altering the node interface. In this example there is a unit hierarchy beginning from {@link Commander}. This hierarchy is traversed by visitors. {@link SoldierVisitor} applies its operation on {@link Soldier}s, {@link SergeantVisitor} on {@link Sergeant}s and so on.
Concurrency Design Patterns • Asynchrnonous Method Invocation • Half-sync Half-async • Mutex • Producer Consumer • Semaphore • Thread Pool
ThreadPool (concurrency design pattern) Runnables are queued up to the executor threadpool. Available threads consume them. Restrict the number of Threads running at any given time. Timeslicing may occur anyway if the num threads exceeds The num of cores on the system.
Half and Half (concurrency design pattern) Execute on main or UI thread. Safe to Touch UI elements. onPreExecute() { } doInBackground() { } onPostExecute() { } Execute on background thread. Do NOT Touch UI elements. Execute on main or UI thread. Safe to Touch UI elements. Have one method that executes on the background. All Other methods are on the main or UI thread. AysncTask SwingWorker.
Producer Consumer (concurrency design pattern) Runnables are queued up via one pool (producer) and consumed by another (consumer). Often uses blocking queue as intermediary. Decouple the producer and consumer roles on Different threads. Use queue as intermediary. See ProducerConsumerMain
Semaphore (concurrency design pattern) Semaphores are like locks only they have a certain number of Permits. If permits == 0, the semaphore blocks a thread (makes It wait).
Mutex (concurrency design pattern) Mutex is the simplist of concurency patterns. It is a lock that blocks and prevents concurrent Access.
SportsVans with Thymeleaf • >thymeleaf example • Examine POM for starters added -web and thyme • Web, thyme, jpa, hal, h2 • Other possible apps: make/model : movie/actor : restaurant/dish : country/attraction