Object Oriented Analysis and Design Using Um L
Object Oriented Analysis and Design Using Um L
za
Table of Contents
Preface: About Solms TCD ....................................................................................xx 1. Copyright ................................................................................................xx 1.1. Solms Public License (SPL) .............................................................xx 1.1.1. Terms ................................................................................xx 1.1.2. Application domain ..............................................................xx 1.1.3. Conditions ..........................................................................xx 2. Overview ...............................................................................................xxi 2.1. Vendor-neutral, concepts-based training with short- and long-term value .xxi 2.2. Training methods ..........................................................................xxi 2.2.1. Instructor-Led Training ........................................................xxi 3. About the Author(s) .................................................................................xxi 3.1. Fritz Solms ..................................................................................xxi 3.2. Dawid Loubser ............................................................................ xxii 4. Solms TCD Guarantee ............................................................................ xxiii 1. Introduction and Overview .................................................................................. 1 1. Introduction to Object-Oriented Modeling ...................................................... 1 1.1. What is Object-Oriented Modeling? .................................................... 1 1.2. What is Object-Oriented Analysis and Design? ..................................... 1 1.3. Why use Object-Oriented Modeling? .................................................. 1 1.3.1. Clean conceptual modeling of domains ..................................... 1 1.3.2. Reducing Realization Costs .................................................... 1 1.3.3. Improved Communication between Role Players ........................ 2 1.3.4. Reducing Complexity ............................................................ 2 1.3.5. Component Based Approach ................................................... 2 1.3.6. Increasing Productivity and System Quality ............................... 3 1.3.7. Reducing Risk of Failures ...................................................... 3 1.3.8. Reduced Maintenance Costs ................................................... 4 1.3.9. Facilitating Dynamic Systems ................................................. 4 1.3.10. Availability of Analysis and Design Tools ............................... 4 2. Overview of the Unified Modeling Language (UML) ....................................... 4 2.1. What is the UML? ........................................................................... 4 2.1.1. Where does UML come from? ................................................ 4 2.2. What is object-oriented modeling? ...................................................... 5 2.3. Why UML? .................................................................................... 5 2.4. Applicability of the UML ................................................................. 5 2.5. The UML diagrams ......................................................................... 6 2.5.1. Use case diagrams ................................................................. 6 2.5.2. Class diagrams ..................................................................... 6 2.5.3. Interaction diagrams .............................................................. 6 2.5.4. Behavior Diagrams ............................................................... 7 2.5.5. Components and component diagrams ...................................... 7 2.5.6. Deployment diagrams ............................................................ 8 2.6. Views onto a context ........................................................................ 8 2.6.1. The Use-Case View .............................................................. 8 2.6.2. Responsibilities view ............................................................. 9 2.6.3. The Static View .................................................................... 9 2.6.4. The Dynamic View ............................................................... 9 2.6.5. The Deployment View ..........................................................10 2.6.6. Views at different levels of abstraction and granularity ...............10 3. Introduction into the core object-oriented concepts ..........................................10 3.1. OO as our natural language ..............................................................10 3.1.1. Mapping between natural language and OO ..............................10 3.2. What is an object? ..........................................................................11 3.3. Classes as abstractions of objects .......................................................11 3.4. Service request messages .................................................................11 3.4.1. Synchronous messages ..........................................................11 3.4.2. Asynchronous messages ........................................................12 3.4.3. Timeout messages ................................................................12 iv
Object-Oriented Analysis and Design using UML 3.5. Encapsulation ................................................................................12 3.6. Composition ..................................................................................12 3.7. Links and associations .....................................................................12 3.8. Abstraction via superclasses .............................................................13 3.9. Interfaces ......................................................................................14 3.10. Polymorphism ..............................................................................14 3.11. The state of an object, events and state transitions ...............................14 3.12. What is a component? ...................................................................14 4. Contract Based Approach ...........................................................................14 4.1. Example .......................................................................................15 4.2. Benefits of a contract-based approach ................................................15 5. Overview of CORBA ................................................................................16 5.1. A broker for service requests to objects ..............................................16 5.2. Overview of the Core CORBA Architecture ........................................16 5.3. CORBA is an object-oriented middleware technology ...........................18 5.4. The CORBA object model ...............................................................18 5.4.1. The CORBA object is thus an object from the user's perspective ...18 5.5. CORBA wrapping ..........................................................................19 5.6. CORBA object request brokers .........................................................19 I. UML with Code Mappings ..................................................................................20 2. The Use-Case View ..................................................................................27 1. Introduction to Use Cases ...................................................................27 1.1. What is the context? ................................................................27 1.2. What is a use case? .................................................................27 2. Objects and StereoTypes in use case diagrams ........................................27 2.1. UML stereotypes ....................................................................28 3. Simple use case diagrams ...................................................................28 3.1. Actors ..................................................................................29 3.1.1. Users (primary actors) ..................................................29 3.1.2. Secondary actors .........................................................29 3.1.3. Actors as roles .............................................................30 3.2. The context ...........................................................................30 3.3. Use case ...............................................................................30 3.4. Communication channels .........................................................31 4. Notes in UML ..................................................................................32 5. Relationships between use cases ..........................................................32 5.1. Use-case specialization ............................................................32 5.1.1. Abstract (high-level) uses cases and scoping .....................33 5.2. Includes relationships ..............................................................33 5.3. Specifying use-case extensions .................................................34 5.3.1. The use case extension ..................................................34 5.3.2. Extension points ..........................................................34 5.3.3. Conditionality of an extension ........................................35 6. Actor specialization ...........................................................................35 7. Packaging use cases ..........................................................................35 8. Scoping ..........................................................................................36 9. Using sequence diagrams to elaborate on use cases .................................38 9.1. Components of a typical sequence diagram .................................40 9.1.1. Messages ...................................................................40 10. High-level activity diagram for a use case ............................................41 10.1. Example: Showing multiple scenarios for the withdraw-cash use case of an auto teller ............................................................................42 10.2. Components of a simple activity diagram ..................................42 10.2.1. Automatic transitions ..................................................42 10.2.2. The context of the activities .........................................42 10.2.3. Entry states ...............................................................42 11. Mapping between sequence and activity diagrams .................................42 12. Documenting Use Cases ...................................................................42 12.1. Allister Cockburn's use case template .......................................43 12.2. Using UML .........................................................................43 12.3. Example: ATM ....................................................................44 13. Exercises .......................................................................................46 3. The Responsibilities View ..........................................................................48 v
Object-Oriented Analysis and Design using UML 1. Introduction .....................................................................................48 2. Identifying the core responsibilities for a use case ...................................48 3. Allocating responsibilities to core components .......................................49 4. Exercises .........................................................................................50 4. The Static View ........................................................................................51 1. Objects and classes ...........................................................................51 1.1. What is an object? ..................................................................51 1.2. What is a class? .....................................................................51 1.3. Identifying objects ..................................................................51 1.4. Generalization of objects to classes ............................................52 1.5. Simple object and class diagrams ..............................................52 1.6. Attributes ..............................................................................53 1.6.1. Specifying attributes for a class ......................................53 1.6.2. Default values .............................................................53 1.6.3. Constraints .................................................................53 1.6.4. Multiplicities in UML ...................................................54 1.6.5. Collection attributes .....................................................54 1.6.6. Derived attributes ........................................................55 1.7. Services ................................................................................55 1.8. OO (Camel) naming convention ................................................56 1.9. Access control .......................................................................57 1.10. Encapsulation ......................................................................57 1.11. Incomplete member list ..........................................................58 1.12. Assigning responsibilities to classes .........................................58 2. Implementation mappings for object and class diagrams ...........................59 2.1. Mapping class and object diagrams onto Java ..............................59 2.1.1. Mapping objects and classes ..........................................59 2.1.2. Mapping UML attributes onto Java .................................59 2.1.3. Mapping UML operations onto Java methods ....................60 2.1.4. Mapping UML access levels onto Java .............................60 2.2. Mapping class and object diagrams onto C++ ..............................61 2.2.1. Mapping objects and classes ..........................................61 2.2.2. Mapping UML attributes onto C++ .................................61 2.2.3. Mapping UML operations onto C++ methods ....................62 2.2.4. Mapping UML access levels onto Java .............................62 2.3. Mapping class and object diagrams onto XML .............................62 2.3.1. Mapping objects and classes ..........................................62 2.3.2. Mapping UML attributes onto XML ................................62 2.3.3. What about the operations? ............................................63 3. Specialization through sub-classing ......................................................63 3.1. Specialization as an is a relationship ..........................................63 3.1.1. Abstract references .......................................................63 3.2. Documenting a Specialization relationship in UML ......................63 3.3. Inheritance as a by-product of sub-classing ..................................64 3.3.1. Don't subclass for inheritance sake only ...........................64 3.4. Implementing specialization in Java ...........................................64 3.4.1. Account.java ...............................................................65 3.4.2. ChequeAccount.java ....................................................65 3.4.3. InheritanceTest.java .....................................................66 3.5. Implementing specialization in C++ ...........................................66 3.5.1. Public versus protected and private specialization ..............66 3.5.2. Why use only public specialization? ................................67 3.5.3. Specialization in C++ ...................................................67 3.6. Implementing specialization in XML .........................................69 3.7. Polymorphism .......................................................................70 3.7.1. Polymorphism in UML .................................................70 3.8. Polymorphism in Java .............................................................70 3.8.1. PolymorphismTest.java .................................................70 3.9. Polymorphism in C++ .............................................................71 3.10. Polymorphism and substitutability in XML ................................72 3.11. Abstract classes ....................................................................73 3.11.1. What is an abstract class? ............................................73 3.11.2. Concrete versus abstract methods ..................................73 vi
Object-Oriented Analysis and Design using UML 3.11.3. Why abstract classes? .................................................74 3.12. Implementing abstract classes in Java .......................................74 3.13. Implementing abstract classes in C++ .......................................75 3.14. Implementing abstract classes in XML ......................................75 3.15. Multiple inheritance ..............................................................75 3.16. Implementing multiple inheritance in Java .................................76 3.17. Implementing multiple inheritance in C++ .................................76 3.18. Implementing multiple inheritance in XML ...............................77 3.19. Applying constraints during sub-classing ..................................77 3.19.1. The disjoint constraint .................................................77 3.19.2. Preventing subclassing via a complete constraint ..............77 3.19.3. The incomplete constraint ............................................78 3.19.4. Extensive versus restrictive specializations ......................78 3.20. Enforcing specialization constraints in Java ...............................79 3.21. Enforcing specialization constraints in C++ ...............................79 3.22. Enforcing specialization constraints in XML ..............................79 3.23. Lessons from Design-By-Contract ...........................................80 3.23.1. Pre-conditions, post-conditions and invariants .................80 3.23.2. Example: the debit service ...........................................80 3.23.3. Design by contract and overriding methods .....................81 3.23.4. Example: Overriding the debit service ............................82 3.24. Implementation guidelines from design-by-contract ....................82 3.25. Alternatives to sub-classing ....................................................83 3.25.1. Mapping specialization onto composition .......................83 4. Interfaces ........................................................................................84 4.1. Some example interface specifications .......................................84 4.2. Defining an interface in UML ...................................................85 4.3. Specifying interface realizations ................................................86 4.4. Provided and required interfaces ...............................................87 4.4.1. Alternative notation for provided and required interfaces .....87 4.5. Viewing an interface as the skeleton of a contract between clients and service providers ..........................................................................88 4.5.1. Aspects of the contract not included in the interface ...........88 4.5.2. SLA for a Caterer ........................................................88 4.6. Implementing multiple interfaces ..............................................89 4.7. Extending interfaces ...............................................................90 4.7.1. Extending multiple interfaces .........................................90 4.8. Benefits of using interfaces ......................................................91 5. Implementing interfaces .....................................................................91 5.1. Implementing interfaces in Java ................................................91 5.1.1. Defining and interface ..................................................91 5.1.2. Implementing an interfaces ............................................91 5.1.3. Extending interfaces .....................................................92 5.1.4. Using interfaces to provide partial support for multiple inheritance ...................................................................................92 5.2. Implementing interfaces in C++ ................................................93 6. Ports ..............................................................................................93 6.1. Specifying ports .....................................................................93 6.1.1. Portals for a restaurant ..................................................94 6.2. Benefits of using ports .............................................................94 7. Composition ....................................................................................95 7.1. What is composition? ..............................................................95 7.2. Documenting composition in UML ............................................96 7.2.1. Specifying role names and multiplicities ..........................96 7.3. Composition as a relationship enforcing encapsulation ..................97 7.4. When not to use composition ....................................................97 8. Implementing composition relationships ...............................................97 8.1. Implementing composition in Java .............................................97 8.1.1. Enforcing ownership and bounded life-span ......................97 8.1.2. Supporting state change notification ................................98 8.2. Implementing composition in C++ .............................................98 8.2.1. Composition as a mechanism for simplifying memory management ..................................................................................99 vii
Object-Oriented Analysis and Design using UML 8.3. Mapping composition relationships onto XML .............................99 9. Aggregation .....................................................................................99 9.1. UML notation for aggregation ..................................................99 10. Implementing aggregation .............................................................. 101 10.1. Implementing Aggregation in Java ......................................... 101 10.1.1. State change notification ............................................ 101 10.2. Implementing Aggregation in XML ....................................... 101 11. Associations ................................................................................. 101 11.1. What are association relationships? ........................................ 101 11.1.1. Associations as message paths for client/server relationships ........................................................................................ 102 11.2. UML notation for association ................................................ 102 11.2.1. Unary associations for client-server relationships ........... 102 11.2.2. Binary associations ................................................... 103 11.3. Using verbs to identify associations ........................................ 104 11.3.1. A data acquisition, processing and control system .......... 104 11.3.2. Decoupling via interfaces .......................................... 105 11.4. Role names ........................................................................ 105 11.4.1. Example: Bonds and interest rate sources ...................... 106 11.5. Use interfaces or the server side of associations ........................ 106 11.5.1. Interfaces in bi-directional associations ........................ 107 11.6. Association constraints ........................................................ 108 11.6.1. Ordering constraints ................................................. 108 11.6.2. Or and xor constraints between relationships ................. 109 11.6.3. Accommodating or and xor relationships naturally through specialization .................................................................... 109 11.7. Association classes ............................................................. 110 11.8. Qualifications .................................................................... 111 11.9. N-ary associations .............................................................. 112 11.10. Simplify N-ary associations by introducing a mediator ............. 113 11.11. Avoid spaghetti communication networks .............................. 114 12. Implementing association relationships ............................................. 114 12.1. Implementing associations in Java ......................................... 114 12.2. Implementing association in C++ ........................................... 115 12.3. Implementing associations in XML ........................................ 115 13. Dependencies ............................................................................... 118 13.1. What is a dependency? ........................................................ 118 13.2. UML notation for specifying a dependency ............................. 118 13.3. Dependency as a weak uses relationship .................................. 119 14. Friendship ................................................................................... 119 14.1. Implementing frienship in Java .............................................. 120 14.2. Implementing friendship in C++ ............................................ 120 15. Overview of OO relationships supported in UML ................................ 120 15.1. The 5 relationships between classes ........................................ 120 15.1.1. Dependency ............................................................ 121 15.1.2. Association ............................................................. 121 15.1.3. Aggregation ............................................................ 121 15.1.4. Composition ........................................................... 121 15.1.5. Specialization .......................................................... 121 15.2. Relationships between classes and interfaces ............................ 122 15.2.1. Service providers and interfaces .................................. 122 15.2.2. Clients and interfaces ................................................ 122 15.3. A Precise Summary of the UML relationships .......................... 122 15.3.1. Shopping for relationships ......................................... 124 16. Packaging .................................................................................... 124 16.1. UML notation for packaging ................................................. 125 16.2. Exported and internal elements of a package ............................ 125 16.3. Nested packages ................................................................. 125 16.4. Importing packages ............................................................. 126 16.4.1. Importing is transitive ............................................... 126 16.5. Package specialization ......................................................... 126 16.6. Package stereoTypes ........................................................... 127 16.7. How to group elements into packages ..................................... 127 viii
Object-Oriented Analysis and Design using UML 17. Implementing packaging ................................................................ 127 17.1. Implementing packages in Java ............................................. 128 17.2. Implementing packages in C++ ............................................. 128 17.3. Implementing packages in XML ............................................ 129 18. Metaclasses .................................................................................. 130 18.1. What is a metaclass? ........................................................... 130 18.2. Constructors ...................................................................... 130 18.3. UML notation for metaclasses ............................................... 130 18.4. Class services are not resolved polymorphically ....................... 131 19. Implementing meta-classes ............................................................. 132 19.1. Implementing metaclasses in Java .......................................... 132 19.2. Implementing metaclasses in C++ .......................................... 132 20. Inner classes ................................................................................. 133 20.1. What is an inner class? ........................................................ 133 20.2. Why use inner classes? ........................................................ 133 20.3. Specifying inner classes in UML ........................................... 133 20.3.1. Example: Embedded service provider .......................... 133 20.3.2. Example: Iterators and nodes as inner classes ................ 133 21. Template types ............................................................................. 134 21.1. When should you consider using a template type? ..................... 134 21.2. Vectors ............................................................................. 134 21.3. UML notation for template types ........................................... 135 21.4. Implementing template types ................................................ 136 21.4.1. Implementing template types in Java ............................ 136 21.4.2. Implementing template types in C++ ............................ 141 22. Exercises ..................................................................................... 142 5. The Dynamic View ................................................................................. 143 1. Introduction ................................................................................... 143 1.1. UML diagrams for the dynamic model ..................................... 143 1.1.1. Interaction diagrams ................................................... 143 1.1.2. Behavior diagrams ..................................................... 144 2. Sequence Diagrams ......................................................................... 144 2.1. A vending machine example ................................................... 144 2.2. Responsibility identification and allocation for the buy-product use case of a vending machine .................................................................. 146 2.3. Sequence diagrams showing the interactions of the core components 147 2.4. Generic sequence diagrams .................................................... 148 2.4.1. Branching ................................................................ 148 2.4.2. Disadvantages of generic sequence diagrams ................... 149 2.4.3. Alternatives to generic sequence diagrams ...................... 149 2.5. Object life cycle modeling with sequence diagrams ..................... 149 2.5.1. Life lines and activity bars ........................................... 150 2.5.2. Object creation and destruction ..................................... 150 2.5.3. Iteration ................................................................... 150 2.6. Message types ..................................................................... 150 2.6.1. Synchronous messages ................................................ 151 2.6.2. Timeout messages ...................................................... 151 2.6.3. Asynchronous messages .............................................. 151 2.6.4. Returns .................................................................... 151 2.7. Implementing different types of messages in Java ....................... 151 2.7.1. Synchronous messages ................................................ 152 2.7.2. Simple calls .............................................................. 152 2.7.3. Asynchronous messages .............................................. 152 2.7.4. Sychronous call with immediate return .......................... 152 2.8. Further timing features for sequence diagrams ........................... 152 2.8.1. Non-instantaneous messages ........................................ 152 2.8.2. Timing constraints ..................................................... 153 2.9. Concurrencies ...................................................................... 153 2.9.1. Concurrent activities within an object ............................ 153 2.9.2. Concurrencies versus branching .................................... 153 2.10. Making classes safe for concurrent access ............................... 153 2.10.1. Why do we need access control? ................................. 153 2.10.2. Protection against corruption due to concurrent access .... 154 ix
Object-Oriented Analysis and Design using UML 3. Activity diagrams ........................................................................... 155 3.1. Exit states ........................................................................... 155 3.2. Forking and synchronization ................................................... 155 3.2.1. Forking .................................................................... 155 3.2.2. Synchronization ........................................................ 156 3.3. Activities across objects: swim-lanes ....................................... 156 3.4. Showing object flow in an activity diagram ............................... 157 3.5. Processing an insurance claim ................................................. 158 3.6. Nested activities ................................................................... 159 4. State charts .................................................................................... 160 4.1. States ................................................................................. 160 4.2. Messages and events ............................................................. 161 4.2.1. Call events ............................................................... 161 4.2.2. Signals ..................................................................... 161 4.2.3. Time events .............................................................. 161 4.2.4. State change events .................................................... 161 4.2.5. Event specialization ................................................... 162 4.2.6. External versus internal events ..................................... 163 4.2.7. Full signature for state transition label ............................ 163 5. Communication diagrams ................................................................. 164 5.1. Example: Communication diagram for a vending machine ........... 164 6. The context of the collaboration ......................................................... 165 6. Deployment View ................................................................................... 167 1. Introduction ................................................................................... 167 2. Showing deployment aspects ............................................................ 167 7. The Object Constraint Language (OCL) ...................................................... 169 1. Introduction ................................................................................... 169 1.1. Where does the OCL come from? ............................................ 169 1.2. Applications for OCL ............................................................ 169 1.3. Some core features of OCL .................................................... 169 1.4. Types of constraints .............................................................. 169 1.5. The context of a constraint ..................................................... 170 1.6. Constraint expressions ........................................................... 170 2. Invariants ...................................................................................... 170 2.1. Positive balance constraint for savings accounts ......................... 170 2.2. OCL operators ..................................................................... 171 2.3. Conditionals and operations ................................................... 173 2.4. Navigating object graphs ....................................................... 173 2.5. Constraints involving collections ............................................. 174 2.5.1. Collection operators ................................................... 175 2.5.2. Iterating across a collection .......................................... 177 2.5.3. Selecting a specific type of collection ............................ 178 2.5.4. Collecting and summing across a collection .................... 178 2.5.5. Selecting and rejecting elements from a collection ........... 178 2.5.6. Testing an expression across all elements in a collection .... 178 3. Pre- and Postcondition in OCL .......................................................... 179 4. OCL and Testing ............................................................................ 179 4.1. Functional testing ................................................................. 179 4.2. System integrity testing ......................................................... 180 5. Exercises ....................................................................................... 180 8. URDAD for System Design .............................................................................. 181 1. Introduction ........................................................................................... 181 1.1. Design versus development processes .............................................. 181 1.2. Background ................................................................................. 181 1.3. Design versus Architecture ............................................................. 181 1.4. Requirements for good design ......................................................... 182 1.4.1. Benefits of adhering to these design principles ........................ 183 1.5. URDAD drivers ........................................................................... 183 2. URDAD: The Process .............................................................................. 184 2.1. Overview of URDAD ................................................................... 184 2.2. Responsibility Identification ........................................................... 185 2.3. Responsibility Allocation ............................................................... 186 2.4. Specifying the collaboration ........................................................... 186 x
Object-Oriented Analysis and Design using UML 2.5. Projecting out the context of the collaboration .................................... 188 2.6. Service provider contracts .............................................................. 189 2.6.1. Pre-Conditions .................................................................. 190 2.6.2. Post-Conditions ................................................................. 190 2.6.3. Invariance constraints ......................................................... 190 2.6.4. Quality requirements .......................................................... 190 2.6.5. Contracts and testing .......................................................... 190 2.6.6. Contracts and the Object Constraint Language ......................... 190 2.6.7. MailSender contract ........................................................... 191 2.7. Value objects ............................................................................... 191 2.8. Transition to the next level of granularity .......................................... 191 3. Summary and conclusions ........................................................................ 193 9. Design Patterns .............................................................................................. 194 1. History of design patterns ......................................................................... 194 1.1. The classical design patterns book ................................................... 194 1.2. Patters in architecture .................................................................... 194 1.3. Early patterns in software development ............................................ 194 2. Introduction ........................................................................................... 194 3. Benefits of patterns ................................................................................. 195 4. Discovering patterns ................................................................................ 195 5. Documenting Patterns .............................................................................. 195 5.1. Documentation template ................................................................ 195 6. Pattern repositories .................................................................................. 197 7. The composite pattern .............................................................................. 197 7.1. Intent ......................................................................................... 197 7.2. Structure ..................................................................................... 197 7.3. Example applications .................................................................... 198 7.3.1. File system ....................................................................... 198 7.3.2. Portfolios and assets ........................................................... 199 7.3.3. Java GUI libraries .............................................................. 200 7.3.4. Document structures ........................................................... 201 7.4. Consequences .............................................................................. 201 7.5. Implementation guidelines ............................................................. 202 7.5.1. Implementing composition relationships ................................ 202 7.5.2. Implementing aggregation relationships ................................. 202 7.5.3. Implementing associative composite patterns .......................... 202 7.5.4. Simple implementation of asset/portfolio example ................... 203 7.6. Related patterns ........................................................................... 206 8. The decorator pattern ............................................................................... 206 8.1. Intent ......................................................................................... 206 8.2. Structure ..................................................................................... 207 8.3. Example applications .................................................................... 208 8.3.1. GUI components ............................................................... 208 8.3.2. Account decorators ............................................................ 209 8.3.3. I/O stream decorators ......................................................... 209 8.4. Benefits above method overriding ................................................... 210 8.5. Consequences .............................................................................. 210 8.5.1. Object identity is not preserved ............................................ 211 8.6. Implementation guidelines ............................................................. 211 8.7. Related patterns ........................................................................... 211 9. The visitor pattern ................................................................................... 211 9.1. Intent ......................................................................................... 212 9.2. Solution ...................................................................................... 212 9.2.1. Responsibility Allocation .................................................... 212 9.2.2. Structure .......................................................................... 213 9.2.3. Dynamics ......................................................................... 213 9.3. Example applications .................................................................... 214 9.3.1. Total salary calculator ......................................................... 214 9.4. Consequences .............................................................................. 215 9.5. Implementation guidelines ............................................................. 216 9.6. Related patterns ........................................................................... 218 10. Aspect Oriented Development ......................................................................... 220 1. Aspect-Oriented Development ................................................................... 220 xi
Object-Oriented Analysis and Design using UML 1.1. Apect-oriented development and non-functional requirements .............. 220 1.2. Core concepts of aspect oriented development ................................... 220 1.2.1. Cross cutting concern ......................................................... 220 1.2.2. Advice ............................................................................. 220 1.2.3. Point cut .......................................................................... 220 1.2.4. Aspect ............................................................................. 220 1.2.5. Weaving .......................................................................... 220 1.3. Aspect versus Object oriented development ....................................... 220 1.4. Frameworks for aspect-oriented programming ................................... 221 1.4.1. Aspects via annotations ....................................................... 221 1.4.2. Real-time weaving ............................................................. 221 1.5. A simple example ......................................................................... 221 1.6. Benefits of aspect-oriented development ........................................... 221 1.6.1. Improved responsibility location ........................................... 221 1.6.2. Core functional logic not polluted by non-functional logic ......... 221 1.6.3. Clean responsibility distribution across architecture, functional design and aspects ............................................................................... 222 11. Software Development Processes ..................................................................... 223 1. Introduction ........................................................................................... 223 2. What do we want from a development process ............................................. 223 3. Basic Process Elements ............................................................................ 223 4. Best Practices ......................................................................................... 224 4.1. Managing System Requirements ..................................................... 224 4.2. Iterative Development ................................................................... 225 4.3. Component-Based Architectures ..................................................... 225 4.4. Visual Modeling .......................................................................... 225 4.5. Software Verification Process ......................................................... 225 4.6. Change Control ............................................................................ 226 5. Ideas from the Rational Unified Process ...................................................... 226 5.1. History of RUP ............................................................................ 226 5.2. RUP as an Iterative Process ............................................................ 226 5.3. 6 Core Workflows ........................................................................ 226 5.3.1. Business modeling ............................................................. 227 5.3.2. Requirements modeling ...................................................... 227 5.3.3. Analysis and Design ........................................................... 227 5.3.4. Implementation ................................................................. 227 5.3.5. Testing ............................................................................ 228 5.3.6. Deployment ...................................................................... 228 5.4. 3 Supporting Workflows ................................................................ 228 5.5. The Inception Phase ...................................................................... 228 5.5.1. The deliverables of the inception phase .................................. 229 5.5.2. Evaluation criteria for the inception phase .............................. 229 5.6. The Elaboration Phase ................................................................... 229 5.6.1. Deliverables of the elaboration phase ..................................... 229 5.6.2. The evaluation criteria for the elaboration phase ...................... 230 5.7. The Construction Phase ................................................................. 230 5.7.1. Deliverables of the construction phase ................................... 230 5.7.2. Evaluation criteria for the construction phase .......................... 231 5.8. Transition ................................................................................... 231 5.8.1. Evaluation criteria for the transition phase .............................. 231 5.9. Feasibility Evaluations .................................................................. 231 5.10. RUP Life-Cycle Artifacts ............................................................. 231 5.10.1. Requirements Artifacts ...................................................... 232 5.10.2. Management Artifacts ....................................................... 232 5.10.3. Technical Artifacts ........................................................... 233 6. Lessons from Extreme Programming .......................................................... 233 6.1. A Light-Weight Alternative ............................................................ 234 6.2. A Process for Continually Changing Requirements ............................. 234 6.3. The 4 basic values of XP ............................................................... 234 6.3.1. Communication ................................................................. 234 6.3.2. Simplicity ........................................................................ 234 6.3.3. Feedback .......................................................................... 234 6.3.4. Courage ........................................................................... 234 xii
Object-Oriented Analysis and Design using UML 6.4. Business versus Development Cycles ............................................... 235 6.5. The XP Phases ............................................................................. 235 6.6. Iterative Development ................................................................... 235 6.6.1. Guidelines for writing stories ............................................... 236 6.6.2. Story should describe a business value ................................... 236 6.6.3. Stories must be understandable to the customer. ....................... 236 6.6.4. Stories should be short. ....................................................... 236 6.6.5. Stories must be implementable within one iteration .................. 237 6.6.6. Stories must be testable. ...................................................... 237 6.7. XP Activities ............................................................................... 237 6.8. The 12 XP practices ...................................................................... 237 6.8.1. Planning .......................................................................... 237 6.8.2. On-site customer ............................................................... 238 6.8.3. Simple design ................................................................... 238 6.8.4. Small releases ................................................................... 239 6.8.5. Pair programming .............................................................. 239 6.8.6. Testing ............................................................................ 240 6.8.7. Continuous integration ........................................................ 241 6.8.8. Collective ownership .......................................................... 241 6.8.9. Refactoring ....................................................................... 241 6.8.10. 40 hour week ................................................................... 242 6.8.11. Coding standards ............................................................. 242 6.8.12. Metaphor ........................................................................ 242 6.9. The 4 variables ............................................................................ 242 6.9.1. Increasing the project cost ................................................... 242 6.9.2. Trading off scope for time ................................................... 243 6.9.3. Quality ............................................................................ 243 6.10. Monitoring Project Status and Quality ............................................ 243 7. The Agile Manifesto ................................................................................ 244 8. The Capability Maturity Model for Software ................................................ 245 8.1. Characteristics of Immature Software Organizations ........................... 245 8.2. Characteristics of Mature Software Organizations ............................... 245 8.3. CMM Maturity Levels .................................................................. 246 8.3.1. What is a maturity level? ..................................................... 246 8.3.2. Level 1: The Initial Level .................................................... 246 8.3.3. Level 2: The Repeatable Level ............................................. 247 8.3.4. Level 3: The Defined Level ................................................. 247 8.3.5. Level 4: The Managed Level ................................................ 248 8.3.6. Level 5: The Optimizing Level ............................................. 249 8.4. How is maturity expected to influence performance? ........................... 249 8.5. Key process areas of the CMM ....................................................... 250 8.5.1. Key process areas for level 2 maturity .................................... 251 8.5.2. Key process areas for level 3 maturity .................................... 251 8.5.3. Key process areas for level 4 maturity .................................... 252 8.5.4. Key process areas for level 5 maturity .................................... 252 8.6. Practices of High-Maturity Organizations ......................................... 253 Bibliography ..................................................................................................... 254
xiii
List of Figures
1.1. Overview of the core CORBA Architecture .........................................................16 2.1. Simple class diagrams with stereotypes ..............................................................28 2.2. Elements of a use case diagram .........................................................................28 2.3. A simple use case diagram of a watch ................................................................29 2.4. A student (the user) uses a training institution (the context) for to present a course (a use case). The training institution delegates the responsibility of preparing lunches to a caterer (a secondary actor) ...................................................................................................30 2.5. The same person could play at times the role of an operator and at other times the role of a administrator .....................................................................................................30 2.6. Use case diagram for an ATM ..........................................................................31 2.7. A more general use case can have a number of specializations. ...............................33 2.8. One use case can include the behavior of other use cases. .......................................33 2.9. One use case can extend the behaviour of another providing more deliverables to the actors. ....................................................................................................................34 2.10. One actor can be a specialization of another. ......................................................35 2.11. Summary of use case diagram with packaging. ...................................................35 2.12. A typical example of a use case explosion. ........................................................36 2.13. Developing higher-level, more abstract understanding of a context identifies the scope of the context. .........................................................................................................37 2.14. Showing the concrete student management use cases. ..........................................37 2.15. A use-case diagram for an auto teller. ...............................................................38 2.16. A sequence diagram for the withdraw-cash use-case. ...........................................39 2.17. An activity diagram for an auto teller. ...............................................................41 3.1. Identifying the responsibilities which need to be addressed for the withdraw-cash usecase. ..................................................................................................................48 3.2. Identifying the responsibilities which need to be addressed for in the context of processing an insurance claim. ....................................................................................48 3.3. Allocating the responsibilities which need to be addressed for the withdraw-cash use-case to core system components. ....................................................................................49 3.4. Allocating the responsibilities around processing an insurance claim to core business units. .................................................................................................................50 4.1. UML class and object diagrams ........................................................................52 4.2. Attributes are shown in a second compartment of the class diagram. ........................53 4.3. Default values for attributes are specified via an assignment. ..................................53 4.4. Attribute values and access can be constrained by placing the constrain in curly brackets behind the attribute. ..............................................................................................54 4.5. Collection attributes and derived attributes ..........................................................55 4.6. ....................................................................................................................55 4.7. A service is requested providing certain parameters and the service may provide a return value. .................................................................................................................56 4.8. A service need not provide a return value. ...........................................................56 4.9. UML uses + for public access, - for private access and # for protected access. ............57 4.10. Three dots can be used to show an incomplete member list. Responsibilities are specified via a responsibilities comment. ...............................................................................58 4.11. Aspects of a date class ...................................................................................59 4.12. Subclassing is shown in UML via a triangular arrow pointing from the of the subclass to the superclass. .....................................................................................................63 4.13. A subclass inherits all instance members (attributes and operations) of the superclass. 64 4.14. GraphicsObjects is an abstract class with an abstract draw method. ........................73 4.15. A CreditCardChequeAccount is a CreditCardAccount and a ChequeAccount. ..........76 4.16. The disjoint constraint prevents multiple inheritance from within a class hierarchy. ...77 4.17. The {complete} constraint prevents subclassing when applied to a class and method overriding if applied to a method. ............................................................................77 4.18. During restrictive specialization the subclass only applies constraints to the elements inherited from the superclass. ....................................................................................78 4.19. Pre- and post-conditions and invariants can be specified in UML with corresponding pre- and post-condition comments. ..........................................................................81 4.20. When overriding a method the pre-conditions may only be decreased and the postconditions may only be increased. ...........................................................................82 xiv
Object-Oriented Analysis and Design using UML 4.21. Inheritance hierarchy for employees. ................................................................83 4.22. Using roles for employees. .............................................................................84 4.23. The interest rate source interface specifies the services which must be supplied by interest rate sources. Differnt service providers may realize these services in different ways. .85 4.24. Two tea provider realizations which provide the makeTea service. .........................86 4.25. Clients use an InterestRateSource only through a standard interafe, thereby avoiding vendor locking. ....................................................................................................87 4.26. Showing provided and required interfaces explicitly ............................................88 4.27. SLA for a caterer ..........................................................................................89 4.28. Some banks have entered the bank-assurance model providing the services of both, a bank and an assurer while other remain pure banks. ....................................................89 4.29. Documents are Printable and hence also Viewable, providing both, print and show services. .................................................................................................................90 4.30. Introducing a concept of a bank assurance business with different organizations realizing that concept. ........................................................................................................90 4.31. Realizing multiple inheritance in a language which does not support it ....................92 4.32. Ports for a restaurant .....................................................................................94 4.33. Offering the dame services through different portals ............................................94 4.34. Cheques have as components an amount and a payDate. ......................................96 4.35. Accounts have a transaction history. .................................................................96 4.36. Clients have accounts via aggregation. ............................................................ 100 4.37. Graphics objects have a style via aggregation. .................................................. 100 4.38. Unary associations are drawn as a solid line with an arrow head on the server side of the relationship. ...................................................................................................... 102 4.39. UML notations for binary associations. ........................................................... 103 4.40. Mapping the textual description onto UML. ..................................................... 105 4.41. Decoupling clients and service providers via interfaces. ..................................... 105 4.42. Mapping the textual description of a bond onto UML. ....................................... 106 4.43. Decoupling a binary relationship through two interfaces. .................................... 107 4.44. Using or and xor constraints between relationships. ........................................... 109 4.45. Specifying an ordered collection via a constraint on the many side of an association or composition relationship. ..................................................................................... 109 4.46. Removing or and xor constraints through by introducing more abstract concepts usually leads to a cleaner, more flexible and more scalable model. ......................................... 109 4.47. Association classes enable one to assign attributes and services to the association itself. ........................................................................................................................ 110 4.48. Association classes can be mapped onto more vanilla UML notation. ................... 111 4.49. Qualifications reduce the multiplicity of a relationship. ...................................... 111 4.50. Qualifications need not reduce a one-to-many to a one-to-one relationship. ............ 112 4.51. UML notation for n-ary associations. .............................................................. 112 4.52. N-ary associations provide a compact notation to hide a total mess. ...................... 113 4.53. Simplifying a communication network by introducing a mediator. ....................... 113 4.54. A parts catalog containg composition, specialization and association relationships. . 115 4.55. Cashiers have a weak uses relationship with your credit card. .............................. 118 4.56. Association as a strong uses vs dependency as a weak uses relationship. ............... 119 4.57. The LinkedList class declares the LinkedListIterator a friend. ............................. 119 4.58. The core UML relationships are specializations of each other. ............................. 123 4.59. The relationships between packages are dependency, sub-packaging (nesting of packages) and package specialization. .......................................................................... 125 4.60. Nested packages may also be specified using the scope resolution operator, ::. ....... 126 4.61. A metaclass defining the class (static) members of an Account class. .................... 130 4.62. Class services are not resolved polymorphically. ............................................... 131 4.63. Post-offices being packaged with supermarkets ................................................ 133 4.64. Iterator and Node defined as inner classes ....................................................... 134 4.65. A vector template and various classes generated from it. .................................... 135 4.66. Scalar defines the minimum requirements for elements of linear algebra classes like Vector or Matrix. Scalar::Integer, ..., Scalar::Rational implement Scalar and can hence be used as elements. ...................................................................................................... 140 5.1. Use case diagram for a vending machine. .......................................................... 144 5.2. A sequence diagram for the buy-product use case. .............................................. 145 5.3. An activity diagram for the buy-product use case. ............................................... 145 5.4. Identifying the responsibilities which need to be addressed for the buy-product use-case. ........................................................................................................................ 146 xv
Object-Oriented Analysis and Design using UML 5.5. Allocating the responsibilities which need to be addressed for the buy-product use-case to core system components. ..................................................................................... 147 5.6. A sequence diagram for the buy-product use-case, showing how the core components of the vending machine collaborate to realize the use case. ............................................. 148 5.7. A generic sequence diagram showing multiple scenarios for the buy-product use-case. 149 5.8. A sequence diagram showing the creation and destruction of an order processor. ...... 150 5.9. Types of messages supported in UML. ............................................................. 150 5.10. Sequence diagram with concurrencies, non-instantaneous messages and timing constraints. ............................................................................................................ 152 5.11. Corruption of an object's due to concurrent access. ............................................ 154 5.12. The concurrent constraint ............................................................................. 154 5.13. Entry and exit states. ................................................................................... 155 5.14. Forking into concurrent activities. .................................................................. 155 5.15. Forking and joining via synchronization bars. .................................................. 156 5.16. Activity diagram showing how the core components collaborate to realize the buyproduct use-case of a vending machine. .................................................................. 156 5.17. Showing object flows in an activity diagram. ................................................... 158 5.18. Activity diagram showing how the business units collaborate to realize the process-claim use-case. ........................................................................................................... 159 5.19. Showing common transitions via nested activities. ............................................ 159 5.20. State diagram in UML. ................................................................................ 160 5.21. Event specialization. ................................................................................... 162 5.22. Exception hierarchy. ................................................................................... 162 5.23. Exceptions at different levels of abstraction guide process flow. .......................... 162 5.24. The complete UML signature for state transitions. ............................................ 163 5.25. A simple control system. .............................................................................. 163 5.26. Communication diagram showing how the core components collaborate to realize the buy-product use-case. ......................................................................................... 164 5.27. The context of the collaboration .................................................................... 165 6.1. Deploying the restaurant and its procurement office. ........................................... 167 6.2. Deploying for the MobileOrder PDA application. ............................................... 168 7.1. The balance of savings accounts is constrained to be always positive. ..................... 171 7.2. Customers get a 5% discount for orders above R500.00 and a 10% discount on orders above R1000.00 ................................................................................................. 173 7.3. Booking for a presentation must be done before the start of the presentation. ........... 174 7.4. Using an association class for a booking. .......................................................... 174 7.5. Class hierarchy for OCL collections. ................................................................ 174 7.6. Specifying pre- and postconditions for the credit and debit services. ....................... 179 8.1. Use-Case/Responsibility Driven Design ............................................................ 184 8.2. Responsibility identification. .......................................................................... 185 8.3. Responsibility allocation. ............................................................................... 186 8.4. A scenario of realizing a use case at a specific level of granularity. ........................ 187 8.5. The use case collaboration in general. .............................................................. 187 8.6. Communication diagram simplifying transition to collaboration context. ................. 188 8.7. The context of the collaboration. ..................................................................... 189 8.8. Contracts are specified for each responsibility and hence for each service provider. .. 191 8.9. Class diagram for the e-mail value object. ......................................................... 191 8.10. Use case diagram for a component at the next lower level of granularity. ............... 192 8.11. Responsibility identification at next lower level of granularity. ............................ 192 8.12. Responsibility allocation at next lower level of granularity. ................................ 192 9.1. Use-case view of the composite pattern ............................................................ 197 9.2. Structure of the composite pattern. ................................................................... 198 9.3. Responsibilities of the components of the composite pattern. ................................ 198 9.4. A directory has files, but is itself a file. ............................................................. 199 9.5. The design of the Linux's virtual file system ...................................................... 199 9.6. A portfolio holds asset and can be itself viewed as an asset. .................................. 200 9.7. Java's user interface libraries achieve resolution independence partially through the composite pattern. .................................................................................................... 200 9.8. Structure of the decorator pattern. .................................................................... 207 9.9. The responsibilities of the role players of the decorator pattern .............................. 207 9.10. Any Gui component can be decorated with a border or a scroll pane. .................... 208 9.11. The debit service of an account can be decorated by voyage miles, transaction fees and potentially further decorators. ............................................................................... 209 xvi
Object-Oriented Analysis and Design using UML 9.12. The various concrete input streams can be decorated with a combination of input stream decorators. ........................................................................................................ 210 9.13. Responsibility allocation across the members of the visitor pattern ....................... 212 9.14. Structure of the visitor pattern ....................................................................... 213 9.15. Dynamics of the visitor pattern ...................................................................... 214 9.16. The structure used for a visitor adding a getTotalSalary() service to employees. ...... 215 9.17. The dynamics of the TotalSalaryCalculator. ..................................................... 215 9.18. VisitorTest.java .......................................................................................... 216 11.1. The 5 CMM levels of Software Process Maturity. ............................................. 246 11.2. Process capability and performance predictions taken from The capability Maturity Model for Software published by Paulk, Curtis, Chrissis and Weber. ............................ 250 11.3. Key process areas for the different CMM levels. ............................................... 250
xvii
List of Tables
4.1. The objects identified from the nouns: ................................................................52 4.2. The objects generalized to classes ......................................................................52 4.3. Multiplicites ..................................................................................................54 7.1. OCL Logical Operators ................................................................................. 171 7.2. OCL Relational Operators .............................................................................. 171 7.3. OCL Arithmetic Operators ............................................................................. 172 7.4. OCL String Operators ................................................................................... 172 7.5. OCL Collection Operators ............................................................................. 175 7.6. OCL Bag Operators ...................................................................................... 176 7.7. OCL Set Operators ....................................................................................... 177 7.8. OCL Sequence Operators ............................................................................... 177 11.1. Source of errors in software systems and the cost incurred in order to correct these errors. ................................................................................................................. 224
xviii
List of Examples
2.1. A use case diagram for an ATM ........................................................................31 3.1. Responsibilities of a process claim use case of an insurance company ......................49 4.1. Graphics objects .............................................................................................73 4.2. Credit-card cheque account ..............................................................................76 4.3. Computer monitors .........................................................................................84 4.4. Low-level component framework: CORBA .........................................................84 4.5. Business logic containers: Enterprise Java Beans ..................................................85 4.6. Business-2-business services via Web Services and SOAP .....................................85 4.7. Cheque .........................................................................................................95 4.8. Enforcing true composition on the components of a cheque ....................................97 4.9. Graphics objects have styles ........................................................................... 100 4.10. A parts catalog ........................................................................................... 115 4.11. Cashier has a dependency relationship with your credit card ............................... 118 4.12. Cheque has dependency to interest rate source .................................................. 119 5.1. Vending machine ......................................................................................... 157 5.2. Processing an insurance claim ......................................................................... 159 7.1. Pre- and postconditions of the account services .................................................. 179
xix
1. Copyright
We at Solms Training, Consulting and Development (STCD) believe in the open and free sharing of knowledge for public benefit. To this end, we make all our knowledge and educational material freely available. The material may be used subject to the Solms Public License (SPL).
1.1.1. Terms
Material below, refers to any such knowledge components, documentation, including educational and training materials, or other work. Work based on the Material means either the Material or any derivative work under copyright law: that is to say, a work containing the Material or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Licensee means the person or organization which makes use of the material.
1.1.3. Conditions
The licensee may freely copy, print and distribute this material or any part thereof provided that the licensee 1. prominently displays (e.g. on a title page, below the header, or on the header or footer of a page or slide) the author's attribution information, which includes the author's name, affiliation and URL or e-mail address, and conspicuously and appropriately publishes on each copy the Solms Public License.
2.
Any material which makes use of material subject to the Solms Public License (SPL) must itself be published under the SPL. The knowledge is provided free of charge. There is no warranty for the knowledge unless otherwise stated in writing: the copyright holders provide the knowledge as is without warranty of any kind. In no event, unless required by applicable law or agreed to in writing, will the copyright holder or any party which modifies or redistributes the material, as permitted above, be liable for damages including any general, special, incidental or consequential damages arising from using the information. xx
Neither the name nor any trademark of the Author may be used to endorse or promote products derived from this material without specific prior written permission.
2. Overview
The training pillar of Solms TCD focuses on vendor-neutral training which provides both, short- and long-term value to the attendees. We provide training for architects, designers, developers, business analysts and project managers.
xxi
the company. Besides the management role, he is particularly focused on architecture, design, software development processes and requirements management. Fritz Solms has a PhD and BSc degrees in Theoretical Physics from the University of Pretoria and a Masters degree in Physics from UNISA. After completing a short post-doc, he took up a senior lectureship in Applied Mathematics at the Rand Afrikaans University. There he founded, together with Prof W.-H. Steeb, the International School for Scientific Computing - developing a large number of courses focused on the immediate needs of industry. These include C++, Java, Object-Oriented Analysis and Design, CORBA, Neural Networks, Fuzzy Logic and Information Theory and Maximum Entropy Inference. The ISSC was the first institution in South Africa offering courses in Java and the Unified Modeling Language. During this period he was also responsible for presenting the OO Training for the Education Division of IBM South Africa. In 1998 he joined the Quantitative Applications Division of the Standard Corporate and Merchant Bank (SCMB). Here he was the key person developing the architecture and infrastructure for the QAD library and applications. These were based on Java and CORBA technologies, with a robust object-oriented analysis and design backbone. In 2000 he and Ellen Solms founded Solms TCD. E-Mail: Tel: Mobile: fritz@solms.co.za 011 646 6459 072 128 2314
applications in the financial industry, and specialises in Application Architecture, Graphical Interxxii
faces (web and otherwise), and usability. In addition to object-oriented and web technologies, he also takes great interest in various graphical formats and frameworks - especially the application of XML for this purpose. After a career at the JSE Securities Exchange (formerly Johannesburg Stock Exchange) as Systems Analyst and Web Architect, he joined Solms TCD in order to explore a larger field for applying interesting technologies to solve interesting problems, and to share this passion with others through mentoring and consulting. E-Mail: Tel: dawidl@solms.co.za 011 646 6459
Please feel free to discuss any complaints you may have with us. We will do our best to address your complaints. Should you feel that your complaints are not satisfactorarily addressed within our organization, then you can raise your complaints with: Professor W.-H. Steeb from the University of Johannesburg, Tel: +27 (11) 486-4270, EMail: whs@rau.ac.za Dr A. Gerber from the Computer Science Department of the University of South Africa, E-Mail: gerberaj@unisa.ac.za
At the time of writing we are in the process of obtaining ISETT SETA accreditation. Complaints can be raised directly to that institution.
xxiii
xxiv
they provide an ideal communication medium between the various role players in the system analysis and development process, from domain expert to analysts, designer, implementor and maintainer. Graphical languages like the Unified Modeling Language (UML) allow for diagrammatic designs which provide selective views, focusing only on those elements which are relevant to those points one currently wants to illustrate.
Each component deployed on a machine or in a component container complies to some specifications and has a well defined interface. The components themselves can be produced by component vendors. Such components may be bought from these component vendors. A component-based approach aims for increases in productivity, quality and re-use.
lett Packard [Coleman-Arnold-Bodoff-1994] which is a fusion of the OMT, Booch, CRC cards and Objectory methods, and the Object Oriented Analysis and Object Oriented Design method (OOA/ OOD) of Coad and Yourdon (see [Coad-Yourdon-1991a] and [Coad-Yourdon-1991b]). In October 1994 Jim Rumbaugh and Grady Booch joined forces in order to unify the OMT and Booch methods resulting in a draft for the Unified Method as it was then called. In the second half of 1995 Ivar Jacobson joined the group, resulting in the unification of OOSE with the unified method. The result, which was called Unified Modeling Language or UML. UML is not simply a unification of the most widely used object-oriented modeling methods. It is a new modeling language built on a sound and thorough semantic basis upon which a consistent notation was developed. This foundation is the UML Meta-Language. It includes many concepts which have not been included in either of its predecessors, OMT, Booch or OOSE. In 1996 several businesses joined as UML partners and actively participated in the formalization of UML 1.0. These include Digital Equipment Corp., HP, i-Logix, Intellicorp, IBM, ICON Computing, MCI Systemhouse, Microsoft, Oracle, Rational Software, TI and Unisys. In January 1997 UML 1.0 was submitted to the Object Management Group (OMG) to be considered for adoption as a standard. The OMG in a non-profit organization formed for the promotion of object-oriented technology. It has now about 1000 member companies and its most notable publications are the specifications are CORBA, the Common Object Request Broker Architecture which forms a language and location transparent brokering service for object-oriented service requests (it is an OO middleware) and UML. UML is now public property and is maintained by the OMG. The current language specifications can be downloaded from http://www.omg.org.
UML is an object-oriented modeling language supporting all the standard object-oriented concepts.
The use of UML has spread quite rapidly from being used mainly for software design to being used in a wide range of areas including requirements analysis and specification, business analysis and modeling, data modeling and modeling of hardware (e.g. engineering) systems.
These diagrams are used to generate a range of complimentary views,the sum-total of which defines the system one is modeling.
Communication diagrams, on the other hand, show the messages sent along message paths, i.e. in the context of the static structure in which they are exchanged. The time ordering is specified via a numbering system. Collaboration diagrams can help to make the transition between the dynamics of the model and the structure supporting the dynamics.
Note
Communication diagrams where known in UML 1.x as collaboration diagrams.
web containers like servlet and JSP containers for Java-based deployable presentation layer components.
the actors may be users or other systems our system is interfacing with. The context being modeled is thus viewed as a black box, exposing only what the context used for and how the external objects, the actors, interact with the context in the context of these use cases.
Obviously we are going to use UML use-case diagrams for the use-case view. However, in addition to use-case diagrams we will also use Sequence diagrams. to document the sequence of messages exchanged between the context and its actors in the context of a scenario (an example flow) of a use case and Activity diagrams. to show the multiple paths for a use case.
In either case the context is still viewed as a black box, exposing only how it interacts with the external objects.
For the former we use use case diagrams showing the use case, the abstract collaboration and the responsibilities within responsibilities comments. To show the responsibility assignments we use a class diagram showing the abstract collaboration, the components which partake in the collaboration and the responsibilities assigned to these components.
One uses 9
Sequence diagrams. showing the messages exchanged between components of the context and between these components and the actors, Activity diagrams. showing the activities done by the various components of the context in the context of a workflow as well as the events which cause the transition from one object performing a particular activity to another (or the same) performing another activity, and State charts. providing a state machine view onto the components of the context.
10
verbs onto operations performed by objects or services offered by objects, and adverbs onto attributes of operations,
11
3.5. Encapsulation
We need not know the way in which the service is supplied by the object. We only need to know what message we have to send to request the service. For example, we do not need to know the implementation details of the engine and gearbox to be able to request the accelerate service. Those implementation details are hidden from the user. The hiding of implementation details is called encapsulation.
3.6. Composition
An object is usually composed of a number of components which are themselves objects. The question which is not always trivial to answer is What makes one object a component of another? To this end we need to understand the implications of a composition relationship. Composition implies Ownership. Linguistically one would say that the aggregate object (the container object) has a component. For example The car has an engine. The container object must be able to say with a good conscience that the component is his/hers. Adopting Responsibility for Component. If a car is yours then you are responsible for it. For example, if the car crashes into a building because the brakes failed, then you are responsible for the damage. Similarly, if the car is yours, nobody should be able to make use of it or to change its state without your permission. We shall see later that a lot of object-oriented modeling revolves around judicious distribution of responsibilities. Coincident life spans. In object-oriented software systems composition may imply that the life span of the component is limited to that of its owner/container. For example, when an account is closed and deleted, its balance and account number will no longer exist.
can provide services. It's abstraction is a class. On a class level one says that clutch pedals are associated with clutches. Associations between classes implies links between instances of the corresponding classes. For example, a particular clutch pedal is linked to a particular clutch. The difference between composition and association is that the former implies ownership and coincident life spans. A good example illustrating the difference between the two is a financial contract like a bond. If you buy a bond from an institution (government or corporate) then that institution usually agrees to pay a specific interest rate on your investment over a certain period. For example, the R150 is a South African government bond which pays 12.5% interest biannually. The notional (i.e. amount invested) and the interest you earn are part of the contract. You cannot change these without changing the actual contract and hence these attributes are components of the contract. However, once you bought the contract, its value depends on environmental factors which are not part of the contract. In the case of a bond these would include the prevailing interest rates. Assume the remaining period of the bond is for 5 years. Then, if the interest you can earn by investing for 5 years increases (i.e. if rates go up), the value of your bond diminishes, because you could earn higher interest elsewhere. On the other hand, if rates fall, then the value of your bond increases because you could sell it at a higher price to somebody who wants to invest his/her money over the 5 year period at a higher rate than the prevailing interest rate. Thus the interest the bond pays (i.e. the coupon) is part of the contract while the prevailing interest rate is part of the environment in which the contract lives. The relationship between the bond and its coupon is a composition relationship while you need an link between the bond and the environmental 5-year rate in order to value the bond. Once your contract is annulled, its coupon is annulled, but the 5-year interest rate prevailing in the market still exists. Also, the prevailing interest rate changes due to a series of factors, while the coupon can only be changed by changing the bon contract -- the bond takes responsibility/ownership of its coupon.
Hence, these attributes and services can be specified at the more abstract level of Volvo T80 and will be inherited among all Volvo T80s, e.g. Volvo T80Es and T80Ss.
3.9. Interfaces
An interface represents a client's view of a service provider. It encapsulates the services required by the client as well as the messages which the client will send when requesting the services. Different service providers may implement the same interface and a client can switch between these service providers without changing the way in which the service is requested.
3.10. Polymorphism
Polymorphism in the OO sense is a direct consequence of the fact that you request services by sending messages, NOT by calling functions. The object which receives the message decides how it is going to realize the service, i.e. what function is going to be called. You as client simply send the service request message. Simply think of Frank Sinatra's I do it my way. You can request a service from several objects, but of these service providers may realize the service in a different way.
If any of these change the object undergoes a state transition. For example, my telephone has certain attributes (e.g. color), has a link to an exchange and might be in the idle state. If I paint it, or if it starts ringing or if I change the connection of the phone to another exchange, the telephone has undergone a state transition. If on, the other hand the state of the exchange changes (e.g. the number of connections it currently serves), the state of my telephone does not.
who offer services to clients do this in the context of a contract. The contract is made up of 1. the interface which specifies the message through which the service is requested including all objects/information clients must provide to service providers when requesting the service as input parameters, the pre-conditions (i.e. the conditions under which the service provider will not provide the service) in the form of exceptions which notify the client that the service provider will not realize the service the client requested, and the output parameters and return value which represent the deliverables the service provider will provide to the client upon successful completion of the service.
2.
any other post-conditions which apply to the state of the service provider,
4.1. Example
Consider, for example, an internet banking portal. One of the services it offers may be that of making a payment to another party. The interface specifies that the client must send a makePayment message providing the source account details, the destination account details and the transfer amount to the service provider, that the service provider may raise either an InsufficientFunds exception or a DestinationAccountDoesNotExist exception (the preconditions which must be met before a service provider ralizes the service are thus that the source account must have sufficient funds and that the destination account details are correct), and that the service provider will provide a TransactionConfirmation to the client.
Other post-conditions which apply to the final state of the service provider include that the balance of the account must have been adjusted accordingly, and that the transaction must have been entered into the transaction history of the sourcec account.
Note
One will test that if a service is requested in a way as specified in the interface, with all preconditions having been met, that the service provider provides all deliverables/ post-conditions as per contract. the encapsulation of the client requirements in a contract which contains the information of the 15
exact dependencies of the client on the service provider, and an open competitative market for service providers which have an exact requirements specification for any services they wish to tender for.
5. Overview of CORBA
CORBA is a universal, non-proprietry standard for object-oriented middle ware. Similar to Java RMI, it supports remote service requests, but the service requests may be to CORBA objects which may be implemented in any language of choice. For example, CORBA can be used to wrap legacy COBOL-based mainframe systems and clients (for example Java and C++ clients) can access the services of the wrapped legacy system in an object-oriented, simple way without knowing the implementation language, platform or network protocols used by the server. CORBA has also standardized a wide range of general and industry specific services and is a universal standard for integrating systems.
16
Some of the core elements of CORBA are GIOP and IIOP. IIOP, the Internet Inter-ORB Protocols is CORBA's vendor-neutral service request protocol across the internet. It is based on the General Inter-ORB Protocol which may form a base protocol for other inter-ORB protocols using other transport layer protocols. The client-side ORB. uses the CORBA object reference to establish a connection to the service provider via a server-side ORB, marshalls service requests onto a IIOP/GIOP message and sends the message to the service provider and receives and demarshalls the service provider responses and forwards them back to the client code.
The server side ORB. de-marshalls the service request and maps it onto a call in the server side implementation language. marshalls the response with the return values back onto a IIOP message returned to the client code.
Interface repository. provides a resource where service providers can publish their interfaces in a vendor and implementation technology neutral language, the IDL (CORBA's Interface Definition Language). Naming Services. provide a mechanism for obtaining object handles from names. A naming service is often compared to a normal telephone book. Trader Services. enable clients to find service providers from a hierarchical service classifica17
tion for the service they require. A trader service is often compared to a yellow pages telephone book which enables you to get handles to service providers (telephone numbers in that case) by looking up a service provider from the type of service your require.
5.4.1. The CORBA object is thus an object from the user's perspective
CORBA implements complete implementation hiding publishing only an abstract/virtual object handle and the interface containing the service request messages supported. For each service offered the interface contains the service name, the information which the client needs to provide to the service provider upon service request (the input parameters), the preconditions under which the service provider offers the service,
Note
These are the exceptions which are potentially raised. The service provider will check the preconditions prior to providing the service and throw an exception if the service cannot be provided. Should the service provider not be able to check the preconditions up-front, the service provider will have to start a transaction which can be rolled back. and the deliverables of the service, i.e. the output parameters.
Note
These deliverables are an essential part of the post-conditions. There may be further postconditions around the state of the server side system after the service request. These should be added in order to have a complete requirements specification for a service.
18
But CORBA goes beyond implementation hiding, providing a virtual object representation whose realization may change at any stage. Nevertheless, from the client's perspective it is still the same object, e.g. the same account and the client continues to use the same object reference (message path).
Note
It is important that the CORBA wrapper should be designed from a clean use-case/business perspective and should be a direct mapping of the current system interface onto CORBA.
19
Table of Contents
2. The Use-Case View ..........................................................................................27 1. Introduction to Use Cases ...................................................................27 1.1. What is the context? ........................................................................27 1.2. What is a use case? .........................................................................27 2. Objects and StereoTypes in use case diagrams ........................................27 2.1. UML stereotypes ............................................................................28 3. Simple use case diagrams ...................................................................28 3.1. Actors ..........................................................................................29 3.1.1. Users (primary actors) ..........................................................29 3.1.2. Secondary actors .................................................................29 3.1.3. Actors as roles .....................................................................30 3.2. The context ...................................................................................30 3.3. Use case .......................................................................................30 3.4. Communication channels .................................................................31 4. Notes in UML ..................................................................................32 5. Relationships between use cases ..........................................................32 5.1. Use-case specialization ....................................................................32 5.1.1. Abstract (high-level) uses cases and scoping .............................33 5.2. Includes relationships ......................................................................33 5.3. Specifying use-case extensions .........................................................34 5.3.1. The use case extension ..........................................................34 5.3.2. Extension points ..................................................................34 5.3.3. Conditionality of an extension ................................................35 6. Actor specialization ...........................................................................35 7. Packaging use cases ..........................................................................35 8. Scoping ..........................................................................................36 9. Using sequence diagrams to elaborate on use cases .................................38 9.1. Components of a typical sequence diagram .........................................40 9.1.1. Messages ...........................................................................40 10. High-level activity diagram for a use case ............................................41 10.1. Example: Showing multiple scenarios for the withdraw-cash use case of an auto teller ...........................................................................................42 10.2. Components of a simple activity diagram ..........................................42 10.2.1. Automatic transitions ..........................................................42 10.2.2. The context of the activities .................................................42 10.2.3. Entry states .......................................................................42 11. Mapping between sequence and activity diagrams .................................42 12. Documenting Use Cases ...................................................................42 12.1. Allister Cockburn's use case template ...............................................43 12.2. Using UML .................................................................................43 12.3. Example: ATM ............................................................................44 13. Exercises .......................................................................................46 3. The Responsibilities View ..................................................................................48 1. Introduction .....................................................................................48 2. Identifying the core responsibilities for a use case ...................................48 3. Allocating responsibilities to core components .......................................49 4. Exercises .........................................................................................50 4. The Static View ................................................................................................51 1. Objects and classes ...........................................................................51 1.1. What is an object? ..........................................................................51 1.2. What is a class? .............................................................................51 1.3. Identifying objects ..........................................................................51 1.4. Generalization of objects to classes ....................................................52 1.5. Simple object and class diagrams ......................................................52 1.6. Attributes ......................................................................................53 1.6.1. Specifying attributes for a class ..............................................53 1.6.2. Default values .....................................................................53 1.6.3. Constraints .........................................................................53 xxi
1.6.4. Multiplicities in UML ...........................................................54 1.6.5. Collection attributes .............................................................54 1.6.6. Derived attributes ................................................................55 1.7. Services ........................................................................................55 1.8. OO (Camel) naming convention ........................................................56 1.9. Access control ...............................................................................57 1.10. Encapsulation ..............................................................................57 1.11. Incomplete member list ..................................................................58 1.12. Assigning responsibilities to classes .................................................58 2. Implementation mappings for object and class diagrams ...........................59 2.1. Mapping class and object diagrams onto Java ......................................59 2.1.1. Mapping objects and classes ..................................................59 2.1.2. Mapping UML attributes onto Java .........................................59 2.1.3. Mapping UML operations onto Java methods ............................60 2.1.4. Mapping UML access levels onto Java .....................................60 2.2. Mapping class and object diagrams onto C++ ......................................61 2.2.1. Mapping objects and classes ..................................................61 2.2.2. Mapping UML attributes onto C++ .........................................61 2.2.3. Mapping UML operations onto C++ methods ............................62 2.2.4. Mapping UML access levels onto Java .....................................62 2.3. Mapping class and object diagrams onto XML .....................................62 2.3.1. Mapping objects and classes ..................................................62 2.3.2. Mapping UML attributes onto XML ........................................62 2.3.3. What about the operations? ....................................................63 3. Specialization through sub-classing ......................................................63 3.1. Specialization as an is a relationship ..................................................63 3.1.1. Abstract references ...............................................................63 3.2. Documenting a Specialization relationship in UML ..............................63 3.3. Inheritance as a by-product of sub-classing ..........................................64 3.3.1. Don't subclass for inheritance sake only ...................................64 3.4. Implementing specialization in Java ...................................................64 3.4.1. Account.java .......................................................................65 3.4.2. ChequeAccount.java ............................................................65 3.4.3. InheritanceTest.java .............................................................66 3.5. Implementing specialization in C++ ...................................................66 3.5.1. Public versus protected and private specialization ......................66 3.5.2. Why use only public specialization? ........................................67 3.5.3. Specialization in C++ ...........................................................67 3.6. Implementing specialization in XML .................................................69 3.7. Polymorphism ...............................................................................70 3.7.1. Polymorphism in UML .........................................................70 3.8. Polymorphism in Java .....................................................................70 3.8.1. PolymorphismTest.java .........................................................70 3.9. Polymorphism in C++ .....................................................................71 3.10. Polymorphism and substitutability in XML ........................................72 3.11. Abstract classes ............................................................................73 3.11.1. What is an abstract class? ....................................................73 3.11.2. Concrete versus abstract methods ..........................................73 3.11.3. Why abstract classes? .........................................................74 3.12. Implementing abstract classes in Java ...............................................74 3.13. Implementing abstract classes in C++ ...............................................75 3.14. Implementing abstract classes in XML ..............................................75 3.15. Multiple inheritance ......................................................................75 3.16. Implementing multiple inheritance in Java .........................................76 3.17. Implementing multiple inheritance in C++ .........................................76 3.18. Implementing multiple inheritance in XML .......................................77 3.19. Applying constraints during sub-classing ..........................................77 3.19.1. The disjoint constraint .........................................................77 3.19.2. Preventing subclassing via a complete constraint ......................77 3.19.3. The incomplete constraint ....................................................78 3.19.4. Extensive versus restrictive specializations ..............................78 3.20. Enforcing specialization constraints in Java .......................................79 3.21. Enforcing specialization constraints in C++ .......................................79 xxii
3.22. Enforcing specialization constraints in XML ......................................79 3.23. Lessons from Design-By-Contract ...................................................80 3.23.1. Pre-conditions, post-conditions and invariants .........................80 3.23.2. Example: the debit service ...................................................80 3.23.3. Design by contract and overriding methods .............................81 3.23.4. Example: Overriding the debit service ....................................82 3.24. Implementation guidelines from design-by-contract ............................82 3.25. Alternatives to sub-classing ............................................................83 3.25.1. Mapping specialization onto composition ...............................83 4. Interfaces ........................................................................................84 4.1. Some example interface specifications ...............................................84 4.2. Defining an interface in UML ...........................................................85 4.3. Specifying interface realizations ........................................................86 4.4. Provided and required interfaces .......................................................87 4.4.1. Alternative notation for provided and required interfaces .............87 4.5. Viewing an interface as the skeleton of a contract between clients and service providers ............................................................................................88 4.5.1. Aspects of the contract not included in the interface ...................88 4.5.2. SLA for a Caterer ................................................................88 4.6. Implementing multiple interfaces ......................................................89 4.7. Extending interfaces .......................................................................90 4.7.1. Extending multiple interfaces .................................................90 4.8. Benefits of using interfaces ..............................................................91 5. Implementing interfaces .....................................................................91 5.1. Implementing interfaces in Java ........................................................91 5.1.1. Defining and interface ..........................................................91 5.1.2. Implementing an interfaces ....................................................91 5.1.3. Extending interfaces .............................................................92 5.1.4. Using interfaces to provide partial support for multiple inheritance 92 5.2. Implementing interfaces in C++ ........................................................93 6. Ports ..............................................................................................93 6.1. Specifying ports .............................................................................93 6.1.1. Portals for a restaurant ..........................................................94 6.2. Benefits of using ports .....................................................................94 7. Composition ....................................................................................95 7.1. What is composition? ......................................................................95 7.2. Documenting composition in UML ....................................................96 7.2.1. Specifying role names and multiplicities ..................................96 7.3. Composition as a relationship enforcing encapsulation ..........................97 7.4. When not to use composition ............................................................97 8. Implementing composition relationships ...............................................97 8.1. Implementing composition in Java .....................................................97 8.1.1. Enforcing ownership and bounded life-span ..............................97 8.1.2. Supporting state change notification ........................................98 8.2. Implementing composition in C++ .....................................................98 8.2.1. Composition as a mechanism for simplifying memory management ..................................................................................................99 8.3. Mapping composition relationships onto XML .....................................99 9. Aggregation .....................................................................................99 9.1. UML notation for aggregation ..........................................................99 10. Implementing aggregation .............................................................. 101 10.1. Implementing Aggregation in Java ................................................. 101 10.1.1. State change notification .................................................... 101 10.2. Implementing Aggregation in XML ............................................... 101 11. Associations ................................................................................. 101 11.1. What are association relationships? ................................................ 101 11.1.1. Associations as message paths for client/server relationships .... 102 11.2. UML notation for association ........................................................ 102 11.2.1. Unary associations for client-server relationships ................... 102 11.2.2. Binary associations ........................................................... 103 11.3. Using verbs to identify associations ................................................ 104 11.3.1. A data acquisition, processing and control system .................. 104 11.3.2. Decoupling via interfaces .................................................. 105 xxiii
11.4. Role names ................................................................................ 105 11.4.1. Example: Bonds and interest rate sources .............................. 106 11.5. Use interfaces or the server side of associations ................................ 106 11.5.1. Interfaces in bi-directional associations ................................ 107 11.6. Association constraints ................................................................ 108 11.6.1. Ordering constraints ......................................................... 108 11.6.2. Or and xor constraints between relationships ......................... 109 11.6.3. Accommodating or and xor relationships naturally through specialization ........................................................................................ 109 11.7. Association classes ..................................................................... 110 11.8. Qualifications ............................................................................ 111 11.9. N-ary associations ...................................................................... 112 11.10. Simplify N-ary associations by introducing a mediator ..................... 113 11.11. Avoid spaghetti communication networks ...................................... 114 12. Implementing association relationships ............................................. 114 12.1. Implementing associations in Java ................................................. 114 12.2. Implementing association in C++ ................................................... 115 12.3. Implementing associations in XML ................................................ 115 13. Dependencies ............................................................................... 118 13.1. What is a dependency? ................................................................ 118 13.2. UML notation for specifying a dependency ..................................... 118 13.3. Dependency as a weak uses relationship .......................................... 119 14. Friendship ................................................................................... 119 14.1. Implementing frienship in Java ...................................................... 120 14.2. Implementing friendship in C++ .................................................... 120 15. Overview of OO relationships supported in UML ................................ 120 15.1. The 5 relationships between classes ................................................ 120 15.1.1. Dependency .................................................................... 121 15.1.2. Association ..................................................................... 121 15.1.3. Aggregation .................................................................... 121 15.1.4. Composition ................................................................... 121 15.1.5. Specialization .................................................................. 121 15.2. Relationships between classes and interfaces .................................... 122 15.2.1. Service providers and interfaces .......................................... 122 15.2.2. Clients and interfaces ........................................................ 122 15.3. A Precise Summary of the UML relationships .................................. 122 15.3.1. Shopping for relationships ................................................. 124 16. Packaging .................................................................................... 124 16.1. UML notation for packaging ......................................................... 125 16.2. Exported and internal elements of a package .................................... 125 16.3. Nested packages ......................................................................... 125 16.4. Importing packages ..................................................................... 126 16.4.1. Importing is transitive ....................................................... 126 16.5. Package specialization ................................................................. 126 16.6. Package stereoTypes ................................................................... 127 16.7. How to group elements into packages ............................................. 127 17. Implementing packaging ................................................................ 127 17.1. Implementing packages in Java ..................................................... 128 17.2. Implementing packages in C++ ..................................................... 128 17.3. Implementing packages in XML .................................................... 129 18. Metaclasses .................................................................................. 130 18.1. What is a metaclass? ................................................................... 130 18.2. Constructors .............................................................................. 130 18.3. UML notation for metaclasses ....................................................... 130 18.4. Class services are not resolved polymorphically ............................... 131 19. Implementing meta-classes ............................................................. 132 19.1. Implementing metaclasses in Java .................................................. 132 19.2. Implementing metaclasses in C++ .................................................. 132 20. Inner classes ................................................................................. 133 20.1. What is an inner class? ................................................................ 133 20.2. Why use inner classes? ................................................................ 133 20.3. Specifying inner classes in UML ................................................... 133 20.3.1. Example: Embedded service provider .................................. 133 xxiv
20.3.2. Example: Iterators and nodes as inner classes ........................ 133 21. Template types ............................................................................. 134 21.1. When should you consider using a template type? ............................. 134 21.2. Vectors ..................................................................................... 134 21.3. UML notation for template types ................................................... 135 21.4. Implementing template types ........................................................ 136 21.4.1. Implementing template types in Java .................................... 136 21.4.2. Implementing template types in C++ .................................... 141 22. Exercises ..................................................................................... 142 5. The Dynamic View ......................................................................................... 143 1. Introduction ................................................................................... 143 1.1. UML diagrams for the dynamic model ............................................. 143 1.1.1. Interaction diagrams ........................................................... 143 1.1.2. Behavior diagrams ............................................................. 144 2. Sequence Diagrams ......................................................................... 144 2.1. A vending machine example ........................................................... 144 2.2. Responsibility identification and allocation for the buy-product use case of a vending machine ................................................................................ 146 2.3. Sequence diagrams showing the interactions of the core components ...... 147 2.4. Generic sequence diagrams ............................................................ 148 2.4.1. Branching ........................................................................ 148 2.4.2. Disadvantages of generic sequence diagrams ........................... 149 2.4.3. Alternatives to generic sequence diagrams .............................. 149 2.5. Object life cycle modeling with sequence diagrams ............................. 149 2.5.1. Life lines and activity bars ................................................... 150 2.5.2. Object creation and destruction ............................................. 150 2.5.3. Iteration ........................................................................... 150 2.6. Message types ............................................................................. 150 2.6.1. Synchronous messages ........................................................ 151 2.6.2. Timeout messages .............................................................. 151 2.6.3. Asynchronous messages ...................................................... 151 2.6.4. Returns ............................................................................ 151 2.7. Implementing different types of messages in Java ............................... 151 2.7.1. Synchronous messages ........................................................ 152 2.7.2. Simple calls ...................................................................... 152 2.7.3. Asynchronous messages ...................................................... 152 2.7.4. Sychronous call with immediate return .................................. 152 2.8. Further timing features for sequence diagrams ................................... 152 2.8.1. Non-instantaneous messages ................................................ 152 2.8.2. Timing constraints ............................................................. 153 2.9. Concurrencies .............................................................................. 153 2.9.1. Concurrent activities within an object .................................... 153 2.9.2. Concurrencies versus branching ............................................ 153 2.10. Making classes safe for concurrent access ....................................... 153 2.10.1. Why do we need access control? ......................................... 153 2.10.2. Protection against corruption due to concurrent access ............ 154 3. Activity diagrams ........................................................................... 155 3.1. Exit states ................................................................................... 155 3.2. Forking and synchronization ........................................................... 155 3.2.1. Forking ............................................................................ 155 3.2.2. Synchronization ................................................................ 156 3.3. Activities across objects: swim-lanes ............................................... 156 3.4. Showing object flow in an activity diagram ....................................... 157 3.5. Processing an insurance claim ......................................................... 158 3.6. Nested activities ........................................................................... 159 4. State charts .................................................................................... 160 4.1. States ......................................................................................... 160 4.2. Messages and events ..................................................................... 161 4.2.1. Call events ....................................................................... 161 4.2.2. Signals ............................................................................. 161 4.2.3. Time events ...................................................................... 161 4.2.4. State change events ............................................................ 161 4.2.5. Event specialization ........................................................... 162 xxv
4.2.6. External versus internal events ............................................. 163 4.2.7. Full signature for state transition label .................................... 163 5. Communication diagrams ................................................................. 164 5.1. Example: Communication diagram for a vending machine ................... 164 6. The context of the collaboration ......................................................... 165 6. Deployment View ........................................................................................... 167 1. Introduction ................................................................................... 167 2. Showing deployment aspects ............................................................ 167 7. The Object Constraint Language (OCL) .............................................................. 169 1. Introduction ................................................................................... 169 1.1. Where does the OCL come from? .................................................... 169 1.2. Applications for OCL .................................................................... 169 1.3. Some core features of OCL ............................................................ 169 1.4. Types of constraints ...................................................................... 169 1.5. The context of a constraint ............................................................. 170 1.6. Constraint expressions ................................................................... 170 2. Invariants ...................................................................................... 170 2.1. Positive balance constraint for savings accounts ................................. 170 2.2. OCL operators ............................................................................. 171 2.3. Conditionals and operations ........................................................... 173 2.4. Navigating object graphs ............................................................... 173 2.5. Constraints involving collections ..................................................... 174 2.5.1. Collection operators ........................................................... 175 2.5.2. Iterating across a collection .................................................. 177 2.5.3. Selecting a specific type of collection .................................... 178 2.5.4. Collecting and summing across a collection ............................ 178 2.5.5. Selecting and rejecting elements from a collection ................... 178 2.5.6. Testing an expression across all elements in a collection ............ 178 3. Pre- and Postcondition in OCL .......................................................... 179 4. OCL and Testing ............................................................................ 179 4.1. Functional testing ......................................................................... 179 4.2. System integrity testing ................................................................. 180 5. Exercises ....................................................................................... 180
xxvi
Use cases are particularly important when developing a requirements model for the system (or class). By nature they specify what the system should be able to do, not how the system should do it. They are generally used to identify and document the requirements specifications of the system. Use cases can be stated as text and/or can be graphically represented via Use Case Diagrams.
27
For example, a particular switch is an object which has attributes (whether it is on or off), services (that the switch can be toggled) and relationships to other objects (for example a message path to the object being controlled by the switch). For now we are not interested in the attributes and services. We simply want to show a class. A class is shown in UML as a rectangle with the name of the class in the center. (see the left diagram in Figure 2.1, Simple class diagrams with stereotypes).
The elements of a simple use case diagram are the actors, i.e. the external objects interfacing with the system, the context responsible for realizing the use cases, 28
the actual use cases and communication links between actors and use cases.
3.1. Actors
The actors are roles played by objects which interface with the context in the context of a use case. An actor is usually shown in a UML diagram using a stick man icon -- this is the default stereotype icon for actors. The stick man icon does not imply that the actor role will be fulfilled by a person. Even if the role is realized by a machine or a software component, one still may use the stick man stereotype icon. Nothing prevents one, however, to define other icons for specialized types of actors. Stereotypes provide an extension mechanism in UML and one can thus define one's own stereotypes and assign one's own icons to them.
external service provider, i.e. the responsibility of preparing the lunches is no longer within the scope of the training institution (the context). In this case it delegates this responsibility to a secondary actor who plays the role of a caterer.
Figure 2.4. A student (the user) uses a training institution (the context) for to present a course (a use case). The training institution delegates the responsibility of preparing lunches to a caterer (a secondary actor)
Figure 2.5. The same person could play at times the role of an operator and at other times the role of a administrator
with observable deliverables for the actors. A use case must enable an actor to realize a complete user goal. The goal must be meaningful from the perspective of the user (primary actor). A use case is shown in UML as an ellipse with the name of the use case inserted into it. The name starts with a capital letter which tells us that a use case should itself be seen as a class. This is because a usage represents a conceptual object. The ellipse is thus a stereotype icon for a use case.
Note
This is not necessarily a customer: he or she may have picked up the card and would like to make use of it fraudulently. Having identified the actor correctly makes one more aware of the generality of the actor and may help to avoid neglecting aspects (like security) which are important for non-customers. the bank
Note
It would most probably be more realistic to factor out the role of an auto teller owner which may be the bank itself, another bank or even an independent company.
31
There are two actors involved in most of the use cases. The card holder is, for those use cases in which he/she is involved, the primary actor. He drives these use cases and gets the primary use out of them. The bank plays in these cases the role of a secondary actor who also may exchange messages and hence participates in the use case.
4. Notes in UML
UML supports the assignment notes. A note is an annotational element used to either attach a comment to some UML element or collection of elements or to specify a constraint for those elements.
A note is shown ion UML as a piece of paper with the top right hand corner turned over. The note is attached to a UML model element via a dashed line. For example, in Figure 2.6, Use case diagram for an ATM we have attached a comment note to the MakePayment use case.
A more specialized realization can extend a more general use case. Use case specialization enables us to look at the uses of a system at different levels of abstraction. We shall see the benefit of having a hierarchical structure of use cases.
Figure 2.7. A more general use case can have a number of specializations.
Specialization is shown in UML as a solid line with a triangular arrow pointing from the specialized entity to the more general entity.
Figure 2.8. One use case can include the behavior of other use cases.
33
An includes relationship is a special form of a dependency. Dependencies are shown in UML as a dashed line pointing from the entity which has the dependency to the entity it is dependent on. We show that a particular dependency resembles an include relationship by adding an include stereotype. In the example shown in Figure 2.8, One use case can include the behavior of other use cases. the PerformATMTransaction use case includes the CardValidation, CustomerAthentication and PrintTransactionSlip use cases. Consequently all its specializations like WithDrawCash, MakePayment, DepositFunds and TransferFunds will too.
Figure 2.9. One use case can extend the behaviour of another providing more deliverables to the actors.
Extensions are, like include relationships, a special form of a dependency. This is because the extension is accessed from the context of the use case it extends. A extends stereotype is added to show that the dependency resembles an extension.
UML supports thus the definition of such extension points within a use case which is to be extended (see Figure 2.9, One use case can extend the behaviour of another providing more deliverables to the actors. ). However, the existence of such extension points do not require that the use case needs to be extended before it can be used. The extended use case is a complete use case with or without extensions, even if it does define extension points.
6. Actor specialization
UML also supports the concept of specializing actors. For this we use the standard specialization relationship,the solid line with the triangular arrow, between the actors. Recall that actors resembled roles fulfilled by external objects in the context of using the system. Actor specialization resembles thus role specialization.
Figure 2.10, One actor can be a specialization of another. shows the Administrator role as a specialization of the Operator role, i.e. every Administrator is also an Operator and hence administrators will also make use of the use case RefillCash.
35
In Figure 2.11, Summary of use case diagram with packaging. we packaged the auto teller use cases across three packages: 1. 2. Customer services package. This package contains the use cases resembling complete customer services. These are the use cases customers use the auto teller for. Low-level use cases package. These are lower-level use cases which are either 3. included by the high-level use cases or optional extensions to the high-level use cases.
Maintenance package. This package includes the use cases for maintaining the system.
8. Scoping
Even for simple systems one may very quickly end up with a very large number of use cases. For example, in Figure 2.12, A typical example of a use case explosion. we have a lot of at best semirelated use cases and it is not easy to understand the system responsibilities from this diagram. And, you can be certain, if we spend a little more time with the use case elicitation we will end up with many multiple times the use cases shown in Figure 2.12, A typical example of a use case explosion..
For systems which one is not intimately familiar with, this development is virtually unavoidable. One simply needs to collect the bag full of use cases before one is able to develop a more abstract, higher-level understanding of the system one is modeling. However, once one has collected the bag full of use cases, one should sit back in order to try and understand the system at a more abstract, higher level. After spending some time with the use case diagram shown in Figure 2.13, Developing higher-level, more abstract understanding of a context identifies the scope of the context. , one may come up with the following conceptualization of the system:
Figure 2.13. Developing higher-level, more abstract understanding of a context identifies the scope of the context.
We then show the concrete use cases as specializations of these more abstract use cases. We can also add packaging to modularize and through this simplify our understanding of the system.
37
38
Consider, for example, an auto teller. Figure 2.15, A use-case diagram for an auto teller. shows the use cases for our auto teller. For each use case one develops one or more sequence diagrams. In Figure 2.16, A sequence diagram for the withdraw-cash use-case. we show a sequence diagram for the WithDrawCash use case.
39
9.1.1. Messages
Between the life lines (or activity bars) we show arrows representing the messages which are exchanged between objects. The message itself is shown as a label on the message arrow. Service request messages are shown as a solid line with an arrow pointing from the client to the service provider. The label contains the name of the service, the information provided with the service requests as parameters of the service request.
The sequence diagram in Figure 2.15, A use-case diagram for an auto teller. shows messages being sent from the card holder to the auto teller and the auto teller services from itself as well as from the bank. Note that the auto teller does not really have a message path to the card holder. For example, the showWelcomeMessage is shown, irrespective of whether there is a card holder in front of the auto teller or not. It is simply a request to the system itself to perform a actor-visible function.
40
Note
Even though we show the operations the context is to perform, we are still modeling the system as black box. The operations shown are the operations as they are to be perceived by the actors and does not constrain the realization of the use case any more than required by the client, (these operations are requirements specifications). For example, we show that the card holder request a withdrawal of a certain amount from a specified account. How the amount is provided or how the account is to be selected is left to the design of the system. Similarly, we specify that a transaction slip is to be issued containing information from the transaction confirmation received from the bank. We don't specify how the transaction slip is to be generated.
The signature for a general state transition label looks as follows: eventName /activity ^messageSentToOtherObject
Naturally use cases are documented using use case diagrams. This is done first at a very abstract level where the use cases are simply stated within use case icons. For a particular instance usage (scenario) there is usually a sequence of messages which is exchanged between the product and the actors. These are naturally documented using sequence diagrams. Activity diagrams can be used to document multiple scenarios within a single diagram.
2. 3. 4. 5.
6. 7. 8. 9.
10. Scenarios. The sequence of messages exchanged between the actors and the system during a use case. Note that there are scenarios for successful and unsuccessful completion of the use case. The complete set of scenarios may be shown in an activity diagram. 11. Use Case completion. When is the use case completed. 12. Priority. The priority the use case from the perspective of the client (driver, constraint, important, optional). 13. Constraints. List each constraint for that use case. This should include the non-functional requirements like performance constraints, stability, scalability, usability, modifiability/maintainability, integrability constraints and so on. 14. Channels to Actors. For each actor list the communication channel(s) used to transmit the messages between the system and that actor. 15. Open Issues. Any issues about the use case which have not yet been resolved.
how these elements are specified in UML. Users and secondary actors. The actors are of course shown in the use case diagram. A <<User>> or <<Primary Actor or stereotype may be added to define the concept of a primary actor in UML. Context. The context is directly shown in the use case diagram as the system or subsystem which contains the use cases. Preconditions. The preconditions can be specified in the use case diagram by attaching a precondition constraint on the the use-case. Post-conditions. Similarly, post-conditions for a use case can be specified by attaching a postconditions constraint to the use case. Trigger. The trigger will be documented in the activity diagram as the event launching the process realizing the use case and in the sequence diagram as the first message coming into the system. Scenarios. These will be naturally documented in sequence diagrams and an activity diagram showing the multiple scenarios. Use case completion. Once again, this is shown in the sequence and activity diagrams. Channels to actors. The requirements specifications around communication channels to the actors are part of the deployment requirements and are best documented using an UML deployment diagram. Priority. This may be documented by attaching priority constraints to the use cases. Often one would document the priority also in the textual description for the use case.
So, nearly all information is naturally contained in the UML diagrams, and often in a clearer and more complete way then what the textual descriptions would (e.g. the guarantees for the individual scenarios). The remaining aspects which need to be documented in text include the primary actor's goal which is realized by the use case, the stakeholders and their interest in the use case, the priority of the use case and the non-functional requirements like the performance, legal, and maintainability requirements.
1. 2. 3. 4. 5.
User. The ATM card holder typically an account holder at a bank. Secondary Actors. The ATM company managing the ATM. Goal. The card holder withdraws money from an account linked to the card and receives it. Context of Use. The client of a bank needs cash. Context. The ATM. 44
6.
Stakeholders and Interest. Card holder: Wants to withdraw funds from his/her account and receive it in cash. ATM company: Wants to offer the use case and receive service fees from the client. Bank: Wants to make certain that the client only withdraws funds which are available to the client.
7.
Preconditions. The card must be linked to an account at a bank which is registered with the ATM company. The bank is prepared to provide the service.. The ATM must have sufficient funds. The ATM must be able to establish communication to the ATM company. The ATM company must be able to establish communication to the card holders bank.
8.
Post-conditions. The card holder is given the withdrawel amount in cash. The card holder has been provided with a transaction slip (either on the user interface or a printed copy). The card is returned to the card holder.
9.
10. Scenarios. Here show sequence diagrams for the messages exchanged during a successful withdrawal as well as for unsuccessful attempts due to Invalid pin number. Insufficient funds in ATM. Insufficient funds in account. Communication to bank cannot be established. User aborted transaction.
11. Use Case completion. The card is returned to the user or the card is withheld by the ATM and the user is asked to contact her/his bank. 12. Priority. Driver. 13. Constraints. 45
Performance constraints. All responses from the bank should be received within at most 10 seconds. Maintainability constraints. The auto teller must be able to print five thousand transaction slips before requiring paper or ink refilling. Usability constraints. 90% of the users must be able to effectively use the system without any prior training.
14. Channels to Actors. Screen and keypad to user. Communication channel to bank.
15. Open Issues. What happens if the ATM encounters a power failure during a transaction?
13. Exercises
1. Develop a use case model for a system for an e-commerce retailer like Amazon. In this context you should: Identify and name the context (system, module, organization, business unit, ...) for which you are developing the requirements and provide a one or two sentence description of the context. Identify the users (primary actors) which will make use of the context (e.g. the users which use a system for the system use cases or the clients which use your organization for certain client use cases). From the perspective of the user(s), identify the concrete leaf use cases (the actual use cases used by the users). Identify any secondary actors, i.e. other systems or users the system is required to interface with in the context of realizing a use case or any other organizations your organization will interface with (e.g. in the context of outsourcing some responsibilities) in the context of realizing the use cases for its clients.
Note
One should only identify those actors which the system is required to interface with. During design (system design or business process design) the designers may introduce further secondary actors in order to delegate some responsibilities to them. This will, however, be a design decision and it is not a user/client requirement that these actors are used. Identify use case abstractions using specialization relationships. The highest level (most abstract) use cases will define the scope of the system or organization. Identify the core quality attributes for the system or the organization. These may include performance, reliability, scaleability, modifiability, security, usability, integrability, portability, ...
46
Note
These quality attributes will be used to design the architecture of the system or the organization. The requirements will typically be realized iteratively by introducing the system or business processes which realize use case for use case. The detailed requirements of each use case are, in the context of iterative use case realization or iterative development, themselves elicited, documented and verified iteratively. To this end select one concrete leaf use case and perform the following steps for that concrete leaf use case: a. Identify the responsibilities/deliverables the system/organization has to address/realize for its users/clients.
Note
The required responsibilities are documented in UML using include relationships between use cases. b. Identify the optional responsibilities/deliverables.
Note
Use extends relationships. c. Document the typical user/client work flow for that concrete leaf use case.
Note
Use a sequence diagram for this. d. Document the use/client work flow for that use case in general.
Note
Use an activity diagram for this showing the activities of the system/organization as perceived by the user/client. e. For that concrete leaf use case show the structure of the entity/information objects exchanged between the actors and the context (system or organization).
Note
Use UML class diagrams with only attributes and composition/aggregation relationships between classes. (This step you will only be able to do once we have covered UML class diagrams.) f. For each secondary actor, introduce a contract for the service requests/messages that service provider needs to be able to process. You will use an interface diagram with pre- and post-condition constraints on each service. (This step you will only be able to do once we have covered UML class diagrams.) Fill in Allister Cockburn's use case template for that concrete leaf use case.
g.
47
1. Introduction
The next step would be to look at a decomposition of the system into its core components and look how these core components interact to realize the use case. Those components can be business units or system components. In either case,we are no longer treating the system as a black box and we are going to expose design information. UML provides a notation for introducing the abstract concept of a collaboration in a diagram. A collaboration resembles a collaboration of objects in the context of realizing a use case. A collaboration is drawn as an ellipse with dashed lines instead of a solid line. An abstract collaboration can be used in use case and class diagrams.
Figure 3.1. Identifying the responsibilities which need to be addressed for the withdraw-cash use-case.
Figure 3.2. Identifying the responsibilities which need to be addressed for in the context of processing an insurance claim.
48
Figure 3.3. Allocating the responsibilities which need to be addressed for the withdraw-cash use-case to core system components.
49
Figure 3.3, Allocating the responsibilities which need to be addressed for the withdraw-cash usecase to core system components. shows the core components we have identified for the auto teller, each of which acquires one of the core responsibilities which need to be addressed to realize the withdraw-cash use case.
Figure 3.4. Allocating the responsibilities around processing an insurance claim to core business units.
Similarly, Figure 3.4, Allocating the responsibilities around processing an insurance claim to core business units. shows the business units of an insurance company which acquire the core responsibilities which need to be addressed when processing an insurance claim.
4. Exercises
1. Reconsider the use case you focused on in the previous chapter. Identify the core responsibilities which need to be addressed for that use case and host each responsibility in a separate object/component.
50
51
transactionDate statement
The UML diagram in Figure 4.1, UML class and object diagrams also shows 3 notations for an object diagram. The first object diagram for the client, sam, has the object name followed by a colon and the class name. It specifies that the object sam is an instance of the class Client. The second object diagram specifies that there is an object, jill, without specifying the class for that object. The colon specifies that jill is an object of some or other class. In the third object diagram we specify an instance of the class Client without specifying a name for the object. 52
1.6. Attributes
Most objects have further features or further components. These can be specified as attributes in UML.
Figure 4.2. Attributes are shown in a second compartment of the class diagram.
An attribute is conceptually an object which is a component of another object. For example, the balance itself is an object which is a component of the account. This object is an instance of the Tender class which encapsulates an amount in a currency. The tender concept is itself explained in another class diagram. The first class diagram shows the attributes without specifying their class (their type). The other class diagrams show the attribute types. We also show an object diagram for which we specify the values of its attributes.
Figure 4.3. Default values for attributes are specified via an assignment.
1.6.3. Constraints
A constraint is specified in UML via curly brackets. In the context of class attributes, one can use constraints to restrict the domain of the attribute values, i.e. to restrict the values an attribute can acquire or to 53
For example, in Figure 4.4, Attribute values and access can be constrained by placing the constrain in curly brackets behind the attribute. we add a {read-only} constraint to both, the balance and the accountNumber attributes, preventing anybody to set the value directly to anything else (though one will still be able to change the balance by crediting or debiting the account as we shall see in Section 1.7, Services).
Figure 4.4. Attribute values and access can be constrained by placing the constrain in curly brackets behind the attribute.
We have also constrained the value of balance to be non-negative via a {balance >= 0} constraint.
54
Figure 4.6.
1.7. Services
So far we have looked at attributes of objects and classes. Objects may also perform operations or offer services. If we specify a service for a class it implies that all instances (objects) of the class will provide that service. In UML one specifies the services offered by instances of a class in a third operations compartment. A service is specified by a service interface specification containing A service name. The name is part of the signature which identifies the service. The service name is often chosen as a verb which clearly describes what you want the instance of the class do for you. Service arguments. The parameters provided to a service specify any information the client sends with the service request. For example, if you request me to make you a cup of tea, you will have to provide as additional information with your service request the number of spoons of sugar you would like in your tea and whether you take milk or not. The parameters themselves are objects and hence instances of classes. The return value of a service (if any). A service might have a return value. For example, if I provide you the service of making you a cup of tea, I will return you a cup of tea (see Figure 4.7, A service is requested providing certain parameters and the service may provide a return value.
55
Figure 4.7. A service is requested providing certain parameters and the service may provide a return value.
Hence the class TeaProvider starts with a capital letter, but an instance of that class, say fritz, starts with a lower case letter. So does the service name, makeCupfTea, while the classes CupOfTea, Integer and Boolean all start with capital letter. Lets, as a second example, revisit our Account class. One can credit an account and debit it. In either case one should provide the tender (amount in a currency) one is crediting the account by.
In the specification of the debit service in Figure 4.8, A service need not provide a return value. we did not give the parameter a name. We simply state that the account is debited by an instance of a Tender.
Figure 4.9. UML uses + for public access, - for private access and # for protected access.
In Figure 4.9, UML uses + for public access, - for private access and # for protected access. we have a thermometer with 4 attributes. Two of them are public while the other two are private. The values which the attributes units van acquire is constrained to degrees celsius, kelvin or degrees fahrenheit. We have applied a {read-only} constrain to the temperature specifying that users can query, but not to set the temperature of a thermometer. Users can, however, calibrate thermometers, but access to the internal convert service which converts between the raw voltage reading and a temperature is restricted to within instances of that class and instances of its subclasses, i.e. the method has been declared with access level protected. Note also that we assigned the monitor stereotype to the thermometer, conceptually classifying it as an object which can be used to monitor other objects. As a business analyst one usually one shows public members.
1.10. Encapsulation
Encapsulation is about hiding implementation details, i.e. the way in which attributes and services 57
are realized. A service provider could make use of different algorithms, different internal data representations and even delegate some the responsibilities down to lower level service providers. All this should be transparent to clients of the service provider, i.e. should be hidden. In UML one uses access control via private and protected members to enforce encapsulation.
Figure 4.10. Three dots can be used to show an incomplete member list. Responsibilities are specified via a responsibilities comment.
58
Note, however, that the class is not as empty as it looks. A default constructor and a this reference are automatically generated. Note though that a default constructor is only generated automatically if no other constructor is defined. Furthermore, Java implements a single-tree inheritance model where every class is ultimately derived from the mother of all Java classes, Object. Any class will thus inherit all the services from Object like a default toString() method and many others. In order to implement an object diagram, one has to instantiate a class: Account acc1 = new Account(); Here we define a reference, acc1, which can refer to any instance of the Account class. The new operator creates a Bond object and returns a reference to that object. The remainder of the statement is simply reference assignment.
Consider, for example the Date class shown in the left diagram of Figure 4.11, Aspects of a date class. From a user's perspective a date has a day, month and year. From an implementation perspective you may decide that using the earth's rotation around its own axis, that around the sun and 59
the moon as reference systems results in a convoluted logic which manifests itself in, for example, a very complex leap year calculation: Every 4'th year is a leap year except every century which isn't except every fourth century which is. In the day/month/year basis the implementation of the services offered by dates (e.g. the increment service) are excessively complex and a loop like for (Date d=d1; d.before(d2); d.increment()) ... has considerable computational overheads. So you decide to select your favourite date (e.g. your birth date, date on which democracy was introduced, ...) as reference date and represent any other date as the number of days between it and the reference date. Now most of the services are straight-forward. Incrementing a date is now simply incrementing an integer. To calculate the number of days between two dates involves merely integer subtraction. Only when users query the actual day, month or year,will we have to do the transformation between our internal representation for that date and the day/month/year format. The implementation view of a date is shown in the right diagram of Figure 4.11, Aspects of a date class and the mapping of the attributes onto Java code would be public class { public int public int public int Date getDay() {...} getMonth() {...} getYear() {...}
public void setDay(int day) {...} public void setMonth(int month) {...} public void setYear(int year) {...} ...
Furthermore, Java defines an additional access level, friendly or package which gives access to all other classes in the same package. This access level is requested in Java by completely omitting an access level keyword -- it is the default access level.
};
If one does not want some of these feature,one has to explicitly disable them by declaing them private.
public: int getDay() const; int getMonth() const; int getYear() const; void setDay(int day); void setMonth(int day); void setYear(int day);
};
The trailing const in the method headers specifies impotent services,i.e. services which do not change the state of that object which supplies the service.
62
<xsd:schema xmlns:xsd='http://www.w3.org/2001/XMLSchema'> <xsd:complexType name="Account"> <xsd:sequence> <xsd:element name="accountNumber" type="xsd:string"/> <xsd:element name="balance" type="xsd:decimal"/> </xsd:sequence> </xsd:complexType> </xsd:schema>
Figure 4.12. Subclassing is shown in UML via a triangular arrow pointing from the of the subclass to the superclass.
63
Figure 4.13. A subclass inherits all instance members (attributes and operations) of the superclass.
3.4.1. Account.java
public class Account { public Account(String accountNumber) { this.accountNumber = accountNumber; } public double getBalance() {return balance;} public void credit(double amount) {balance += amount;} public void debit(double amount) throws Exception { balance -= amount; } public String toString() { return accountNumber + ": bal=" + amountFormatter.format(balance); } private double balance = 0; private String accountNumber; public static final java.text.DecimalFormat amountFormatter = new java.text.DecimalFormat("########0.00");
3.4.2. ChequeAccount.java
public class ChequeAccount extends Account { public ChequeAccount(String accountNumber, double chequeFee) { super(accountNumber); this.chequeFee = chequeFee; } public void setChequeFee(double newChequeFee) { this.chequeFee = chequeFee; } public void setMinimumBalance(double minimumBalance) { this.minimumBalance = minimumBalance; } public void debit(double amount) throws Exception { double totalAmount = amount + chequeFee; if (getBalance() - totalAmount < minimumBalance) throw new InsufficientFundsException(); } super.debit(totalAmount);
public double getChequeFee() {return chequeFee;} public double getminimumBalance() {return minimumBalance;} public String toString() { return super.toString() 65
} }
3.4.3. InheritanceTest.java
Instances of ChequeAccount will inherit the credit, debit, getBalance and getAccountNumber services: public class InheritanceTest { public void run() { ChequeAccount acc = new ChequeAccount("876532762", 5); acc.credit(300); try { acc.debit(150); } catch (InsufficientFundsException e) { System.out.println("You're broke, bloke"); } catch (Exception e) {System.out.println(e);} } System.out.println(acc);
Running the application provides the following output: 876532762: bal=145.00 (chequeFee=5.00, overdraft limit=0.00)
66
Finally, private specialization reduces the access levels of all inherited members to private.
3.5.3.1. Account.h
#ifndef ACCOUNT_H #define ACCOUNT_H #include <iostream> #include "Exception.h" using namespace std; class Account { public: Account(const char* accountNumber); virtual ~Account(); virtual void credit(double amount); virtual void debit(double amount); double balance() const; const char* accountNumber() const; char* toString() const; private: double _balance; const char* _accountNumber;
};
3.5.3.2. Account.cpp
#include "Account.h" #include <iostream> using namespace std; Account::Account(const char* accountNumber) : _balance(0), _accountNumber(accountNumber) {} Account::~Account() {} 67
void Account::credit(double amount) {_balance += amount;} void Account::debit(double amount) {_balance -= amount;} double Account::balance() const {return _balance;} const char* Account::accountNumber() const {return _accountNumber;} ostream& operator<< (ostream& os, const Account& account) { os << account.accountNumber() << ": balance=" << account.balance(); return os; }
3.5.3.3. ChequeAccount.h
#ifndef CHEQUEACCOUNT_H #define CHEQUEACCOUNT_H #include <iostream> #include "Account.h" using namespace std; class ChequeAccount: public virtual Account { public: ChequeAccount(const char* accountNumber, double chequeFee); virtual void debit(double amount); double chequeFee() const; void chequeFee(double chequeFee); double minimumBalance() const; void minimumBalance(double minimumBalance); char* toString() const; private: double _chequeFee, _minimumBalance;
};
3.5.3.4. ChequeAccount.cpp
#include "ChequeAccount.h" #include <iostream> using namespace std; ChequeAccount::ChequeAccount(const char* accountNumber, double chequeFee) : Account(accountNumber), _chequeFee(chequeFee) {} void ChequeAccount::debit(double amount) { double totalAmount = amount + _chequeFee; if (balance() - totalAmount < _minimumBalance) throw InsufficientFundsException("You're broke,bloke."); 68
Account::debit(totalAmount);
double ChequeAccount::chequeFee() const {return _chequeFee;} void ChequeAccount::chequeFee(double chequeFee) { _chequeFee = chequeFee; } double ChequeAccount::minimumBalance() const {return _minimumBalance;} void ChequeAccount::minimumBalance(double minimumBalance) { _minimumBalance = minimumBalance; } ostream& operator<< (ostream& os, const ChequeAccount& account) { os << account.accountNumber() << ": balance=" << account.balance() << " (chequeFee=" << account.chequeFee() << ", " << " minimumBalance=" << account.minimumBalance() << ")"; return os; }
3.5.3.5. InheritanceTest.cpp
#include <iostream> #include "Account.h" #include "ChequeAccount.h" #include "Exception.h" using namespace std; int main() { ChequeAccount* acc = new ChequeAccount("876532762", 5); acc->credit(300); try { acc->debit(150); } catch (InsufficientFundsException e) { cout << "You're broke, bloke" << endl; } cout << (*acc) << endl; delete acc; } return 0;
</xsd:sequence> </xsd:complexType> <xsd:complexType name="ChequeAccount"> <xsd:complexContent> <xsd:extension base="Account"> <xsd:sequence> <xsd:element name="chequeFee" type="xsd:decimal"/> <xsd:element name="minimumBalance" type="xsd:decimal"/> </xsd:sequence> </xsd:extension> </xsd:complexContent> </xsd:complexType> <xsd:element name="accounts"> <xsd:complexType> <xsd:sequence> <xsd:element name="account" type="Account" maxOccurs="unbounded"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema> Here the type ChequeAccount inherits accountNumber and balance from the Account type.
3.7. Polymorphism
Polymorphism is one of the central concepts and key benefits of object-orientation. It provides the mechanism through which one can work at higher levels of abstraction. Polymorphism is, however, not foreign to us in everyday life. We are quite comfortable with the fact that one service provider will realize a service differently from another. Frank Sinatra even wrote a song on polymorphism: I do it my way. And this is really all there is conceptually to polymorphism. In object-orientation you are not calling a particular function, you are requesting a service from an object and each object will decide itself which functions are called to realize the service.
3.8.1. PolymorphismTest.java
public class PolymorphismTest { public void run() { 70
Account[] accounts = new Account[3]; accounts[0] = new Account("376632865"); accounts[1] = new ChequeAccount("876532762", 5); accounts[2] = new Account("654324532"); for (int i=0; i<accounts.length; ++i) { accounts[i].credit(300); System.out.println(accounts[i]); /* resolved polymorphically */ } for (int i=0; i<accounts.length; ++i) { try { raiseSubscriptionFees(accounts[i]); } catch (InsufficientFundsException e) { System.out.println("You're broke, bloke"); } catch (Exception e) {System.out.println(e);} } System.out.println("After raising subscription fees:"); for (int i=0; i<accounts.length; ++i) System.out.println(accounts[i]);
public void raiseSubscriptionFees(Account account) throws Exception { account.debit(100); /* resolved polymorphically */ } public static void main(String[] args) { new PolymorphismTest().run(); }
Running the application yields the following output: 376632865: bal=300.00 876532762: bal=300.00 (chequeFee=5.00, overdraft limit=0.00) 654324532: bal=300.00 After raising subscription fees: 376632865: bal=200.00 876532762: bal=195.00 (chequeFee=5.00, overdraft limit=0.00) 654324532: bal=200.00
71
In the following example program the debit method is resolved polymorphically: #include <iostream> #include "Account.h" #include "ChequeAccount.h" #include "Exception.h" using namespace std; void raiseSubscriptionFees(Account* account) { account->debit(100); /* resolved polymorphically */ } int main() { const int numAccounts = 3; Account** accounts = new Account*[numAccounts]; accounts[0] = new Account("376632865"); accounts[1] = new ChequeAccount("876532762", 5); accounts[2] = new Account("654324532"); for (int i=0; i<numAccounts; ++i) { accounts[i]->credit(300); cout << *accounts[i] << endl; } for (int i=0; i<numAccounts; ++i) { try { raiseSubscriptionFees(accounts[i]); } catch (InsufficientFundsException e) { cout << "You're broke, bloke" << endl; } } cout << "After raising subscription fees:" << endl; for (int i=0; i<numAccounts; ++i) cout << *accounts[i] << endl;
<account xsi:type="ChequeAccount"> <accountNumber>7832876</accountNumber> <balance>2334.34</balance> <chequeFee>5.50</chequeFee> <minimumBalance>-2000</minimumBalance> </account> <account> <accountNumber>8763287632</accountNumber> <balance>500.00</balance> </account> </accounts>
subclasses will. GraphicsObject defines one abstract method, draw. The class itself does not provide an implementation (what should an abstract graphics object draw anyway?). The abstract method represents a requirements specification for the concrete subclasses, i.e. they must all implement a draw service. Any class which does not provide an implementation of draw must itself be declared {abstract} because it does not yet fullfill all the requirements of a graphics object.
3.
74
};
<xs:complexType name="Drawing"> <xs:sequence> <xs:element name="graphicsObject" type="GraphicsObject" maxOccurs="unbound </xs:sequence> </xs:complexType> </xs:schema>
Note
If the inheritance links between CreditCardAccount and ChequeAccount are not declared virtual, two accounts, each with their own account number and balance, would be inherited. This is never correct -- in that case it would be a has a relationship, perhaps 76
composition.
Figure 4.16. The disjoint constraint prevents multiple inheritance from within a class hierarchy.
Figure 4.17. The {complete} constraint prevents subclassing when applied to a class and method overriding if applied to a method.
77
In Figure 4.17, The {complete} constraint prevents subclassing when applied to a class and method overriding if applied to a method. the authenticate service for users has been declared {complete} and its behavior may thus not be altered by any of its sub-classes, i.e. the method may not be overridden. Furthermore, the Administrator class has been declared {complete} and hence every instance of an administrator will be an instance of that particular class with exactly that behavior.
Figure 4.18. During restrictive specialization the subclass only applies constraints to the elements inherited from the superclass.
78
Circle does not add any features to ellipse -- it simply applies the constaint that the major axis is equal to the minor axis. Similarly, quadangles are polygons with the number of points constrained to 4 and rectangles apply further positioning constraints on the four points of a quadangle. We may also use a combination of restrictive and extensive specialization. In this case the subclass applies certain constraints to the elements inherited from the superclass and adds other elements which are not present in the subclass. We had an example earlier, that of a savings account shown in Figure 4.13, A subclass inherits all instance members (attributes and operations) of the superclass. . The SavingsAccount added to Account the interest rate it earned but at the same time constrained the account balance to a positive balance.
The {disjoint} constraint implicitly always applies in XML since multiple inheritance is not supported. XML provides explicit support for the {complete} constraint on classes (services are not relevant for XML). To declare a class (type) as {complete} one assigns the value of the attribute final to true: <complexType name="Administrator" final="true"> <complexContent> <extension base="User"> ... </extension> </complexContent> </complexType>
2. 3.
Post-Conditions: 1. 2. The account has been debited with the supplied amount. A debit transaction has been written into the account's transaction history.
80
Invariants: 1. The balance plus the total credits minus the total debits is zero.
Figure 4.19. Pre- and post-conditions and invariants can be specified in UML with corresponding pre- and post-condition comments.
UML supports the specification of pre- and post-conditions as well as invariants in corresponding pre- and post-condition and invariant comments attached to a service (see Figure 4.19, Pre- and post-conditions and invariants can be specified in UML with corresponding pre- and post-condition comments. ). The comments may be written in the formal Object Constraint Language (OCL) or less formally in text. This is not a particularly elegant solution. These aspects will be addressed in a more satisfactory way with the UML 2.0 specification.
Reason
A client may request an instance of the superclass. You may always give him an instance of one of the sub-classes instead. He/she knows that the object provides a certain service as long as a specific set of pre-conditions is met. If the subclass instance violates this, substitutability is violated. 2. Post-conditions may not be decreased. The realization of the subclass service must provide at least all those deliverables which the corresponding service of the superclass provides. It may, though, provide additional deliverables which are not provided by the corresponding service of the superclass.
Reason
81
A client may request an instance of the superclass. You may always give him an instance of one of the sub-classes instead. He/she knows that a service of the instance provides certain deliverables. Substitutability would be violated if the sub-class service does not provide at least the deliverables the superclass service provides. These rules are graphically illustrated in Figure 4.20, When overriding a method the preconditions may only be decreased and the post-conditions may only be increased. .
Figure 4.20. When overriding a method the pre-conditions may only be decreased and the post-conditions may only be increased.
guidelines
from
design-
From the implementation perspective one has to ensure that when a method is overridden, that the pre-conditions are never increased and that the post-conditions are never decreased. To this end the replacement implementation should Not throw more exceptions than the implementation in the superclass. The pre-conditions are checked before the service is provided and, if not met, the service provider throws an exception notifying the client who requested a service that the pre-conditions have not been met. Since 82
the pre-conditions may not be increased when overriding a method, the subclass implementation of a service may not throw any exceptions which are not potentially thrown by the superclass implementation of that service. If possible, the subclass implementation of a service should call the superclass implementation . Doing this enforces that all the superclass post-conditions will be met. The subclass implementation may then go ahead and add additional deliverables.
This analysis solution has, however, some quite serious drawbacks. Consider the case where a developer changes his/her job to become a manager in the same organization. It is still the same person and the same employee and deleting the developer with all his/her history to create a manager for the same employee sounds at least un-ethical if not down-right wrong. In Figure 4.22, Using roles for employees. we have mapped the specialization relationship onto 83
roles. Now an employee simply acquires a new role in an organization when he/she changes jobdescription.
4. Interfaces
So, what is an interface? An interface provides a mechanism for decoupling from any particular service provider and specify the services you require and the messages you will send when requesting these services.
Service providers can then implement these interfaces by providing the services specified in the interface. A client can use any of the service providers which implement the interface -- they are decoupled from a concrete realization of a service provider and hence avoid vendor locking.
work which enables one object to make use of the services of another object without being exposed to any of the implementation details like development language, location of the service, network protocols required to communicate with the object and so forth. The entire CORBA specification is an interface specification -- the OMG itself has never provided an implementation. Many companies (e.g. IBM, Sun, HP, IONA, ...) and many open source development teams have provided concrete realizations (implementations) of the specification.
Figure 4.23. The interest rate source interface specifies the services which must be supplied by interest rate sources. Differnt service providers may realize these services in different ways.
85
In Figure 4.23, The interest rate source interface specifies the services which must be supplied by interest rate sources. Differnt service providers may realize these services in different ways. we show an InterestRateSource interface which states that any interest rate source must provide two services providing interest rates and discount factors over specified periods respectively.
For example, in Figure 4.24, Two tea provider realizations which provide the makeTea service. , we have an interface, TeaProvider, with two service providers who implement the interface and 86
hence provide the service makeTea. Note that the classes which implement the interface may have very little in common bar that they, among other things, provide the services specified in the interface. For example, have another look at the interest rate sources shown in Figure 4.23, The interest rate source interface specifies the services which must be supplied by interest rate sources. Differnt service providers may realize these services in different ways. . Reuters, as financial information provider, provides the market information against a fee. A bank will provide interest rates for investements in its products. Alternatively you might have calculated your own interest rate curve (getting interest rates from various banks, for example) and the resulting interest rate curve could be queried for an interest rate or a discount factor over a specified period. Alternatively you may be working in an organization which employs interest rate dealers who know the market very well. You could pop up a little window on a dealer terminal asking him/her for the market rate for a specific investment period. Finally, if you have a portfolio of priced bonds, you can also strip (calculate) interest rate information from them. These service providers are very different ranging from a bank to Reuters to a portfolio of bonds. They have very little in common except that they all can provide interest rate information.
Figure 4.25. Clients use an InterestRateSource only through a standard interafe, thereby avoiding vendor locking.
A PortfolioManager requires interest rates for making investment decisions and a cheque requires interest rates to be able to calculate its value on a date other than the payment date. Both make use of service providers in a way which decouples them from any concrete realization of an interest rate source.
UML now supports an alternative notation for highlighting that a client requires a service provider realizing a particular contract and for showing service providers which realize the contract.
4.5. Viewing an interface as the skeleton of a contract between clients and service providers
An interface can be viewed as part of a contract formalizing the relationship between a client and its service providers. The interface specifies the services which must be provided by service provider fulfilling the contract and the messages which will be sent when requesting the service as well as the return value of the service.
The first two aspects can (and should) be handled in the framework of design-by-contract. All three aspects are handled in UML by further formalizing the contract skeleton provided by the interface with sequence and activity diagrams which fully specify the interaction between a client and its service providers. We will cover these aspects in detail in the discuss using UML for business and requirements modeling.
88
Figure 4.28. Some banks have entered the bank-assurance model providing the services of both, a bank and an assurer while other remain pure banks.
89
Figure 4.29. Documents are Printable and hence also Viewable, providing both, print and show services.
In Figure 4.29, Documents are Printable and hence also Viewable, providing both, print and show services. any class which implements Printable must provide both, print and show services.
Figure 4.30. Introducing a concept of a bank assurance business with different organizations realizing that concept.
90
2.
5. Implementing interfaces
Here we show mappings of UML interfaces onto Java and C++.
Note
The compiler enforces the specification at instance level. For example, to specify that our InterestRateCurve fulfills the requirements laid down for interest rate sources, we specify 91
public class InterestrateCurve implements InterestRateSource { ... public double getDiscountFactor(Period period) {...} public InterestRate getInterestRate(Period period) {...} ... }
Note
We can reduce the amount of code duplication by encapsulating the shared code in another helper class which is used by both, ChequeAccount and ModernAccount, but we cannot get rid of it completely.
Figure 4.31. Realizing multiple inheritance in a language which does not support it
92
The design is shown in Figure 4.31, Realizing multiple inheritance in a language which does not support it.
Note
We use the more natural name for the interface and a more convoluted name for the class since most of the code will work at interface level.
6. Ports
A port represents an interaction point between a classifier, the context, and its actors. Typically the context makes a set of services available through the port, but may also, at times, request services from other service providers through that port.
port may be used to not only accept service requests, but also to send service requests to external service providers.
Figure 4.32, Ports for a restaurant shows how external objects interface with restaurants through a waiter and a telephone port.
94
7. Composition
Specialization is a very strong relationship -- it is an is a relationship where every instance of the subclass is a special instance of the superclass. The next weaker relationship is composition which is a strong has a relationship. This is one of the core relationships facilitating the recursive decomposition of high-level objects into lower level objects.
Furthermore, the owner object takes full responsibilities of its components (i.e. if one of the components fails and the owner does not handle this problem, then the owner object fails).
95
The first notation allows on to show more details about the component, while the second is often used for its compactness and readability. In Figure 4.34, Cheques have as components an amount and a payDate. we show both notations. The payDate component is shown as an attribute, while the amount component is shown using a UML composition relationship.
96
import java.util.Date; public class Cheque { public Cheque(Date date, double amount) { this.date = (Date)date.clone(); this.amount = amount; } public Date getDate() {return (Date)date.clone();} public void setDate(Date newDate) {this.date = (Date)newDate.clone();} public double getAmount() {return amount;} public void setAmount(double newAmount) {amount = newAmount;} public Object clone() { Cheque copy = null; try { copy = (Cheque)super.clone(); copy.date = (Date)this.date.clone(); } catch (CloneNotSupportedException e) {/* never thrown,just removing pre-conditions. */} } return copy;
The former are always copied when passed as a parameter to a service (i.e. we have a copy already). The latter cannot be modified and furthermre, one cannot substitute a mutable subclass instance because subclassing has been prevented by virtue of the class being declared final.
and hence not resolved polymorphically. There is, however, the additional aspect of memory management which applies to C++ and any other programming language wich does not support automatic memory management through a mechanism like garbage collection.
9. Aggregation
Aggregation is a weak has a relationship. The components of the aggregate object still form part of the state of the aggregate object (i.e. a state transition in the component still results in a state transition in the aggregate object), but the component is not owned by the aggregate object. The consequences of this are the component can be accessed directly without going through the aggregate object, the component may survive the aggregate object, the same component may be a component of multiple aggregate objects, the aggregate object does not typically take responsibility for its components.
used instead of the solid diamond. The notation is illustrated in Figure 4.36, Clients have accounts via aggregation. .
Clients may potentially have multiple acccounts. This is a has a relationship where a state transition in the clients accounts result in a state transition of the client (e.g. his/her credit worthyness). However, it is a weak has a i.e. aggregation and not composition because the account can be credited and debited directly without going through the client.
An ellipse has a single point, the center of the ellipse as well as a majorAxis and a minorAxis. Circles are ellipses with the constrained that the major and minor axes are equal. All graphics objects have a style (aggregation) defining the border and the fill style. Changing the style of a graphics object does result in a change in the graphics object. i.e. state transition propagation still holds. However, the same style object can be applied to multiple graphics object (changing it would change them all) and the style which is associated with a graphics object may continue to exist after the graphics object has been deleted.
100
11. Associations
An association is the next weaker relationship after aggregation. It is perhaps the most widely used relationship in UML and UML provides extensive notation for associations.
Specialization is an is a relationship and composition and aggregation are stong and weak has a relationships. The former facilitate inheritance and the ability to work at various levels of abstraction while the latter enabled us to assemble complex objects from simpler ones. The objects of our system have to collaborate to perform the tasks required from the system. To this end they send messages to one another requesting services from one another. In order for an object to send a message to another object it needs a link to that object. A link can be seen as a message path between objects. An association is a template from which links are generated. We shall see that associations can be modeled as classes and their instances (objects) will be links. For example, if the PortfolioManager class has an association to the InterestRateSource, then a particular portfolio manager will have a link to particular interest rate source. The portfolio manager can then send a service request message to the interest rate source requesting, for example, the interest rate applicable to an investment over a specified period. An association can thus be seen as a uses or is associated with relationship.
Figure 4.38. Unary associations are drawn as a solid line with an arrow head on the server side of the relationship.
102
Note
A binary association is simply a short-hand notation for two inverse unary directions. Each can have its own association name and own role names. At times it is better to draw a binary association as two separate unary associations. 103
These are the core statements contained in the textual description for the system. In Figure 4.40, Mapping the textual description onto UML. we map them onto a UML diagram. Note that the last two sentences mapped onto a binary association. We were, however, a little uncertain about the management style of the supervisor. In particular, it may not yet be clear if there is a binary or only a unary message path between them.
104
The little solid arrow designates the direction in which we are to read off the sentences. This is typically, but not necessarily the same direction as what the messages flow. If the direction of message flow is the same as the direction in which the association label is read,we usually get the normal Subject verb object. sentence structure. If the directions are different we get a more complex sentence structure (see the third sentence above). In most cases we would resort to the two arrows pointing in the same direction (i.e. to the simpler sentence structure). In those cases the label arrow may be omitted as is done in the Operates association. The label arrow is, however, important for binary associations.
Note
105
The role is part of the association, not part of the class. The role name, in UML, is specified by a text label at that end of the association which links to the class whose instance assumes the role of the role name. Role name map onto variable names. This is particularly apparent in Section 11.4.1, Example: Bonds and interest rate sources.
in any service provider who supplies the required services. To achieve this the server side of an association should virtually always be an interfaces. this decouples clients fom the actual realizations of service providers and avoids vendor locking. Furthermore, the client's requirements are clearly documented in an interface. This alone may be reason enough to always insert interfaces between clients and their service providers.
107
Note
It is often possible to modify the model in such a way that the introduction of an additional constraint is no longer necessary, i.e. that the constraint is automatically satisfied through the model. If this is possible, it usually leads to a cleaner, more natural and more flexible analysis or design solution.
108
Figure 4.45. Specifying an ordered collection via a constraint on the many side of an association or composition relationship.
Figure 4.46. Removing or and xor constraints through by introducing more abstract concepts usually leads to a cleaner, more flexible and more scalable model.
109
Here we encapsulated the services required by the voltmeter from a display in an interface. The model is not only conceptually cleaner,but can also readily absorb further types of displays. Similarly, the fact that an account is associated with either a person or a company can be modeled more naturally by introducing the more abstract concept of a client, with persons and companies being different specializations of a client.
Note
For every instance of the association (every link) there wil be an instance of the association class.
Figure 4.47. Association classes enable one to assign attributes and services to the association itself.
110
People not very familiar with UML may find the concept of an association class a little difficult. One can, however, map an association class onto more vanilla UML notation (see Figure 4.48, Association classes can be mapped onto more vanilla UML notation. ).
11.8. Qualifications
The unified modeling language also includes support for qualifications of association, aggregation and composition relationships. association. A qualifier is a link attribute which reduces the effective multiplicity of the association. We can thus attach qualifiers to an end of an association which has a multiplicity greater than one. Let us illustrate the use of qualifiers by an example. For each bond there is a yield quoted at the close of trading, the closing yield. On any given date there is at most one closing yield. There might be none if there was no trading on that date (e.g. on a public holiday). This relationship is shown in Figure 4.49, Qualifications reduce the multiplicity of a relationship. .
In UML qualification is shown as a small rectangle attached to a class in an association which has a non-unity multiplicity in the association. The qualifier might visually give the impression that it belongs to the class, but that is not so. What really is specified is that the client should have a service which returns a subset of its associations.
111
Qualification reduces the multiplicity of a many-to-one association but it need not reduce the multiplicity to a one-to-one association. For example, giving a directory the qualifier that the extension of a file name is xml could resolve all Java files present in the directory.
112
N-ary associations are one of the sins of UML. You many want to consider putting an outright ban on the use of n-ary associations. They leed to excessive complexity which is hidden behind some compact UML notation. Figure 4.52, N-ary associations provide a compact notation to hide a total mess. shows the message paths specified in the harmlessly looking diagram of Figure 4.51, UML notation for n-ary associations. .
Figure 4.52. N-ary associations provide a compact notation to hide a total mess.
113
114
You may also want to consider the following guidelines: Do not clone (i.e. do not make a copy) of the associated class because then you do not have an association to the real thing, i.e. you will no longer feel the effects of a changing environment. Your constructor arguments would typically contain all mandatory components (at least all for which there are no default values), but the association are usually provided via set methods. For example, our cheque may exist without assigning a discounting rate source. We cannot value our cheque then,but we still have the cheque as a legally binding contract.
Figure 4.54. A parts catalog containg composition, specialization and association relationships.
The XML mapping of the UML diagram in Figure 4.54, A parts catalog containg composition, specialization and association relationships. is shown below. Note the mapping of associations onto key/keyref pairs.
<xsd:element name="partsCatalog"> <xsd:complexType> <xsd:sequence> <xsd:element name="parts" type="Parts"/> <!-- some of which may be prod <xsd:element name="manufacturers" type="Manufacturers"/> </xsd:sequence> </xsd:complexType> <xsd:key name="partID"> <xsd:selector xpath="parts/part"/> <xsd:field xpath="@code"/> </xsd:key> <xsd:key name="manufacturerID"> <xsd:selector xpath="manufacturers/manufacturer"/> <xsd:field xpath="@id"/> </xsd:key> <xsd:keyref name="manufacturerPartRef" refer="partID"> <xsd:selector xpath="manufacturers/manufacturer"/> <xsd:field xpath="part/@ref"/> </xsd:keyref> <xsd:keyref name="partManufacturerRef" refer="manufacturerID"> <xsd:selector xpath="parts/part"/> <xsd:field xpath="manufacturer"/> </xsd:keyref> </xsd:element> <xsd:complexType name="Parts"> <xsd:sequence> <xsd:element name="part" type="Part" maxOccurs="unbounded"/> </xsd:sequence> </xsd:complexType>
<xsd:complexType name="Part"> <xsd:sequence> <xsd:element name="name" type="xsd:string"/> <xsd:element name="description" type="xsd:string" minOccurs="0"/> <xsd:element name="assemblyInstruction" type="xsd:string" minOccurs="0" ma <xsd:element name="part" type="Part" minOccurs="0" maxOccurs="unbounded"/> <xsd:element name="manufacturer" type="xsd:string"/> </xsd:sequence> <xsd:attribute name="code" type="xsd:string"/> </xsd:complexType> <xsd:complexType name="Product"> <xsd:complexContent> <xsd:extension base="Part"> <xsd:sequence> <xsd:element name="price"> <xsd:complexType> <xsd:sequence> <xsd:element name="amount" type="xsd:decimal"/> <xsd:element name="currency" type="xsd:string"/> 116
</xsd:sequence> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:extension> </xsd:complexContent> </xsd:complexType> <xsd:complexType name="Manufacturer"> <xsd:sequence> <xsd:element name="name" type="xsd:string"/> <xsd:element name="address" type="xsd:string"/> <xsd:element name="part" minOccurs="0" maxOccurs="unbounded"> <xsd:complexType> <xsd:attribute name="ref" type="xsd:string"/> </xsd:complexType> </xsd:element> </xsd:sequence> <xsd:attribute name="id" type="xsd:string"/> </xsd:complexType> </xsd:schema> An example XML document which would be parsed by this schema is shown below: <?xml version="1.0" encoding="UTF-8"?> <partsCatalog xmlns="http://www.ManufacturingUnlimited.co.za/PartsCatalog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.ManufacturingUnlimited.co.za/PartsCatalog PartsCatalogKeys.xsd">
<parts> <part code="0112"> <name>PC-Flash</name> <description>The ultimate -- at least for this week</description> <assemblyInstruction>Plug keyboard in green socket</assemblyInstruction> <assemblyInstruction>Plug mouse or rat in purple socket</assemblyInstructi <part code="0113"> <name>GrindAlong Motherboard</name> <description>The board your mother wished she had.</description> <manufacturer>123</manufacturer> </part> <manufacturer>123</manufacturer> </part> <part code="0114"> <name>MickyMouse</name> <manufacturer>123</manufacturer> </part> <part xsi:type="Product" code="1111"> <name>Deep Thought</name> <description>A model capable of very deep thinking.</description> <manufacturer>123</manufacturer> <price> <amount>231</amount> <currency>ZAR</currency> </price> </part> </parts> <manufacturers> <manufacturer id="123"> <name>Slap bam</name> <address>15 Semble-It Road, Industria</address> <part ref="0112"/> <part ref="0114"/> <part ref="1111"/> 117
13. Dependencies
A dependency is the weakest and last of the UML static relationships. While association, aggregation, composition and specialization all imply a structural relationship, there may be a dependency between two entities with there being any structural relationship.
Figure 4.55. Cashiers have a weak uses relationship with your credit card.
Example 4.11. Cashier has a dependency relationship with your credit card
In order for a cashier to complete his/her work flow, he/she must be able to process a credit card transaction using your credit card as message path to your credit card account. The card is not his/ hers (thus the relationship is neither composition nor aggregation) and the teller will (hopefully) not maintain the message path (the credit card) to your credit card account in order to make, at a later stage, further service requests to you credit card account.
118
14. Friendship
In UML one class can declare another class a friend, exposing its private members (e.g. private data fields and methods) to the friend. The class who has been declared a friend can thus access the private members of the class from whom it obtained the friendship and through this it has a dependency not only on the public interface, but even on the private implementation details. This is then shown as a dependency with stereotype <<friend>>.
For example, in Figure 4.57, The LinkedList class declares the LinkedListIterator a friend. , the 119
LinkedList declares the LinkedListIterator a friend, thereby giving it access to its private members (e.g. the head node). The iterator is thus dependent on changes to the implementation details of LinkedList.
There are, however, some consequences to implementing friendship via inner classes. Firstly, instances of inner classes must live within the context of an instance of the outer class. Thus, our linked list iterator would have to live within the context of a particular linked list and would only have access to the private attributes and operations of that particular linked list. In most cases this is exactly what one wants and hence inner classes provide the preferred implementation framework.
These relationships have very precise meaning in object-oriented modeling which we shall review below.
15.1.1. Dependency
The dependency is the weakest relationship where a change in one class (particularly it's public interface) can result in change requirements for the dependent classes. A dependency relationship is typically direct or indirect uses relationship without there being a client-server relationship maintained. For example, an object which uses another object temporarily in the context of supplying a service is a dependency is dependent on the object whose services it makes use of.
Note
The temporary reference is often obtained by receiving a message path to the object as parameter to a service request. The service makes use of that object, but the object offering the service does not maintain the message path after the service has been provided.
15.1.2. Association
An association relationship is a client-server relationship which is a special type of dependency where one object, the client, maintains a message path (handle) to the other object, the server.
15.1.3. Aggregation
Aggregation is a special form of association where there is still a message path maintained, but where there is a weak has a relationship between the client which is now called the aggregate object and the server which is viewed as a part of the aggregate object. Aggregation implies state propagation in the sense that a state transition in the component implies a state transition in the owner.
15.1.4. Composition
Composition is a strong has a relationship implying full ownership. It is thus a special form of aggregation were the aggregate object takes full control of the component, i.e. The component can only be modified through the owner and the component does not survive the owner.
15.1.5. Specialization
Specialization specifies a is a relationship at the instance level. For example, a a CreditCardAccount is a special type of Account and a CorporateClient is a special type of Client. 121
The two core features of specialization are Substitutability: that we can substitute an instance of a sub-class for an instance of the superclass. For example, if somebody needs an account to, say, subtract some subscription fee, publlic void subtractSubscriptionFee(Account acc) { ... acc.debit(fee); ... }
we can provide an instance of a CreditCardAccount instead and the debit service is typically resolved polymorphically. Inheritance: All instance members (attributes and methods) are inherited, though access to some of these may be restricted due to access control specifications (i.e. they have been declared private). However, specialization can also be seen as a string form of composition where the instance of the subclass has full ownership of an instance of the superclass. A state transition in the superclass instance (the inherited fields) does result in a state tansition for the subclass instance and the superclass instance does not live beyond the subclass instance.
vice provider, but now the client maintains a message path rigrizing the client-server relationship. Aggregation is a special form of association. The aggregate object still uses its components and maintains a message path to them, but now a state transition is propagated through to the aggregate object (i.e. a state transition in the component implies a state transition in the aggregate object). Composition is a special form of aggregation. In a composition relationship the owner maintains a message path to its components and a state transition in the component is still propagated through to the owner. But now the owner applies full access control on its components (i.e. the component can only be accessed through its owner). Furthermore, the component does not survive the owner. Specialization is a special form of composition and realization. That specialization is a special form of composition may be surprising. Let us test it. The instance of the subclass still maintains a message path to the instance of the superclass it specializes and a state transition in the instance of the superclass it specializes does result in a state transition of the instance of the subclass (if the account balance changes the cheque account it is also changes). Furthermore, the instance of account the cheque account is, can only be accessed through the cheque account and does not survive the latter. Hence specialization is indeed a special form of composition. But what does it add? It adds inheritance of the services of the superclass and substitutability with instances of the superclass -- this is then also what is sacrificed if one maps specialization onto composition.
Note
Note that specialization is of course also a special form of realization. Realization. Here a class is a special realization of a contract (interface or abstract superclass).
Figure 4.58. The core UML relationships are specializations of each other.
123
16. Packaging
A package in UML is a grouping of UML model elements. These can include class diagrams and object diagrams, further packages as well as other UML model elements like Use Cases or Sequence Diagrams. Packages can themselves be packaged into higher level packages. Elements contained in a package may either be visible only from within the package, or may be externally accessible (i.e. from within other packages).
124
Figure 4.59. The relationships between packages are dependency, sub-packaging (nesting of packages) and package specialization.
Figure 4.60. Nested packages may also be specified using the scope resolution
125
operator, ::.
A nested package can also be denoted in UML without showing its container package. A scope resolution operator similar to that used in C++ is used. The UML diagram in Figure 4.60, Nested packages may also be specified using the scope resolution operator, ::. shows this notation and also demonstrates how version information can be supplied for a package. This is particularly relevant when one wants to show that a system (or package or class) depends on a particular version of another package.
Note
The substitution principle also applies to packages, i.e. a generalized package can be replaced by any of the more specialized packages. For example, the backPropagationNets and conjGradNets packages in Figure 4.59, The relationships between packages are dependency, sub-packaging (nesting of packages) and package 126
specialization. are specializations of the neuralNets package. They replace the FeedForwardNet and RecurrentNet with their own implementations where either the backpropagation or the conjugate gradients optimization method is used for the learning process. The Neuron is inherited by both packages, but, as it is defined with protected visibility, it is not exported for public use by either package.
In order to make elements globally unique and facilitate re-use accross organizations one usually inserts the inverted domain name in front of the conceptual package structure:
za::co::solmstraining::math::numeric::rootsolvers::multidimensional::NewtonRaphs
Any elements which should explicitly NOT be re-used should be grouped into a package for the system they are exclusively meant for.
127
Package specialization is not supported in Java. To map package specialization onto Java one could first define a stub package for the package interface. The super and sub package classes would then both implement the interfaces specified in the stub. One can import a single class from a package via import dataProcessing.transforms.FastFourierTransform; or the entire package (all its elements) via import dataProcessing.transforms.*;
128
dataProcessing::transforms::FastFourierTransform
Package specialization is not supported in C++. To map package specialization onto C++ one could first define a stub package for the package interface. The super and sub package classes would then both implement the interfaces specified in the stub. One can import the elements of a package via using namespace dataProcessing::transforms;
<xsd:schema targetNamespace="http://www.ManufacturingUnlimited.co.za/PartsCatalo xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:parts="http://www.ManufacturingUnlimited.co.za/PartsCatalog" elementFormDefault="qualified"> <xsd:complexType name="PartsCatalog"> ... </xsd:complexType> <xsd:element name="partsCatalog" type="parts:PartsCatalog"/> ... </xsd:schema>
Below we have an XML instance document which imports the parts-catalog namespace into the default prefix. The elements are then used directly without referring to them through a prefix: <?xml version="1.0" encoding="UTF-8"?> <partsCatalog xmlns="http://www.ManufacturingUnlimited.co.za/PartsCatalog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.ManufacturingUnlimited.co.za/PartsCatalog PartsCatalogKeys.xsd">
<parts> <part code="0112"> <name>PC-Flash</name> <description>The ultimate -- at least for this week</description> <assemblyInstruction>Plug keyboard in green socket</assemblyInstruction> <assemblyInstruction>Plug mouse or rat in purple socket</assemblyInstructi <part code="0113"> <name>GrindAlong Motherboard</name> 129
<description>The board your mother wished she had.</description> <manufacturer>123</manufacturer> </part> <manufacturer>123</manufacturer> </part>
18. Metaclasses
<xi:include></xi:include>
18.2. Constructors
Many implementation languages support the concept of a constructor which is responsible for creating instances of the class. From a user perspective constructors are class services. You requesting the class to create an instance for you (how, otherwise would you create the first instance, if it was an instance, i.e. nonstatic, service). However, from an implementation perspective the constructor body is an instance service initializing the instance itself. Effectively, a constructor is a package containing 1. 2. a class service (static function) which creates an instance of the class, and an instance service initializing the instance itself (the constructor body).
Figure 4.61. A metaclass defining the class (static) members of an Account class.
130
For example, Figure 4.62, Class services are not resolved polymorphically. specifies a class A with service f and a subclass B which overrides that service with its own implementation. Here f is an instance service (offered by instances of the classes A and B) which will be resolved polymorphically, i.e. A a = new B(); a.f(); will resolve the instance service as specified in the class B. Figure 4.62, Class services are not resolved polymorphically. also shows the corresponding metaclasses which provide a service g. The service g is thus a class (static) service. That service will, however, not be resolved polymorphically, i.e. A a = new B(); a.g(); will not resolve the service g as specified in the metaclass B, but instead the one specified in A, even though the reference a actually refers to a B.
131
public static int getNumAccounts() {return numAccounts;} public void finalize() {--Account.numAccounts;} private static int numAccounts = 0; ...
All the methods shown, except the finalize method, are actually class services (i.e. static). The constructor is implicitly so. The class attribute, numInstances, is initialized upon loading the class. Each instance of the class has, in Java, access to the class attributes and services. In the finalize method, which is called by Java's garbage collector before an instance is released from memory, the counter for the number of instances is decremented.
Account::numAccounts = 0;
Note that the destructor ~Client() is used instead of Java's finalize and that the class variable, numInstances, must be initialized at global scope. 132
Instead, this is a form of packaging instances of one class within an intsance of another.
Potentially the post-office may have access to private components of the supermarket. For example, the post-office could use the rest-rooms reserved for staff of the supermarket.
Iterators resemble a form of a pointer which provides access to the collection's elements and supports iterating across these. The iterator for a particular collection is tightly bound to that collection. For example, the iterator for a linked list needs access to the nodes of the list and in particular to the head node of the list. The existence of the iterator makes sense only in the context of the esistence of the collection itself. Each instance of the iterator thus exists within an instance of the linked list and has access to its private members.
Even though the iterator class would be defined as a private inner class, clients may request an iterator for a collection receiving a message path (reference) to an iterator which does not expose the private class itself, but only provides access to it via the Iterator interface.
21.2. Vectors
A vector is a special kind of array used in mathematical modeling for which there are certain mathematical operations defined. For example, we can add two vectors, take the dot product of two vec134
tors or calculate the norm of a vector. These operations do not, in general, make sense for arrays. However, we do not want to define a whole collection of vector classes, one for each data type to be stored in a vector, i.e. we do not want to define separate classes for vectors of integers, vectors of floating point numbers, vectors of complex numbers and say vectors of rational numbers. Instead, we want to define a single vector template which receives the data type of the vector elements and the length (dimensionality) as parameters. Classes are created from the template by binding it to other classes, integral constants or even operations. In the case of our vector template we would bind the vector template with a class for the vector elements and an integer constant representing the dimensionality of the vector. For example, if we wanted to generate the class VectorOfRational from a Vector template, we would bind the template to the class Rational. A template type thus defines a family of classes, each class being specified by binding the parameters of the parameterized type to specific classes, constants or operators. Template types are particularly useful when we have a group of related classes with a very high degree of structural and functional similarity. Parametrized types reduce duplication of design structures and make it easier to achieve consistency in the family of related classes. They also reduce the maintenance burden, i.e. only the parametrized type has to be changed and the whole family of classes is consistently redefined. Programming languages which support templates (e.g.\ C++) will automatically generate the required classes from the template, i.e. developers only have to modify the template class and the compilation step will generate the classes generated by binding the template arguments.
Figure 4.65. A vector template and various classes generated from it.
Figure 4.65, A vector template and various classes generated from it. shows a vector template with a number of classes generated from it. The dashed rectangle in the top right corner specifies that one has to bind the Vector template to a class T and an integer constant n in order to generate one of the family of related classes specified by the parametrized type. We then use this template to generate the class Point3D by binding it to the class Real and the integer constant 3 For this purpose we use a binding dependency, i.e. a with the stereotype <<binding>> and the template arguments. Alternatively we can define a specific class by a class diagram with the template name and the tem135
plate arguments in the name field of the class diagram. For example Vector<Complex,20> specifies the class generated from the template by binding it to the data type Complex and the integer constant, n, to 20, i.e. it defines a vector of 20 complex numbers. To define an instance of one of the classes generated by the template we can use an object diagram like the one shown in the bottom right-hand corner of Figure 4.65, A vector template and various classes generated from it. . Here data is a vector of 100 real (floating point) numbers.
Note
To this end developers of the resource class must make certain that the clone method is implemented in such a way that it creates new, functionally equivalent resources. For example, the clone of a database connection must be a separate connection through which database queries can be made. 21.4.1.1.1. The prototype interface package za.co.solms.utils.resource.pooling; public interface Prototype<T> extends Cloneable { public T clone(); } 21.4.1.1.2. The resource pool contract 136
package za.co.solms.utils.resource.pooling; /** * Contract for resource pools (e.g. connection or thread pools). * The pool must be initialized with a prototype and an initial * pool size before the pool can be used. */ public interface ResourcePool<R extends Prototype<R>> { /** * Provides and locks a handle to a particular resource. */ public R getResource(); /** * Returns the size of the pool. */ public int getSize(); /** * Returns the current number of available resources. */ public int getNumFreeResources(); /** * Releases the provided resource back to the pool It is the * user's responsibility to drop all references to that instance * directly after having released it. */ public void releaseResource(R resource); /** * Resizes the pool to contain the specified number of instances. * Pool sizes are increased by cloning the prototype. */ public void resize(int numResourceInstances); /** * Initializes the pool for use by providing the prototype which * is cloned when increasng the pool size. * The pool is initialized to the specified pool size. */ public void init(R resource, int initialPoolSize);
21.4.1.1.3. An implementation for a basic resource pool package za.co.solms.utils.resource.pooling; import java.util.Set; import java.util.HashSet; import java.util.Iterator; public class BasicResourcePool<R extends Prototype<R>> implements ResourcePool<R> { public R getResource() { if (prototype == null) throw new IllegalStateException ("Pool not yet initialized with prototype."); boolean resourceAvailable = false; synchronized (availableResources) { // Spin lock for extracting resource 137
while (!resourceAvailable) { resourceAvailable = true; if (availableResources.isEmpty()) { try { availableResources.wait(); } catch (InterruptedException e) { if (availableResources.isEmpty()) resourceAvailable = false; else resourceAvailable = true; } } } Iterator<R> iter = availableResources.iterator(); R resource = iter.next(); availableResources.remove(resource); return resource;
public int getSize() {return resources.size();} public int getNumFreeResources() { return availableResources.size(); } public void releaseResource(R resource) { if (resources.contains(resource)) { synchronized(availableResources) { availableResources.add(resource); availableResources.notify(); } } else throw new IllegalArgumentException ("Resource instance not in pool."); } public void resize(int numResourcesInPool) { if (numResourcesInPool < 1) throw new IllegalArgumentException ("Pool size may not be less than 1"); int instancesToAdd = numResourcesInPool - resources.size(); if (numResourcesInPool > 0) { for (int i=0; i<instancesToAdd; ++i) { R resource = (R)((R)prototype).clone(); add(resource); } } else if (numResourcesInPool < 0) { synchronized (availableResources) { synchronized (resources) { for (int i=instancesToAdd; i<0; ++i) 138
// Spin lock for removing resource from pool while (availableResources.isEmpty()) try { availableResources.wait(); } catch (InterruptedException e) {} R resource = getResource(); resources.remove(resource);
private void add(R resource) { synchronized(resources) { synchronized(availableResources) { resources.add(resource); availableResources.add(resource); availableResources.notify(); } } } public void init(R prototype, int initialPoolSize) { this.prototype = prototype; add(prototype); resize(initialPoolSize); } private Set<R> resources = new HashSet<R>(); private Set<R> availableResources = new HashSet<R>(); private R prototype;
21.4.1.1.4. Using the basic resource pool package za.co.solms.utils.resource.pooling; import java.util.*; public class ResourcePoolTest { class A implements Prototype<A> { public A clone() { A copy = null; try { copy = (A)super.clone(); } catch (CloneNotSupportedException e) {/* never thrown */} return copy; } } public void run() { 139
System.out.println("Creating pool"); resourcePool = new BasicResourcePool<A>(); System.out.println("Pool state: " + resourcePool.getNumFreeResources() + " available from a total of " + resourcePool.getSize()); System.out.println("Initializing pool"); resourcePool.init(new A(), 5); System.out.println("Pool state: " + resourcePool.getNumFreeResources() + " available from a total of " + resourcePool.getSize()); new Thread() { public void run() { try { Thread.currentThread().sleep(4000); } catch (InterruptedException e) {} System.out.println("Now resizing"); ResourcePoolTest.this.resourcePool.resize(7); System.out.println("Pool state: " + ResourcePoolTest.this.resourcePool.getNumFreeResources() + " available from a total of " + ResourcePoolTest.this.resourcePool.getSize()); try { Thread.currentThread().sleep(4000); } catch (InterruptedException e) {} Iterator<A> iter = as.iterator(); A a = iter.next(); as.remove(a); System.out.println("Releasing 1 resource"); resourcePool.releaseResource(a); } }.start(); as = new HashSet<A>(); for (int i=0; i<8; ++i) { System.out.print((i+1) + ": Retrieving resource: "); A a = resourcePool.getResource(); as.add(a); System.out.println(a); }
public static void main(String[] args) { new ResourcePoolTest().run(); } private ResourcePool<A> resourcePool; private Collection<A> as;
Figure 4.66. Scalar defines the minimum requirements for elements of linear algebra classes like Vector or Matrix. Scalar::Integer, ..., Scalar::Rational implement Scalar and can hence be used as elements.
140
Consider, for example, our vector template specified. The Java implementation could be provided by a Vector class obtaining a collection of elements as arguments. The minimal requirements could be defined in a Scalar interface as is done in Figure 4.66, Scalar defines the minimum requirements for elements of linear algebra classes like Vector or Matrix. Scalar::Integer, ..., Scalar::Rational implement Scalar and can hence be used as elements. . The vector operations can now be implemented, since it is known that the elements supply the required functionality. Note that the composition link refers to a interface implying that the components may be any objects of any class implementing the interface.
};
typedef Vector<float,3> Point3D; Here we defined the parametrized Vector type and we generated the class Point3D by binding the Vector template to the type float and the integer constant 3. Note that instances of the class acquire an additional private integer constant, {\bf n}, as data attribute. We cannot create instances (objects) of the template type Vector without binding the parameters. However, we can create instances of Point3D and we can create instances of Vector if we bind the template parameters: Point3D point3D; Vector<Complex,20> data;
141
The compiler will generate the specified classes from the template type. This is done at compile/link time and there are no run-time overheads.
22. Exercises
1. Select one of the use cases for the system for an e-commerce retailer for which you developed the use case view and identify the core objects, their abstractions as classes, their attributes and services, and the relationships these classes have amongst each other.
142
1. Introduction
So far we looked at use case diagrams which identified the external objects interfacing with the system and the use they get out of the system and at
object and class diagrams which are used to document the system structure including the objects and their abstractions as classes, the attributes of the objects, the services they supply and the relationships they have with other objects.
In this chapter we will look at the dynamics of the system. This dynamics will occur within the context of the static structure. Ultimately we need a process to identify the structure required to support the dynamics (e.g. the business or system processes).
Sequence diagrams are particularly intuitive and can be used to explain business and system processes even to people who may not be familiar with the notation. Collaboration diagrams are less intuitive, but they will prove very useful as a transition path from the dynamic to the static model.
143
An activity diagram for a single object can be viewed as a subset of a state chart where only the activity aspect of the states is taken into account. However, an activity diagram can also show the activities across objects and provides a simple, intuitive graphical notation for business processes and processes.
2. Sequence Diagrams
We have encountered sequence diagrams already in the use-case view where we treated the system we are modeling as a black box and showed the messages exchanged between the system and its actors. In this section we shall use sequence diagrams to show how the components of a system interact to realize a use case. In this context we will cover further features of sequence diagrams including generic sequence diagrams, object life-cycle management, message types, timing constraints and concurrencies in sequence diagrams.
144
Looking at the buy-product use case we could come up with the following high-level sequence diagram showing the messages exchanged between the client and the vending machine:
We can introduce a high level activity diagram showing multiple scenarios of buying a product from a vending machine.
145
2.2. Responsibility identification and allocation for the buy-product use case of a vending machine
In Figure 5.4, Identifying the responsibilities which need to be addressed for the buy-product usecase. we identify the core responsibilities which need to be addressed for the buy-product use case.
Figure 5.4. Identifying the responsibilities which need to be addressed for the buy-product use-case.
Figure 5.5, Allocating the responsibilities which need to be addressed for the buy-product use-case 146
to core system components. shows the core components of a vending machine, each of which acquires one of the core responsibilities which need to be addressed to realize the buy-product use case. Having identified the responsibilities, we can now go ahead and assign them to core system components or business units.
Figure 5.5. Allocating the responsibilities which need to be addressed for the buy-product use-case to core system components.
Figure 5.5, Allocating the responsibilities which need to be addressed for the buy-product use-case to core system components. shows the core components of a vending machine, each of which acquires one of the core responsibilities which need to be addressed to realize the buy-product use case.
The next step is to look at how these high-level components interact to realize the use case. Fig147
ure 5.6, A sequence diagram for the buy-product use-case, showing how the core components of the vending machine collaborate to realize the use case. depicts a particular scenario (the one where the purchase is successful) of the buy-product use case.
Figure 5.6. A sequence diagram for the buy-product use-case, showing how the core components of the vending machine collaborate to realize the use case.
2.4.1. Branching
To show multiple paths within a single sequence diagram one uses branching. Branching is thus used to show a number mutually exclusive paths where, in each scenario only one path is chosen. In principle, one can use a generic sequence diagram to specify a whole range of instance sequence diagrams (scenarios). An instance sequence diagram is thus a particular path through a generic sequence diagram.
Figure 5.7. A generic sequence diagram showing multiple scenarios for the buy-product use-case.
So far the object which paricipated in the interactions depicted in the sequence diagrams excisted accross all time. Often we need to show objects which are created and destroyed within a workflow.
Figure 5.8. A sequence diagram showing the creation and destruction of an order processor.
At a later stage, after the client received a quote for the order and rapidly pressed the cancel-order button, the warehouse destroys the Reservation. A message requesting the destruction of the object terminates its life-line. Additionally a cross is added to mark the destruction of the object more clearly.
2.5.3. Iteration
Figure 5.8, A sequence diagram showing the creation and destruction of an order processor. also makes use iteration. We indicate an iteration using a * while the condition for continuing with the iteration is shown in a standard conditional (within square brackets).
150
Figure 5.9, Types of messages supported in UML. shows the message types supported in UML.
Note
The service provider may, in principle still continue to process the service request.
2.6.4. Returns
A return represents the response to a synchronous service request. It may contain certain deliverables for the client (return values and output parameters) or simply act as acknowledgement that the requested service has been supplied. In either case the service provider does not require a message path to the client. Consider, the example of placing an order via telephone. The client has a message path to the service provider (the telephone number). He/she uses this message path to send a sychnronous service request to the service provider. The client will wait (block) until he/she received a response. The service provider can provide the response to the client without having a message path to the client (he does not need to know the client's telephone number to provide the response).
151
Figure 5.10. Sequence diagram with concurrencies, non-instantaneous messages and timing constraints.
152
2.9. Concurrencies
Concurrencies involve simultaneous activities. Concurrencies may be accross objects or within the same object. Every time you see multiple activity bars at the same instant, you have a concurrency.
with amount1, while the second thread wants to, say, debit it with an amount2. The first thread starts by querying the balance,calculates the new balance and updates it.
While the first thread is busy processing, the second thread concurrently perform the debit process. It queries the balance, calculates the new balance and updates it. Notice, however, that the first transaction is effectively since the second thread get the balance before the first transaction is completed.
UML provides a {concurrent} constraint to specify that a certain services will be provided by a service provider in a way which is safe under concurrent access.
154
3. Activity diagrams
3.1. Exit states
An activity diagram may have only a single entry state, but may have multiple or exit states. There are no further activities performed after the exit state in the context of the process documented in the activity diagram. An exit state is drawn as a filled circle with an empty circle around it.
In Figure 5.13, Entry and exit states. we show the activities of a game of chess with transitions to the exit state from either a draw or if one of the players wins.
155
3.2.2. Synchronization
Similarly, multiple exection threads can join into a single execution thread. At the join the concurrent flows synchronize, i.e. all threads of activity wait until all incoming threads have reached the join. Thereafter execution continues with the single flow of control leaving the join.
For example, the activity diagram in Figure 5.15, Forking and joining via synchronization bars. shows how concurrent implementation of a Monte Carlo (random path) simulation. After the Monte Carlo parameters have been obtained the thread forks into multiple threads, each calculating a single Monte Carlo path. Each path has to be completed before the concurrent threads or processes recombine into a single execution thread calculating the average over the paths and displaying the result.
Figure 5.16. Activity diagram showing how the core components collaborate to realize the buy-product use-case of a vending machine.
156
So far we have not shown object flow in activity diagrams. UML does support object flow in activity diagrams by inserting object diagrams into the transition.
158
Figure 5.18. Activity diagram showing how the business units collaborate to realize the process-claim use-case.
159
For example, Figure 5.19, Showing common transitions via nested activities. shows that help and exit are available in all states of the game,i.e. whenever the game application is running.
4. State charts
Activity diagrams show one aspect of a state, namely the activity (or activities) performed while the object is in a state. State charts can be used to show the full aspect of the states including local variables of a state. They are used to model the object/system as a state machine. Such state machines are often used to validate a system.
4.1. States
The state of an object or a class is defined by the value of its attributes, the associations to other objects and the operations it currently performs. A state has a duration and thus occupies a period of time. The UML notation for a state is a rectangle with rounded corners. A state may have a number of attributes and an object may perform a number of actions while it is in that state. The state attributes and actions are specified in separate compartments similar to the compartments for the attribute and operations lists of a class diagram. For example, while the operator is prompted for his/her password a system would be in the TypingPassword state. The state diagram for this state is shown in Figure 5.20, State diagram in UML. . The left hand diagram shows a simple state. In the right-hand diagram the state is expanded to show a state attribute as well as the actions performed on entry, exit, help event and while the object is in the specified state.
The name of the state is shown in bold letters in the top compartment of the state diagram. The name is optional. Unnamed states are anonymous, but they are still distinct. If, on the other hand, two states have the same name then they are the same state. It is sometimes useful to place the same state in various places on a state diagram in order to simplify the graphical representation. An action is an operation and it usually involves some computation or the traversing of some al160
gorithm. The actions performed while an object is in a particular state are specified in the last compartment of the state diagram. A do action is an ongoing process performed while an object is in a particular state. Actions may be interruptible by external events. For example, our do-action can be interrupted by a help event which performs the action display help. The actions performed on entry or exit of a state are, however, non-interruptible. They are specified by a entry and exit events. The UML notation for actions is event-name argument-list '/' action-expression
The last compartment holds the state variables. State variables can be class attributes. Alternatively they may be local variables used by the object only while it is in a particular state. State attributes are optional.
4.2.2. Signals
A signal-event is an event triggered by a signal. A signal event is the receipt of a named asynchronous event. The event source dispatches the signal but does not wait for a response. Instead it continues with its own execution thread directly after sending the signal. To specify that a particular event is a signal event we attach a <signal>> stereotype to the event. A very large class of signals is that of exceptions. Exceptions are modeled in UML as signals, that is as named asynchronous events. Note that although Java supports exceptions, they are implemented by default as synchronous calls. This is unsatisfactory except in those cases where the exception handler can return virtually immediately. In most cases the exception handler (i.e. the listener) should launch a separate execution thread for processing the exception. Other signals should be implemented in a similar fashion. The recipient of the signal should launch a new execution thread to process the signal asynchronously.
ition. Generally such events are asynchronous events and hence state change events are special kinds of signals. Similarly, time events can be modeled as a special kind of state change event where the state of the clock changes from, for example, before noon to after noon.
Event specialization is particularly useful for specifying and handling abstract events. For example, the specialization hierarchy for exceptions shown in Figure 5.22, Exception hierarchy. allows us to handle exceptions at various levels of abstraction as is done in Figure 5.23, Exceptions at different levels of abstraction guide process flow. .
162
One of the advantages for introducing event hierarchies is that it enables a design using events at various levels of abstraction. Consider, for example, the case where we want to read a data file to its end. In this case we might want to use EOFExceptions as a signal telling us that we can start processing the data. If we encounter any other IOException (EOFExcetion is an IOException we might want to retrieve a backup file. If there is any other exception we don't know what to do. In this case we simple pop up a dialog box displaying the error message.
The complete event signature in UML is [guard condition] eventName /actionUponStateTransition ^object.sendMessage()
163
5. Communication diagrams
We have documented abstract collaborations which abstractly name a collaboration which will realize the use case. We have then identified the responsibilities which need to be addressed and assigned them to core system components or core business units. After that we looked at how these objects collaborate using sequence diagrams and activity diagrams. We now need a convenient transition from the dynamic model to the static model. This is where a communication diagram is really useful. It shows the message paths required for the objects to communicate as well as the messages sent along these message paths. The time-sequencing of messages is depicted via a numbering system.
Figure 5.26. Communication diagram showing how the core components collaborate to realize the buy-product use-case.
164
The communication diagram thus directly leeds to the identification of the message paths required between the components at a particular level of granularity, and 165
This information provides then the static context of the collaboration, i.e. that subset of the static model at that level of granularity which is required to support the collaboration realizing the use case.
166
1. Introduction
We have modeled the business use cases, business processes and the business structure supporting the business processes as well as the business entities. We have, however, not yet looked at the environment in which we are going to deploy the business (or a particular business unit of an organization). For example, we could decide to deploy the procurement arm of a global antique dealer in London, with retail outlets in New York, Cape Town, Sydney and Paris. We need to model the environments in which the retail outlets are being deployed (for example, a shopping centre) as well as the physical realization of the integration paths (e.g. shipping organization between procurement and the retail outlets).
Orders are placed with procurement via telephone and the orders are delivered via some or other refrigerated deliveries service. Both, Lightning Deliveries and GetEmThere have services, CoolDeliveries and GetEmThereFresh which provide the services specified in the interface RefrigeratedDeliv167
Deployment View
eries. Our business is decoupled from the physical realizations of that service and only binds via a standard contract defined in the RefrigeratedDeliveries interface.
168
1. Introduction
Defining the constraints in our UML diagram in informal text often leads to incomplete or imprecise constraints. Furthermore, such constraints are often open to mis-interpretation. In order to address this deficiency, UML has absorbed a formal constraint specification,the Object Constraint Language (OCL).
169
Invariants. Class invariants specify constraints which must at all times be met by all instances of a class. One may specify more complex invariants in OCL which have to be evaluated across the object graph. Preconditions. Preconditions specify constraints which must be met before a service becomes available. Postconditions. Postconditions are constraints which must be met after a service has been completed.
2. Invariants
An invariant is a constraint which must hold at all times. The invariant is associated with a class and the invariant must hold at all times for all instances of that class. For an invariant, we have to 1. 2. specify the context to which the invariant applies followed by the specification of one or more invariants.
Here self is a self reference which is a reference to that instance of the context to which the constraint is being applied. We could have omitted the self since this is the default for OCL. This constraint may be rendered by different UML tools in different ways, though they should all provide a mechanism to enter the formal OCL constraint. MagicDraw renders the constraint by default in OCL. The constraint is packaged with the UML element to which it is attached. In our case the constraint is attached to specialization link and rendered next to it (left diagram in Figure 7.1, The balance of savings accounts is constrained to be always positive. ). Other UML tools may render the constraint in a constraint comment with stereotype, 170
<<invariant>> as shown in the right diagram of Figure 7.1, The balance of savings accounts is constrained to be always positive. .
description relational less than relational greater than relational less than or equal to relational greater than or equal to
x1 >= x2
Integer or Real
Boolean
172
Figure 7.2. Customers get a 5% discount for orders above R500.00 and a 10% discount on orders above R1000.00
Figure 7.3. Booking for a presentation must be done before the start of the
173
presentation.
Note that we applied two invariance constraints to the context. A neater UML diagram which states the same is shown in Figure 7.4, Using an association class for a booking. . Here we use an association class which still provides the same navigation paths. t emphasis the fact that a booking is created every time a link between a customer and a presentation is instantiated.
174
The three concrete collections are thus Bag. A bag is the most general concrete collection in OCL. It is an unordered collection of elements and may contain duplicate elements. Set. A sets is still an unordered collection, but it removes any duplicate elements -- it is a singleton collection. Sequence. A sequences is an ordered collections which provides random access and may contain duplicates.
OCL collection fields and methods are accessed via the arrow operator, ->. For example, reconsider Figure 7.3, Booking for a presentation must be done before the start of the presentation. . If we wanted to limit the number of bookings to less than the maximum number of participants we could attach the following constraint to the context, Presentation: context Presentation inv: self.bookings->size <= maxCandidates
Here size an attribute provided by OCL for collections. It returns the number of elements in the collection to which it is applied. Below we discuss some of the more commonly used collection functions.
col1->isEmpty
Boolean
col1->notEmpty
Boolean
175
description number of occurrences of object obj1 returns true if obj1 is contained in col1 returns true if all objects in the collection col2 are contained in col1 returns true if the two collections have identical elements returns the union of the two collections returns the intersection of the two collections returns a collection which includes the object obj1 returns a collection which excludes the object obj1 returns a sub-collection where all elements satisfy the expression expr1 returns a collection where each element is the result of applying the expression expr1 to the corresponding element in col1 Boolean Boolean Integer or Real
col1->includes(obj1)
Boolean
col1->includes(col2)
Boolean
col1 = col2
Boolean
col1->union(col2)
Collection
col1->excluding(obj1) Collection
col1->select(expr1)
Collection
col1->collect(expr1)
Collection
bag1->asSequence()
Sequence
176
Type of first element in se- returns first element in sequence quence seq1 Type of last element in se- returns last element in sequence quence seq1 Type of element at position i1 returns i1'th element in sequenceseq1 Sequence returns sequence with object appended returns sequence with object prepended returns sequence as bag returns sequence as set
seq1->last
seq1->at(i1)
seq1->append(obj1)
seq1->prepend(obj1)
Sequence
seq1->asBag seq1->asSet
Bag Set
The previous constraint on the number of bookings is insufficient since a booking can be a booking of more than one candidate. We actually have to iterate over the bookings and some up the number of candidates and compare that to the maximum number of candidates. The resultant OCL constraint could be something like this:
177
context Presentation inv: maxCandidates >= self.bookings->iterate(b: Booking; result: Real = 0 | result + b.numCandidates)
in the above example the collect operator creates a new collection containing the selection (in our case we get a collection of the number of candidates enrolled in the various bookings) and then we apply the sum operator to that result collection and compare the result with the maximum number of candidates which can be accommodated in that presentation.
In OCL collections provide a corresponding reject method which is similar to the select service except that the matching selections are rejected from the result collection.
Assume you want to apply the constraint to presentations that all bookings must be bookings for at least one candidate but for no more than the maximum number of candidates for the presentation. This can be done in OCL via
which consists of the interface through which the services are requested, i.e. a specification of the structure of the service request messages, and the pre- and postconditions for each service specifying 1. 2. the conditions which must hold before the service is available to the client and the deliverables upon successful completion of the service.
Instances of any class which realizes this contract can be plugged in as service providers. The unit test for the service provider should typically test that if the preconditions as specified in the contract (i.e. on the interface) are satisfied the service is provided as per contract, i.e. that the all the deliverables are provided.
Note
The design-by-contract rules state that post-conditions may never be reduced and preconditions may never be increased during specialization. Since pre-conditions may indeed be reduced we cannot test that the service is refused if the preconditions of the contract (as specified on the interface) are not met -- after all service providers may provide the service more generously. However, if we specify pre-conditions on the individual classes which realize that contract, then the unit test on the class should test that the service is refused if the pre-conditions for that particular service provider are not met.
5. Exercises
1. Use the Object Constraint Language (OCL) to formalize the constraints for the e-commerce retailer you have been modeling.
180
1. Introduction
Good design makes systems more flexible and robust, reduces maintenance cost and increases life expectancy. Yet, generating a good design is a non-trivial task. This article looks at core attributes of good design and explains how URDAD provides a simple algorithmic design process which leads to a design satisfying many of the requirements of a good design.
1.2. Background
URDAD has grown out of Responsibility Driven Design (RDD) methodology pioneered by Rebecca Wirfs-Brock and Brian Wilkerson ( see [Wirfs-Brock-Wilkerson-1989], [Wirfs-Brock-Wilkerson-Wiener-1990] and [Wirfs-Brock-McKean-2002]). Like RDD, URDAD focuses during the early stages of the design on identifying and assigning responsibilities. Also, like RDD, URDAD puts a lot of emphasis on client-server contracts. However, unlike RDD, URDAD critically requires that responsibilities should be identified before one identifies the objects which will ultimately host the responsibilities. Furthermore, RDD does not provide a framework which generates the different layers of granularity naturally and cleanly. The ability to look at use case realization at different levels of granularity is a major benefit of URDAD. Finally, URDAD provides a step-for-step algorithm for designing a system across its levels of granularity. Other methods like the ICONIX process from Doug Rosenberg discussed in [Rosenberg-Scott-1999] provide a structured process for evolving the static model from the collaboration requirements, but are not really responsibility driven, nor do they project out clean layers of granularity.
should be used to improve performance and reduce resource demand, the choice of integration technologies and so on. Technologies change quite frequently and a change in implementation technology should not require a change in design. URDAD generates a design which is architecture and technology neutral. This approach is aligned with OMG's Model Driven Architecture (MDA) -- see [Frankel-2003]. MDA requires that the design phase yields a Platform Independent Model (PIM) which ensures that design survives technologies and architectures. MDA then maps the PIM onto the chosen architecture and technologies resulting in the Platform Specific Model (PSM). URDAD thus generates MDA's PIM. The PIM is then mapped onto the chosen architecture and technologies. This may be done manually or using MDA tools.
Note
To illustrate the benefit of being able to understand a system at different levels of granularity, let us have a look at a car. A non-technical person can learn to effectively drive a car. This is only possible because they do not have to understand the details of the lower level functioning of the car. A mechanic in the local service station will have to understand the car at a lower level of granularity, but does not need to understand the finer details of how the gearbox works. Again, it would be difficult (and expensive) to source a mechanic who would be able to understand the functioning of the car at all levels of granularity. Finally a gearbox specialist will understand the system at an even lower level of granularity, without having to understand the higher-level workflows. The various levels of granularity facilitate that different role players can all function effectively without anybody having to understand the entire system. Decoupling. Decoupling provides a high level of flexibility and improves maintainability. If one component uses another component we effectively have a client-server relationship. Generally clients would not want to lock into a particular service provider. Instead, the client defines the requirements in a contract (in business modeling this would be an SLA). The contract specifies the services which service providers need to provide (the interface), the pre- and postconditions for those services and the non-functional requirements. Simplicity. If everything else is equal, then the simpler solution is preferable. Complexity results in increased development costs, risk and maintenance costs. A design which is understandable and conceptually intuitive is preferable above one which is difficult to explain and nonintuitive. Architecture and technology neutral. The design should remain valuable over a long period. To this end the design should be able to survive technologies, changes in access mechanisms and architectural changes. This is usually achieved by following the guidelines of OMG's Model Driven Architecture, (MDA), which suggests that the core design should be technology and ar182
chitecture neutral and that this core design should then be mapped onto one's choice of technologies and architecture.
183
Decoupling via contracts at all levels of granularity. URDAD requires responsibility identification followed by responsibility allocation to core system components and core external service providers (actors). For each responsibility, irrespective of whether the responsibility is by an internal component or an actor, URDAD requires a contract. Contract are specified along the guidelines provided by Design by Contract.
In URDAD re-usability is viewed as a consequence of responsibility localization and contract (interface) based decoupling.
Figure 8.1, Use-Case/Responsibility Driven Design provides an overview of URDAD. The core steps of an iteration in URDAD are 1. Identify the core responsibilities which need to be addressed when realizing the use case. 184
2. 3. 4. 5. 6. 7.
Allocate each responsibility to either a component of the current context or an actor. Specify how these components and actors collaborate to realize the use case. Project out the context of the collaboration. This is that subset of the static model which at the current level of granularity is required to realize the use case. Specify for each responsibility the contract they have to realize in the context of the current use case. Specify the structure of exchanged value objects using class diagrams. Traverse to the next lower level of granularity by selecting one of the components from the previous iteration as the new context with the services at the previous level of granularity becoming the use cases of this new, lower level of granularity. Repeat the above steps for the use cases at the next lower level of granularity.
8.
Note
URDAD is a double-iterative process with 1. 2. use case iterations ensuring the system is designed iteratively, realizing use case after use case, and design iterations taking the design iteratively through lower and lower levels of granularity.
In the following sections these steps will be explained in detail, using the design of a simple mail client as an example.
Note
URDAD requires that the responsibilities should be identified before identifying system components. As a second step these responsibilities will be assigned to core system components, ensuring good responsibility localization across system components. Consider, as an example, a simple mail client. Assume we want to realize the send-new-mail use case. This use case will be realized through the collaboration of certain system components and potentially some actors. In Figure 8.2, Responsibility identification. we identify the responsibilities which need to be addressed when realizing the use case. They include the workflow control and user interfacing responsibilities for the current context (the mail client as a whole), and the functional responsibilities for the mail client including that of generating the e-mail, sending it and storing the sent mail.
Responsibilities like that of managing addresses or marshaling the message on to the SMTP protocol are not relevant at this highest level of granularity. The responsibility of selecting addresses for an e-mail will be addressed in the context of creating the mail object and that of marshaling the mail onto the SMTP protocol will be addressed in the context of sending the e-mail. Hence both these responsibilities are lower level responsibilities which will be addressed at a lower level of granularity.
Revisiting our mail client we could potentially assign the responsibilities as illustrated in Figure 8.3, Responsibility allocation..
Having 1. 2. identified the responsibilities which need to be addressed when realizing the use case, and assigned these responsibilities to core system components and external service providers (actors),
we now need to look at how these components and actors collaborate to realize the use case. Usually one first looks at a particular example (scenario) of realizing the use case. To this end one generally starts with a sequence diagram. Figure 8.4, A scenario of realizing a use case at a specific level of granularity. shows an example of such a sequence diagram.
Note that the only objects participating in the collaboration shown in the sequence diagram are those which address the core responsibilities as identified for this level of granularity. Once one is comfortable with a particular scenario (often a typical success scenario is chosen), one can look at the collaboration in general. This is commonly documented using a UML activity diagram. In Figure 8.5, The use case collaboration in general. we show an activity diagram documenting the general send new mail collaboration at the current level of granularity as fixed by the initial responsibility identification step.
187
Finally, to simplify the transition to the collaboration context, one can use a UML communication diagram. It highlights the required communication paths as well as the service request messages sent along these paths and may contain other information from the static model. URDAD refrains from adding further structural information at this stage. The communication diagram corresponding to the sequence diagram in Figure 8.4, A scenario of realizing a use case at a specific level of granularity. is shown in Figure 8.6, Communication diagram simplifying transition to collaboration context..
Note
Note that since URDAD only feeds message path information into communication diagram, the latter contains essentially the same information as the sequence diagram and may be auto-generated from the latter. This step may be (and often is) omitted.
The context of the collaboration is thus that subset of the static model which, at the current level of granularity, is required to realize the use case. The objects from that level of granularity are peers and hence the relationships between them will be associations (client-server) and not aggregation or composition relationships (otherwise the objects would not all be at the same level of granularity). However, some of these are components of the higher level context, filling in composition relationships between layers of granularity. Note that unlike many other design methodologies (see for example [Ben-Abdallah-et.al-2004]) which go from the use case model to the static model (often via an object dictionary), URDAD defines the dynamics realizing the use case first. Only then is the required static structure identified. URDAD thus generates minimal structural complexity, i.e. only those structural features which are actually required to realize the use case. Note also that the objects and classes generated are all at the same level of granularity. They are all either components of the use case context or actors. We have explicitly refrained from introducing any lower level classes at this stage. Instead URDAD provides a simple approach for going over to the next lower level of granularity.
Note
Tests should be written for contracts (interfaces), not for classes. Any service provider claiming to realize a specific contract should be tested against the test for that contract. URDAD requires that for each responsibility there should be a contract against which all service providers (components) which realize that responsibility should be tested. The contract may have functional aspects and non-functional aspects. The functional aspects are defined within the standard design-by-contract framework (see [Meyer-1991] and [Meyer-1992]) by an interface with pre- and post-conditions on the services and, if applicable, invariance constraints on the service provider itself. Contracts are developed from the perspective of the client. They thus resemble the signed contracts of Andreas Rausch (see [Rausch-2002]). The non-functional aspects may include features like scaleability, usability, reliability, security, and so on. These are typically specified in a quality requirements note.
189
2.6.1. Pre-Conditions
If any of the pre-conditions is not met, the service provider is entitled to refuse the service without breaking the contract. On the other hand, if all preconditions are met, the service provider is obliged to provide the service. Otherwise it is a breach of contract and hence a failure. For example, for the debit service of an account there may be the pre-condition that there must be sufficient funds in the account. If there are insufficient funds the account may refuse the service without breaking the contract. In software systems service providers use exceptions to notify clients that a requested service is refused due to a pre-condition violation.
2.6.2. Post-Conditions
The post-conditions are the deliverables of the service provider. These include the return value, but may also include service provider state information. For example, the post-condition of debiting an account may include the requirement that the transaction must have been entered into the account's transaction history.
Figure 8.8. Contracts are specified for each responsibility and hence for each service provider.
Figure 8.9, Class diagram for the e-mail value object. shows a simplified class diagram for the email value object exchanged between the MailEditor, MailClientController and MailSender.
191
Figure 8.10. Use case diagram for a component at the next lower level of granularity.
Of course the object may choose to realize the use case in a way which makes use of further actors. This should, however, be responsibility driven. We thus first identify the responsibilities at this new, lower level of granularity and before assigning them to components and/or actors of this lower level object as shown in figure Figure 8.11, Responsibility identification at next lower level of granularity..
Each responsibility is, once again, assigned to either a component of this lower level component (this is where the composition relationships are identified) or an actor. This is shown in Figure 8.12, Responsibility allocation at next lower level of granularity.
192
Note that we have a workflow controller at each level of granularity taking over the responsibility of managing the workflow for the use case at that level of granularity Similarly, if the user interfaces directly with the lower level object (as, for example, the MailEditor would), then there would also be the responsibility of interfacing with the user. URDAD is thus an iterative design process which projects out one level of granularity after another. Typically one will require between 2 and 4 levels of granularity depending on the complexity of the system.
193
2. Introduction
Design patterns were the first patterns which found widespread use in the software development field. Today it is virtually expected of any software developer to have at least a rudimentary background in design patterns. Design patterns are generic, re-usable design solutions. These simple design components can often
194
Design Patterns
simplify your design considerably, improve system functionality, and make systems more flexible and more maintainable.
Many of these design patterns are extremely simple and, in hind sight, you will often be tempted to thing of course. However, without having seen some of these simple and obvious solutions, you may have potentially ended up with a solution which is significantly more complex and less flexible.
3. Benefits of patterns
The use of patterns typically simplifies the solution to a problem, makes the resultant solution more flexible, and hence more maintenance friendly.
Having had exposure to a collection of generic patterns enables one to identify patterns in problems and come up with a solution more readily. The solution is often also more elegant and powerful. In hind-sight one often finds that the solution is so obvious. However, not having had exposure to patterns may result in many cases in a more complex and less generic solution. Once patterns have been used in a design, the design can be explained in a simpler and more compact way -- at least to people who have had exposure to patterns.
4. Discovering patterns
Patterns are not typically designed. In the context of a particular problem one comes up with a design solution. When working on another problem one may face some similar aspects and the correlation may lead to a similar design solution. Over time the generic core is identified. This core is usually a simple generic component of the specific solutions for the various problems and this can be regarded as a pattern.
5. Documenting Patterns
Over the years standards for documenting patterns have become more important. The classical design patterns book by the so-called gang-of-four already uses a documentation template for documenting patterns. Most of the pattern documentation templates are variations of this documentation template and we, too, shall follow this approach.
Name: Every patterns should have a name. The following criteria should typically be applied to naming a pattern
195
Design Patterns
The name should uniquely identify the pattern within your pattern repository. Standard names should be used when the pattern is documented in public pattern resources. The name should be descriptive. If the pattern is known under different names add a Also-Known-As sub-section.
Intent: The type of problem the pattern aims to solve. Solution: The design which solves the problem. For this one typically uses UML diagrams including: Sequence, activity and collaboration diagrams showing how objects which participate in a pattern collaborate to realize the solution. Class diagrams showing the static structure required by the pattern including attributes and services required from the objects participating in the pattern, message paths between objects including associations, aggregation and composition relationships, specialization relationships and interfaces and other dependencies.
Consequences: The consequences of using the patterns including the benefits provided by the pattern, the trade-offs made when using the pattern, and any issues introduced by using the pattern.
Example applications: Some example problems which have been solved by using the pattern. Implementation Guidelines: List any issues implementors should be aware of including Potential pitfalls. Special techniques for implementing elements of the pattern. Implementation issues (e.g. for different programming languages or different technologies).
Related Patterns: List any related patterns including Alternatives you should consider. The elements which differentiate this pattern from the alternatives. Any patterns often used in conjunction with this pattern.
196
Design Patterns
6. Pattern repositories
There are many design patterns repositories on the web. Two of the most widely used generic patterns repositories are http://hillside.net and the Portland pattern repository, http://c2.com/cgi/wiki .
Other pattern repositories which you may find useful include the Object-Oriented Pattern Digest at http://patternDigest.com as well as the pattern repository hosted tp://www.theserverside.com/patterns. by TheServerSide at ht-
Having identified a new pattern,you may want to submit the pattern to one or more of these repositories. Additionally you may want to consider hosting a design pattern repository within your own organization, collecting patterns particularly useful in your domain.
7.1. Intent
Typically there are two core intents when using the compsite pattern: 1. 2. To represent tree structures supporting recursive part-whole relationships. To facilitate services which are realized recursively through the structure.
7.2. Structure
Containers have many components, but is itself a component. Hence containers may may hold as components further containers. The structure is shown in Figure 9.2, Structure of the composite pattern. .
197
Design Patterns
The core objects of the composite pattern are thus the container, the root component and the leaf components. The responsibilities of these objects within the composite pattern are shown in the abstract collaboration depicted in Figure 9.3, Responsibilities of the components of the composite pattern. .
Typycally all components in the recursive structure provide at least one comnmon generic service which usually is realized polymorphically. The benefit of using the composite pattern lies thus not only in providing a recursive polymorphic structure, but also inpotentially providing services which are realized polymorphically across the recursive structure. We shall see examples of this in Section 7.3, Example applications.
Design Patterns
This structure is shown in Figure 9.4, A directory has files, but is itself a file. .
The design is shown in the UML diagram of Figure 9.5, The design of the Linux's virtual file system.
Note
The design makes use of the classical bridge pattern to introduce an abstraction layer which isolates file system users from the concrete realization of the file system.
Design Patterns
be viewed (and traded) as an asset and hence it is itself an asset. This very natural design for this is a direct application of the composite pattern (see Figure 9.6, A portfolio holds asset and can be itself viewed as an asset. ).
Figure 9.6. A portfolio holds asset and can be itself viewed as an asset.
Figure 9.7. Java's user interface libraries achieve resolution independence partially through the composite pattern.
200
Design Patterns
7.4. Consequences
Primitive and composite objects are interchangeable. Client applications may treat both, primitive and composite objects uniformly and often don't know or care whether they are working with a primitive or a complex object. You can support a wide range of custom made object, each with its own set of components. Services can be realized polymorphically across the recursive containment structure. The composite pattern can be realized for all 3 core OO relationships: Composition. In this case the components are fully owned by the container and may be accessed only through the container. In this case two containers cannot contain the same component in the sense of being the same object -- the same instance. They can at most contain each their own copy of a component. Composite patterns using a composition relationship between the container and its components are not used very often. Aggregation. This is the most common form of the composite pattern. Here the components are part of the state of the container. This implies that if a component's state changes the state of the container changes (e.g. if the state of an asset in the portfolio changes, for ex201
Design Patterns
ample, its value, then the state of the portfolio itself changes -- it too changes its value). Here multiple containers can contain the same component. Association. An association represents a client/server relationship. Thus, if a composite pattern uses an association relationship between the container and its components, then we have a potentially recursive client/server relationship. This structure provides facilities for adding responsibilities to a service on the fly. In that sense it would be similar to the decorator pattern except that lower level service providers are added to the other end of the structure -- the decorated component is the container itself, a whole range of extra deliverables to a service can be added at the same time, clients continue interfacing with the same object, i.e. the client reference along which the service requests are sent need not be modified to point to a decorator but continues to request the service from the original service provider.
In the case of an associative composite pattern the root component is usually an interface which is implemented by both, leaf components and containers.
Design Patterns
7.5.4.1. Valuable.java
package za.co.stc.finance; public interface Valuable { public double getValue(java.util.Date date); }
7.5.4.2. Asset.java
package za.co.stc.finance; public abstract class Asset implements Valuable { public Asset(String id) {this.id = id;} public String toString() {return id;} public String getId() {return id;} } private String id;
7.5.4.3. PurchasedAsset.java
package za.co.stc.finance; import java.util.*; public abstract class PurchasedAsset extends Asset { public PurchasedAsset(String id, double purchasePrice, Date purchaseDate) { super(id); this.purchasePrice = purchasePrice; this.purchaseDate = purchaseDate; } public double ageInYears(Date date) { double ageInMilliSecs = date.getTime() - purchaseDate.getTime(); return ageInMilliSecs / milliSecsPerYear; } public double getPurchasePrice() {return purchasePrice;} public Date getPurchaseDate() {return purchaseDate;} public String toString() { return super.toString() + " purchased on " + purchaseDate + " for R" + purchasePrice; 203
Design Patterns
} private static final double milliSecsPerYear = 1000.0 * 60 * 60 * 24 * 365.25; private double purchasePrice; private Date purchaseDate;
7.5.4.4. Vehicle.java
package za.co.stc.finance; import java.util.*; public class Vehicle extends PurchasedAsset { public Vehicle(String id, double purchasePrice, Date purchaseDate, double writeOffPeriodInYears) { super(id, purchasePrice, purchaseDate); writeOffPeriod = writeOffPeriodInYears; } public double getValue(Date date) { double age = ageInYears(date); return getPurchasePrice() * (1 - age / writeOffPeriod); } public String toString() { return " Vehicle " + super.toString() + " written off over " + writeOffPeriod + " years, " + " current value = R" + getValue(new Date()); } } private double writeOffPeriod;
7.5.4.5. Property.java
package za.co.stc.finance; public class Property extends PurchasedAsset { public Property(String id, double purchasePrice, java.util.Date purchaseDate) { super(id, purchasePrice, purchaseDate); } public double getValue(java.util.Date date) { return getPurchasePrice(); } public String toString() { return " Property " + super.toString(); }
204
Design Patterns
7.5.4.6. Portfolio.java
package za.co.stc.finance; import java.util.*; public class Portfolio extends Asset { public Portfolio(String id) {super(id);} public void add(Valuable asset) { assets.add(asset); } public double getValue(Date date) { double sum = 0; Iterator iter = assets.iterator(); while (iter.hasNext()) { Asset asset = (Asset)iter.next(); sum += asset.getValue(date); } return sum; } public String toString() { StringBuffer result = new StringBuffer(); result.append("Portfolio: " + super.toString()); result.append(", current value = " + getValue(new Date()) + eol); Iterator iter = assets.iterator(); while (iter.hasNext()) result.append(iter.next()).append(eol); return result.toString(); } private Collection assets = new LinkedList(); private final static String eol = System.getProperty("line.separator");
7.5.4.7. PortfolioTest.java
Now we can add assets to portfolios. Some of these may be portfolios themselves. The portfolios are recursively valuated down to leaf-asset level: package za.co.stc.finance; import java.util.*; public class PortfolioTest { public static void main(String[] args) { new PortfolioTest().run(); } public void run() { Portfolio p1 = new Portfolio("myStuff"); p1.add(new Property("myHouse", 180000, new GregorianCalendar(1999, 0, 20).getTime())); 205
Design Patterns
p1.add(new Vehicle("myCar", 350000, new GregorianCalendar(2000, 10, 22).getTime(), 5)); System.out.println("portfolio (p1) value = " + p1.getValue(new Date())); System.out.println(p1); try { Thread.currentThread().sleep(10000); } catch (InterruptedException e) {} System.out.println(p1); Portfolio p2 = new Portfolio("myOtherStuff"); p2.add(new Property("myBeachHouse", 120000, new GregorianCalendar(2002, 0, 20).getTime())); p2.add(new Vehicle("myBeachBuggy", 35000, new GregorianCalendar(2001, 10, 22).getTime(), 10)); p1.add(p2); } System.out.println("\n\n" + p1);
8.1. Intent
To add responsibilities or tasks to a service at object (instance) level without modifying the class which hosts the original service, i.e. different instances of the same class can thus realize a service in different ways. To be able to plug in these extra responsibilities on the fly (at run-time). To be able to remove extra responsibilities on the fly. To simplify the maintainance of services which may be provided with a wide range of add-ons. 206
Design Patterns
8.2. Structure
The decorator is a specialization of the decorated component facilitating substitutability. has the decorated component, i.e. the decorated component is contained facilitating run-time plug-ins.
Note
The is a (specialization) relationship is used solely for facilitating substitutability and not for either inheritance or to delegate the service request up the specialization hierarchy as is commonly done.
The abstract collaboration shown in Figure 9.9, The responsibilities of the role players of the decorator pattern shows the responsibilities of the role players of the decorator pattern.
Figure 9.9. The responsibilities of the role players of the decorator pattern
207
Design Patterns
The structure of the decorator pattern is very similar to that of the composite pattern except that the decorator has only one component it decorates and the decorator provides the same service as the component it decorates and in its implementation it 1. 2. Calls the corresponding service of the object it decorates using the aggregation relationship as service request path. After the decorated component has realized the service up to its level of responsibility the decorator adds further responsibilities.
Figure 9.10. Any Gui component can be decorated with a border or a scroll pane.
208
Design Patterns
Figure 9.11. The debit service of an account can be decorated by voyage miles, transaction fees and potentially further decorators.
Design Patterns
Figure 9.12. The various concrete input streams can be decorated with a combination of input stream decorators.
Once again, we can plug the decorators one into another. For example, we can attach a BufferedInputStream to a FileInputStream to provide buffering, then a DigestInputStream which accumulates the message digest (i.e. hashing function value) during reading and provides a mechanism for querying the message digest after the data has been read, and finally a ZipInputStream onto the BufferedInputStream which unzips the contents as it is read.
8.5. Consequences
Avoids complex specialization hierarchies. Using the decorator pattern avoids complex specialization hierarchies with a subclass for any particular combination of responsibilities. Better localization of responsibilities. Each decorator encapsulates a specific responsibility 210
Design Patterns
which can be added to different components. The responsibility is only defined at that particular place. For example, scrolling support is only defined within a single class in the Java GUI class libraries -- ScrollPane. Any object which requires scrolling (e.g. an editor pane, a regular or drop-down list box, or an entire panel) is simply decorated with a ScrollPane. Decorating at object-level. Individual instances of the same class can be decorated with different responsibilities. Adding/removing responsibilities dynamically. The decorator pattern enables you to add and remove responsibilities for a service on the fly.
Design Patterns
At times one has a compiled class library and one wants to add some polymorphic functionality to the classes without modifying the classes themselves. The reason for this may be that Source code is not available. The source code may not be available and hence one may not be able to modify the classes to add the desired functionality. Maintain ownership status of classes. At other times the source may be available but the team who is responsible for maintaining the source is unwilling to modify it and you do not want to maintain your own branch of the source. Protect the responsibility focus (cohesion level) of the classes. The classes may be used across the organization and one has not got the primary responsibility of the classes. The development team may be hesitant to add the functionality because they feel that functionality is only useful to a specific user group and they fear that their classes will bloat over time and loose their cohesion -- that they will acquire over time a wide range of responsibilities which are not aligned with the primary responsibility of the classes.
In such cases the Visitor pattern may be useful. It enables one to add polymorphic functionality to a class hierarchy without modifying or sub-classing the classes. This is quite an ambitious task and the visitor pattern provides a novel solution to this problem.
9.1. Intent
To add a polymorphic service to a class hierarchy without sub-classing the classes in the hierarchy and without modifying any of the classes in the class hierarchy.
9.2. Solution
The solution has 3 aspects: 1. 2. 3. The responsibility distribution across the elements of the visitor pattern. The static structure required by the visitor pattern. The dynamics (i.e. the algorithm) used by the visitor pattern.
Figure 9.13. Responsibility allocation across the members of the visitor pattern
212
Design Patterns
9.2.2. Structure
The structure of the visitor pattern is relatively straight forward. We have a class hierarchy which accepts visitors. Different specializations of a visitor add different polymorphic services to the class hierarchy. The structure of the visitor pattern is shown in Figure 9.14, Structure of the visitor pattern.
9.2.3. Dynamics
The dynamics of the visitor pattern may look a little convoluted at first: 1. 2. Clients request a service added to a class hierarchy via a visitor from an element added to that class hierarchy by asking the element to accept the vistor. The element then invites the visitor to visit it, providing the visitor with its address -- how else 213
Design Patterns
could the visitor come and visit? 3. 4. 5. The visitor then makes one or more call-backs to that element, requesting any information it may need from the element to realize its service. Upon completion of the service, the visitor returns control to the element which, in turn, returns control back to the client. At this stage the client may request the deliverables of the service request directly from the visitor.
Note
Alternatively the visitor may accumulate a result across multiple service requests and the result may be queried at the end.
Design Patterns
Figure 9.16. The structure used for a visitor adding a getTotalSalary() service to employees.
The TotalSalaryCalculator adds a polymorphic getTotalSalary() method to the class hierarchy which executes different algorithms for different types of employees. The dynamics of the pattern is illustrated in the sequence diagram shown in Figure 9.17, The dynamics of the TotalSalaryCalculator..
9.4. Consequences
215
Design Patterns
The Visitor pattern enables one to add polymorphic functionality to classes without modifying or sub-classing them. It can help preserve the focus of classes encapsulating functionality which is not part of the core responsibility within separate visitors. You can define as many visitors as you like, each only adding services within a narrow responsibility focus. In this way one ensures that the design elements maintain a high cohesion level. Although our Visitor example only operates within a class hierarchy, the Visitor pattern can also be used at add functionality to classes across separate class hierarchies. The visitor provides a mechanism to aggregate information across service requests. Adding new concrete elements results in a lot of maintenance across the entire Visitor hierarchy. You should only consider applying the visitor pattern to mature class hierarchies where modifications and additions are not expected. Visitors can only add functionality which uses the public interface of the elements. The temptation to sacrifice encapsulation may become overwhelming. The visitor pattern introduces cyclic dependencies which makes it difficult to maintain (see the acyclic visitor pattern). There is no clean way to add visitors which are meant to only visit a subset of the element hierarchy.
Design Patterns
} //--------------------------------------------------------------class Manager extends Employee { public Manager(String name, double salary, double carAllowance) { super(name, salary); this.carAllowance = carAllowance; } public double getCarAllowance() { return carAllowance; } public void accept(EmployeeVisitor visitor) { visitor.visit(this); } public String toString() { return super.toString() + " (" + carAllowance + ")"; } private double carAllowance;
return salary; } public void accept(EmployeeVisitor visitor) { visitor.visit(this); } public String toString() { return name + " : " + salary; } private String name; private double salary;
} //---------------------------------------------------------------class Developer extends Employee { public Developer(String name, double salary, double computerAllowance) { super(name, salary); this.computerAllowance = computerAllowance; } public double getComputerAllowance() { return computerAllowance; } public void accept(EmployeeVisitor visitor) { visitor.visit(this); } public String toString() { return super.toString() + " (" + computerAllowance + ")"; } private double computerAllowance;
217
Design Patterns
public void visit(Manager m); public void visit(Developer m); } //---------------------------------------------------------------class TotalSalaryCalculator implements EmployeeVisitor { public void visit(Employee employee) { totalSalary += employee.getSalary(); } public void visit(Manager manager) { totalSalary += manager.getSalary(); totalSalary += manager.getCarAllowance(); } public void visit(Developer developer) { totalSalary += developer.getSalary(); totalSalary += developer.getComputerAllowance(); } public double getTotalSalary() {return totalSalary;} private double totalSalary = 0; } //---------------------------------------------------------------public class VisitorTest { public void run() { Employee[] employees = new Employee[6]; employees[0] = new Employee("Peter", 100000); employees[1] = new Manager("Tandi", 100000, 32000); employees[2] = new Employee("Jannie", 100000); employees[3] = new Manager("Ahmed", 100000, 27000); employees[4] = new Developer("Li", 100000, 6000); employees[5] = new Employee("Jill", 100000); TotalSalaryCalculator totalSalaryCalculator = new TotalSalaryCalculator(); for (int i=0; i<employees.length; ++i) employees[i].accept(totalSalaryCalculator); }
Design Patterns
Exposed state pattern. While the visitor pattern enables you to add a polymorphic service without changing any of the classes in the class hierarchy, the exposed state pattern enables you to add state specific services to a context without changing the context itself. Acyclic visitor pattern. The acyclic visitor pattern addresses 3 of the core issues which may be raised against the classical visitor pattern: The visitor pattern is not maintenance friendly since all visitors must be modified every time a new class is added to the class hierarchy to which a polymorphic functionality is added. There are circular dependencies between the elements of the class hierarchy and the visitors. The consequence of this is that the visitor pattern has considerable compilation overheads, requiring that all classes are recompiled when any of the classes are modified. The classical visitor pattern does not support partial visitations, i.e. that a visitor adds a service to only part of the class hierarchy.
219
1. Aspect-Oriented Development
Aspect oriented development is being used more widely as the benefits of this paradigm become more appreciated.
1.2.2. Advice
An advice is a workflow step which is applied to an existing model. This could be the logic for the logging or authorization code.
1.2.4. Aspect
The combination of a point cut and an advice.
1.2.5. Weaving
Weaving is used to refer to the process of inserting the aspect logic into the core application logic.
stead it complements object oriented development by being able to effectively address cross-cutting concerns. The conceptual solution as well as the implementation realizing the use case (functional) requirements would typically be designed using object-oriented concepts. However, those non-functional requirements which are not addressed by architecture (infrastructure), could typically be addressed by designing aspects into the solution and weaving the resultant code into the object-oriented system.
Note
AspectJ and AspectWerkz are collaboraborating on a new common implementation for a Java-based AOP framework.
221
1.6.3. Clean responsibility distribution across architecture, functional design and aspects
The introduction of aspects complements architecture and object-oriented design by adressing the one aspect which is not well covered by the other two. The result is that Architecture. addresses the non-functional requirements which can be addressed through infrastructure, Functional (Object-Oriented) design. realizes the use case requirements, and Aspects. address the non-functional requirements which require logic.
222
1. Introduction
In this chapter we look at general software development methodologies including general best practices, ideas from the Rational Unified Process (RUP) and ideas from Extreme Programming.
223
4. Best Practices
A number of people have looked at a wide range of projects in order to try and identify those aspects of a development process which seem to differentiate the more successful projects from the less successful ones. The result of these studies is a collection of best practices. These best practices resemble general guidelines which should increase the success rate of your projects. They include 1. 2. 3. 4. 5. 6. Management of System Requirements. Iterative development. Visual modeling. Component-based architectures. A process for verifying software quality. A framework for change control for requirements and designs and implementations.
Furthermore, because an error at the requirements is much more expensive to fix than an implementation error it was found that more than 80% of the cost of errors were due to errors in the system requirements while the cost of implementation errors was found to be less than 1% (see Table 11.1, Source of errors in software systems and the cost incurred in order to correct these errors.). Things have perhaps improved a little bit but even recent studies suggest that more that around 50% of errors arise from the system requirements specification.
Table 11.1. Source of errors in software systems and the cost incurred in order to correct these errors.
Development Stage Requirements Analysis/Design Implementation Source of error 56% 27% 7% Effort (cost) to correct 82% 13% 1%
224
System requirements must be elicited, verified, organized and documented in a form which is accessible to the client, users of the system and other domain experts as well as to developers. These system requirements are really business requirements and should be treated as such. UML diagrams are very useful for documenting system requirements, especially the use-case, sequence and deployment diagrams. The process of eliciting, documenting and managing system requirements is so important that a separate course is offered focusing solely on these aspects of the software development process.
usually on how the element is used. In a complex system it is usually extremely difficult to understand the implications of a modification. A testing framework can facilitate automatic testing of all system elements and it helps to monitor any problems which are introduced by system modifications.
The amount of time spent on each of these work flows is typically different from phase to phase. During the inception phase a most of the time is spent on understanding the business and, to a lesser 226
extend on establishing the system requirements. During the elaboration phase a lot of time is still spent on the business model, but the main focus is on developing the requirements Specification and on Analysis and Design. The first prototypes are being developed during this stage and time is spent on testing (verifying) the system requirements. As we go through the phases we obtain a better understanding of both the business and the requirements and hence less time is spent on these work flows. During the construction phase the main focus is of course on implementation. The system requirements are refined further and the analysis and design is completed during this phase. A lot of time is spent on testing. Finally, during the transition phase the main focus is on deployment. The system requirements are refined further to thrash out any loose ends. The deployment typically requires some further implementation work and a lot of testing is done during this stage.
5.3.4. Implementation
The implementation workflow covers The lower-level design of the system. The actual construction of the system in terms of components, subsystems and classes. The development of low-level unit tests. 227
5.3.5. Testing
In addition to unit testing done for individual objects the testing workflow tests that the objects interact correctly, that the integration of higher level components and subsystems results in a stable system, that the requirements have been implemented correctly, and that any failures are fed beck to the development team and that the system is not deployed with any defects.
5.3.6. Deployment
The deployment workflow delivers the product to the end users. It includes the following activities: Producing external releases of the software. Packaging the software. Distributing the software. Installing the software. Providing training and assistance to users. Beta testing. Migration of existing software or data. initiating the process of formal acceptance.
After the inception phase the stakeholder should have reached agreement on project scope, cost estimates and schedule estimates. The project may be reconsidered or cancelled if consensus is not reached.
229
The requirements specification should be refined including the functional as well as the nonfunctional requirements and constraints. A description of the proposed system architecture. A prototype demonstrating the architecture. A revised risk list. A project plan showing the evaluation criteria for each iteration. The project plan should cover the construction plan in some detail and the credibility of the estimates should be demonstrated. A preliminary user manual helps keeping the focus on the user requirements.
230
5.8. Transition
During the transition phase the product is deployed on the client side and opened to the user community. Once the product is used problems feedback about problems or minor changes to the requirements Specification are the norm. The reasonable requests should be taken up and the requirements Specification and product should be revised to support these. Incomplete features should also be added and tested during this phase. During the transition phase the system is subjected to the following: The user testing phase is usually called beta testing. This may require some user training. The system is tested in its real environment and against user expectations. If some or all of the use cases were previously delivered by some legacy system (manual or computerized), the new system usually runs for some time in simulation mode next to the legacy system. Any difference in behavior and results should be understood. Users and maintainers and potentially marketing staff are trained to fulfill their roles in the context of the new system. The client should potentially achieve self-supportability. If applicable, the product is rolled out to the marketing, distribution and sales teams and maintenance teams should be trained.
231
A Vision Document discussing the key requirements and limitations of the proposed system. This document is expected to evolve only very slowly during the development cycle. Requirements Specification Documents which are largely developed during the elaboration phase but which are refined further during the construction phase where the requirements have to be known in all its gory details.
A Development Plan containing The plan for the outermost iterations. More detailed descriptions of the current iteration and the upcoming iteration.
An Evaluation Criteria Document containing The high-level requirements specifications. The acceptance criteria. The current technical objectives. Iteration goals.
A Release Description documenting the scope of the current release. A Deployment Document containing information useful for Transition (deployment). Training
232
Installation Sales
Status Assessment Documents containing the status of the project at the document date including A progress section specifying work which has been completed. Any issues regarding the current staffing situation Expenditures incurred thus far and expenditures which are expected to be incurred in the current and next iterations. A Results section specifying work which has been completed. The Critical Risks identified at this stage. Action items specifying what actions have to be taken to complete the next tasks or to correct certain problems encountered. Post mortems of problems encountered.
233
6.3.1. Communication
Constant communication with the client is facilitated in XP by requiring that the customer should always be on-site. Communication between developers is driven partially by introducing the concept of pair programming. The customer decides what will be built and in what order.
6.3.2. Simplicity
Constant refactoring of the design and code is introduced in XP to ensure that simplicity is continuously maximized. Furthermore, XP requires a minimal set of non-code artifacts (status reports, formal requirements specifications, grant charts, ).
6.3.3. Feedback
Feedback is achieved in XP through Releasing increments to the customer in very short intervals. Introducing unit tests for each code unit. Running acceptance tests for each release.
6.3.4. Courage
Courage is about
234
Being honest about what you can and cannot do. Doing the correct thing which you know works, even if it is not good for your popularity.
The initial exploration phase which leads into the first release is going to scope the project. This phase includes a feasibility study where one evaluates whether it is worth-while continuing with the project.
235
but each cycle covers only a the restricted scope of one or a few features and is completed in a few weeks (typical XP recommendation is a two-week cycle per iteration).
Stories should be written by the customer and the development team should be able to estimate how long it will take and what resources it will require to deliver a story.
In the context of XP this is acceptable because it is assumed from the outset that the requirements
6.7. XP Activities
Extreme programming followers see themselves as engaging nearly exclusively in the following activities Listening Designing Coding Testing
6.8.1. Planning
During the planning phase one determines the features of the next release from from a combination of prioritized stories and technical estimates.
237
XP identifies 3 critical steps to iteration planning: Customers present user stories and the development team tries to understand the story. Team brainstorms engineering tasks. Designers identify the tasks required to implement the story. If their are multiple design solutions, the simplest is chosen. The customer partakes in this process, ensuring that the story is understood correctly and that the user requirements are met. Programmers estimate the work and sign up. Programmers or pairs of programmers sign up to take primarily responsibility for stories and make estimates for the time required to complete the individual tasks. Note that developers select and estimate their own tasks. Consequently developers will feel more commitment to the work and to the schedule. XP recommends that an effort should be made to have programmers take responsibility for complete stories and that tasks within a story are not assigned to different programmers. If the story is large the principal holds in slightly modified form. A small team of programmers takes on the story and team members are, in the context of a particular iteration, not involved in any other stories. The reason behind this is that if developers are involved in multiple stories, then one developer could be working on one story, having it virtually complete bar the task(s) assigned to another developer who is involved virtually completing another story. The end result of this could be that one has a large number of virtually complete stories and nothing to show to the customer.
XP is of the view that formal requirements specifications are very expensive to obtain and that very often they do not communicate the requirements very well. Instead, XP claims that it is much more effective to discuss the requirements with the client verbally as the project continues.
siderations of distributed systems. When team members discover a design pattern themselves it should be inserted into a patterns repository maintained by the team and one should consider introducing now and then seminars or informal discussions on design patterns.
239
The younger college, on the other hand May be more up to date with the latest technology developments and latest academic trends. Is not predisposed by a long history of development and may come up with new, original ideas.
6.8.6. Testing
The first guideline recommended by XP is WRITE THE TEST FIRST. There are very many reasons why it is beneficial to write the test before writing the component you are testing: Test represents low-level, precise requirements Specification. If the developer has a complete test, he/she has complete requirements Specification. More focused development process. Having complete requirements Specification removes any ambiguities about what the developer should develop. The development process is thus a streamlined process guided by the testable requirements Specification. Test not biased by implementation. If the developer writes the test after the code has been developed, the test may be strongly biased by what has been developed. The developer will simply test what they have just implemented. This may not be the actual test required and the resulting component could pass the test but fail the customer requirements, Test less likely to be neglected. After the component has been completed developers may get the comfortable feeling of having virtually completed the task. The test is a minor final plutocratic overhead which may not get the attention which it should. Who should write the test? XP requires that the tests should be conceptually devised by the on-site customer. The developer then puts the tests into code, clarifying any uncertainties as he/she does 240
that. So, what should be tested? XP's guideline is simply: test everything that can break. There are some extremely simple things which really cannot break. Those do not require testing. Everything else does. What if there are so many scenarios that writing an exhaustive test would take forever? Typically this is an indication that the component which you are testing is too complex and that it should be broken up into simpler sub-components which require simpler tests. What should be done if a component fails in real life but passes its tests? Obviously the component breaks and the tests do not test everything that can break. Developers should update the test first, then the design and code.
6.8.9. Refactoring
Refactoring is about improving the design or the implementation of completed code without changing the behavior of the code. Often the resultant design and code is much more compact and much less complex than the original design and code. This makes it difficult to sell to project managers because time is invested without immediate payoff. Particularly if critical deadlines are looming, refactoring is not very popular. Still, even in the case where critical deadlines have to be met, refactoring can actually speed up the remaining development. It is virtually insane to refactor production code if there are no tests in place. In fact, if there are no tests in place, project managers may have to introduce the unpopular rule that nothing in production is modified until the tests have been written. One potential danger of refactoring is that as one digs further and further into the design and code, one fends more and more problems and modifies more and more, slowly digging ones own grave. 241
To avoid this one should always refactor a small step at a time, retesting after every design/code change.
The standards should cover the regular code as well as the tests.
6.8.12. Metaphor
XP suggests that it is beneficial if one can find a metaphor for a system. The metaphor represents a conceptual equivalent though not a literal equivalent.
Changing any one of these variables will result in a change in at least one of the others. You can lock one or two of these variables and still change the others, but locking three of the variables results in the fourth variable be fixed too. The relationship between the variables is, however, non-linear and at times not predictable. Doubling the cost (by, for example, hiring more people) does typically not half the development time and as you add more people the benefit curve will start #attening off.
tially they may not be productive and furthermore will require time resources from the existing staff to get familiarized with the project. Thus, adding more people to a project which is behind its deadline may shift the delivery date out even further. Paying for longer hours: This can be useful for solving the odd crisis, but generally the morale sinks and tired people are less productive and make more mistakes. Investing in more powerful software tools: The right tools can make a significant contribution to the project. However, they require training time and often the tools do not live up to their promises. Investing in more powerful hardware tools: If a project looses significant amounts of time due to the time required to recompile the increments or due to running testing frameworks it is most probably wise to spend some money on hardware. Furthermore, relatively modest amounts spend on faster workstations with more memory and bigger screens for these workstations can increase productivity significantly by increasing the enthusiasm of team members.
6.9.3. Quality
XP differentiates between external, perceived quality and internal quality.
At any stage one has thus a clear view of what has been developed,tested and accepted by the customer and the team is never in the process of doing long stretches of work without acceptance testing. The rate at which stories are being delivered and the proportion of acceptance tests passed give a clear indication of productivity and quality.
243
Some of the proponents of these light methodologies including Kent Beck Martin Fowler Alistair Cockburn Robert C. Martin Ron Jeffries
and 12 others met in February 2001 where they produced a document which they called the Agile Manifesto. It reads as follows: We have come to value Individuals and interactions over processes and tools. Working software over comprehensive documentation. Customer collaboration over contract negotiation. Responding to change over following a plan.
That is, while we value the items on the right, we value the items on the left more. We follow the following principles: Our highest priority is to satisfy the customer through early and continuous delivery of valuable software. Welcome changing requirements, even in late development. Agile processes harness change for the customer's competitive advantage. Deliver working software frequently, from a couple of weeks to a couple of months, with preference to the shorter timescale. Business people and developers work together daily throughout the project. Build projects around motivated individuals. Give them the environment and support they need, and trust them to get the job done. 244
The most efficient and effective method of conveying information to and within a development team is face-to-face conversation. Working software is the primary measure of success. Agile processes promote sustainable development. The sponsors, developers and users should be able to maintain a constant pace indefinitely. Continuous attention to technical excellence and good design enhances agility. Simplicity the art of maximizing the amount of work not done is essential. The best architectures, requirements and designs emerge from self-organizing teams. At regular intervals, the team reflects on how to become more effective, then tunes and adjusts its behaviour accordingly.
ization: Effective management of software development and maintenance processes. Software processes are generally adhered to due to the processes being usable and tailored for the companies requirements. The benefts of the process are effectively and accurately communicated to existing staff and new employees which tend to adhere to them naturally because they understand the benefts of following the prescribed process. Clear Role defnitions where the roles in the project context as well as in the wider organizational context are accurately defined. Accurate, objective quality monitoring of both the software product as well as the process which produced the software. Ability to provide realistic schedules and budgets largely based on historical performance. Ability to effectively evolve processes through the introduction of pilot projects which are subjected to productivity and quality evaluations as well as a solid cost-beneft analysis.
An organization would work itself sequentially through these levels. Skipping of levels is counter productive because each level provides the foundation for the next level.
246
i.e. to the heroic achievements of certain individuals and CMM claims that these successes cannot be repeated unless the same competent individuals are assigned to future software projects. Level 1 capability is thus attributed to individuals and not to the organization. Problems typically experienced by level 1 organizations include Schedules and budgets are regularly overrun. Development dynamics deteriorates into crisis management where the dynamics carries the development team from one crisis to the nest. During these criseses the process is being abandoned resulting in the production of poor quality designs and code.
Planning and managing new projects is based on experience with similar projects resulting in realistic schedule and cost estimates. Integrity control is applied to software requirements and the work products developed to satisfy them. Installation of basic software management controls including the ability to track schedules, costs and functionalities.
i.e. throughout the development process the schedule and cost estimates are baselined the estimates are updated with the latest information and communicated to the customer. Introduction and enforcement of software project standards.
The result is that the planning and tracking of software projects is stable and that early success can be repeated without relying on the heroic effort of certain individuals. Note that for level 2 organizations the processes may differ across projects and that there need not be any linking between the policies guiding different projects.
At the defined level the organization standardizes its software development processes. CMM characterizes a level-3 compliant organization by The standard process for developing and maintaining software across the organization is documented including software engineering processes and management processes
and these processes are integrated into a coherent whole. This enables management to obtain objective status information across all projects. A group, the software engineering process group, takes ownership of the organization's process activities. An organization-wide training program ensures that all role players are aware of their roles and are able to fulfll their duties. For each project the organization's standard process is tailored to fulfll the specifc project requirements. The resultant tailored process is called the defined software process. The defined software process includes readiness criteria, process input defnitions, standards and procedures for performing the work, verifcation mechanisms, outputs and completion criteria.
Software processes are instrumented with well-defined and consistent measurement processes for productivity and quality. Management continuously measures productivity and quality across all defined software projects and maintains an organization-wide software process database for this information.
248
Projects obtain control of their processes by narrowing the variation in process performance. This enables management to distinguish between standard process variations (random noise) and systematic problems which should be addressed. The risks involved moving up the learning curve of a new application domain are known and carefully managed.
As the maturity increases the organization is expected to experience A decrease in difference between targets and actual achievements. A decrease in the variability of the actual results around targets. A general increase in productivity and quality.
The expected tendencies are shown in Figure 11.2, Process capability and performance predictions taken from The capability Maturity Model for Software published by Paulk, Curtis, Chrissis and Weber..
Figure 11.2. Process capability and performance predictions taken from The
249
capability Maturity Model for Software published by Paulk, Curtis, Chrissis and Weber.
Figure 11.3. Key process areas for the different CMM levels.
250
Software Project Planning which aims to establish reasonable plans for the software engineering and the managing of the software project. Software Project Tracking and Oversight is about making projects monitorable in order that management can take effective action when the software project's performance deviates signifcantly from the plans. Software Subcontract Management aims to establish a process to evaluate, select and manage subcontractors effectively. Software Quality Assurance aims to provide management with appropriate visibility into the software products being developed and process used to develop them. Software Confguration Management focuses on establishing and maintaining all products of the software project throughout the project's life cycle.
251
Organization Process Focus establish the organizational responsibility for software process activities enabling the organization to improve its overall software process capability. Organization Process Defnition includes Developing and maintaining software process assets that improve process performance across projects. These software process assets should provide a basis for obtaining meaningful information for quantitative process management. The software process assets provide a stable foundation that can be institutionalized via training and common information and guideline repositories.
Training Programs are introduced to develop the skills and knowledge of individuals so that they can perform their roles effectively and efficiently. Integrated Software Management is applied on a per-project basis. It aims to integrate the software engineering and management aspects into a coherent, defined software process that is tailored from the organization's standard software process. The tailoring is based on the business environment and the technical needs
of the project. Software Product Engineering describes the technical activities of the software project like Requirements analysis, specifcation and management. Architectural design process. System design. Implementation. Testing.
It aims to establish an effective, well-defined engineering process which is applied consistently to integrate all software engineering activities to produce correct and consistent software products effectively and efficiently. Intergroup Coordination aims to establish an infrastructure enabling different software engineering groups to interact and collaborate effectively. Peer Reviews aims to decrease the defect level of software early and efficiently. In addition the understanding of individual products of the software process is distributed. Typical methods used include inspections and structured walkthroughs.
The key process areas of level 5 address issues which help the organization to establish the infrastructure to continually improve the software process. They include: Defect Prevention aims to Identify the causes of defects before they occur and prevent the defects from occurring. Initiate a process of introducing changes to the defined software process.
Technology Change Management focuses on performing innovation and introducing innovations efficiently in order to remain competitive in a changing environment. It is responsible for Identifying benefcial new technologies including tools, methods and processes. Transfer benefcial managers in a structured, well managed way into the organization.
Process Change Management is responsible for continually improving the software processes used in the organization in order to improve software quality and increase productivity.
Use cost models such as COCOMO and Price-S. Perform systematic risk management and continuously maintain a top-10 risk list. Use the Project Evaluation and Review technique (PERT). Employ chief architects and chief engineers.
253
Bibliography
[Alexander-Ishikawa-Silverstein-Jacobson-1977b] Christopher Alexander, Sara Ishikawa, Murray Silverstein, and Max Jacobson. A Pattern Language. Oxford University Press. 1977. [Alexander-1979] Christopher Alexander. The Timeless Way of Building. Oxford University Press. 1979. [Anderson-2003] Kenneth M. Anderson. Object Design: Roles, Responsibilities and Collaborations. Addison-Wesley/Pearsons Education. 2003. [Ashmore-Henson-Chancellor-Nelson-2004] Perryn Ashmore, Joel Henson, Jeff Chancellor, and Mark Nelson. Is you enterprise architecture all it can be?. Business Process Trends. June 2004. [Bass-Clements-Kazman-2003] Len Bass, Paul Clements, and Rick Kazman. Software Architecture in Practice. second edition. Addison Wesley. 2003. [Beane-Giddings-Silverman-1984] J. Beane, N. Giddings, and J. Silverman. Quantifying Software Designs. Proceedings of the Seventh International Conference on Software Engineering. 314-322. March 1984. [Beck-Cleal-1999] Kent Beck and Dave Cleal. Optional Scope Contracts. 1999. [Beck-Fowler-2000] Kent Beck and Martin Fowler. Extreme Programming Explained. Addison Wesley. 0201710919. 2000. [Ben-Abdallah-et.al-2004] H. Ben-Abdallah, N. Bouassida, F. Gargouri, and A. Ben-Hamadou. A UML Based Framework Design Method. Journal of Object Technology. 3. 8. 2004. [Booch-1994] Grady Booch. Object-Oriented Analysis and Design with Applications. Benjamin Cummings. 1994. [Booch-Rumbaugh-Jacobson-1999] Grady Booch, Jim Rumbaugh, and Ivar Jacobson. The Unified Modeling Language Reference Guide. Addison-Wesley. 1999. [Brickley-Smith-Zimmermann-2001] James Brickley, Clifford W. Smith, and Jerold Zimmermann. Managerial Economics and Organizational Architecture . McGraw-Hill. 2001. [Buschmann-Meunier-Rohnert-Sommerlad-Stal-1996] Frank Buschmann, Regine Meunier, Hans Rohnert, Peter Sommerlad, and Michael Stal. Pattern-Oriented Software Architecture. A system of patterns. John Wiley & Sons. 1996. [Cantor-1998] Murray R. Cantor. Object-Oriented Software Management. Wiley. 1998. [Carlson-2001] D. Carlson. Modeling XML Applications with UML. Addison-Wesley. 2001. [Clements-Kazman-Klein-2002] Paul Clements, Rick Katzman, and Mark Klein. Evaluating Software Architectures. Methods and case studies. Addison-Wesley. 2002. [Coad-Yourdon-1991a] P. Coad and E. Yourdon. Object Oriented Analysis. Yourdon. 1991. [Coad-Yourdon-1991b] P. Coad and E. Yourdon. Object Oriented Design. Yourdon. 1991. [Cockburn-2001] Alister Cockburn. Writing Effective Use Cases. Addison-Wesley. 2001. [Coleman-Arnold-Bodoff-1994] D. Coleman, P. Arnold, S. Bodoff, C. Dollin, H. Gilchrist, F. Hayes, and P. Jeremes. Object-Oriented Development. The Fusion Method. rentice-Hall. 1994. [Duell-1997] Object Magazine. Michael Duell. Non-software examples of software design patterns . 54. July 1997.
254
Bibliography
[Eriksson-Penker-2000] Hans-Erik Eriksson and Magnus Penker. Business Modeling with UML. Business Patterns at Work. Wiley. 2000. [Ethiraj-Levinthal-2004] Sendil K. Ethiraj and Daniel Levinthal. Modularity and innovation in complex systems. Management Science. 159-173. 50. 2004. [Fowler-2000] Martin Fowler. UML Distilled. second. Addison-Wesley. 2000. [Frankel-2003] David S. Frankel. Model Driven Architecture: Applying MDA to enterprise computing. John Wiley & Sons. 2003. [Galbraith-Downy-Kates-2001] Jay Galbraith, Diane Downy, and Amy Kates. Designing Dynamic Organizations: A Hands-On Guide for Leaders at All Levels . American Management Association. November 2001. [Gamma-Helm-Johnson-Vlissides-1995] Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides. Design Patterns. Addison-Wesley. 1995. [Harel-1988] CACM. 31. 5. May 1998. D. Harel. On Visual Formalism . 26-49. [Jacobson-Christerson-Johnson-Overgaard-1992] Ivar Jacobson, M. Christerson, P. Johnson, and G. Overgaard. Object-Oriented Software Engineering. Addison-Wesley. 1992. [Jacobson-Booch-Rumbaugh-1999] Ivar Jacobson, Grady Booch, and Jim Rumbaugh. The Unified Software Development Process. Addison Wesley. 1999. [Jeffries-Anderson-Hendrickson-2000] Ron Jeffries, Ann Anderson, and Chat Hendrickson. Extreme Programming Installed. Addison-Wesley. 0201710919. 2000. [Jacobson-Ericsson-Jacobson-1995] Ivar Jacobson, Maria Ericsson, and Agnetta Jacobson. The Object Advantage. Business Process reengineering with Object Technology. Addison-Wesley Longman. 1995. [Kao-ReferenceArchitectures] James Kao. Reference Architectures. A foundation for robust J2EE systems. The Middleware Company. [Katzman-1994] Rick Katzman. Toward Deriving Software Architectures from Quality Attributes. 1994. [Krasner-Pope-1988] Journal of Object-Oriented Programming. 1. 3. Glenn E. Krasner and Stephen T. Pope. A cookbook for using the model-view-controller user interface paradigm in Smalltalk-80 . 26-49. [King-1995] W.R. King. Creating a strategic capabilities architectures. Information Systems Management. 67-69. 12. 1. 1995. [Kruchten-2000] Philip Kruchten. The Rational Unified Process. An Introduction. second. Addison Wesley. 2000. [Leavitt-2004] Harold J. Leavitt. Why Hierarchies Are Here to Stay and How to Manage Them More Effectively. Harvard Business School Press. November 2004. [Leffingwell-Widrig-2000] Dean Leffingwell and Don Widrig. Managing Software Requirements. Addison-Wesley. 2000. [Marshall-2000] Chris Marshall. Enterprise Modeling with UML. Designing successful software through business analysis. [Meyer-1991] Bertrand Meyer. Design by Contract. Prentice Hall. 1991. [Meyer-1992] Computer (IEEE). 25. 10. October 1992. Bertrand Meyer. Applying Design by Contract . 40-51. [Mindful-Business-And-Leadership] Mindful Business & Leadership. Governing Ideas of Any Or255
Bibliography
ganization or Individual. [Moncrieff-Smallwood-1997] James Moncrieff and Janet Smallwood. Ideas for the New Millenium. FT mastering. Pearson Proffesional. 1997. [Nadler-Gerstein-Shaw-1992] David A. Nadler, Marc C. Gerstein, and Robert B. Shaw. Organizational Architecture: Designs for Changing Organizations . Jossey-Bass. May 1992. [Nickols-1997] Fred Nickols. Measurement-Based Analysis. Hooking what you do to the bottom line. The Distance Consulting Company. 1997. [OMG-1995] The Object Management Group. BOMSIG White Paper. OMG. 1995. [Pande-Neumann-Cavanaugh-2000] P.S. Pande, R.P. Neumann, and R.R. Cavanaugh. The Six Sigma Way. How GE, Motorola, and other top companies are honing their performance. McGraw-Hill. 2000. [Ponnambalam-1997] K. Ponnambalam. Characterization and Selection of Good Object-Oriented Design. OOPSLA. 1997. [Rausch-2002] Andreas Rausch. Design by Contract + ComponentWare = Design by Signed Contract. Journal of Object Technology. 1. 3. 2002. [Rosenberg-Scott-1999] Doug Rosenberg and Kendall Scott. Use Case Driven Object Modeling with UML: A Practical Approach. Addison-Wesley Professional. 1999. [Rosenberg-Scott-2000] Doug Rosenberg and Kendall Scott. Driving design with use cases. Software Development. 2000. [Rumbaugh-Blaha-Premerlani-1991] Jim Rumbaugh, M. Blaha, W. Premerlani, F. Eddy, and F. Lorenzen. Object-Oriented Modeling and Design. Prentice-Hall. 1991. [Schonberger-1982] Richard J. Schonberger. Japanese Manufacturing Techniques. Nine hidden lessons in simplicity. Free Press. 1982. [Shaw-Garlan-1996] Mary Shaw and David Garlan. Software Architecture. Perspectives on an emerging discipline. Prentice Hall. 1996. [Unhelkar-2003] Bhuvan Unhelkar. Process Quality Assurance for UML-Based Projects. AddisonWesley. 2003. [Wirfs-Brock-McKean-2002] Rebecca Wirfs-Brock and Alan McKean. Object Design: Roles, Responsibilities and Collaborations. Addison Wesley Professional. 2002. [Wirfs-Brock-Wilkerson-1989] Rebecca Wirfs-Brock and Brian Wilkerson. Object-Oriented Design: A Responsibility-Driven Approach. OOPSLA '89 Proceedings. 71-75. October 1-6, 1989. [Wirfs-Brock-Wilkerson-Wiener-1990] Rebecca Wirfs-Brock, Brian Wilkerson, and Lauren Wiener. Designing Object-Oriented Software. Prentice Hall. 1990.
256