Low-level Design and Implementation Lecture 8 1 2 Outline Low-level design Implementation issues UML Interaction diagrams B. Bühnová, FI MU, PB007 2 Low-level Design Lecture 8/Part 1 3B. Bühnová, FI MU, PB007 Low-level design Purpose:  Include all code-level details into the model  Decide how exactly the system shall be implemented  Typically an implicit part of implementation  Techniques  Design patterns  SOLID principles  Guidelines for dependable/testable/.. programming Chapter 7 Design and implementation 4 Design patterns  A design pattern is a way of reusing abstract knowledge about a problem and its solution in object-oriented world.  Pattern descriptions make use of object-oriented characteristics such as inheritance, polymorphism and interface realization.  A pattern is a description of the problem and the essence of its solution.  Not a concrete design but a template for a design solution that can be instantiated in different ways.  It should be sufficiently abstract to be reusable in different settings. 5Chapter 7 Design and implementation The “Gang of Four” design patterns  Introduced in a book by GoF in 1995  Collection of 23 classic software design patterns divided into three groups:  Creational  Structural  Behavioral  Observer pattern  Behavioral pattern  Separates the display of object state from the object itself when multiple displays of state are needed. 6Chapter 7 Design and implementation A UML model of the Observer pattern 7Chapter 7 Design and implementation Design problems  Be aware that any design problem you are facing may have an associated pattern that can be applied.  Tell several objects that the state of some other object has changed (Observer pattern).  Tidy up the interfaces to a number of related objects that have often been developed incrementally (Façade pattern).  Allow classes with incompatible interfaces to work together by wrapping a new interface around that of an already existing class (Adapter pattern).  Reduce the cost of creating and manipulating a large number of similar objects (Flyweight pattern).  Restrict object creation for a class to only one instance (Singleton pattern). 8Chapter 7 Design and implementation SOLID principles  The “first five principles” identified by Robert C. Martin in the early 2000s that stand for five basic principles of object-oriented programming and design.  Single responsibility  Open/closed  Liskov substitution  Interface segregation  Dependency inversion B. Bühnová, FI MU, PB007 9 Single responsibilityprinciple  The principle states that every class should have a single responsibility, and that responsibility should be entirely encapsulated by the class.  A responsibility can be understood as a reason to change, so a class or module should have one, and only one, reason to change.  As an example, consider a module that compiles and prints a report. Such a module can be changed for two reasons – because the content or the format changes.  If there is a change to the report compilation process, there is greater danger that the printing code breaks. B. Bühnová, FI MU, PB007 10 Open/closed principle  The principle states that software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.  Use inheritance and interfaces to avoid code changes when extending system functionality. B. Bühnová, FI MU, PB007 11 Component Specialization1 Specialization2 Interface Implementation1 Implementation2 Liskov substitution principle  The principle states that, in a computer program, if S is a subtype of T, then objects of type T may be replaced with objects of type S without altering any of the desirable properties of that program (correctness, task performed, etc.). B. Bühnová, FI MU, PB007 12 Rectangle Square width and height can be changed independently width and height must not be changed independently T S Interface segregation principle  The principle states that no client should be forced to depend on methods it does not use.  ISP splits large interfaces into smaller and more specific “role” interfaces so that clients will only have to know about the methods that are of interest to them.  ISP is intended to keep a system decoupled and thus easier to refactor, change, and redeploy. B. Bühnová, FI MU, PB007 13 iATM iWithdraw iChangePIN iCheckBalance Dependency inversion principle  The principle refers to a specific form of decoupling where conventional dependency relationships established from high-level modules to low-level modules are inverted. The principle states:  A. High-level modules should not depend on low-level modules. Both should depend on abstractions.  B. Abstractions should not depend upon details. Details should depend upon abstractions. B. Bühnová, FI MU, PB007 14 iSwitchableSwitch LightSwitch Light Clean code by Robert C. Martin  A handbook of agile software craftsmanship  Guidelines for:  Meaningful names  Functions  Comments  Formatting  Objects and data structures  Error handling  Concurrency  … and others  Smells and heuristics B. Bühnová, FI MU, PB007 15 Design for non-functional qualities  Design patterns and programming principles help us to implement specific functionality while maintaining high code quality  Respect of design patterns and principles improves system maintainability  What if also other non-functional qualities are of high importance?  Are there any “patterns” for dependability, performance, testability, etc.? 16Chapter 7 Design and implementation Programming guidelines for Dependability 1. Limit the visibility of informationin a program 2. Checkall inputs for validity 3. Providea handler for all exceptions 4. Minimizethe use of error-proneconstructs 5. Providerestart capabilities 6. Checkarray bounds 7. Include timeouts when calling external components 8. Name all constantsthat representreal-world values 17Chapter 13 Dependability Engineering Limit the visibility of information in a program  Program components should only be allowed access to data that they need for their implementation.  This means that accidental corruption of parts of the program state by these components is impossible.  You can control visibility by making data representation private and only allowing access to the data through predefined operations such as get() and set(). Chapter 13 Dependability Engineering 18 Check all inputs for validity  Range checks  Check that the input falls within a known range.  Size checks  Check that the input does not exceed some maximum size e.g. 40 characters for a name.  Representation checks  Check that the input does not include characters that should not be part of its representation e.g. names do not include numerals.  Reasonableness checks  Use information about the input to check if it is reasonable rather than an extreme value. Chapter 13 Dependability Engineering 19 Provide a handler for all exceptions  A program exception is an error or unexpected event.  Exception handling constructs allow for such events to be handled without the need for continual status checking to detect exceptions. 20Chapter 13 Dependability Engineering Exception handling  Exception handling is a mechanism that implements some level of fault tolerance.  Exception handling strategies delegate responsibility to:  Caller. Signal to a calling component that an exception has occurred and provide information about the type of exception.  Callee. Carry out some alternative processing to the processing where the exception occurred. This is only possible where the exception handler has enough information to recover from the problem that has arisen.  Controller. Pass control to a run-time support system to handle the exception. Chapter 13 Dependability Engineering 21 Minimize the use of error-prone constructs  Program faults are usually a consequence of human error because programmers lose track of the relationships between the different parts of the system  This is made worse by error-prone constructs in that they are inherently complex or do not check for mistakes.  Unconditional branch (goto) statements  Pointers  When referring to the wrong memory areas can corrupt data.  Dynamic memory allocation  Run-time allocation can cause memory overflow. Chapter 13 Dependability Engineering 22 Error-prone constructs  Parallelism  Can result in unforeseen interaction between processes.  Recursion  Errors in recursion can cause memory overflow.  Aliasing  Using more than 1 name to refer to the same state variable.  Floating-point numbers  Inherently imprecise, leading to invalid comparisons.  Interrupts  Interrupts can cause a critical operation to be terminated. 23Chapter 13 Dependability Engineering Provide restart capabilities  For systems that involve long transactions or user interactions, you should always provide a restart capability that allows the system to restart after failure without users having to redo everything that they have done.  Restart depends on the type of system  Keep copies of forms so that users don’t have to fill them in again if there is a problem  Save state periodically and restart from the saved state Chapter 13 Dependability Engineering 24 Check array bounds  In some programming languages, such as C, it is possible to address a memory location outside of the range allowed for in an array declaration.  This leads to the well-known ‘bounded buffer’ vulnerability where attackers write executable code into memory by deliberately writing beyond the top element in an array.  If your language does not include bound checking, you should therefore always check that an array access is within the bounds of the array. Chapter 13 Dependability Engineering 25 Include timeouts when calling external components  In a distributed system, failure of a remote computer can be ‘silent’ so that programs expecting a service from that computer may never receive that service or any indication that there has been a failure.  To avoid this, you should always include timeouts on all calls to external components.  After a defined time period has elapsed without a response, your system should then assume failure and take whatever actions are required to recover from this. Chapter 13 Dependability Engineering 26 Name all constants that represent real-world values  Always give constants that reflect real-world values (such as tax rates) names rather than using their numeric values and always refer to them by name  You are less likely to make mistakes and type the wrong value when you are using a name rather than a value.  This means that when these ‘constants’ change (for sure, they are not really constant), then you only have to make the change in one place in your program. Chapter 13 Dependability Engineering 27 Programming guidelines for Performance  Reduce the resources required for processing an event stream.  Increase computational efficiency.  Reduce computational overhead.  Reduce the number of events processed.  Manage event rate.  Control frequency of sampling.  Control the use of resources.  Bound execution times.  Bound queue sizes. 28 © Software Architecture in Practice by L. Bass, P. Clements and R. Kazman Programming guidelines for Testability  Record/playback. The information crossing an interface during normal operation can be saved and accessed.  Separate interface from implementation. This allows substitution of implementations for testing purposes.  Specialize access routes/interfaces. Having specialized testing interfaces allows the capturing or specification of variable values for a component through a test harness, independently from its normal execution.  Built-in monitors. The component can maintain state, performance load, capacity, security, or other information accessible through an interface.  29 © Software Architecture in Practice by L. Bass, P. Clements and R. Kazman Implementation Issues Lecture 8/Part 2 30Chapter 7 Design and implementation Implementation issues  Some implementation issues that are often not covered in programming texts:  Reuse Most modern software is constructedby reusing existing components or systems. When you are developing software, you should make as much use as possible of existing code.  Configuration management During the development process, you have to keep track of the many different versions of each software component in a configuration management system.  Host-target development Production software does not usually execute on the same computer as the software development environment. Rather, you develop it on one computer (the host system) and execute it on a separate computer (the target system). 31Chapter 7 Design and implementation Reuse  From the 1960s to the 1990s, most new software was developed from scratch, by writing all code in a highlevel programming language.  The only significant reuse or software was the reuse of functions and objects in programming language libraries.  Costs and schedule pressure mean that this approach became increasingly unviable, especially for commercial and Internet-based systems.  An approach to development based around the reuse of existing software emerged and is now generally used for business and scientific software. 32Chapter 7 Design and implementation Reuse levels  The object level  At this level, you directly reuse objects from a library rather than writing the code yourself.  The component level  Components are collections of objects and object classes that you reuse in application systems.  The system level  At this level, you reuse entire application systems.  The abstraction level  At this level, you don’t reuse software directly but use knowledge of successful abstractions in the design of your software. 33Chapter 7 Design and implementation Reuse costs  The costs of the time spent in looking for software to reuse and assessing whether it meets your needs.  Where applicable, the costs of buying the reusable software. For large off-the-shelf systems, these costs can be very high.  The costs of adapting and configuring the reusable software components or systems to reflect the requirements of the system that you are developing.  The costs of integrating reusable software elements with each other (if you are using software from different sources) and with the new code that you developed. 34Chapter 7 Design and implementation Configuration management  Configuration management is the name given to the general process of managing a changing software system.  The aim of configuration management is to support the system integration process so that all developers can access the project code and documents in a controlled way, find out what changes have been made, and compile and link components to create a system. 35Chapter 7 Design and implementation Configuration management activities  Version management, where support is provided to keep track of the different versions of software components. Version management systems include facilities to coordinate development by several programmers.  System integration, where support is provided to help developers define what versions of components are used to create each version of a system. This description is then used to build a system automatically by compiling and linking the required components.  Problem tracking, where support is provided to allow users to report bugs and other problems, and to allow all developers to see who is working on these problems and when they are fixed. 36Chapter 7 Design and implementation Host-target development  Most software is developed on one computer (the host), but runs on a separate machine (the target).  More generally, we can talk about a development platform and an execution platform.  A platform is more than just hardware.  It includes the installed operating system plus other supporting software such as a database management system or, for development platforms, an interactive development environment.  Development platform usually has different installed software than execution platform; these platforms may have different architectures. 37Chapter 7 Design and implementation Key points  When developing software, you should always consider the possibility of reusing existing software, either as components, services or complete systems.  Configuration management is the process of managing changes to an evolving software system. It is essential when a team of people are cooperating to develop software.  Most software development is host-target development. You use a development environment on a host machine to develop the software, which is transferred to a target machine for execution. 38Chapter 7 Design and implementation © Clear View Training 2010 v2.6 39 Lecture 5/Part 3 Interaction Diagrams © Clear View Training 2010 v2.6 40 Interaction diagrams  Sequence diagrams  Emphasize time-ordered sequence of message sends  Show interactions arranged in a time sequence  Are the richest and most expressive interaction diagram  Do not show object relationships explicitly - these can be inferred from message sends  Communication diagrams  Emphasize the structural relationships between objects  Use communication diagrams to make object relationships explicit  Timing diagrams  Emphasize the real-time aspects of an interaction  Interaction overview diagrams  Show how complex behavior is realized by a set of simpler interactions (discussed earlier together with Activity diagrams) © Clear View Training 2010 v2.6 41 Sequence diagram syntax  Interactions are captured via lifelines (participants in the interaction) and messages (communications between lifelines)  Activations indicate when a lifeline has focus of control - they are often omitted from sequence diagrams :Registrar :RegistrationManager uml:Course addCourse("UML" ) «create» notes can form a "script" describing the flow lifeline sd AddCourse objectcreation message synchronous message objectis created at this point message return activation The Registrar selects "add course". The system creates the new Course. © Clear View Training 2010 v2.6 42 Lifelines  A lifeline represents a single participant in an interaction  Shows how a classifier instance may participate in the interaction  Lifelines have:  name - the name used to refer to the lifeline in the interaction  selector - a boolean condition that selects a specific instance  type - the classifier that the lifeline represents an instance of  They must be uniquely identifiable within an interaction by name, type or both  The lifeline has the same icon as the classifier that it represents jimsAccount [ id = "1234" ] : Account name selector type © Clear View Training 2010 v2.6 43 Messages  A message represents a communication between two lifelines synchronous message asynchronous send message return arrow type creation:A type of message destruction found message lost message calling an operation synchronously the senderwaits for the receiverto complete calling an operation asynchronously,sendinga signal the senderdoes notwait for the receiverto complete semantics returning from a synchronous operation call the receiverreturns focus of controlto the sender the sendercreates the target the senderdestroysthe receiver the message is sentfrom outside the scope of the interaction the message fails to reach its destination © Clear View Training 2010 v2.6 44 Deletion and self-delegation  Self delegation is when a lifeline sends a message to itself  Generates a nested activation :Registrar :RegistrationManager uml:Course deleteCourse("UML" ) sd DeleteCourse objectis deleted at this point «destroy» self delegation findCourse("UML" ) nested activation RegistrationManager addCourse() findCourse() deleteCourse() Course 0..* 1 © Clear View Training 2010 v2.6 45 Combined fragments – opt and alt  OPT semantics:  single operand that executes if the condition is true  ALT semantics:  two or more operands each protected by its own condition  an operand executes if its condition is true  use else to indicate the operand that executes if none of the conditions are true :A :B :C :D opt [condition] do this if condition is true alt do this if condition1 is true [condition1] [condition2] do this if condition2 is true [else] do this if neither condition is true sd example of opt and alt IF .. THEN SELECT.. CASE © Clear View Training 2010 v2.6 46 Combined fragments – loop and break  LOOP semantics:  Loop min times, then loop (max – min) times while condition is true  LOOP syntax:  A loop without min, max or condition is an infinite loop  condition can be • Booleanexpression • Plain text expression providedit is clear!  Break specifies what happens when the loop is broken out of:  The break fragment executes  The rest of the loop after the break does not execute  The break fragment is outside the loop and so should overlap it as shown :A :B loop min, max [condition] do something sd examples of loop loop [condition] do something loop while guard condition is true break on breaking out do this do something else must be global relative to loop © Clear View Training 2010 v2.6 47 Loop idioms type of loop semantics loop expression infinite loop keep looping forever loop * for i = 1 to n {body} repeat ( n ) times loop n while( booleanExpression ) {body} repeat while booleanExpression is true loop [ booleanExpression ] repeat {body} while( booleanExpression ) execute once then repeat while booleanExpression is true loop 1, * [booleanExpression] forEach object in collection {body} Execute the loop once for each object in a collection loop [for each object in collection] forEach object in ObjectType {body} Execute the loop once for each object of a particular type loop [for each object in :ObjectType] © Clear View Training 2010 v2.6 48 The rest of the operators operator long name semantics par parallel Both operands execute in parallel seq weak sequencing The operands execute in parallel subject to the constraint that event occurrences on the same lifeline from different operands must happen in the same sequence as the operands ref reference The combined fragment refers to another interaction strict strict sequencing The operands execute in strict sequence neg negative The combined fragment represents interactions that are invalid critical critical region The interaction must execute atomically without interruption ignore ignore Specifies that some messages are intentionally ignored in the interaction consider consider Lists the messages that are considered in the interaction (all others are ignored) assert assertion The operands of the combined fragments are the only valid continuations of the interaction © Clear View Training 2010 v2.6 49 addCourse( "UML" ) uml = Course("UML") addCourse( "UML" ) Sequence diagrams in design :Registrar :RegistrationUI uml:Course sd AddCourse-design :RegistrationManager :DBManager save(uml)  Could you draw a UML Class diagram corresponding to the sequence diagram above? © Clear View Training 2010 v2.6 50  Communication diagrams emphasize the structural aspects of an interaction - how lifelines connect together  Compared to sequence diagrams they are semantically weaker  Object diagrams are a special case of communication diagrams 2: addCourse("MDA" ) :Registrar :RegistrationManager mda:Course uml:Course 1: addCourse("UML" ) 1.1:«create» 2.1:«create» sd AddCourses link messagesequence number lifeline objectcreation message Communication diagram syntax © Clear View Training 2010 v2.6 51 Iteration  Iteration is shown by using the iteration specifier (*), and an optional iteration clause  There is no prescribed UML syntax for iteration clauses  Use code or pseudo code  To show that messages are sent in parallel use the parallel iteration specifier, *// iteration clause 1: printCourses() :Registrar :RegistrationManager [i]:Course 1.1.1:print() 1.1 * [for i = 1 to n] : printCourse(i ) sd PrintCourses iteration specifier © Clear View Training 2010 v2.6 52 Branching  Branching is modelled by prefixing the sequence number with a guard condition  There is no prescribed UML syntax for guard conditions  In the example above, we use the variable found. This is true if both the student and the course are found, otherwise it is false :RegistrationManager 1: register( "Jim", "UML" ) :Registrar course:Course 1.3 [found]: register( student) 1.1:student= findStudent("Jim" ) 1.4 [!found]: error() 1.2:course = findCourse("UML" ) sd registerstudentforcourse It’s hard to show branching clearly! found = (student!= null) & (course != null) guard condition return value from message © Clear View Training 2010 v2.6 53 {t <= 15} {t = 10}{t > 30} {t <= 15} {t = 30} Timing diagrams  Emphasize the real-time aspects of an interaction  Used to model timing constraints  Lifelines, their states or conditions are drawn vertically, time horizontally  It's important to state the time units you use in the timing diagram sd IntruderThenFire soundingFireAlarm soundingIntruderAlarm off :Siren 0 10 20 30 40 50 state or condition lifeline intruder intruder fire time in minutes event timing ruler duration constraint 60 resting 70 80 90 100 sd IntruderThenFire sounding Intruder Alarm :Siren off resting sounding Intruder Alarm sounding fire Alarm state or condition all times in minutes compact form © Clear View Training 2010 v2.6 54 {t <= 0.016} {t <= 0.016} soundIntruderAlarm() soundIntruderAlarm() soundFireAlarm() Messages on timing diagrams  You can show messages between lifelines on timing diagrams  Each lifeline has its own partition sd SirenBehavior soundingIntruderAlarm off :Siren {t <= 15} triggered notTriggered :IntruderSensorMonitor {t <= 15}{t = 30} all times in minutes resting triggered notTriggered :FireSensorMonit or soundingFireAlarm messages © Clear View Training 2010 v2.6 55 Key points  There are four types of interaction diagrams:  Sequence diagrams – emphasize time-ordered sequence of message sends  Communication diagrams – emphasize the structural relationships between lifelines  Timing diagrams – emphasize the real-time aspects of an interaction  Interaction overview diagrams – show how complex behavior is realized by a set of simpler interactions; presented together with Activity diagrams