Download presentation
Presentation is loading. Please wait.
1
Object-Oriented Software Engineering Practical Software Development using UML and Java Design Patterns – Part 2 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.
2
© Lethbridge/Laganière 2001 Chapter 6: Using design patterns2 Grasp Pattern – The Controller Pattern This GRASP Pattern is very useful for those developing web-based applications, among other things. Problem: Who should be responsible for handling an input system ‘event?’ Solution: Assign the responsibility for handling some kind of event message to some kind of class representing one of the following choices: Represents the overall system, device, or subsystem (façade controller) Represents a use case scenario within which the system event occurs, often named Handler, or Coordinator or Session (use-case or session controller). Many names.
3
© Lethbridge/Laganière 2001 Chapter 6: Using design patterns3 Controller Pattern: Window, Applet, Widget, View, Document, View,… classes Not Used These types do not fulfill the tasks associated with system events These typically receive events and delegate to some kind of controller. System Event – event generated by external actor. Associated with system operations in response to a system event. Actor depressing a button signifying End Sale. Only indicates a desired system operation. The ‘view’ does NOT realize this request. Requests passed on to a controller. A Controller is a non-user interface object responsible for receiving or handling a system event. Controllers define methods for the system operation.
4
© Lethbridge/Laganière 2001 Chapter 6: Using design patterns4 Controller Pattern: System Events Most applications do have ‘system events.’ Can model system as a class: Consider: (p. 237, Larman’s book) System endSale() enterItem() makeNewSale() makePayment() … Often done during analysis – assigning overall System operations to a system. Does not mean a class named System will fill these needs during Design. Rather, during Design, a Controller class is assigned the responsibilities for system operations.
5
© Lethbridge/Laganière 2001 Chapter 6: Using design patterns5 Controller: Why? Who controls system events? Presumably, there is an interface layer that sends a message (a system event message) to the domain layer via an interface (boundary) object… A Controller (coordinator…) is a type of class responsible for receiving such messages and delegating to other objects. A Controller object is kind of a ‘façade’ or ‘front’ onto the domain layer from an interface layer.
6
© Lethbridge/Laganière 2001 Chapter 6: Using design patterns6 Controller: A Controller pattern is used for: representing the overall ‘system,’ device, or subsystem. may represent a receiver or handler of all system events in a use case scenario. Please note that it is the system operations that may be defined during system behavior analysis that are designed to one or more controller classes.
7
© Lethbridge/Laganière 2001 Chapter 6: Using design patterns7 Controller - Discussion Input events. might be from a GUI operated by a person, or. a call from a telecommunications switch, or. a signal from a sensor, etc. Need some kind of ‘handler’ to orchestrate satisfying these events. It is the Controller pattern that provides some guidance for generally acceptable choices. Usually have a single controller for an entire use case, so that the state of the use case is maintained in the controller. We often, thus, have different controllers for different use cases.
8
© Lethbridge/Laganière 2001 Chapter 6: Using design patterns8 Controller - Discussion Do not give too much responsibilities to the Controllers. Controller classes delegate work to other objects; it, in turn, can coordinate / control the activity, but NOT do too much of the work itself. Remember, the Controller ‘knows’ where the model is and what the system event was that triggered it into action. It ‘knows’ (has) the logic to satisfy the system events.
9
© Lethbridge/Laganière 2001 Chapter 6: Using design patterns9 Controllers – Categories: Façade Controller This kind of controller may represent a system, device, or a subsystem. Select class name that suggests a ‘cover’ or façade over the other layers of the application, and that provides the main point of service calls from the UI layer down to other layers. Could be an abstraction, such as Register. It is a class that may represent an entire software system or subsystem. Façade Controllers are used when there are not too many events to control, and there is not sufficient need for alternating controllers. Somewhat lightweight.
10
© Lethbridge/Laganière 2001 Chapter 6: Using design patterns10 Controllers – Categories: Use Case Controller For Use Case Controllers – there is usually a different controller for each use case. Use Case Controller: NOT a domain object; Is a fabrication used to handle events. (Pure Fabrication = Grasp Pattern) Consider switching to a use case controller when a façade controller starts becoming too large and starts to lose cohesion and starts having high coupling. A use case controller is a good choice when there are a number of system events across different processes; it factors their handling into manageable classes and also forms the basis for knowing the state of the current scenario in progress.
11
© Lethbridge/Laganière 2001 Chapter 6: Using design patterns11 Connection to the RUP In the RUP, we use the terms boundary, control, and entity classes. These were used in Analysis to identify separation of concerns, etc. Boundary objects are the abstractions of the interfaces; No design objects; certainly no implementation details. Entity objects are the application-independent (and usually persistent) domain software objects; Remember, these are conceptual! Control objects are the use case handlers described in Controller pattern. ----------------------------------------------------------------------------------------------- Boundary Objects: We know from our study of the RUP that interface objects (e.g. windows or widgets) and the presentation layer should NOT have the responsibility for fulfilling system events. System operations should be handled by the application logic or domain layers of objects rather than in the interface layer of a system. “application logic / domain layers” means details handled by application /domain objects under the control of the controller (use case handler) for delegation of tasks and sequencing of tasks.
12
© Lethbridge/Laganière 2001 Chapter 6: Using design patterns12 Connection to the RUP Important to note that: A Controller object is typically a client-side object within the same process as the UI (for example, an application with a Java Swing GUI), This note is not exactly applicable when the UI is a Web client in a browser, and there is server-side software involved. Consider the following two slides:
13
© Lethbridge/Laganière 2001 Chapter 6: Using design patterns13 Client IS a Web Client: If the client is a Web client, there are various common patterns of handling the system events that are strongly influenced by the chosen server-side technical framework, such as Java servlets or Enterprise Java Beans (EJB). So, it is quite common to create server-side use case controllers with either a servlet for each use case or an Enterprise JavaBeans (EJB) ‘session bean’ for each use case. The server-side session object represents a ‘session’ of interaction with an external actor.
14
© Lethbridge/Laganière 2001 Chapter 6: Using design patterns14 Client IS NOT a web client: If the UI is not a web client (for example, it is a Swing or Windows GUI), but the application calls on remote services, it is still common to use the Controller pattern.. UI forwards the request to the local client-side Controller.. Controller may forward all or part of the request handling on to remote services. This design reduces coupling of the UI to remote services, and makes it easier, for example, to provide the services either locally or remotely, through the indirection of the client-side Controller.
15
© Lethbridge/Laganière 2001 Chapter 6: Using design patterns15 Summary. To summarize, the Controller receives the service requests from the UI layer and coordinates their fulfillment, usually be delegation to other objects. Controller can be client-side or server-side and its implementation is deeply influenced by available technologies
16
© Lethbridge/Laganière 2001 Chapter 6: Using design patterns16 GRASP Patterns Continued. We have looked at three GRASP Patterns so far: Information Expert (give responsibilities to object who has the data…) Creator (who creates instances? Object who contains, records, aggregates, closely uses the instances in question) Controller Who ‘handles’ delegation of responsibilities and orchestrates the proper sequence of activities among domain objects? And did not look at Low Cohesion High Cohesion.
17
© Lethbridge/Laganière 2001 Chapter 6: Using design patterns17 GRASP Patterns Continued There are four more GRASP Patterns, and we will look at the first one – before then looking at the Gang of Four Patterns. Polymorphism Indirection Pure Fabrication Protected Variations
18
© Lethbridge/Laganière 2001 Chapter 6: Using design patterns18 Polymorphism – a GRASP Pattern Two Problems to Consider: 1.How do we handle alternatives based on ‘type?’ (to be explained…) 2.How do we create pluggable software components? (Very desirable nowadays…) Solution: When related alternatives or behaviors vary by type (class) assign responsibilities for the behavior – using polymorphic operations – to the specific types for which the behavior varies. ------------------------------------------------------------------------------------- Consider the need to calculate the area of a geometric figure. Common problem: compute_area. But calculation varies by type, of course. Where should we assign responsibilities for the behaviors? How can we improve our design to handle additional alternatives with least disruption / error prone activities and at the same time create pluggable components??? What if we have more geometric figures to consider but same problem??
19
© Lethbridge/Laganière 2001 Chapter 6: Using design patterns19 1. Problem: Alternatives Based on Type Alternatives Based on Type – a very common occurrence in object oriented applications; Conditional variation, however, is basic in programs and this is a POOR way to accommodate our needs> Here, we are merely saying: IF rectangle Calculate: length times width; Else IF circle Calculate 3.1416*r**2; etc…. If a new variation should arrive, we need to modify EVERY IFTHENELSE or other conditional statements to allow for the variation. This is awkward to manage and error prone! So easy to miss one!
20
© Lethbridge/Laganière 2001 Chapter 6: Using design patterns20 2. Problem: Pluggable Software Components We desire to replace components in a, say, server without affecting the client. Equivalently, we wish to swap components with ‘no’ impacts. Let’s consider a realistic example. We have a Point of Sales application where there are a number of external third-party tax calculators that need to be supported. The system needs to integrate with each of these and further, there may be more calculators coming…(similar to the geometric figure area problem.) Each tax collector object has a different interface, and, while there are similarities, each does have different behavior (different way of doing the same business). We need our application to adapt to each of the external fixed interfaces or APIs. Also, we need to be able to add more with minimal disruption!!
21
© Lethbridge/Laganière 2001 Chapter 6: Using design patterns21 Question: What objects should be responsible for handling these varying external tax calculator interfaces? We really want to do the same things – but with different types! We also continue to recognize that the behaviors of the calculators will vary ‘by type’ of calculator. By Polymorphism, we should be able to assign the responsibility for adaptation to different calculator objects themselves (or calculator adaptor), and implemented with a polymorphic getTaxes operation.
22
© Lethbridge/Laganière 2001 Chapter 6: Using design patterns22 Continuing… These calculator adaptor objects are NOT the external calculators, but rather local “software objects” that represent the external calculators, or the adapter for the calculator. By sending a message to the local object, a call will ultimately be made on the external calculator in its native API. Each getTaxes method takes the Sale object as a parameter, so that the calculator can analyze the sale. This is critically important! It is then the type of the Sales object that will determine which implementation of getTaxes will be invoked. Clearly, the implementation of each getTaxes method will be different. TaxMasterAdaptor will adapt the request to the API of Tax-Master, as will the other objects via polymorphism.
23
© Lethbridge/Laganière 2001 Chapter 6: Using design patterns23 > ITaxCalculatorAdapter getTaxes(Sale) : List of TaxLineItems TaxMasterAdapter GoodAsGoldTaxProAdapter Others…. …… By Polymorphism, multiple tax calculator adapters have their own similar, but varying behavior for adapting to different external tax calculators Note that here we refer to the objects as Adapter objects… This is an ‘interface’ It is not instantiable! (next slide) (that is, cannot make objects…) Each of these objects below ‘implement’ the interface by providing a concrete implementation of getTaxes(Sale). (In the interface, this is abstract (not implemented))
24
© Lethbridge/Laganière 2001 Chapter 6: Using design patterns24 Interfaces and “implements” > ITaxCalculatorAdapter getTaxes(Sale) : List of TaxLineItems TaxMasterAdapter GoodAsGoldTaxProAdapter Others…. …… This UML notation uses the notation for specifying interfaces (a descriptor of operations without implementation, and for ‘collection’ return types; We are using a UML stereotype (interface here), which is a mechanism to categorize an element in some way. A stereotype name is surrounded by guillemets symbols, as in >. Here, our ‘element’ is a class. But we are making it a special class: an interface, which cannot be instantiated. The interface class has no objects and is ‘implemented’ by the classes that ‘realize’ the common interface. (Return or parameter types that represent a collection can be specified in any syntax, but this is the generally accepted common UML style.)
25
© Lethbridge/Laganière 2001 Chapter 6: Using design patterns25 Discussion Polymorphism is a very fundamental principle in designing how a system is organized to handle similar variations. A design based on assigning responsibilities by Polymorphism can be easily extended to handle new variations. For example, adding a new calculator adapter class with its own polymorphic getTaxes method will have minor impact on the existing design and can be readily plugged in. We merely design an additional class that implements the interface! There is NO impact on the interface nor the other classes that implement the interface!
26
© Lethbridge/Laganière 2001 Chapter 6: Using design patterns26 But be careful: Careful: Don’t do too much to ‘future-proof’ your design for unknown variations. If the variation is very likely, then go ahead; otherwise, do not. Benefits of using the Polymorphic Pattern: 1. Extensions required for new variations are easy to add. 2. New implementations can be introduced without affecting clients.
27
© Lethbridge/Laganière 2001 Chapter 6: Using design patterns27 Previews: Gang of Four (GoF) Design Patterns Based on a book by four authors that introduced some high-use patterns… We will look at the following GoF Patterns. Adapter Façade Delegator Singleton Observer Proxy Patterns.
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.