Design Patterns – Part 3 Sources:

Slides:



Advertisements
Similar presentations
Observer Method 1. References Gamma Erich, Helm Richard, “Design Patterns: Elements of Reusable Object- Oriented Software” 2.
Advertisements

The Bridge Pattern.. Intent Decouple an abstraction from its implementation so that the two can vary independently Also known as: Handle/Body.
Chapter 6: Using Design Patterns
1 Software Testing and Quality Assurance Lecture 12 - The Testing Perspective (Chapter 2, A Practical Guide to Testing Object-Oriented Software)
Reza Gorgan Mohammadi AmirKabir University of Technology, Department of Computer Engineering & Information Technology Advanced design.
Inheritance and Class Hierarchies Chapter 3. Chapter 3: Inheritance and Class Hierarchies2 Chapter Objectives To understand inheritance and how it facilitates.
Object-Oriented Software Engineering Practical Software Development using UML and Java Design Patterns – Part 2 Sources: Chapter 6: Using Design Patterns,
Chapter 25 GRASP: More Objects with Responsibilities 1CS6359 Fall 2011 John Cole.
System Architecture Lecture 3 CSE 111 Spring /22/20151Copyright William E. Howden.
Satzinger, Jackson, and Burd Object-Orieneted Analysis & Design
Object-Oriented Software Engineering Practical Software Development using UML and Java Design Patterns Sources: Chapter 6: Using Design Patterns, and Chapter.
Object-oriented Programming Concepts
Adapters Presented By Zachary Dea. Definition A pattern found in class diagrams in which you are able to reuse an ‘adaptee’ class by providing a class,
Marcelo Santos – OOAD-CDT309, Spring 2008, IDE-MdH 1 Object-Oriented Analysis and Design - CDT309 Period 4, Spring 2008 Design Patterns: someone has already.
Chapter 6: Using Design Patterns
Object-Oriented Software Engineering Practical Software Development using UML and Java Chapter 6: Using Design Patterns.
Chapter 25 More Design Patterns.
Client/Server Software Architectures Yonglei Tao.
REFACTORING Lecture 4. Definition Refactoring is a process of changing the internal structure of the program, not affecting its external behavior and.
Design Patterns.
Object-Oriented Software Engineering Practical Software Development using UML and Java Chapter 6: Using Design Patterns Part 1.
Draw a small class diagram (2 or 3 classes) for each of the following examples: For Netflixs, you have to keep track of the movie details AND the copies.
CISC6795: Spring Object-Oriented Programming: Polymorphism.
GRASP Principles. How to Design Objects The hard step: moving from analysis to design How to do it? –Design principles (Larman: “patterns”) – an attempt.
SOEN 6011 Software Engineering Processes Section SS Fall 2007 Dr Greg Butler
Design Patterns – Details Part 2 Gang of Four (GoF) Patterns GRASP Patterns More Sources: Chapter 6: Using Design Patterns, and Chapter 30 (parts) Designing.
Object-Oriented Software Engineering Practical Software Development using UML and Java Chapter 6: Using Design Patterns 1.
Software Engineering 1 Object-oriented Analysis and Design Applying UML and Patterns An Introduction to Object-oriented Analysis and Design and Iterative.
Chapter 26 GoF Design Patterns. The Adapter Design Pattern.
Patterns in programming 1. What are patterns? “A design pattern is a general, reusable solution to a commonly occurring problem in software. A design.
Method Overriding Remember inheritance: when a child class inherits methods, variables, etc from a parent class. Example: public class Dictionary extends.
Chapter 9 Object-Oriented Software Development F Software Development Process F Analyze Relationships Among Objects F Class Development F Class Design.
Object-Oriented Software Engineering Practical Software Development using UML and Java Design Patterns – Part 2 Sources: Chapter 6: Using Design Patterns,
Object-Oriented Software Engineering Practical Software Development using UML and Java Chapter 6: Using Design Patterns.
Design Patterns Gang Qian Department of Computer Science University of Central Oklahoma.
Patterns COM379 University of Sunderland James Malone.
Structural Design Patterns
Object Oriented Software Development
Introduction to Design Patterns Part 1. © Lethbridge/Laganière 2001 Chapter 6: Using design patterns2 Patterns - Architectural Architectural Patterns:
 All calls to method toString and earnings are resolved at execution time, based on the type of the object to which currentEmployee refers.  Known as.
Summing Up Object Oriented Design. Four Major Components: Abstraction modeling real-life entities by essential information only Encapsulation clustering.
08 - StructuralCSC4071 Structural Patterns concerned with how classes and objects are composed to form larger structures –Adapter interface converter Bridge.
Programming with Java © 2002 The McGraw-Hill Companies, Inc. All rights reserved. 1 McGraw-Hill/Irwin Chapter 5 Creating Classes.
Sadegh Aliakbary. Copyright ©2014 JAVACUP.IRJAVACUP.IR All rights reserved. Redistribution of JAVACUP contents is not prohibited if JAVACUP.
Software Design Patterns Curtsy: Fahad Hassan (TxLabs)
Object-Oriented Software Engineering Practical Software Development using UML and Java Chapter 6: Using Design Patterns.
Design Patterns Software Engineering CS 561. Last Time Introduced design patterns Abstraction-Occurrence General Hierarchy Player-Role.
More Design Patterns From: Shalloway & Trott, Design Patterns Explained, 2 nd ed.
1 Chapter 5:Design Patterns. 2 What are design pattern?  Schematic description of design solution to recurring problems in software design and,  Reusable.
CHAPTER 14 Classes, Objects, and Games XNA Game Studio 4.0.
Copyright © Craig Larman All Rights Reserved COMP-350 Object-Oriented Analysis and Design GRASP: Designing Objects with Responsibilities Reference:
Inheritance and Class Hierarchies Chapter 3. Chapter 3: Inheritance and Class Hierarchies2 Chapter Objectives To understand inheritance and how it facilitates.
Inheritance and Class Hierarchies Chapter 3. Chapter Objectives  To understand inheritance and how it facilitates code reuse  To understand how Java.
L10: Model-View-Controller General application structure. User Interface: Role, Requirements, Problems Design patterns: Model – View – Controller, Observer/Observable.
Terms and Rules II Professor Evan Korth New York University (All rights reserved)
9.1 CLASS (STATIC) VARIABLES AND METHODS Defining classes is only one aspect of object-oriented programming. The real power of object-oriented programming.
Object-Oriented Software Engineering Practical Software Development using UML and Java Chapter 6: Using Design Patterns.
Phil Tayco Slide version 1.0 Created Sep 18, 2017
Design Patterns (Chapter 6 of Text Book – Study just 8)
Chapter 6: Using Design Patterns
Chapter 5:Design Patterns
GoF Patterns (GoF) popo.
MPCS – Advanced java Programming
Chapter 6: Using Design Patterns
Design Patterns – Part 2 Sources:
Introduction to Design Patterns Part 1
Week 6 Object-Oriented Programming (2): Polymorphism
Design Patterns – Part 3 Sources:
CS 350 – Software Design Singleton – Chapter 21
CMPE 135 Object-Oriented Analysis and Design March 21 Class Meeting
Presentation transcript:

Object-Oriented Software E ngineering Practical Software Development using UML and Java Design Patterns – Part 3 Sources: Chapter 6: Using Design Patterns, and Chapter 30 (parts) Designing the Logical Architecture with Patterns Craig Larman’s Text: Applying UML and Patterns, Chaps: 16, 22, & 23.

Gang of Four (GoF) Design Patterns Based on a book by four authors that introduced some high-use patterns. You will note that a few of these are VERY similar to some GRASP Patterns. We will look at the following GoF Patterns. Adapter Façade Delegator Singleton Observer Proxy Patterns. Chapter 6: Using design patterns © Lethbridge/Laganière 2001

The Façade Pattern (GoF) (1 of 4) Context: Often, an application contains several complex packages. A programmer working with such packages has to manipulate many different classes within these packages. Problem: How do you simplify the view that programmers have of a complex package? Forces: It is difficult for a programmer to understand and use an entire subsystem or complex package with many classes. If several different application classes call methods of the complex package, then any modifications made to the package will necessitate a complete review of all these classes. This is a lot of work and error prone! Chapter 6: Using design patterns © Lethbridge/Laganière 2001

Chapter 6: Using design patterns Façade Pattern (2 of 4) For packages that represent subsystems, the most common pattern of access is Façade, a GoF design pattern. Have a public façade object defining the services for the subsystem Clients collaborate with the façade, not internal subsystem components. The façade should not normally expose many low-level operations. Rather, it exposes a small number of high-level operations – the coarse-grained services. A façade does not normally do its own work. Is consolidator/mediator to underlying subsystem objects, which do the work. Façade is a wrapper - single point of access into the ‘rules engine’ of subsystem. Other packages do not see implementation of subsystem - hidden behind façade. If the subsystem is implemented by collaborating with another package or subsystem, it may be that this other package is fine-grained operations. But again, only the high-level operations are shown. Chapter 6: Using design patterns © Lethbridge/Laganière 2001

Chapter 6: Using design patterns Façade (3 of 4) Solution: «Class3» «Class2» «Class1» * «Facade» Create special class called a <<Façade>> Façade simplifies the use of the package. Simply contains a simplified set of public methods. Create a class containing the most often used / needed facilities in the package. Clients desiring services of this complex package can avail themselves of the Façade class, where it is likely what services they want are simpler to acquire. (sometime present…) Since we are talking about a complex package, other clients that need some of the complexities of the package can access these services as they normally would – via the public interfaces of these other classes – if this is indeed a package and not a subsystem. Chapter 6: Using design patterns © Lethbridge/Laganière 2001

Chapter 6: Using design patterns Façade (4 of 4) Example: Airline * * * * * * RegularFlight <<façade>> findFlight Other Subsystems or Packages… makeBooking * * * * * * Person deleteBooking Airline reservation systems have many classes and methods. Some design elements, like subsystems, may need to interact with the airline system but don’t want to be exposed to any changes that might be made to it (via dependencies).  So, we can define and Airline class to be a <<Façade>> that contains methods (access) to the most important query and booking operations in other classes in the airline system.  Thus any dependency arising from this relation is only on the Façade class. Chapter 6: Using design patterns © Lethbridge/Laganière 2001

The Singleton Pattern (Gang of Four) Context: It is very common to find classes for which only one instance should exist (singleton) Examples: a Main Window; Company or University class. Problem: How do you ensure that it is never possible to create more than one instance of a singleton class? Forces: The use of a public constructor cannot guarantee that no more than one instance will be created, and, The singleton instance itself must also be accessible to all classes that require it Chapter 6: Using design patterns © Lethbridge/Laganière 2001

Chapter 6: Using design patterns Singleton (2 of 3) Solution: «Singleton» -theInstance +getInstance Have a private class variable possibly called, ‘theInstance.’ This stores the instance itself. Then have a public class method (static method) possibly called, ‘getInstance.’ First time method is called, it creates a single instance and stores it in theInstance. Subsequent calls simply return theInstance. The public class method getInstance() makes this instance globally accessible. Note, effectively, the Singleton instance is effectively a global variable. Minimize these. Chapter 6: Using design patterns © Lethbridge/Laganière 2001

Chapter 6: Using design patterns Singleton (3 of 3) Example: getInstance(): Company if (theCompany==null) -theCompany theCompany= new Company(); -Company +getInstance return theCompany; Note: We have a private Constructor, which ensures no other class will be able to create an instance of the singleton class is needed. Chapter 6: Using design patterns © Lethbridge/Laganière 2001

The Observer Pattern (Gang of Four) This is another VERY popular design pattern. Context: When you have a two-way association created between two classes, the code for the classes becomes inseparable. If you want to reuse one class, then you also have to reuse the other. There is a dependency. Problem: How do you reduce the interconnection between classes, especially between classes that belong to different modules or subsystems? Can easily see how this increases coupling! Forces: You want to maximize the flexibility of the system to the greatest extent possible Chapter 6: Using design patterns © Lethbridge/Laganière 2001

Chapter 6: Using design patterns Observer (2 of 4) Solution: Abstract class So, what do we do? We create an abstract class we will call <<Observable>> that maintains a collection of <<Observer>> instances. <<Observable>> class is very simple; it merely has a mechanism to add and remove observers (method addObserver) as well as a method, notifyObservers, that can send an update message to each <<Observer>> in the collection. Now, any application class can declare itself to be a subclass of the <<Observable>> class. More coming: «Observable» «interface» * * * * * * * «Observer» addObserver notifyObservers update «ConcreteObservable» «ConcreteObserver» * * * * * Chapter 6: Using design patterns © Lethbridge/Laganière 2001

Chapter 6: Using design patterns Observer (3 of 4) Solution: <<Observer>> is an interface, defining only an abstract update method. Any class can thus be made to observe an <<Observable>> by declaring that it implements the interface, and by asking to be a member of the observer list of the <<Observable>>. The <<Observer>> can then expect a call to its update method whenever the <<Observable>> changes. Using this pattern, the <<Observable>> neither has to know the nature of the number of classes that will be interested in receiving an update messages nor what they will do with this information. WeatherViewer * Observers are notified when a new prediction is ready Forecaster Observable «ConcreteObservable» «ConcreteObserver» «Observable» addObserver notifyObservers «interface» «Observer» update Observer Chapter 6: Using design patterns © Lethbridge/Laganière 2001

Chapter 6: Using design patterns Observer (4 of 4) Example: Java has an Observer interface and an Observable class. This is a specific implementation of this pattern. Consider: a ‘forecast’ requires a lot of computations. Once done, it ‘notifies’ all interested instances. Forecaster is thus an observable object. One observer object (Weather Viewer) might be an interface object responsible for displaying weather forecast; it needs to know when something happens; (another might be dependent on weather information to plan a schedule). So, whenever forecaster changes, a message is sent to WeatherViewer! Observer pattern is widely used to structure software cleanly into relatively independent modules. It is the basis of MVC architecture. Observable * * * * * * * «interface» Observer Observers are notified when a new Forecaster prediction is ready WeatherViewer Chapter 6: Using design patterns © Lethbridge/Laganière 2001

The Delegation Pattern (GoF; (5)) Context: You are designing a method in a class You realize that another class has a method which provides the required service Inheritance is not appropriate (e.g. because the ‘isa’ rule does not apply Problem: How can you most effectively make use of a method that already exists in the other class? Forces: You want to minimize development cost by reusing methods; also reduce coupling between classes. Too, methods should be near the data, and the existing class with the method might be the more appropriate place for the existing method. So, … Chapter 6: Using design patterns © Lethbridge/Laganière 2001

Chapter 6: Using design patterns Delegation (2 of 5) Solution: Class containing desired method Created class that only calls a method delegatingMethod() «Delegator» «Delegate» { delegate.method(); delegatingMethod method } Create a method in a Delegator class that only calls a method in a neighboring Delegate class. In this way, we are reusing the method for which Delegate has responsibility. By neighboring class, we mean that the Delegate has an association with the Delegator class. This does increase coupling but at a much greater savings in other far less desirable design choices. Chapter 6: Using design patterns © Lethbridge/Laganière 2001

Chapter 6: Using design patterns Delegation (3 of 5) Example: push() Stack LinkedList { list.addFirst(); push addFirst } pop addLast Developed association isEmpty addAfter removeFirst removeLast object.method call… delete Created class isEmpty Here we can see that Stack operations push, pop, and isEmpty can readily use existing methods from Linked List class – addFirst, addLast, and isEmpty. Thus, we have the above relationship. We create an instance of LinkedList called list and send it a message: addFirst(); Chapter 6: Using design patterns © Lethbridge/Laganière 2001

Chapter 6: Using design patterns Delegation (4 of 5) Normally, the association already exists, and association need only be unidirectional. We may sometimes need to create a new association, if the additional complexity doesn’t increase overall complexity too much. Kind of a ‘selective inheritance.’ Chapter 6: Using design patterns © Lethbridge/Laganière 2001

Chapter 6: Using design patterns Delegation (5 of 5) Antipatterns – This is not good: Overuse generalization and inherit the method that is to be reused instead of creating a single method in the «Delegator» that does nothing other than call a method in the «Delegate>> Handling by generalization involves much unneeded baggage created only to get access to this single method. Delegator is certainly an improvement. Chapter 6: Using design patterns © Lethbridge/Laganière 2001

The Adapter Pattern (Gang of Four) Context: You are building an inheritance hierarchy and want to incorporate a method into an existing class. The reused class is also often already part of its own inheritance hierarchy. Problem: How to obtain the power of polymorphism when reusing a class whose methods have the same function but not the same signature as the other methods in the hierarchy? Remember the example I gave about calculating the area of a geometric figure or the getTaxes() polymorphic method in previous lecture slides? Chapter 6: Using design patterns © Lethbridge/Laganière 2001

Chapter 6: Using design patterns Adapter (2 of 3) Solution: «Adaptee» adaptedMethod «Superclass» polymorphicMethod «Adapter» polymorphicMethod() return adaptee.adaptedMethod(); { } Our existing hierarchy above… Here (below) is class whose method we wish to use. This class is already a part of its own inheritance hierarchy Polymorphic method We don’t want to directly incorporate the reused class into our inheritance hierarchy. Better: Use an <<Adapter>> class that is connected via association to the reused class. (Adaptee) The polymorphic methods of <<Adapter>> delegate to methods of <<Adaptee>>, and delegate method in <<Adaptee>> may / may not have same name as delegating polymorphic method. Anything else in <<Adapter>> will be unaware that it is indirectly using the facilities of an instance of <<Adaptee>>. Importantly: the Adaptee is NOT added into the inheritance hierarchy of <<Superclass>> Chapter 6: Using design patterns © Lethbridge/Laganière 2001

Chapter 6: Using design patterns Adapter (3 of 3) TimsTorus calcVolume ThreeDShape volume Sphere Torus volume() return adaptee.calcVolume(); { } Example: calcVolume calcVolume We want to create a hierarchy of three-dimensional shapes, and we’d like to use an existing implementation of calcVolume in TimsTorus. (TimsTorus is already in its own hierarchy) We cannot modify the code in TimsTorus because it is being used by others, and thus cannot make it a subclass of ThreeDShape. (multiple inheritance?) So, we develop Torus (an <<Adapter>>) such that its instances have a link to the instance of TimsTorus and these instances can delegate calcVolume (and other operations) to TimsTorus. Adapters are sometimes called Wrappers. Java wrapper classes Integer, Float, Double, etc are adapters for the Java primitive types. Chapter 6: Using design patterns © Lethbridge/Laganière 2001

The Proxy Pattern (Gang of Four) Context: Often, it is time-consuming and complicated to create instances of a class (heavyweight classes). There is a time delay and a complex mechanism involved in creating the object in memory. Large classes must be loaded from a database to support usage. Problem: How to reduce the need to create instances of a heavyweight class? Other objects may need to refer to or use instances of heavyweight classes. Many domain classes are heavyweight classes; also common for the collection classes used to implement associations (like ArrayList or Vector) to be heavyweight classes too. So, how can we reduce the need to create instances of heavyweight classes and/or to load large numbers of them from a database or server when not all of them may be needed? Chapter 6: Using design patterns © Lethbridge/Laganière 2001

Chapter 6: Using design patterns Proxy – 2 of 4 Forces: We want all the objects in a domain model (like the heavyweight classes) to be available for programs to use when they execute a system’s various responsibilities. It is also important for many objects to persist from run to run of the same program and it is frequently very impractical for all the objects to be loaded into memory when a program starts. It would be much better to do the programming as if all objects were loaded into memory. Some programmers concerned with loading and storing the objects Some programmers concerned with implementing the responsibilities of the domain model. Chapter 6: Using design patterns © Lethbridge/Laganière 2001

Chapter 6: Using design patterns Proxy (3 of 4) «interface» Note that both the Proxy and the Heavyweight implement the Interface. Solution: «ClassIF» Proxy: much simplier version of heavyweight class; contains same interface as heavyweight. * * * * * * * «Client» «Proxy» «HeavyWeight» Create a simpler version of the heavyweight class, which we call a Proxy, which has the same interface as the heavyweight class so programmers can declare variables without caring about whether the Proxy or its Heavyweight version will be put in the variable. The Proxy object is really only a placeholder, and the operations in the Proxy delegate the operation to the HeavyWeight – if and when needed…. But application progresses as if heavyweights present! Advantages: If/when needed, the Proxy can obtain the real heavyweight object. Proxy only needs to obtain the heavyweight one time and make it available in memory to all others who use the proxy. (Can have many occurrences of the proxy.) Some proxies may have implementations of a limited number of operations that can be performed without the effort of loading the Heavyweight object. Chapter 6: Using design patterns © Lethbridge/Laganière 2001

Chapter 6: Using design patterns Proxy (4 of 4) «interface» ListIF The list elements will be loaded into local memory only when needed. ListProxy PersistentList Example: «interface» Student PersistentStudent StudentProxy Here we have a variable that is to contain a List. This variable would, however, actually contain a ListProxy, since it would be expensive to load an entire list of objects into memory, and the list might not actually be needed. However, as soon as an operation accesses the list, the ListProxy might at that point create an instance of PersistentList. (Both ListProxy and PersistentList implement ListIF) On the other hand, the ListProxy might be able to answer certain queries, such as the number of elements in the list (list size given via a class variable), without going to the effort of loading the PersistentList. Imagine that the PersistentList is actually a list of students. These objects might also be proxies – in this case, instances of StudentProxy. Again, instances of PersistentStudent would only be loaded when necessary. Chapter 6: Using design patterns © Lethbridge/Laganière 2001