COMP201 (Software Engineering)
Cost Components
- Hardware and Software Costs
- Travel and Training Costs
- Effort Costs (The dominant factor in most projects)
- Salaries of engineers involved in the project.
- social and insurance costs.
- Effort costs must take overheads into account:
- Costs of building, heating, lighting.
- Costs of networking and communications.
- Costs of shared facilities (library, staff restaurant).
Pricing Factors
The cost is how much the company spends on making the software product. The price is what the customer pays.
- Market Opportunity - A low price may be quoted when moving into a new segment. This may bring the opportunity of more profit later.
- Cost Estimate Uncertainty - The price may be increased if the cost is unknown.
- Contractual Terms - If the source code is withheld then the price could be less.
- Requirements Volatility - If the requirements are likely to be changed an organisation may lower its price to win the contract. High prices may then be charged for changes to the requirements.
- Financial Health - Developers in financial difficult may lower their price to gain a contract. It is better to make a small profit than go out of business.
Programmer Productivity
These are ways of measuring how much work a particular programmer has completed:
Factors Affecting Productivity
- Application Domain Experience
- Development Process Quality
- Project Size
- Due to increased communication.
- Technology Support
- Working Environment
Estimation Techniques
You should ideally use multiple of the following to find the cost of the system:
- If they don’t return approximately the same result, there is insufficient information available.
- Pricing to win is sometimes the only applicable method.
Algorithmic Cost Modelling
This is a formulaic approach based on historical cost information. This is generally based on the size of the software.
\[\text{Effort}=A\times\text{Size}^B\times M\]
Where:
- $A$ - Organisation-dependant constant.
- $B$ - Reflects the disproportionate effort for large projects.
- $M$ - A multiplier reflecting product, process and people attributes.
Expert Judgement
One or more experts in both software development and the application domain use their experience to predict software costs. The process iterates until some consensus is reached.
- Advantages:
- Relatively cheap estimation method.
- Can be accurate if experts have direct experience of similar systems.
- Disadvantages:
- Very inaccurate if there are no experts.
Estimation by Analogy
The cost of a project is computed by comparing the project to a similar project in the same application domain.
- Advantages:
- Accurate if project data is available.
- Disadvantages:
- Impossible if no comparable project has been tackled.
- Needs a systematically maintained cost database.
Parkinson’s Law
The project costs whatever resources are available:
Work expands to fill the time available. The cost is determined by available resources rather than by objective statements.
- Advantages:
- Disadvantages:
- System is usually unfinished.
Parkinson’s Law Example
The project should be delivered in 12 months and there are 5 people therefore:
\[\text{Effort}=60p/m\]
Pricing to Win
The project costs whatever the customer has to spend.
- Advantages:
- Disadvantages:
- The probability that the customer gets the system they want is small.
- Costs do not accurately reflect the work required.
Top-Down or Bottom-Up Estimation
Any of the previous approaches can be completed as top-down or bottom-up.
- Top-Down - Start at the system level and assess the overall system functionality and how this is deliver through sub-systems.
- Bottom-Up - Start at the component level and estimate the effort required for each component. Add these effort to reach a final estimate.
Estimation Accuracy
The size of a software system can only be know accurately when it is finished:
- As the development process progresses the size estimate becomes more accurate.
This is the process of organising, planning and scheduling software projects.
We need to make sure that the product is delivered on time and each component is delivered on schedule.
Management Activities
- Proposal Writing
- Project Planning and Scheduling
- Project Costing
- Project Monitoring and Reviews
- Personnel Selection and Evaluation
- Report Writing and Presentations
- Project Staffing & Training
Project Planning
The following types of project plan exist:
- Quality Plan - Describes the quality procedures and standards that will be used in a project.
- Validation Plan - Describes the approach, resources and schedule used for system validation.
- Configuration Management Plan - Describes the configuration management procedures and structured to be used.
- Maintenance Plan - Predicts the maintenance requirement for the system, maintenance costs and effort required
- Staff Development Plan - Describes how the skills and experience of the project team members will be developed.
The project plan should have the following structure:
- Introduction
- Project Organisation
- Risk Analysis
- Hardware and Software Resource Requirements
- Work Breakdown
- Project Schedule
- Monitoring and Reporting Mechanisms
Activity Organisation
Activities in a project should be organised to produce tangible outputs for management to judge progress:
- Milestones - Are the end-pont of a process activity.
- Deliverable - Are project results delivered to customers.
We can see this in the requirements engineering process:
flowchart LR
subgraph Activities
fs[Feasibility Study] --> ra[Requirements Analysis] --> pd[Prototype Development] --> ds[Design Study] --> rs[Requirements Specification]
end
subgraph Milestones
fs --> fr[Feasibility Report]
ra --> rd[Requirements Definition]
pd --> er[Evaluation Report]
ds --> ad[Architectural Design]
rs --> rs2[Requirements Specification]
end
Project Scheduling
This is the process of splitting projects into tasks and estimating the time and resources required to complete each task. We should:
- Organise tasks concurrently.
- Minimise task dependencies to avoid delays.
We could face the following issues:
- Estimating the difficulty of problems is hard.
- Productivity is not proportional to the number of people.
- Adding people late can delay a project due to communication overheads.
Tasks should not be too small, about a week in length.
Task Durations & Dependencies
Task |
Duration/Days |
Dependencies |
T1 |
8 |
|
T2 |
15 |
|
T3 |
15 |
T1 (M1) |
T4 |
10 |
|
T5 |
10 |
T2, T4 (M2) |
T6 |
5 |
T1, T2 (M3) |
T7 |
20 |
T1 (M1) |
T8 |
25 |
T4 (M5) |
T9 |
15 |
T3, T6 (M4) |
T10 |
15 |
T5, T7 (M7) |
T11 |
7 |
T9 (M6) |
T12 |
10 |
T11 (M8) |
Activity Network
graph LR
Start --- T1 & T2 & T4
T1 --- M1 & M3
T2 --- M3 & M2
T4 --- M2 & M5
M1 --- T3 & T7
M3 --- T6
M2 --- T5
M5 --- T8
T3 --- M4
T6 --- M4
T7 --- M7
T5 --- M7
T8 --- Finish
M4 --- T9
M7 --- T10
T9 --- M6
T10 --- Finish
M6 --- T11
T11 --- M8
M8 --- T12
T12 --- Finish
Start([Start<br>4/7/99])
T1[T1<br>8 days]
T2[T2<br>15 days]
T3[T3<br>15 days]
T4[T4<br>10 days]
T5[T5<br>10 days]
T6[T6<br>5 days]
T7[T7<br>20 days]
T8[T8<br>25 days]
T9[T9<br>15 days]
T10[T10<br>15 days]
T11[T11<br>7 days]
T12[T12<br>10 days]
M1([M1<br>14/7/99])
M2([M2<br>25/7/99])
M3([M3<br>25/7/99])
M4([M4<br>4/8/99])
M5([M5<br>18/7/99])
M6([M6<br>25/8/99])
M7([M7<br>11/8/99])
M8([M8<br>5/9/99])
Finish([Finish<br>19/9/99])
- Minimal time - Length of the longest (critical) path which is 55 days.
Activity Timeline (Gantt Chart)
gantt
dateFormat DD/MM/YYYY
Start:milestone, Start, 04/07/1999, 0d
T1:T1, after Start, 8d
T2:T2, after Start, 15d
T4:T4, after Start, 10d
M1:milestone, M1, after T1, 0d
T3:T3, after M1, 15d
T7:T7, after M1, 20d
M5:milestone, M5, after T4, 0d
T8:T8, after M5, 25d
M2:milestone, M2, after T2, 0d
M3:milestone, M3, after T2, 0d
T5:T5, after M2, 10d
T6:T6, after M3, 5d
M4:milestone, M4, after T3, 0d
T9:T9, after M4, 15d
M7:milestone, M7, after T7, 0d
T10:T10, after M7, 15d
M6:milestone, M6, after T9, 0d
T11:T11, after M6, 7d
M8:milestone, M8, after T11, 0d
T12:T12, after M8, 10d
Finish:milestone, after T12, 0d
You can extend the bars to show lag.
Staff Allocation (Gantt Chart)
gantt
dateFormat DD/MM/YYYY
section Fred
Start:milestone, Start, 04/07/1999, 0d
T4:T4, after Start, 10d
M5:milestone, M5, after T4, 0d
T8:T8, after M5, 25d
T11:T11, after M6, 7d
M8:milestone, M8, after T11, 0d
T12:T12, after M8, 10d
Finish:milestone, after T12, 0d
section Jane
T1:T1, after Start, 8d
M1:milestone, M1, after T1, 0d
T3:T3, after M1, 15d
M4:milestone, M4, after T3, 0d
T9:T9, after M4, 15d
M6:milestone, M6, after T9, 0d
section Anne
T2:T2, after Start, 15d
M2:milestone, M2, after T2, 0d
M3:milestone, M3, after T2, 0d
T6:T6, after M3, 5d
T10:T10, after M7, 15d
section Jim
T7:T7, after M1, 20d
M7:milestone, M7, after T7, 0d
section Mary
T5:T5, after M2, 10d
The milestones weren’t shown on the slide in this chart. I was too lazy to take them out.
Pert Charts
These show the following:
- Early Start - Earliest time a task can start.
- Early End - The earliest time the task can end.
- Late Start - The latest time the task can start without delaying the deadline.
- Late End - The latest time the project can end without delaying the deadline.
- Slack - The amount a task can be delayed without delaying the project.
- Calculated from Late Start - Early Start.
- Slack = 0 means that the task is critical.
They are shown as a set of linked tables with the following format:
Duration: 6 |
Task 1 |
Start |
End |
Early: 0 |
Early: 6 |
Late: 8 |
Late: 14 |
You might find better information on this type of chart by searching for activity networks. Pert charts seem to be a different thing.
Risk Management
This is drawing plans to minimise the effect of risks on the project.
Risks can be in the following categories:
- Project Risks - Affect the schedule or resources.
- Product Risks - Affect the quality or performance of the software being developed.
- Business Risks - Affect the organisation developing or procuring the software.
Risk Management Process
- Risk Identification - Identify project, product and business risks.
- Risk Analysis - Assess the likelihood and consequences of these risks.
- Risk Planning - Draw up plans to avoid or minimise the effects of the risk.
- Risk Monitoring - Monitor the risks throughout the project.
Risk Identification
You could identify risks in the following categories:
- Technology - The database used in the system cannot process as
many transactions per second as expected.
Software components which should be reused contain
defects which limit their functionality.
- People - It is impossible to recruit staff with the skills required.
Key staff are ill and unavailable at critical times.
Required training for staff is not available.
- Organisational - The organisation is restructured so that different
management are responsible for the project.
Organisational financial problems force reductions in the
project budget.
- Tools - The code generated by CASE tools is inefficient.
CASE tools cannot be integrated.
- Requirements - Changes to requirements which require major design
rework are proposed.
Customers fail to understand the impact of requirements
changes.
- Estimation - The time required to develop the software is
underestimated.
The rate of defect repair is underestimated.
The size of the software is underestimated.
Risk Analysis
We need to estimate the following:
- Probability:
- Very Low
- Low
- Moderate
- High
- Very High
- Risk Effects:
- Catastrophic
- Serious
- Tolerable
- Insignificant
We can then put the analysis in the following table:
Risk |
Probability |
Effects |
Organisational financial problems force reductions in the project budget. |
Low |
Catastrophic |
|
|
|
Risk Planning
We can use the following strategies to minimise risk:
- Avoidance Strategies - The probability that the risk will arise is reduced.
- Minimisation Strategies - The impact of the risk on the project or product will be reduced
- Contingency Plans - If the risk arises, contingency plans are plans to deal with that risk.
Risk Monitoring
We can draw up a table of risk factors and indicators so that we can spot issues early:
Risk Type |
Potential Indicators |
People |
Poor staff morale, poor relationships amongst team member, job availability |
|
|
Test Plan Template
Name of Case |
Description |
Input Data |
Action |
Expected Output |
Actual Output |
Pass |
LoginOKPass |
Tests login with a good username and password. |
Username=test1 Password=pass1 |
Click login. |
OK |
Login OK |
True |
|
|
|
|
|
|
|
Black-Box Testing
This is a method of testing where we blindly test inputs and validate the outputs.
There are additional examples of test cases in the slides.
Equivalence Partitioning
Often many inputs produce similar outputs (correct login produces a login event):
- We can then group the related inputs into an equivalence partition.
Testing data at the edge of the equivalence partition is more likely to produce errors.
White-Box Testing (Structural Testing)
This form of testing uses knowledge of the program to identify additional test cases:
- The aim is to exercise all program statements (not all path combinations).
There are additional examples of test cases in the slides.
Cyclomatic Complexity
We can represent the branches in the code as a graph where:
- Nodes - Branches
- Edges - Program Flow
The cyclomatic complexity of a program graph is:
\[e -n+2\]
- $e$ - The number of edges.
- $n$ - The number of nodes.
This represents the number of tests to test all control statements.
There is an example of calculating cyclomatic complexity the the slides.
Integration Testing
This is the testing of complete systems, or sub-systems, composed of integrated components:
- Should be black-box testing with tests derived from the specification.
- We can use incremental integration to find which component interactions cause the issues.
Incremental Integration Testing
This method uses regression testing:
- For each additional component we add, we still complete all of the tests that we have done before.
Top-Down Testing
This is where we start with a high-level system and integration from the top-down, replacing individual components by stubs where appropriate.
This method allows for the following:
- Architectural Validation - This method is better at discovering errors in the system architecture.
- System Demonstration - Top-Down integration testing allows a limited demonstration at an early stage in the development.
Bottom-Up Testing
This is where we integrate individual components in levels until the complete system is created.
This testing is best suited for:
- Object Oriented Systems - There is a neat decomposition into classes and methods.
- Real Time Systems - Allows use to identify slow code quickly.
- Systems with Strict Performance Requirements - Allows us to measure the performance of individual methods early in the testing process.
Interface Testing
This takes place when modules, or sub-systems, are integrates to create larger systems.
The objective is to detect faults due to interface errors or invalid assumptions about interfaces.
Interface Types
- Parameter Interfaces - Data is passed from one procedure to another.
- Shared Memory Interfaces - A block of memory is shared between procedures.
- Procedural Interfaces - Sub-system encapsulates a set of procedures to be called by other sub-systems.
- Message Passing Interfaces - Sub-system request services from other sub-systems.
Interface Errors
- Interface Misuse - A calling component calls another component and makes an error in its use of its interface.
- Interface Misunderstanding - A calling component embeds assumptions about the behaviour of the called component which are incorrect.
- Timing Errors - The called and the calling component operate at different speed and out-of-date information is accessed.
There is information on how to test these types of interfaces, stress testing, object-oriented testing, object class testing and testing levels in the slides.
There is also an example of testing a weather station object interface.
Cluster Testing
Cluster testing is concerned with integrating and testing clusters of cooperating objects. We can use the following testing methods on these systems:
V & V is a whole-life cycle process. it must be applied at each stage in the software process.
Verification
This is whether the software confirms to its specification:
- This may involve checking that it meets its functional and non-functional requirements.
Validation
This is whether the software does what the user requires:
- This goes beyond checking it meets the specification.
- The specification doesn’t walways accurately reflect the real needs of the user.
Program Inspection
Static Verification
This is the analysis of the static system in order to discover problems:
- This can include using tools such as the compiler to find errors and warnings.
- Includes variable naming and style.
- Using the correct domain for methods and attributes.
- Includes using the correct variable types (
short
/int
)
These generally include syntactic errors.
Dynamic Verification
This is concerned with observing whether the product behaves as expected when given an input:
- This is only possible when an executable version of the program is available.
- Incremental development allows for more dynamic verification.
- Real data should be used as input to find errors.
This method generally finds semantic errors.
Testing with Agile
- Development is test driven.
- Test is developed before the target code.
- The target code is developed to pass the test.
- The test purely based on the specification.
- Code is often simpler and closer to the specification.
Types of Testing
Defect Testing:
- Tests are designed to discover system defects.
- A successful test is one which reveals a defect in the system.
- Bugs in the code create defects.
Statistical Testing:
- Test the reliability of the system based on the frequency of user inputs.
Regression Testing:
- After fixing a defect, it is a good idea to retest the program to make sure that the fix hasn’t introduced new problems.
Debugging Process
graph LR
le[Locate Error] --> de[Design Error Repair] --> re[Repair Error] --> rp[Retest Program]
tr([Test Results]) --> le
s([Specification]) --> de
tc([Test Cases]) --> rp
Verification Model of Development (V-Model)
graph
rs[Requirements Specification] --> ss[System Specification] --> sd[System Design] --> dd[Detailed Design] --> mu[Module & Unit Code & Tess] --> ssi[Sub-system Integration Test] --> si[System Integration Test] --> at[Acceptance Test] --> s[Service]
ss & rs --> atp([Acceptance Test Plan]) --> at
sd & ss --> sip([System Integration Test Plan]) --> si
dd & sd --> ssip([Sub-system Integration Test Plan]) --> ssi
Test planning is about defining standards for the testing process rather than describing the product tests.
Software Test Plan
The software test plan has the following structure:
- The Testing Process - A description of the major phases of the testing process.
- Requirements Traceability - Testing should ensure that all requirements are individually tested.
- Tested Items - Specify the products of the software process to be tested.
- Testing Schedule - An overall schedule for the testing of the software is required and resources must be allocated as part of the general project schedule.
- Test Recording Procedures - The results of tests must be systematically recorded. This allows testing audits to ensure the testing has been completed.
- Hardware & Software Requirements - This part sets a list of software tools required and the estimated hardware utilisation.
- Constraints - Any constraints affecting the testing process.
Software Inspection
This is where the code is inspected without running it. It has the aims of identifying:
- Defects
- Poor Programming Style
- Compliance with Standards
- Compliance with Portability & Maintainability
Interaction diagrams record how objects interact to perform a particular use-case.
Collaboration Diagrams
Collaboration diagrams show links, objects and actors.
The labelled arrows show a message sent from one object to another.
actor "aMember:BookBorrower" as member
[theLibraryMember:\nLibraryMember] as librarymember
member -- librarymember:borrow(theCopy) >
librarymember -- librarymember:1: okToBorrow >
[theCopy:Copy] as copy
librarymember -- copy:2: borrow >
[theBook:Book] as book
copy -r- book:2.1: borrowed >
The objects are named as objectName:className
.
Sequence Diagrams
This is the same events as before, shown in a sequence diagram:
sequenceDiagram
actor bb as aMember:BookBorrower
participant lm as theLibraryMember:LibraryMember
participant c as theCopy:Copy
participant b as theBook:Book
activate bb
bb ->> lm:borrow(theCopy)
activate lm
lm ->> lm:1: okToBorrow
lm ->> c:2: borrow
activate c
c ->> b:2.1: borrowed
activate b
deactivate b
deactivate c
deactivate lm
deactivate bb
- Messages are shown as solid lines.
- Returns are shown as dotted lines.
Timing Constraints
You can show timing constraints like so:
sequenceDiagram
actor bb as aMember:BookBorrower
participant lm as theLibraryMember:LibraryMember
participant c as theCopy:Copy
participant b as theBook:Book
activate bb
note over bb:A
bb ->> lm:borrow(theCopy)
activate lm
lm ->> lm:1: okToBorrow
note over bb:{C-A < 5 secs}
lm ->> c:2: borrow
activate c
note left of b:{borrowed'-borrowed < 1 sec}
c ->> b:2.1: borrowed
activate b
deactivate b
deactivate c
lm -->> bb:
deactivate lm
note over bb:C
deactivate bb
Creating & Deleting Objects
In collaboration diagrams:
- You can show if objects are created and destroyed by labelling them with
{new}
and {destroyed}
.
- If an object is created and destroyed in the same interaction, it can be labelled
{transit}
.
actor ":UTO" as UTO
component ":Lecturer {destroyed}" as Lecturer
component ":DirectorOfStudies {new}" as DirectorOfStudies
UTO -r- Lecturer:1: n := getName() >
UTO -r- Lecturer:3: destroy() >
UTO -- DirectorOfStudies:2: new DirectorOfStudies(n) >
You can create and delete objects in a sequence diagram like so:
actor ":UTO" as UTO
participant ":Lecturer" as Lecturer
participant ":DirectorOfStudies" as DirectorOfStudies
activate UTO
UTO ->> Lecturer:1: n := getName()
activate Lecturer
deactivate Lecturer
create DirectorOfStudies
UTO ->> DirectorOfStudies:2: new DirectorOfStudies(n)
UTO ->> Lecturer:3: destroy()
destroy Lecturer
deactivate UTO
Messages from an Object to Itself
If an object sends a message to itself you can use the Java keyword this
. This will call the method on the existing object.
Omitting messages from an object to itself, for internal computation, can be used as a form of abstraction.
Packages
We can split of a sub-collaboration into a package in order to simplify a collaboration:
- Collaboration - Collection of objects and links between them.
- Sub-Collaboration - A subset of the objects together with the links connecting those objects.
Activity Diagrams
The following is an example of an activity diagram:
stateDiagram
state j1 <<join>>
state f2 <<fork>>
state member {
state br <<choice>>
[*] --> br
br --> fb:borrower
br --> wq:returner
fb --> wq
fb: Find Book on Shelf
wq: Wait in Queue
f2 --> [*]
}
wq --> j1
state librarian {
state br2 <<choice>>
j1 --> br2
state f1 <<fork>>
br2 --> f1:returning
br2 --> rb:borrowing
rb:Record Borrowing
f1 --> rr
rr:Record Return
f1 --> pb
pb:Put Book Back on Shelf
state j2 <<join>>
rr --> j2
pb --> j2
rb --> pn
pn:Prepare for Next Member
j2 --> pn
pn --> f2
f2 --> j1
}
It has the following components:
- Activity - A task to complete.
- Transition - Moving from one activity to another.
- Synchronisation Bar - Describes the coordination of activities.
- Decision Diamond - Can be used to show decisions.
- Start/Stop Markers - The same as state diagrams.
There are several differences between activity diagrams and state diagrams:
- Activity diagrams don’t normally include events.
- Activities are intended to proceed, following the flow described by the diagram. Usually one of the guards of an edge leaving an activity should be satisfied.
- Concurrent activities can be modelled by using the synchronisation bar notation.
Aggregation
Aggregation is a way of saying that an object is part of anther class:
This is opposed to an is a relation with inheritance.
classDiagram
direction LR
HonoursCourse "1..*" o-- "6..*" Module
The aggregation also allows the Module
to be involved in multiple HonoursCourses
.
Composition
This is a specialised form of aggregation. In composition the whole strongly owns its parts:
- If the whole object is copied or deleted, its parts are copied or deleted with it.
- Multiplicity at the whole end must be
1
or 0..1
.
classDiagram
direction LR
Car "1" *-- "4" Wheel
One wheel can’t be part of multiple cars.
Roles
Roles can be written on the ends of the arrows like so:
classDiagram
DirectorOfStudies "DoS" -- "directee" Student
Association with No Navigability
You can have associations with no relation type (arrows) but only a cardinality:
classDiagram
Student "1..*" -- "6" Module:is taking
Navigability
We can put an arrow on one, or both ends of the association to represent that it is possible for messages to be send in the direction of the arrow:
classDiagram
Student "1..*" <-- "6" Module:is taking
This arrow head just means that they are associated.
Qualified Composition
This is putting extra attributes on the association.
I can’t make this with either of my graphing tools and I’m pretty sure no-one ever uses this. Just put the attribute in the class like a normal person.
Derived Associations
Derived associations show the associations that are implied by others. They are denoted by a /
:
The direction of an association label is denoted by the black arrow.
Constraints
Constraints are represented as a dotted line between associations with a boolean operand. The two associations is then constrained by that operand.
I can’t make this with either of my graphing tools again. It can also be made using other methods.
Association Class
This is a class with a dotted line, connected to an association. It holds attributes specific to an association.
I can’t make this with either of my graphing tools again. It should be avoided and the following method used instead.
You can avoid using these by making an additional class normally:
classDiagram
Student "1..*" -- "6" Module: is taking
Student "1" -- "6" Mark
Mark: int mark
Mark "1..*" -- "1" Module
Interfaces
Interfaces specify operations that are visible outside of the class. All elements of an interface are public:
classDiagram
class Dog {
<<interface>>
pat() Reaction
}
They don’t require an implementation.
Abstract Classes
These are similar to interfaces but are general classes used to define a set of classes:
classDiagram
class Dog {
<<abstract>>
-int numberOfPats
-bool happy
+pat() Reaction
}
Naming Classes
Classes should be named with:
- Nouns
- Non-plurals
- Not general process descriptors:
- Printing - Bad
- Printer - Good
Class Models
We can use two different methods to derive classes:
- Data Driven Design (DDD) - We identify all the data of the system and divide it into classes. We then assign particular responsibilities (methods) to these classes.]
- Responsibility Driven Design (RDD) - We identify all the responsibilities of the system and divide them into classes. We then find the data each class requires.
Associations
If some object of class $A$ has to know about some object of class $B$ then they have an association.
We can also note multiplicity on the association:
classDiagram
direction LR
Doctor "1" --> "1..*" Patient:has allocated
Attributes & Operations
- Attributes - Describe the data contained in an object of the class and their type.
- Operations - Define the way in which objects may interact.
classDiagram
class Patient {
-String name
-Date dateOfBirth
+addAppointment()
+getDateOfBirth() Date
+addPrescription()
}
Dynamic Binding
You can overwrite the an inherited method using dynamic binding:
classDiagram
direction TB
Vehicle <|-- Car
Vehicle <|-- Boat
Vehicle: startEngine()
Car: +startEngine()
Boat: +startEngine()
Generalisation
All attributes and methods from the top of the inheritance are passed though to the children:
classDiagram
Animal <|-- Cat
Animal <|-- Dog
class Animal {
Integer Age
getAge() Integer
}
Cat: meow()
Dog: bark()
CRC Cards
The following are examples of CRC (classes, responsibilities, collaborations) cards:
LibraryMember |
|
Responsibilities |
Collaborators |
Maintain data about copies currently borrowed. Meet requests to borrow and return copies. |
Copy |
Copy |
|
Responsibilities |
Collaborators |
Maintain data about a particular copy of a book. Inform corresponding Book when borrowed and returned. |
Book |
Book |
|
Responsibilities |
Collaborators |
Maintain data about one book. Know whether there are borrow-able copies. |
|
- Collaborators - Help to carry out each responsibility.
- There should be a low number of responsibilities per class.
- The number of collaborators should be low too.
The Problem
You have been contacted to develop a computer system for a university medical clinic.
The clinic needs the following types of service:
- Staff management
- Booking appointments
- Keeping records
You are asked to build an interactive system which
handles all of these aspects online.
Developing Requirements
We need to identify all the actors:
- Doctors
- Patients
- Admin Staff
and the data we want to keep track of:
We can as the actors about their requirements that can then be made into use-cases.
Use Case Model
We should take the requirements, identify the actors and the use cases (tasks) that the actors must undertake.
left to right direction
:Doctor: as D
:Receptionist: as R
:Patient: as Pa
:Pharmacist: as Ph
package "Clinic System" {
(View Appointments) as va
(Schedule Appointment) as sa
(Cancel Appointment) as ca
(View Notes) as vn
(Add Notes) as an
(Issue Prescription) as ip
(Request Repeat Prescription) as rrp
(Re-book Appointment) as ra
(Supply Prescription) as sp
(Check Stock) as cs
}
D -l-|> R
R --- va
R --- sa
R --- ca
D --- vn
D --- an
D --- ip
Pa -up- rrp
Pa -up- ra
Ph -up- sp
Ph -up- cs
We shouldn’t make addition use-cases without first confirming with the client.
We should make this use-case diagram with an iterative approach.
Identifying Classes
This is where the noun identification technique is used.
Consider that we have the following requirements document:
Clinic, appointments and treatment system.
Before seeing a doctor or nurse the patient needs to make an appointment. The appointment will be made by the receptionist, before making the appointment the patient needs to ask the patient which doctor they wish to see and if the appointment is a standard appointment or urgent appointment. The receptionist will use this information, check the appointment schedule and find a free slot and make the booking. When the patient sees the Dr, the Dr will sometimes issue a prescription. The patient may at some time request a repeat issue of their prescription. Receptionists can also cancel appointments. Each doctor has a maximum of 2000 patients registered to them.
We can then underline all nouns like:
- Clinic
- System
- Doctor
- Appointment
- Prescription
- Time
- …
We can the use these as a list of candidate classes.
We should remove nouns that are:
- Outside the scope of the system.
- Redundant
- Measures, such as “time”.
- Vague (need clarification)
- Meta-language, such as “system”.
Relations Between Classes
We can use the classes we have found to create an initial class model using only the multiplicity relations:
classDiagram
direction LR
Doctor "1" -- "1..*" Patient:Cares For
Doctor "1" -- "1..*" Prescription:Writes/Issues/Confirms
Doctor "1" -- "1..*" Appointment
Receptionist "1" -- "1..*" Appointment:Books/Cancels/Re-Books
Patient "1" -- "1..*" Appointment:Attends
Nurse "1" -- "1..*" Patient:Treats
Nurse "1" -- "1..*" Appointment
Inheritance Class Model
We can see if there are any shared roles between the actors. This can inform the inheritance.
classDiagram
direction TB
HealthcareStaff <|-- Doctor
HealthcareStaff <|-- Nurse
Staff <|-- Receptionist
Staff <|-- HealthcareStaff
Person <|-- Staff
Person <|-- Patient
We can then involve hierarchy this in our initial diagram:
classDiagram
HealthcareStaff <|-- Doctor
HealthcareStaff <|-- Nurse
Staff <|-- Receptionist
Staff <|-- HealthcareStaff
Nurse "1" -- "1..*" Patient:Treats
Nurse "1" -- "1..*" Appointment
Doctor "1" -- "1..*" Patient:Cares For
Person <|-- Patient
Person <|-- Staff
Doctor "1" -- "1..*" Prescription:Writes/Issues/Confirms
Doctor "1" -- "1..*" Appointment
Receptionist "1" -- "1..*" Appointment:Books/Cancels/Re-Books
Patient "1" -- "1..*" Appointment:Attends
Interaction Diagrams (Sequence Diagram)
Consider what happens in the appointment booking scenario when a user wishes to make an appointment:
- The receptionist must check that the person is a valid patient.
- Then the doctor object must be checked to see if there are any available appointments.
- If there are any suitable slots available, a new appointment should be created and assigned to the doctor.
This can be shown in the following sequence diagram:
sequenceDiagram
actor Receptionist
actor Patient
actor Doctor
Receptionist -->> Patient:create(name)
activate Receptionist
Receptionist ->> Patient:valid?
activate Patient
Patient -->> Receptionist:
deactivate Patient
Receptionist ->> Doctor:available(date/time)
activate Doctor
Doctor ->> Appointment:dateMatch(date/time)
Appointment -->> Doctor:match?
Doctor -->> Receptionist:available?
deactivate Doctor
Receptionist -->> Appointment:create(date,time)
Appointment -->> Receptionist:
Receptionist ->> Doctor:setAppointment(Appointment)
activate Doctor
Doctor -->> Receptionist:
deactivate Doctor
Receptionist ->> Patient:setAppointment(Appointment)
activate Patient
Patient -->> Receptionist:
deactivate Patient
deactivate Receptionist
State Diagrams
Objects in the system have a state. State diagrams show how methods can change an object’s state:
stateDiagram
state Doctor {
direction LR
FullyBooked --> Available:cancelAppointment()
Available --> FullyBooked:bookAppointment()[lastAppointment]
Available --> Available:bookAppointment()[notLastAppointment]
Available --> Available:cancelAppointment()
}
This lecture is basically a copy of some COMP122 lectures. For more information on any topic, click on the link below:
Summary
- Objects can have their own private state and operations.
- Objects should have a constructor as well as
inspection operations. They provide services to
other objects.
- Objects may be implemented sequentially or
concurrently.
- Object interfaces should be defined precisely
using, ideally using an object oriented language.
- Object-oriented design potentially simplifies
system evolution.
- The Unified Modelling Language provides
different notations for defining different object
models.
-
For a large project, why is a detailed software design important?
A detailed software design is made for the developers to help them in implementing the software.
This is important as in a system with that many sub-systems and components there needs to be strict requirements concerning the communication between each of the sub-systems. This means developing:
- Classes/Packages
- Should be re-useable on future systems.
- Methods for complying with legislation:
- Securing customer details
- Testing Methods
With so many developers people may have different ideas about how the different parts of the system are implemented. Therefore a detailed software design is both:
This is important as the design should detail every part of the system so that it can be implemented properly and shouldn’t contradict itself.
-
List the benefits of the following java keywords:
private
- This enables encapsulation which is good as it limits coupling.
package
- This is a collection of classes. Classes in the package are private unless otherwise specified.
class
- This creates objects which are good as they enable object cohesion which is a strong level of cohesion. They also encapsulate the data with code.
extends
- This is good as it enables code re-use.
High cohesion, low coupling code is good as it enables code reuse.
These are architectural designs for software the executes on more than one processor.
This can be on the same computer or between many machines.
System Types
- Personal Systems - Not distributed and are designed to run on a personal computer.
- Embedded Systems - Run on a single processor or on an integrated group of processors.
- Distributed Systems - Where the system software runs on a loosely integrated group of cooperating processors linked by a network.
Distributed Systems
Distributed systems have the following advantages:
- Resource Sharing
- Openness
- Concurrency
- Scalability
- Fault Tolerance
- Transparency
There are also several disadvantages:
- Complexity
- Security
- Manageability
- Unpredictability
Middleware
This is software that manages and supports the different components of a distributed system. In essence, it sits in the middle of the system.
Middleware is usually off-the-shelf rather than
specially written software they can be:
- Transaction Processing Monitors
- Data Converters
- Communication Controllers
Distributed System Architectures
- Client-Server - Distributed services which are called on by clients. Servers that provide the services are treated differently from clients that use the services.
- Distributed Object Architectures - No distinction between clients an servers. Any object on the system may provide and use services from other objects.
Multiprocessor Architectures
This is the simplest distributed system model:
- System composed of multiple processes which may execute on different processors.
- Architectural model of many large real-time systems.
- Distribution of process to processor may be pre-ordered or may be under the control of a dispatcher.
Client-Server Architectures
The application is modelled as a set of services that are processed by servers and a set of client that use theses services:
- Clients know of servers by servers need not know of clients.
- Clients and servers are logical processes.
- The mapping of processors to processes is not necessarily 1:1
Layered Application Architecture
System architectures are split into a number of layers:
They are arranged as so:
flowchart LR
pl[Presentation Layer] <--> apl[Application Processing Layer] <--> dml[Data Management Layer]
Thin & Fat Clients
These are two types of organisation in the client-server architecture.
- Thin Client Model - In a thin-client model, all of the application processing and data management is carried out on the server. The client is just responsible for running the presentation software.
- Can be used when legacy systems are migrated to client-server architectures:
- The legacy system acts a a server in its own right with a graphical interface implemented on a client.
- Places heavy processing load on both the server and the network.
- Fat Client Model - In this model, the server is only responsible for data management. The software on the client implements the application logic and the interaction with the system user.
- The capabilities of the client system must be known in advance.
- More complex management than a thin client.
- New versions of the application have to be installed on all clients.
Three-Tier Architectures
This is where each of the application layers are executed on separate processors:
- Allows for better performance.
- A more scalable architecture:
- As demands increase extra servers can be added to the data management or application processing layers.
flowchart LR
subgraph Presentation
c((Client))
end
Presentation <--> Server1
subgraph Server1
ap[Application Processing]
end
Server1 <--> Server2
subgraph Server2
dm[Data Management]
end
Distributed Object Architecture
In this architecture there is no distinction between clients and servers.
Object communication is through a middleware system called an object request broker (software bus):
- Each object can call on the server process of another object on the software bus.
Advantages:
- This allows the system design to delay decisions on where and how services should be provided.
- Service-providing objects can execute on any node of the network and thus the distinction between thin/fat client models becomes irrelevant.
- It is easy to add new nodes onto the server.
- Object communication standards can be used that allow objects written in different languages to communicate.
- Is is possible to reconfigure the system dynamically.
Architectural Design
This stage represents the link between specification and design processes:
- Often carried out in parallel with some specification activities.
- Involves identifying major system components and their communications.
Architectural Design Process
- System Structuring
- The system is decomposed into several principal sub-systems and communications between these sub-systems are identified.
- Control Modelling
- A model of the control relationships between the different parts of the system is established.
- Modular Decomposition
- The identified sub-systems are decomposed into modules.
Sub-Systems vs. Modules
Architectural Models
Several architectural models may be produces during the design process. Each model presents different perspectives on the architecture:
- Static Structural Model - Shows the major system components.
- Dynamic Process Model - Shows that process structure of the system.
- Interface Model - Defines sub-system interfaces.
- Relationships Model - Such as a data-flow model.
System Structuring
This is where you decompose the system into interacting sub-systems.
The architectural design is normally expressed as a block diagram presenting an overview of the system structure:
Packing Robot Control System
flowchart
vs[Vision System] --> ois[Object Identification System]
vs --> controllers
subgraph controllers
ac[Arm Controller]
gc[Gripper Controller]
end
ois --> controllers
ois --> packing
subgraph packing
pss[Packaging Selection System] <--> ps[Packing System]
end
ps <--> controllers
ps <--> cc[Conveyor Controller]
Network Models
You can use network models to represent networked devices, for example in a client-server architecture:
nwdiag {
network highbandwith_network {
group clients {
client1;
client2;
client3;
client4;
}
group servers {
catalogue_server;
video_server;
picture_server;
hypertext_server;
}
}
Control Models
These are concerned with the control flow between sub-systems:
- Centralised Control
- One sub-system has overall responsibility for control and starts and stops other sub-systems.
- Event-Based Control
- Each sub-system can respond to externally generated events from other sub-systems or the system’s environment.
Centralised Control
A control sub-system takes responsibility for managing the execution of other sub-systems. There are two main types of centralised control models:
- Sequential
- Call-return model is used. This is where control starts at the top os a subroutine hierarchy and moves downwards.
- Parallel
-
Manager model is used. One system component controls the stopping, starting and coordination of other system processes.
This can also be implemented in sequential systems as a case statement.
Event-Driven Systems
These are driven by externally generate evens when the timing of the event is out of the control of the sub-systems which process the event.
There are two main event-driven models:
Broadcast Model
An event is broadcast to all sub-systems. Any subsystem which can handle the event may do so.
This is effective in integrating sub-systems on different computers in a network.
- Sub-systems register an interest in specific events. When these occur, control is transferred to the sub-system which can handle the event.
- Control policy is not embedded in the event and message handler. Sub-systems decide on events of interest to them.
Subsystems don’t know if or when an event will be handled.
Interrupt-Driven Models
Used in real-time system where interrupts are detected by an interrupt handler and passed to some other component for processing.
These are used where a fast response to an event is essential.
- There are known interrupt types with a handler (routine) defined for each type.
- Each type is associated with a memory location and a hardware switch causes transfer to its handler.
These are very fast by complex to program and validate.
Modular Decomposition
This is another structural level where sub-systems are decomposed into modules.
If possible, decisions about concurrency should be delayed until modules are implemented.
There are two modular decomposition models covered:
Object Models
These structure the system into a set of loosely coupled objects with well-defined interfaces.
Object-oriented decomposition is concerned with identifying:
When implemented, objects are created from these classes and some control model is used to coordinate object operations.
Class diagrams are a type of object model.
Data-Flow Models
These are functional transformations that process inputs to produce outputs.
May be referred to as a pipe and filter model (as in UNIX shell)
These aren’t really suitable for interactive systems.
Good systems have the following properties:
- Useful and Usable
- Reliable (Low Coupling)
- Flexible (Low Coupling, High Cohesion)
- Easy to modify for different purposes and in event of change.
- Affordable (Software Reuse)
- Available (Decreased development time through reuse.)
Module Interfaces
The interface of a module is how you interact with the module.
Assumptions about interfaces should be documented in the interface:
- This means that changes to the internal of a module shouldn’t change how the interface behaves.
Principles of Good Design
Linguistic Modular Units
This is the idea that modules should correspond to linguistic units (such as classes) in the language used.
Few Interfaces
The overall number of communication channels between modules should be as small as possible.
In a system with $n$ modules there may be a minimum of $n-1$ and maximum of $\frac{n(n-1)}2$ links.
Facade Structure
You can also implement a public interface for a set of modules.
This keeps interfaces down as you can only interact with a package via it’s public interface.
Coupling
This is a measure of the strength of the inter-connection between system component.
Ideally components should exchange as little data as possible between themselves.
-
Loose Coupling - Component changes are unlikely to affect other components.
Loose coupling can be achieved by state decentralisation and component communication via parameters, or message passing.
-
Tight Coupling - Components have shared variables and lots of interaction.
This is only acceptable when using a shared database.
Coupling & Inheritance
Object-oriented systems are loosely coupled because there is no shared state and object communicate using message passing.
-
However, an object class is coupled to its super-classes.
Changes made to the attributes or operations in a super-class propagate to all sub-classes.
Explicit Interfaces
If two modules must communicate, they should do it so that we can see it.
This should be obvious from the documentation of the modules involved.
If we change a module, we need to see if any other modules may be affected by the change. A traceability matrix can be used for this.
All information about a module (and partially how the module doesn’t what it does) should be private to the module unless it is specifically declared otherwise.
Therefore, each modules should have an interface, which is how the world see it. Anything beyond the interface should be hidden.
The default Java rule is to make everything private.
Cohesion
This is a measure of how well a component fits together:
- A component should implement a single logical entity or function.
Levels of Cohesion
Weak:
- Coincidental Cohesion - Parts of a component are simply bundled together.
- Logical Association - Components which perform similar functions are grouped.
- Temporal Cohesion - Components which are activated at the same time are grouped.
Medium:
- Communicational Cohesion - All the elements of a component operation on the same input or produce the same output.
- Sequential Cohesion - The output for one part of a component is the input to another part.
Strong:
- Functional Cohesion - Each part of a component is necessary for the execution of a single function.
- Object Cohesion - Each operation provides which allows object attributes to be modified or inspected.
Ideally you want your cohesion to be as strong as possible with the weakest possible coupling.
Inheriting attributes from super-classes weakens cohesion as you have to examine the super-class as well as each component.
Cohesion vs. Encapsulation
- Cohesion - A measure of abstraction that means developers do not need to concern themselves with the internal working of a module.
- Encapsulation - Means that developers are unable to use hidden information within a modules, ensuring that subtle errors cannot be introduced when using connected modules.
Pluggable Modules
If a module has high cohesion, low coupling and a well defined interface then it may be feasible to reuse that module in other systems.
You should make architectural decisions early as using architecture specific features can make code less reusable.
Software Design
The requirement for software should be split into several object-oriented classes so that development can be distributed between several developers.
Additionally the end software needs to be:
- Simple
- Understandable
- Flexible
- Portable
- Re-usable
Stages of Design
-
Problem Understanding
Look at the problem from different angles to discover the design requirements.
-
Identify One or More Solutions
Evaluate possible solutions and choose the most appropriate depending on the designer’s experience and available resources.
-
Describe Solution Abstractions
Use graphical, formal or other descriptive notations to describe the components of the design.
-
Repeat Process for Each Identified Abstraction
Until the design is expressed in primitive terms.
The Design Process
Any design may be modelled as a directed graph made up of entities with attributes with participate in relationships:
- The system should be described at several different levels of abstraction.
- Design takes place in overlapping stages.
Computer systems are not monolithic. They are usually composed of multiple, interacting modules. The goal of system design is to decode:
- What the modules are.
- What the modules should do.
- How that modules interact with one-anothe.
Design Process Phases
flowchart
ad --> as
rs([Requirement Specification]) --> ad([Architectural Design]) & as([Abstract Specification])
ad --> sa[System Architecture]
sa --> as
as --> id([Interface Design]) & ss[Software Specification]
ss --> id
id --> cd([Component Design]) & is[Interface Specification]
is --> cd
cd --> dsd([Data Structure Design]) & cs[Component Specification]
cs --> dsd
dsd --> ald([Algorithm Design]) & dss[Data Structure Specification]
dss --> ald
ald --> als[Algorithm Specification]
subgraph Design Activities
rs
ad
as
id
cd
dsd
ald
end
subgraph Design Products
sa
ss
is
cs
dss
als
end
- Architectural Design - Identify sub-systems.
- Abstraction Specification - Specify sub-systems.
- Interface Design - Describe sub-system interfaces.
- Component Design - Decompose sub-systems into components.
- Data Structure Design - Design data structures to hold problem data.
- Algorithm Design - Design algorithms for problem functions.
Modular Programming
Modules should have the following properties:
- Autonomous
- Coherent
- Robust (Shouldn’t crash the whole system in the event of an error.)
There are several types of modular programming:
Procedural Abstraction
Procedural abstraction is where procedures in code represent distinct logical functions in a program such as:
- “Display Menu”
- “Get User Option”
Programs as Functions
Programs as function are where programs are viewed as a function from a set $I$ of legal inputs to a set $O$ of legal outputs:
\[x\rightarrow f\rightarrow f(x)\]
ML, Miranda and LISP support this directly and it is useful for non-distributed, terminating systems such as: compilers.
The use of internal state is against functional programming.
Object-Oriented Design
This methodology views the system as a collection of interacting objects.
The system state is decentralised and each object manages its own state.
Objects may be instances of an object class and can communicate by exchanging messages.
Criteria for Design Methods
There are five criteria to help evaluate modular design methods:
Modular Decomposability
This criterion is met by a design method if the method support the composition of a problem into smaller sub-problems, which can be solved independently.
Generally the sub-problems will be divided further.
Top-down design methods fulfil this criterion by using step-wise refinement.
Top-Down Design
In Principle - This involved starting at the upper most components in the system hierarchy and working down the hierarchy level by level.
In Practice - Large systems design is never truly top-down as some branches are designed before others. Designers reuse experience and components during the design process.
Modular Composability
A method satisfies this criterion if it leads to the production of modules that may be freely combined to produce new systems.
Composability is directly related to the issues of re-usability.
Composability is often at odds with top-down design.
Modular Understandability
A design method satisfies this criterion is it encourages the development of modules which are easily understandable.
You should name variables and methods so that they are descriptive about the contents:
A component is understandable if:
- It can be understood on its own.
- If the names used are meaningful.
- If there is good documentation.
- If complex algorithms are limited.
- High complexity involves many relationships between different components.
Modular Continuity
This is satisfied if small changes in the specification lead to small changes in the software.
This can be enforced by only using symbolic constrains.
Modular Protection
This method is satisfied if the effect of an abnormal condition at run-time only effect one (or very few) modules.
To protect modules you can use input validation and use the most appropriate datatypes.
Module Storage & Communication
Sub-systems making up a system must exchange and share data so they can work together.
The is how data is stored in the system.
There are two main approaches to data storage:
- The Repository Model
- All shared data is held in a central database which may be accessed by all sub-systems.
- Each sub-system or component maintains its own database. Data is then exchanged between sub-systems via message passing.
Repository Model
There are several advantages to the repository model:
- Databases are an efficient way to share large amounts of data and data does not have to be transformed between different sub- systems (they agree on a single data representation).
- Sub-systems producing data need not be concerned with how that data is used by other sub-systems.
- Many standard operations such as backup, security, access control, recovery and data integrity are centralised and can be controlled by a single repository manager.
- The data model is visible through the repository schema.
The disadvantages include:
- Sub-systems must agree on the data model which means compromises must be made, for example with performance.
- Evolution may be difficult since a large amount of data is generated and translation may be difficult and expensive.
- Different systems have different requirements for security, recovery and backup policies which may be difficult to enforce in a single database.
- It may be difficult to distribute the repository over a number of different machines.
This tutorial covered the use cases of an online hotel booking system:
ID |
UC1 |
Name |
Password Reset |
Description |
Allows the user to reset their password. |
Pre-condition |
System is in operation. |
Includes |
UC3(UserLogin) |
Event Flow |
User enters new password twice to confirm and submits password. |
Post-condition |
Password is updated. |
Extensions |
Send email to user confirming change. |
Triggers |
User pressed reset password button. |
ID |
UC2 |
Name |
User Registration |
Description |
Allows the user to make an account. |
Pre-condition |
Username and email can’t be taken. System is operational. Password conforms with complexity requirements. Email is valid. |
Event-Flow |
User enters username and email and password. Confirms email and password. User accepts terms and conditions. User accepts privacy policy. Submit the information. |
Post-condition |
Account saved into database. |
Extensions |
Capcha check. Account confirmation email. |
Triggers |
User clicks register button. |
ID |
UC3 |
Name |
User Login |
Description |
Allows the user to log in. |
Pre-condition |
The system must be operational. |
Event flow |
User enters username and password. If information is incorrect, user re-enters information. |
Post-condition |
User is logged in. |
Extensions |
UC1(Password Reset) |
Triggers |
User clicks login button. |
ID |
UC4 |
Name |
Room Search |
Description |
A list of rooms are returned based on a criteria. |
Pre-condition |
System is operational. At least one room is available. |
Event Flow |
User enters dates, price and number of guests/pets. User enters catering requirements. List of available rooms is returned. |
Extensions |
UC3(User login) UC5(Pay Bill via Paypal) |
Triggers |
User click room search button. |
ID |
UC5 |
Name |
Pay Bill via Paypal |
Description |
User pays the bill for a room via PayPal and the room is booked. |
Pre-conditions |
System is operation. PayPal is operational. A room and its attributes are selected to be paid for. |
Includes |
PayPal payment processing. |
Event Flow |
User is redirected to papal. If PayPal window is closed go back to start. Information from PayPal is confirmed. An order confirmation screen is displayed. |
Post-Condition |
Room is booked on the account. Receipt and confirmation is emailed to user. |
Triggers |
User has opted to pay for room via PayPal. |
This lecture covers model based specifications. We use models to specify the behaviour of a system.
Abstract State Machine Language (ASML)
An ASML model is an abstract model that only encodes the aspects of the systems structure that affect the behaviour being modelled.
- The goal is the use the minimum amount of detail that accurately reproduces the behaviour of the system that we which to model.
Abstraction helps us reduce complex problems into manageable units and prevents us from getting lost in implementation details.
Example with Sets
Consider that we have a set that includes integers from one to 20. We want to find the numbers from the set, that when doubled, still belong to the set.
This is the solution in ASML:
A = {1..20}
C = {i|i in A where 2 * i in A}
Main()
step
WriteLine(C)
Sequences
Elements of sequences are contained in square brackets:
They are ordered and can contain duplicate elements.
Sequences Example
The following output is produced when then code is run:
X={1,2,3,4}
Y={1,1,2,3,4}
Z=[1,1,2,3,4]
Main()
step WriteLine("X=" + X)
step WriteLine("Y=" + Y)
step WriteLine("Z=" + Z)
X={1,2,3,4}
Y={1,2,3,4}
Z=[1,1,2,3,4]
Curly braces {}
denote sets so they are simplified on assignment.
Bubble Sort in ASML
To complete a bubble sort in ASML you can use the following code:
var A as Seq of Integer
swap()
choose i in {0..length(A)-1}, j in {0..length(A)-1} where i < j and A(i) > A(j)
A(j) := A(i) # these happen as one atomic operation as there is no `step` keyword
A(i) := A(j) # as a result this swaps the variables
sort()
step until fixpoint # fixpoint is true when no data changes
swap()
Main()
step A := [-4, 6, 9, 0, 2, -12, 7, 3, 5, 6] # test list hard-coded
step WriteLine("Sequence A:")
step sort()
step WriteLine("after sorting:" + A")
Quick-Sort in ASML
To complete a quick-sort, with left had pivot, in ASML you would use the following code:
qsort(s as Seq of Integer) as Seq of Integer # takes a Seq of Integer and returns a Seq of Integer
if s = [] then
return [] # base case
else pivot = Head(s) # recursive step, head as pivot
rest = Tail (s)
# return less than pivot, pivot and greater than/equal to pivot
return qsort([y | y in rest where y < pivot]) + [pivot] + qsort([y | y in rest where y ≥ pivot])
Main()
WriteLine(qsort([7, 8, 2, 42])) # test list hard-coded
Formal specification is part of a more general collection of techniques that are know as formal methods.
Formal methods are all base on the mathematical representation and analysis of software.
Formal methods include:
- Formal Specification
- Specification Analysis & Proof
- Transformational Development
- Program Verification
Formal methods aren’t really used as they are more useful for assembly language programs with limited software testing and tools.
Formal methods have not become mainstream in software development techniques:
- Other software engineering techniques can produce quality systems.
- Formal methods don’t reduce time to market.
- The scope of formal methods is limited.
- Formal methods are had to scale up to large systems.
Formal methods are used to reduce the number of errors in systems. This makes them very applicable to critical systems.
Formal methods are most effective when you want to make systems that are completely error free and may not have means to update systems regularly.
Specification Techniques
There are two main specification techniques:
The formal specification involves investing more effoer in teh early phases of software development.
This reduces requirement errors as it forces a detailed analysis of the requirements.
Incompleteness and inconsistencies can be discovered and resolved reducing the amount of rework due to issues.
Critical systems development usually follows the waterfall model as we won’t be reworking the code:
- The system requirement and design are expressed in detail.
- They are unambiguous and carefully analysed before implementation.
Interface Specification
This is an algebraic formal specification approach. Where large system are decomposed into subsystems with well-defined interfaces:
- Allows independent development of each subsystem.
- Interfaces may be defined as abstract data types or object classes
Sub-System Interface Specification
Sub-system interface specification should be clear and unambiguous to reduce the change of misunderstanding between a provider and user of a sub-system:
- The algebraic approach to specification was originally developed for the definition of abstract data types.
- This idea was then extended to model complete system specifications
flowchart
subgraph Subsystem A
a1
a2
a3
end
subgraph Subsystem B
b1
b2
b3
end
a1 <--> b1
a1 --> b2
b3 --> a2
b2 --> a3
Algebraic Specification
An algebraic specification is defined as below:
<SPECIFICATION NAME>(Generic Parameter) |
sort <name> imports <LIST OF SPECIFICATION NAMES> |
Informal description of the sort and its operations. |
Operation signatures setting out the names and the types of the parameter to the operations defies over the sort . |
Axioms defining the opertions over the sort . |
The parts are defined as follows:
- Introduction - Declares the sort (the type name) of the entity being specified (a set of objects with common characteristics). It also imports other specifications to use.
- Description - An informal description of the operations to aid understanding.
- Signature - Defines the syntax of the interface to the abstract data type (object), including their names, parameter list and return types.
- Axioms - Defines the semantics of the operations by defining axioms characterising the behaviour.
Algebraic Specification of a List
We want to define the data type of a list. This would be represented as such:
List |
List(Elem) sort List imports INTEGER |
Defines a list where elements are added at the end and removed from the front. The operations are Create, which brings an empty list into existence, Cons, which creates a new list with an added member, Length, which evaluates the list size, Head, which evaluates the list size, Head, which evaluates the front element of the list and Tail, which creates a list by removing the head from its input list. |
Create $\rightarrow$ List |
Cons(List, Elem) $\rightarrow$ List Head(List) $\rightarrow$ Elem Length(List) $\rightarrow$ Integer Tail(List) $\rightarrow$ List |
Head(Create) = Undefined exception (empty list) Head(Cons(L, v)) = if L = Create then v else Head(L) Length(Create) = 0 Length(Cons(L, v)) = Length(L) + 1 Tail(Create) = Create Tail(Cons(L, v)) = if L = Create then Create else Cons(Tail(L), v) |
Algebraic Specification for Air Traffic Sector
We want to define the specification of a sector which contains several planes. The planes must be suitably separated:
Sector |
sort Sector imports INTEGER, BOOLEAN |
Enter - Adds an aircraft to the sector if safety conditions are satisfied. Leave - Remoes an aircraft from the sector. Move - Moves an aircraft from on height to another if safe to do so. Create - Creaes an empty sector Put - Adds an aircraft to a sector with no constraint checks InSpace - Checks if a specified height is available. |
Enter(Sector, CallSign, Height) $\rightarrow$ Sector Leave(Sector, CallSign) $\rightarrow$ Sector Move(Sector, CallSign, Height) $\rightarrow$ Sector Lookup(Sector, CallSign) $\rightarrow$ Height Create $\rightarrow$ Sector Put(Sector, CallSign, Height) $\rightarrow$ Sector InSpace(Sector, CallSign) $\rightarrow$ Boolean Occupied(Sector, Height) $\rightarrow$ Boolean |
Enter(S, CS, H) = if InSpace(S, CS) then S exception (Aircraft already in sector) elseif Occupied(S, H) then S exception (Height conflict) else Put(S, CS, H)
Leave(Create, CS) = Create exception (Aircraft not in sector) Leave(Put(S, CS1, H1), CS) = if CS = CS1 then S else Put(Leave(S, CS), CS1, H1)
Move(S, CS, H) = if S = Create then Create exception (No aircraft in sector) elseif not InSpace(S, CS) then S exception (Aircraft not in sector) elseif Occupied(S, H) then S exception (Aircraft not in sector) else Put(Leave(S, CS), CS, H) # NoHeight is a constant indicating that a valid height cannot be returned
Lookup(Create, CS) = NoHeight exception (Aircraft not in sector) Lookup(Put(S, CS1, H1), CS) = if CS = CS1 then H1 else Lookup(S, CS)
Occupied(Create, H) = false Occupied(Put(S, CS1, H1), H) = …
InSpace() … |
It is a good idea to implement basic functions such as Put
and Create
and then use those to implement other functions.
Classical Petri nets can have some problems:
- Petri nets can become too large and complex.
- It takes too long to model a situation.
- It is not possible to handle time or data.
High level Petri nets include the following to handle this:
Colour
Here is a standard example:
stateDiagram-v2
direction LR
state start <<fork>>
waiting(•••) --> start
note left of waiting(•••): Client waiting
state finish <<fork>>
start --> busy
busy --> finish
finish --> free(•)
free(•) --> start
finish --> finished
note right of free(•): Hairdresser waiting
Adding colour involves adding attributes to each token:
stateDiagram-v2
direction LR
state start <<fork>>
waiting(•••) --> start
note left of waiting(•••)
name: Sally
age: 28
hairtype: BL
end note
state finish <<fork>>
start --> busy
busy --> finish
finish --> free(•)
free(•) --> start
finish --> finished
note right of free(•)
name: Harry
age: 28
experience: 2
end note
Colour on Transitions
Transition can also have colour. This can involve:
- The number of tokens to be produced.
- The value of these tokens.
- Optionally, a precondition.
You can see a mathematical example here:
stateDiagram-v2
direction LR
state + <<join>>
a(•) --> +
b(•) --> +
+ --> c
note right of +
c: = a + b
end note
Here is a conditional example:
stateDiagram-v2
direction LR
state select <<fork>>
a(•) --> select
select --> b
select --> c
note left of select
if a > 0
then b: = a
else c: = a
fi
end note
Time
To analyse performance, we must model duration and delays.
A timed Petri net associates a pair $t_\min$ and $t_\max$ with each transition.
stateDiagram-v2
direction LR
state start <<fork>>
waiting(•••) --> start
state finish <<fork>>
start --> busy
busy --> finish
finish --> free(•)
free(•) --> start
note left of start
Tmin = 0
Tmax = 3
end note
note left of finish
Tmin = 5
Tmax = 10
end note
finish --> finished
We could be answered the following questions:
-
What is the minimum and maximum times for all three people to have their hair cut in this system?
\[\begin{aligned}
t_\min&=0 + 5 + 0 + 5=10\\
t_\max&=3 + 10 + 3 + 10 =26
\end{aligned}\]
-
What is the general formula for min and max times with $n$ clients and $m$ haridressers?
\[\lceil\frac n m\rceil(t_\text{start} +t_\text{end})\]
Hierarchy
This allows you to place a sub-nets in place of a transition:
stateDiagram-v2
direction LR
state h1 <<fork>>
state h3 {
direction LR
state start <<fork>>
state finish <<fork>>
[*] --> start
start --> busy
busy --> finish
finish --> [*]
finish --> free(•)
free(•) --> start
}
state h2 <<fork>>
waiting(••) --> h1
waiting(••) --> h2
waiting(••) --> h3
h1 --> ready
h2 --> ready
h3 --> ready
Example
Consider the following scenario that you have to model as a Petri net:
The message must be triplicated. The three copies must be forwarded through three different physical channels. The receiver accepts the message on the basis of a two-out-of-three voting policy.
stateDiagram-v2
[*] --> OriginalMessage
state f1 <<fork>>
state f2 <<fork>>
state f3 <<fork>>
state f4 <<fork>>
state j1 <<join>>
OriginalMessage --> f1
f1 --> Copy1
f1 --> Copy2
f1 --> Copy3
Copy1 --> f2
Copy2 --> f3
Copy3 --> f4
f2 --> P1
f3 --> P2
f4 --> P3
P1 --> j1
P2 --> j1
P3 --> j1
j1 --> [*]
note left of f1
Time to Split:
Tmin = c1
Tmax = k1
end note
note left of f2
Time to Send:
Tmin = c2
Tmax = k2
end note
note left of j1
Time to Vote:
Tmin = c3
Tmax = k3
end note
note right of j1
Tvoting: (P1=P2) or (P2=P3)
or (P1=P3) else "Error"
end note
From the above formal representation we can:
-
Analyse deadlock and live-lock states.
Live-lock are a set of states that aren’t useful in a loop.
-
Represent timing and other constraints.
Functional and non-functional requirements as well as stakeholders are covered in the lectures:
Business Rules
Buisness Rules Link a stake holder to a funciton:
Guests can request a booking, only receptioning can confirm booking.
This then can be used to create a use-case diagram.
Petri nets are often used for distributed systems and for systems with resource sharing.
Since there may be more than one transition in the Petri net active at a time and we don’t know which will fire first, they are non-deterministic.
There are certain additions to Petri nets which make them High-Level:
- Colour - For modelling attributes.
- Time - For performance analysis.
- Hierarchy - For the structuring of models, DFD’s.
Conditions
- A transition is only enabled if each of the input places contains tokens.
- Enabled transitions can fire.
- Firing consumes tokens from the inputs and produces tokens for the outputs according to the arcs.
Example Firing
This is a sequence of firings:
-
stateDiagram-v2
direction LR
state T1 <<fork>>
P1(•••) --> T1
T1 --> P2(•)
T1 --> P3(•)
P3(•) --> T1
-
stateDiagram-v2
direction LR
state T1 <<fork>>
P1(••) --> T1
T1 --> P2(••)
T1 --> P3(•)
P3(•) --> T1
-
stateDiagram-v2
direction LR
state T1 <<fork>>
P1(•) --> T1
T1 --> P2(•••)
T1 --> P3(•)
P3(•) --> T1
Creating & Consuming Tokens
A transitions without any input can fire at any time and produces tokens in all connected places:
-
stateDiagram-v2
direction LR
state T1 <<fork>>
T1 --> P1()
-
stateDiagram-v2
direction LR
state T1 <<fork>>
T1 --> P1(•)
-
stateDiagram-v2
direction LR
state T1 <<fork>>
T1 --> P1(••)
A transition without any output must be enabled to fire and deletes the incoming tokens:
-
stateDiagram-v2
direction LR
state T1 <<fork>>
P1(•••) --> T1
-
stateDiagram-v2
direction LR
state T1 <<fork>>
P1(••) --> T1
-
stateDiagram-v2
direction LR
state T1 <<fork>>
P1(•) --> T1
Non-Determinism
If two transitions fight for the same token there is a conflict. The next transition to fire $T1$ or $T2$ is non-deterministic:
stateDiagram-v2
direction LR
state T1 <<fork>>
state T2 <<fork>>
P1(•) --> T1
P1(•) --> T2
T1 --> P2
T2 --> P3
Even if there are two tokens, there is still conflict.
Modelling
- Tokens - Can represent resources, information, conditions, or states of objects.
- Places - Can represent buffers, channels, locations, conditions, or states.
- Transitions - Represent events, transformations or transportations.
Traffic Light Example
To begin we will model only one traffic light:
stateDiagram-v2
direction LR
state gy <<fork>>
state yr <<fork>>
state rg <<fork>>
Green --> gy
gy --> Amber
Amber --> yr
yr --> Red(•)
Red(•) --> rg
rg --> Green
Having two of this model would enable both sets of traffic lights to be green at the same time. To stop this we can make the following modification:
stateDiagram-v2
direction LR
state gy1 <<fork>>
state yr1 <<fork>>
state rg1 <<fork>>
Green1 --> gy1
gy1 --> Amber1
Amber1 --> yr1
yr1 --> Red1(•)
Red1(•) --> rg1
rg1 --> Green1
state gy2 <<fork>>
state yr2 <<fork>>
state rg2 <<fork>>
Green2 --> gy2
gy2 --> Amber2
Amber2 --> yr2
yr2 --> Red2(•)
Red2(•) --> rg2
rg2 --> Green2
yr1 --> Safe(•)
yr2 --> Safe(•)
Safe(•) --> rg2
Safe(•) --> rg1
This fires the two traffic lights in random order due to the conflict with Safe
. To make them change alternately we can use the following model:
stateDiagram-v2
direction LR
state gy1 <<fork>>
state yr1 <<fork>>
state rg1 <<fork>>
Green1 --> gy1
gy1 --> Amber1
Amber1 --> yr1
yr1 --> Red1(•)
Red1(•) --> rg1
rg1 --> Green1
state gy2 <<fork>>
state yr2 <<fork>>
state rg2 <<fork>>
Green2 --> gy2
gy2 --> Amber2
Amber2 --> yr2
yr2 --> Red2(•)
Red2(•) --> rg2
rg2 --> Green2
yr1 --> Safe1(•)
yr2 --> Safe2()
Safe1(•) --> rg2
Safe2() --> rg1
Definitions
- Current State (Marking) - The configuration of the tokens over the places.
- This is described by a tuple.
- Reachable State - A state reachable from the current state by firing a sequence of enabled transitions.
- Deadlock State - A state where no transition is enabled.
Examples
For the following graph:
stateDiagram-v2
direction LR
state br <<fork>>
state rr <<fork>>
state bb <<fork>>
Red(•••) --> rr:2
rr --> Black(••)
Black(••) --> bb:2
bb --> Black(••)
Black(••) --> br
br --> Red(•••)
Red(•••) --> br
This is because we are ordering the tuple (Red,Black)
and there are three tokens in Red
and two tokens in Black
.
We can also graph the reachable states and deadlock states in a tree:
flowchart LR
32["(3,2)"] -->|rr| 13
13["(1,3)"] -->|bb, br| 12["(1,2)"]
12 -->|bb, br| 11["(1,1)"]
11 -->|br| 10["(1,0)"]
32 -->|bb,br| 31["(3,1)"]
31 -->|rr| 12
31 -->|br| 30["(3,0)"]
30 -->|rr| 11
There are 7 reachable states and one deadlock state.
Reachable are those down stream from your current place and deadlock states are those with no transitions out.
Finite State Machines
Refer to notes on Deterministic Finite Automata (DFAs) for information about finite state machines.
There are several variant of finite state machines:
- Mealy Machines - Have actions (outputs) associated with transitions.
- Moore Machines - Have actions (outputs) associated with states.
- Nondeterministic Finite Automata (NFAs) & Epsilon-NFAs - Allow for multiple transitions with the same input and transitions with no cost.
Moore Machines
A more machine has the following additional attributes:
- It has two alphabets, an input and an output alphabet.
- It has an output letter associated with each state.
- The machine writes that appropriate output letter as it enters each state.
stateDiagram-v2
direction LR
[*] --> q0/1
q0/1 --> q1/0:a
q1/0 --> q1/0:b
q1/0 --> q3/1:a
q3/1 --> q2/0:b
q2/0 --> q3/1:b
q2/0 --> q0/1:a
q3/1 --> q3/1:a
q0/1 --> q3/1:b
Input: abab
Output: 10010
The states are named with there identifier: q0
and then their output: 0
with a slash inbetween.
To find this result we:
- Start at $q_0$, outputting 1.
- Transition via $a$ to $q_1$, outputting 0.
- Transition via $b$ to $q_1$, outputting 0.
- Transition via $a$ to $q_3$, outputting 1.
- Transition via $b$ to $q_2$, outputting 0.
Mealy Machines
These are computationally equivalent to Moore machines, however:
- Mealy machines output on the transition instead of the state.
stateDiagram-v2
direction LR
[*] --> 0
0 --> 1:a/0
1 --> 3:a/1
0 --> 3:b/0
1 --> 2:b/1
2 --> 3:a/0
3 --> 0:b/1
2 --> 3:b/1
3 --> 3:a/1
Input: aaabb
Output: 01110
The transitions are identified $i/j$ where $i$ is the input and $j$ is the output.
- Mealy machines are complete as there is a transition for each character in the input alphabet leaving every state.
- There are no accept states in a Mealy machine as is it not a language recogniser.
- It only outputs and its output will be the same length as its input.
Petri Net Models
Petri nets are a collection of directed arcs connecting places and transitions:
- Places may hold tokens.
- The state/marking of a net is its assignment of tokens to places.
Petri nets are non-deterministic so they can be used to model discrete distributed systems.
stateDiagram-v2
direction LR
state f1 <<fork>>
P1(•) --> f1
f1 --> P2
note right of f1: Transition
The tokens are represented by the number of •
after the place name.
Capacity
- Arcs have capacity 1 by default but this can be marked on the arc.
- Places have infinite capacity by default.
- Transitions have no capacity and can’t store tokens.
Enabled Transitions & Firing
A transition is enabled when the number of tokens in each of its input places is at least equal to the arc weight going from the place to the transition:
- An enabled transition may fire at any time.
stateDiagram-v2
state T1 <<fork>>
P1(•) --> T1
P2(•) --> T1
T1 --> P3
T1 --> P4
T1 --> P5
note left of T1: Enabled, ready to fire.
stateDiagram-v2
state T1 <<fork>>
P1 --> T1
P2 --> T1
T1 --> P3(•)
T1 --> P4(•)
T1 --> P5(•)
note left of T1: Firing complete.
Arcs of Different Weights
When fired the tokens in the input places are consumed and are then generated in the output places in accordance with the arc weights:
- This results in a new marking of the net, a state description of all places.
stateDiagram-v2
state T1 <<fork>>
P1(••) --> T1:2
P2(•) --> T1
T1 --> P3
T1 --> P4:2
T1 --> P5:3
stateDiagram-v2
state T1 <<fork>>
P1 --> T1:2
P2 --> T1
T1 --> P3(•)
T1 --> P4(••):2
T1 --> P5(•••):3
Inhibition
A circle arrow head on an arc means that there is an inhibition. I am representing this like so:
stateDiagram-v2
direction LR
state T1 <<fork>>
P1(•) --> T1:O
T1 --> P2
The following applies when there is no weighting on the arc joining the place to a transition:
An inhibitor arc imposes the precondition that the transition may only fire when the place is empty. - Wikipedia
The following is a generalisation that applies to all weightings:
An inhibitor arc drawn from place to a transition means that the transition cannot fire if the corresponding inhibitor place contains at least as many tokens as the cardinality of the corresponding inhibitor arc. - Stochastic Processes
This means that a transition cannot fire if $T \geq C$, where $T$ is the number of tokens and $C$ is the cardinality of the inhibiting arc.
For example the following Petri net will transition into the next one:
-
stateDiagram-v2
direction LR
state RE <<fork>>
state DE <<fork>>
state PE <<fork>>
state SE <<fork>>
note left of PE: Prepare Email
note left of SE: Send Email
note left of DE: Download Email
note left of RE: Read Email
P1(•) --> SE
SE --> P3(••)
P3(••) --> SE:4, Inhibit
SE --> P2
P2 --> PE
PE --> P1(•)
P3(••) --> DE
DE --> P4
P4 --> RE
RE --> P5
P5 --> DE
-
stateDiagram-v2
direction LR
state RE <<fork>>
state DE <<fork>>
state PE <<fork>>
state SE <<fork>>
note left of PE: Prepare Email
note left of SE: Send Email
note left of DE: Download Email
note left of RE: Read Email
P1 --> SE
SE --> P3(•••)
P3(•••) --> SE:4, Inhibit
SE --> P2(•)
P2(•) --> PE
PE --> P1
P3(•••) --> DE
DE --> P4
P4 --> RE
RE --> P5
P5 --> DE
This example is non-functional as there are no tokens on the reading side. The buffer $P3$ will quickly become full.
I presume that no tokens are used when firing on a weighted, inhibited arc; but I can find no examples of this action.
Primitive Structures
There are several primitive structures that apply to real systems:
-
Sequence
stateDiagram-v2
direction LR
state T1 <<fork>>
state T2 <<fork>>
P1(•) --> T1
T1 --> P2
P2 --> T2
T2 --> P3
-
Conflict
stateDiagram-v2
state T1 <<fork>>
state T2 <<fork>>
state T3 <<fork>>
P1(•) --> T1
P1(•) --> T2
P1(•) --> T3
-
Concurrency
stateDiagram-v2
state T1 <<fork>>
state T2 <<fork>>
state T3 <<fork>>
state T4 <<fork>>
T1 --> P1(•)
T1 --> P2(•)
T1 --> P3(•)
P1(•) --> T2
P2(•) --> T3
P3(•) --> T4
-
Synchronisation
stateDiagram-v2
state T1 <<join>>
P1(•) --> T1
P2(•) --> T1
P3(•) --> T1
T1 --> P4
-
Confusion
stateDiagram-v2
state T1 <<fork>>
state T2 <<fork>>
state T3 <<fork>>
P1(•) --> T1
P1(•) --> T2
P2(•) --> T2
P2(•) --> T3
-
Merging
stateDiagram-v2
state T1 <<fork>>
state T2 <<fork>>
state T3 <<fork>>
state T4 <<fork>>
T1 --> P1(•)
T2 --> P1(•)
T3 --> P1(•)
P1(•) --> T4
-
Priority/Inhibit
stateDiagram-v2
state T1 <<fork>>
state T2 <<join>>
P1(•) --> T1
P1(•) --> T2
P2(•) --> T2:O
Semantic Data Models
These are used to describe the logical structure of data processed by the system.
- Entity-relation-attribute models are a type of semantic data model.
- No specific notation is provided but class diagrams are the most similar structure.
classDiagram
direction LR
class Design {
name
description
C-date
M-date
}
class Link {
name
type
}
class Label {
name
text
icon
}
class Node {
name
type
}
Design "1" --|> "n" Link: has-links
Design "1" --|> "n" Node: has-nodes
Node "1" --|> "1" Design: is-a
Link "1" --|> "2" Node: links
Node "1" --|> "n" Link: has-links
Node "1" --|> "n" Label: has-labels
Link "1" --|> "n" Label: has-labels
Data Dictionaries
Data dictionaries are a list of all the names in a system model:
- Descriptions of the entities, relationships and attributes are also included.
- It may be used for name management so that all names used in a system are consistent and do not clash.
- It serves as a store or organisational information so that all data is stored in one location.
Name |
Description |
Type |
Date |
has-labels |
1:N relation between entities of type Node or Link and entities of type Label. |
Relation |
5/10/1998 |
Label |
Holds structured or unstructured information about nodes or links. Labels are represented by an icon (which can be a transparent box) and associated text. |
Entity |
8/12/1998 |
name (label) |
Each label has a name which identifies the type of label. The name must be unique within the set of label types used in a design. |
Attribute |
8/12/1988 |
$\vdots$ |
$\vdots$ |
$\vdots$ |
$\vdots$ |
Object Models
Object models describe the system in terms of object classes.
Unified Modelling Language
Allows for clear representations of the structures in object-oriented languages. This will be covered later and has been partially covered in COMP122 - Subclasses.
System models are abstract descriptions of systems. They explain the details of a system in a more technical way.
- System representations maintain all the information of a system.
- A system abstraction deliberately simplifies the system and picks the most important characteristics.
System Model Weaknesses
There are several weaknesses of system models:
- They do not model non-functional requirements
- They do not usually include information about whether a method is appropriate for a given problem.
- They may produce to much documentation.
- They are sometime too detailed and difficult to read to be useful.
Class Diagram
Here is an example of a class diagram:
classDiagram
direction LR
CourseOffering "0..*" -- "1..1" Professor: teaches
CourseOffering "0..*" -- "0..*" Student: takes
Student --|> Person: extends
Professor --|> Person: extends
class CourseOffering{
-int sectionNo
-Course course
-Professor instructor
-String schedule
-String location
-int maxEnrollment
-int enrollment
-Set prerequisites
+CourseOffering()
+setSectionNo() void
+setCourse() void
+setInstructor() void
+setSchedule() void
+setLocation() void
+setMaxEnrollment() void
+get...()
+calcAvailable() int
}
class Student{
-String major
-String classStanding
-float graph
+setMajor() void
+setClassStanding() void
+computeGpa void
}
class Professor{
-String rank
-Date tenureDate
-String department
+Professor()
+setRank() void
+setTenureDate() void
+getRank() String
+getTenureDate() Date
+getDepartment() String
}
class Person{
#String name
#String ssn
#Date dob
#Person spouse
#Set children
+Person()
+setName() void
+setSsn() void
+setDob() void
+setSpouse() void
+setChildren() Set
+getName() String
+getSsn() String
+getDob() Date
+getSpouse() Person
+getChildren() Set
+getAge() int
}
The information in this diagram would be significantly harder to explain in natural language.
Model Types
The following models have their own respective purposes:
- Data Processing Model - Showing how that data is processed at different stages.
- Composition Model - Showing how entities are composed of other entities.
- Architectural Model - Showing principle sub-systems and relationships with other systems.
- Classification Model - Showing how entities have common characteristics.
- Stimulus/Response Model - Showing the system’s reaction to events.
- Context Models - Are used to illustrate the boundaries of a system.
- Social and organisation concerns may affect the decision on where to position system boundaries.
Architectural Model of an ATM System
@startwbs
* ATM System
** Security System
** Account Database
** Usage Database
** Maintenance System
** Branch Counter System
** Branch Accounting System
@endwbs
Process Models
There are several different types of data processing models:
- Process Models - Show the overall process and the processes that are supported by the system.
- In process models it is implicit one process is completed before another process begins.
- Process models are similar to flow charts.
- Data Flow Models - Are used to show the processes and the flow of information from one process to another.
- In data flow models it is implicit that processes will happen in parallel.
Example Process Model
This is an example of the equipment procurement process:
flowchart
1[Specify Equipment Required] -->|Equipment Spec| 2[Validate Specification] & 3[Find Suppliers]
4[(Supplier Database)] --> 3
3 -->|Supplier List| 5[Get Cost Estimates]
2 -->|Checked Spec| 5
5 -->|Spec, Suppliers & Estimate| 6[Choose Supplier]
6 -->|Order Details & Bank Order Form| 7[Place Equipment Order]
7 -->|Checked & Signed Order Form| 8[ ]
7 -->|Order Notification| 9[Accept Delivery of Equipment]
10[ ] -->|Delivery Note| 9
9 -->|Delivery Note| 11[Check Delivered Items]
11 -->|Installation Instructions| 12[Install Equipment]
12 -->|Installation Acceptance| 13[Accept Delivered Equipment]
13 -->|Equiptment Details| 14[(Equipment Database)]
subgraph System Boundary
3
4
5
6
7
9
end
Behavioural Models
These are used to describe the overall behaviour of the system. There are two types of behavioural model:
- Data Processing Models - Show how data is processed as it moves through the system.
- State Machine Models - Show the systems response to events.
Both of these models are required for a description of the system’s behaviour.
Data-Processing Models
Data flow diagrams are used to model the system’s data processing. These show the processing steps as data flows through a system. They should:
- Be simple and intuitive to understand.
- Show end-to-end processing os data.
This is part of many analysis methods.
Data flow diagrams can also used to show data exchange between a system and other systems in its environment.
Data flow diagrams show a functional perspective where each transformation represents a single function or process. This is useful for requirements analysis as it shows end-to-end processing.
Example Data Flow Diagram
This is an example of order processing:
flowchart
1[ ] -->|Order Details & Bank Order Form| 2[Complete Order Form]
2 -->|Completed Order Form| 3[Validate Order]
3 -->|Signed Order Form| 4[Record Order]
4 -->|Order Details| 5([Orders File])
4 -->|Signed Order Form| 6[Send to Supplier]
4 -->|Signed Order Form| 7[Adjust Available Budget]
6 -->|Checked and Signed Order & Order Notification| 8[ ]
7 -->|Order Amount & Account Details| 9([Budget File])
Example Data Flow Diagram (DFD) Context Diagram
flowchart LR
dmc((Drinks Machine Controller)) .->|"Heating Element (on/off)"| hws[Hot Water System]
dmc .->|"Hot Water Valve (open/close)"| hws
hws ==>|Hot Water Temperature| dmc
dmc .->|"Holding Vessel Valve (open/close)"| hv[Holding Vessel]
csm[Coin Sense Mechanism] -->|Coin Codes| dmc
dmc .->|"Stirrer (on/off)"| s[Stirrer]
dmc -->|Service Request| Modem
dmc -->|Pricing, Availability and Service Information| ad[Alphanumeric Display]
dmc .->|"Cup Solenoid (on/off)"| pcm[Paper Cup Mechanism]
pcm .->|Cup in Place| dmc
nkp[Numeric Key Pad] -->|Key Codes & Drink Choice| dmc
dih[Dried Ingredients Hopper] .->|Hopper Low Signal| dmc
dmc .->|"Hopper (on/off)"| dih
The hot water temperature (in bold) is a continuous input. It should have a double arrowhead but I can’t do that.
- Solid lines are information flows.
- Dotted lines are control flows.
- Double arrow heads are continuous data.
- Single arrow heads are discrete data.
Level 0 DFD
This is the top level that represents all the systems in the machine:
flowchart
1[ ] ==>|Hot Water Temperature| tc((Temperature Control))
tc .->|"Hot Water Element (on/off)"| 2[ ]
3[ ] .->|"Service Door (open/closed)"| oc((Operation Control))
cm[Coin Mechanism] -->|Coin Codes| oc
mdc((Make Drinks Control)) .->|Drink Made Status| oc
5[ ] .->|Cup in Place?| mdc
dr[(Drink Recipes)] -->|Recipe Data| mdc
oc -->|Drink Code| mdc
mdc .->|"Cup Solenoid (on/off)"| 4[ ]
mdc .->|"Hopper Motors (on/off)"| 6[ ]
mdc .->|"Hot Water Valve (on/off)"| 7[ ]
mdc .->|Holding Vessel Control| 8[ ]
mdc -->|Drink Sales Data| sl[(Sales Log)]
sl -->|Sales Data| mmc((Maintenance Mode Control))
oc .->|"(on/off)"| mmc
oc --> |Engineering Codes| mmc
kp[Key Pad] -->|Key Codes| oc
sl -->|Sales Data| csr
Hoppers .->|Hopper Low?| oc & csr((Control Service Request))
oc -->|Price & Availability| ad[Alpha Display]
csr -->|Service Data| Modem
Level 1 DFD - Operation Control
A level 1 DFD explores a discrete system from the level 0 DFD:
flowchart
1[ ] .->|"Service Door (closed/open)"| cmm((Control Maintenance Mode))
kp[Key Pad] -->|Key Codes| pkc((Process Key Codes))
cm[Coin Mechanism] -->|Coin Codes| cmr((Coin Mechanism Reader))
pkc .->|Password Received| cmm
pkc -->|Echo Key Codes| ad[Alpha Display]
pkc -->|Drink Code| dac
dac -->|Product Information & Availability| ad
dac -->|Available Drink Code| ddc((Drink Dispense Control))
ddc -->|Prompt for Payment| ad
cmr -->|Credit Update| cs[(Credit Store)]
cs -->|Current Credit| cmr
cs -->|Current Credit| ddc
Hoppers .->|Hopper Low?| dac((Drink Availability Checker))
dr[(Drink Recipes)] -->|Drink Data| dac
cmm .->|"Maintenance Mode (enable/disable)"| 3[ ]
ddc -->|Paid For Drink Code| dq[(Drink Queue)]
dq -->|Paid For Drink Code| 5[ ]
pkc -->|Engineering Codes| 2[ ]
State Machine Models
State machine models, also called state chart diagrams, show the behaviour of the system in response to external and internal events.
- State-charts allows the decomposition of a model into sub-models.
- A brief description of the action is required. (
Do
is optional).
- Can be complemented by table describing the states and stimuli.
There are some additional hints for state machines:
- All states need an exit.
- Use an
Idle
state to show when the process isn’t active.
- You don’t need to have a state chart as a sub-state of another state chart.
- The system can be described by multiple state machines running concurrently.
- Use multiple state charts to keep the design simple.
Example State Machine Model
stateDiagram-v2
state "do: Display Time" as w
state "do: Set power = 600" as fp
state "do: Set power = 300" as hp
state "do: get number, exit: set time" as st
state "do: Display 'Waiting'" as d
state "do: Display 'Ready'" as e
state "do: Operate Oven" as o
[*] --> w
w --> fp:Full Power
w --> hp:Half Power
fp --> hp:Half Power
hp --> fp:Full Power
fp --> st:Timer
hp --> st:Timer
st --> st:Number
st --> d:Door Open
st --> e:Door Closed
d --> e:Door Closed
e --> o:Start
o --> d:Door Open
o --> w:Cancel, Done
A state machine model does not show flow of data within the system.
This state graph has the associated stimuli table:
Stimulus |
Description |
Half Power |
The user has pressed the half power button. |
Full Power |
The use has pressed the full power button. |
Timer |
The user has pressed one of the timer buttons. |
Number |
Ther user has pressed a numeric key. |
Door Open |
The oven door switch is not close. |
Door Closed |
The oven door switch is closed. |
Start |
The user has pressed the start button. |
Cancel |
The user has pressed the cancel button. |
State Diagram with Composite States
This diagram makes use of a couple of additional features:
- Guard - On the arrows. Ensures that the system only moves from one state to the other if the expression is satisfied.
- This can be a method as shown on this example.
- Composite Sates - This is a state sub-diagram that models the states of a state.
stateDiagram-v2
ErrorState: printError()
SubsystemChecking: performCheck()
ErrorFound: printError()
state Running {
[*] --> SystemOff
SystemOff --> SystemOn: initiate() [canStart]
SystemOff --> ErrorState: initate() [cannotStart]
ErrorState --> [*]
}
state Maintenance {
SubsystemChecking --> ErrorFound: errorReturned()
}
Running --> Maintenance: checkSystem() [notRunning]
Maintenance --> Running: printCheckReport()
Actions
You can put actions after the event using a /
:
stateDiagram-v2
direction LR
OutOfInk --> Idle: Ink Available/Clear Display
Idle --> OutOfInk: Ink Low/Show Error Message
Finite State Machines
Refer to notes on Deterministic Finite Automata (DFAs) for information about finite state machines.
Security is required in computer systems as they often handle money and customer data. Having these exposed could have costly repercussions to a company.
You can break down the security requirements of a system into the following issues:
- Confidentiality
- Integrity
- Authentication & Authorisation
- Non-repudiation
Availability can also be a requirement of secure systems.
Confidentiality
There are usually two main options:
- Encryption (Hard security)
- Permissions (Soft security)
Data must be kept secure in the following circumstances:
- In storage (final or intermediary).
- On the wire or wireless link.
- For as long as reasonably possible.
- Should depend on the circumstances.
Integrity
Messages or data must not be modifiable without knowledge of the change. There are several approaches:
- CRC checking (not good for security).
- Hash value of data (can be recomputed).
- Hash value over data + secret value.
- Key must be distributed to the recipient.
- Hash value encrypted using asymmetric cipher.
Authentication & Authorisation
- Authentication - Identifying a user.
- Authorisation - Permissions on the system.
You can use usernames, passwords, hardware keys & bio-metrics to confirm authentication.
This if often the first point of attack.
Non-Repudiation
This is when you are sending messages but you want to prove at a later date and time, what the message was and when it was sent.
This often requires:
- A trusted broker.
- Messages are sent to a third party server and then forwarded to the recipient.
- Funding is escrow.
- Allows money to be stored until the transaction is complete.
This is built upon:
- Authentication
- Integrity
- Recording a time stamping.
- Via a trusted third party server.
- Broker style services.
Availability
We specify this in the “9s” terminology:
Up-time |
Max Downtime |
99.9999% |
31.5s per year |
99.999% |
5m35s per year |
99.99% |
52m33s per year |
Most high availability systems aim for five 9s.
Precise Availability
Having a system with a certain number of nines needs to have precise specifications in order to be useful. We should specify:
- Worst case scenarios.
- How long the system can be down at a time in the worst case.
- Worst case delay as well as down time.
- Ho the system can degrade gracefully.
- Notice of downtime for planned maintenance.
Logs & Alerts
Security is dependent on the knowledge of activity. We could have the following types of log:
- Standard Log - Records all logins/logouts, database access requests.
- Failed Login Log - Records all failed logins.
- Unusual Activity Log - High volume of transations on account.
- Alert Log - Failed logins for top level clearance users.
Alerts can be used to track unusual activity and alert operators, suspend accounts and more.
Bell La-Padula Model
All items are given a security clearance:
- Unclassified
- Sensitive
- Secret
- Top-Secret
There are also the following restrictions:
- No Read-Up - A subject cannot read a document above their clearance level.
- No Write-Down - A document cannot be copied/included in another document with lower security clearance.
- Trusted Subjects:
- Can write documents down.
- Must be shown trustworthy with regard to the security policy.
Specifying Security
Ideally security policies should be kept open to allow for upgrading of algorithms and protocols.
The security policy could also include:
- Shredding Documents
- Secure Disposal
- Password Reset Protocols
- Security Training
- Security Audits
You should also bear in mind standards compliance:
- Payment Card Industry Data Security Standard - For card details
Requirements Checking
- Validity - Does the system provide the function which best support the customer’s needs?
- Consistency - Are the any requirement conflicts?
- Completeness - Are all functions required by the customer?
- Realism - Can the requirements be implemented given available budget and technology?
- Verifiability - Can the requirements be tested.?
Scenarios
These are test cases running against a given situation.
They are useful as they show the developer by example what will happen given certain conditions.
Agile Requirements - Cucumber
This is a software tool used to help write requirement which are linked directly to tests.
Cucumber uses a language called gherkin to describe features:
Feature: Login
In order To probe who I am
As a customer
I want to be able to login to the system
Scenario: Login with test account1
Given I have entered a username of account1
And I have entered a password of pass1234
When I click login
Then the result should be login successful
- The
Feature:
is not parted but describes a feature to a developer.
- The
Scenario:
is an example by also is linked to test code.
This is linked to the following test code:
public class LoginSteps {
@Given("^I have entered a username of account(\\d+)$")
public void i_have_entered_a_username_of_account(int arg1) throws Throwable {
throw new PendingException();
}
@Given("^I have entered a password of pass(\\d+)$")
public void i_have_entered_a_password_of_pass(int arg1) throws Throwable {
throw new PendingException();
}
@When("^I click login$")
public void i_click_login() throws Throwable {
throw new PendingException();
}
@Then("^The result should be login succesful$")
public void the_result_should_be_login_succesful() throws Throwable {
throw new PendingException();
}
}
Cucumber has the following advantages:
- Gives simple and clear notation to write a specification.
- Analyst and test teams can learn Gherkin and develop feature files.
- Step files are produced by the development team.
- Test data can be change later without changing the test code.
This tutorial had the aim of recaping the various features of Java. You should revise the built in methods and classes from the Java
package and also recap use of Thread
.
Final
- Final Classes - Cannot be extended.
- Final Methods - Cannot be overridden.
- Final Reference Variable & Fields - A variable that is set forever and cannot change.
Private
Only visible from within the class and not from any other class (including sub-classes).
Other instances of the same class can see private members.
Packages
Packages are the highest level of container in Java. Packages can contain:
- Sub-packages
- Classes
- Interfaces
See geeks for geeks to find out more about packages.
Packages are compiled into a folder hierarchy. This allows you to sort re-usable code and reduces name collision.
You can create the hierarchy in code like so:
package pack;
public class A {
void method1{
}
}
Review Questions
The questions for this section are titled: Workshop Seminar 1
- The major problem with large scale systems is code complexity. This could be lines of code or complexity of algorithms.
-
The maximum number of interactions between lines of code are:
\[\frac{N(N-1)}2\]
- Functions, procedures and methods help in reducing the number of interactions between lines of code
- By limiting the access of certain code and variables you are able to further reduce complexity. For example, only code inside a class can access data and methods inside it (unless it is
public
). As only public
and protected
methods are accessible from outside the class, this reduces entry points and thus complexity.
- To see the main features of software processes see Software Processes.
- Software specification is the process of establishing what services are requires and the constraints on the system’s operation and development whereas software design realises the specification.
- Testing should be based on the specification. Each point of the specification should form the basis of a test.
- Scrum Terms
- Product Back-log - This is the list of remaining features that have not been completed and tested.
- Daily SCRUM - A morning 15 minute meeting with three questions:
- What did I complete yesteday?
- What do I hope to do today?
- What will stop me from completing today’s tasks?
- SCRUM Master - This is the project manager. Their job is to plan and remove obstacles from the development process.
- Sprint - One iteration of development where the team produces and tests a new version of the product with added features.
- Time Box - A time limit for a particular activity.
- Stakeholders - Individuals who are affected by the production of the software.
- Sprint Burndown - A show of progress in the project so we can see if we are ahead or behind schedule.
- Sprint Backlog - Features that are committed to sprint but not yet completed and tested.
- Sprint Planning - A meeting before a sprint to determine what features to complete in the next sprint.
- Inventory loss describes features that are implemented but not useful to the final product.
This lecture is very similar to COMP107 - Requirement Elicitation.
The enginerring process goes as follows:
- Requirement elicitation - What services does the end-user require?
- Requirements analysis - How to we classify, prioritise and negotiate requirements?
- Requirements validation - Does the proposed system do what the users require?
- Requirements management - How do we manage the changes to the requirements document?
Feasibility Study
This decides whether the proposed system is worthwhile. It checks if:
- The system contributes to organisational objectives.
- The system can be engineered using current technology and within budget.
- The system can be integrated with other systems that are used.
- There is a simpler way of doing this.
- Buy in software and customise.
Elicitation & Analysis
This involves the technical staff working with customers to find out the application domain, the services that the system should provide and the system’s operation constraints.
This will involve stakeholders such as:
- End-users
- Managers
- Maintenance Engineers
- Domain Experts
- Trade Unions
These different stake holders will often have conflicting and non-specific requirements.
Requirements Discovery
This is the process of gathering information about the proposed and existing systems. These requirements often come from:
- Similar systems.
- Existing systems to be improved.
- Competitor’s systems.
You can also discover requirements from prototypes.
Viewpoint Identification
Viewpoints are a way of structuring the requirements to represent the perspectives of different stakeholders.
Stakeholders may be classified under different viewpoints.
Interviewing
This involves the requirement elicitation team putting questions to stakeholders about the system. You can ask questions in the following ways:
- Closed interviews - A predefined set of questions are answered.
- Open interviews - There is no pre-defined agenda and a range of issues are explored with stakeholders.
Ethnography
This is the practice of observing workers in order to find out how they complete their work.
People don’t have to explain what they are doing.
Focused Ethnography
This is a combination of ethnography and prototyping. This may answer questions that may never have been asked.
There is an issue that you are studying existing practices which may no longer be relevant.
User Requirements
These are statements in natural language plus diagrams of services the system provides and its operational constraints.
This is written for customers.
System Requirements
A structured document setting out detailed descriptions of system services.
This can be used as a written contract between client and contractor.
Software Specification
A detailed software description which can serve as a basis for a design or implementation.
This is written for the developers.
Example
User requirement
- We need to be able to spell check documents
System requirement
- The system needs to be able to spell check documents and provide auto-correct facilities. Their will be support for the following languages, English, French and German will have plug in support for other languages.
Software specification
CheckResult
spellCheck(String word, Dictionary dictionary)
- Word is defined in UNICODE formatted string
- The Dictionary structure is defined in S.1.2
- The
CheckResult
is defined in S.1.3 and contains a flag if the word has been found or not, plus a Vector object containing a list of possible other word suggestions depending if the word has been found or not
spellCheck
will ideally use Hashing tables to improve code efficiency
- ……
Types of Requirements
Functional requirements - Statements of services the system should provide, how the system should react to particular inputs and how the system should behave in particular situations.
Non-functional requirements - Constraints of the services or functions offered by the system such as timing constraints and standards to be used:
These are usually defined on the system as a whole.
Domain Requirements - Come from the application domain of the system and reflect characteristics of that domain.
Product Requirements - Specify how the product must behave.
Organisational Requirements - A consequence of organisational policies and procedures.
External Requirements - Arise from factors external to the system such as legislation and interoperability requirements.
Completeness & Consistency
Requirements should be both complete and consistent:
- Complete - Should include descriptions of all facilities required.
- Consistent - There should be no conflicts in the descriptions of the system facilities.
Goals vs Requirements
A goal is a general intention of the user such as ease of use.
Goals are helpful to developers as they convey the intentions of the system users.
Requirement Measures
Verifiable non-functional requirements are a pass/fail test for a particular goal.
Example
Property |
Measure |
Speeed |
Processed transactions/second, User/event response time; screen refresh time. |
Requirements Engineering & Specification
Software specification is the process of establishing what services are requires and the constraints on the system’s operation and development.
Requirements Engineering Process
flowchart LR
fs([Feasibility Study]) --> re([Requirements Elicitation & Analysis]) <--> rs([Requirements Specification]) <--> rv([Requirements Validation])
fs --> fr[Feasibility Report]
re --> sm[System Models]
rs --> usr[User & System Requirements]
sm --> rd[Requirements Document]
usr --> rd
Software Design & Implementation
This is the process of converting the system specification into an executable system. This includes:
- Software Design
- Design a software structure that realises the specification.
- There are many tasks that comprise this section.
- Implementation
- Translate this structure into an executable program.
Design and implementation are closely related and may be inter-leaved.
Design Process Activities
- Architectural Design (Separating web service modules)
- Sub-systems making up the ystem and their relationships are identified and documented.
- Abstract Specification
- For each sub-system, an abstract specification of its operation constraints and services is produces.
- Interface Design
- For each sub-system, an unambiguous interface with other sub-systems is designed and documented.
- Components Design
- Services are allocated to components and the interfaces of these components are desgned.
- Data Structure Design
- The data structures used in the system implementation are designed in detail and specified.
- Algorithm Design
- The algorithms used in components to provide services are designed and specified.
Design Methods
Design methods are systematic approaches to developing a software design. This design is usually documented as a set of graphical models.
You could use the following types of model:
- Data-flow
- Entity relation attribute model.
- Structural Model
- Object Models
- State Transition Model (Showing system states and triggers)
Programming & Debugging
Programming should be an iterative activity where small pieces are written and testing is completed.
Testing
flowchart LR
ut[Unit Testing] <--> mt[Module Testing] <--> st[Sub-system Testing] <--> sst[System Testing] <--> at[Acceptance Testing]
subgraph Component Testing
ut
mt
end
subgraph Integration Testing
st
sst
end
subgraph User Testing
at
end
The prior stages are described as:
- Unit Testing - Individual components are tested.
- Module Testing - Related collections of dependent components are tested.
- Testing class integration.
- Sub-system Testing - Modules are integrated into sub-systems and tested. The focus here should be on interface testing.
- Testing classes as a service. An organised package or JAR library.
- System Testing - Testing of the system as a while. Testing of emergent properties.
- Acceptance Testing - Testing with customer data to check that it is acceptable.
When you are completing a process you need to separate the process into individual tasks. These tasks can include planning, execution, testing and review.
A process is a sequence of steps to accomplish a set of tasks.
Characteristics
Any process has the following characteristics:
- It prescribes all of the major activities.
- I uses resources and produces intermediate and final products.
- It may include sub-processes and has entry and exit criteria.
- The activities are organised in a sequence.
- Constraints or controls may apply to activities.
- Budget, availability of resources…
Life Cycle
The process of building a software product is called the software life cycle. This includes:
- Specifying
- Designing
- Implementing
- Testing
Similarities & Differences with Other Engineering
- Software can be changed at anytime.
- Is often required to change after construction.
- Software can be improved almost without limit.
- Software often gets faults as it evolves.
- Software is hard to manage.
- Issues with the user’s experience and expectations.
Software Process Models
- The Waterfall Model
- Separate and distinct phases of specification and development.
- Evolutionary Development
- Specification and development are interleaved.
- Agile and Scrum
- Used widely in the industry today.
Waterfall Model
This model struggles to accommodate change after the process is underway.
flowchart LR
rd[Requirements & Definitions] --> ssd[System & Software Design] --> iut[Implementation & Unit Testing] --> ist[Integration & System Testing] --> op[Operation & Maintenance]
op --> ist & iut & ssd & rd
- Inflexible partitioning of the project into distinct stages.
- This makes it difficult to respond to changing customer requirements.
- This model is only appropriate when the final requirements are well-understood.
This model describes a process of step-wise refinement:
- Based on hardware engineering models.
- Widely used in military and aerospace industries.
Evolutionary Development
This starts with an initial development that can be shown to the user for feedback and refinement.
This is an example of exploratory development:
- Objective is to work with customers and to evolve a final system from an initial outline specification.
- Should start with well-understood requirements.
- The system evolves by adding new features as they are proposed by the customer.
flowchart LR
od[Outline Description] --> ca
subgraph ca[Concurrent Activites]
Specification <--> Development <--> Validation
end
ca <--> iv[Initial Version] & inv[Intermediate Versions] & fv[Final Version]
- Lack of process visibility.
- Don’t know how close you are to finishing.
- Systems are sometimes poorly structured.
- Applicable for all systems by rare in safety critical systems.
Agile Development
- Lightweight approach to software development.
- Light on documentation and heavy on development.
This method is focused on:
- Code development as code activity.
- Test driven development.
- Test developed before code.
- Often use pair programming.
- Iterative development.
- Self organised teams.
Scrum - Incremental Development
Rather than deliver the system as a single delivery, the development and delivery is broken down into increments (SCRUM sprints) with each increment delivering part of the required functionality:
- User requirements are prioritised.
- Once the development of an increment is started the requirements are frozen.
- The requirements of later increments can still be developed.
Incremental Development Considerations
- Customer value can be delivered with each increment so system functionality is available earlier.
- Early increments act as a prototype to help elicit requirements for later increments.
- Lower risk of overall project failure.
- The highest priority system services tend to receive the most testing.
Specification
The specification is the most important part of any project.
This lecture is targeted at coursework 1.1.
Requirements
Requirements can be functional:
- What the system should do.
- Provide a login facility that uses a username and password.
They can also be non-functional:
- Constrains on how the functions are provided.
- Username must be longer than six characters.
Non-functional requirements don’t concern the user and relate to system services.
Use Cases
These show how external actors interact with the system.
A use-case is a task which the actor needs to perform with the help of the system.
Actors can be a user or another system.
A set of use-cases describe all possible interaction with the system.
Actors
Actors are anything external to the system which the system interacts with.
These include:
- Human actors.
- Other systems.
- External sensors.
Use Case Description Example
The details of each use case should also be documented by a use case description:
- Print receipt – A customer has paid for an item via a valid payment method. The till should print a receipt indicating the current date and time, the price, the payment type and the member of staff who dealt with the sale.
- Alternate Case – No print paper available – Print out “Please enter new till paper” to the cashier’s terminal. Try to print again after 10 seconds.
Use Case Diagram Example
left to right direction
rectangle {
actor as Actor
Actor <--> (Article Printing)
}
note right of (Article Printing)
Use Case
endnote
ATM Use Case Example
- Actors
- Customers
- Bank staff
- ATM service engineer
- Use cases
- Withdraw cash
- Check balance
- Add cash to machine
- Check security video recording
ATM Case Diagram
Actor "Bank Customer" as c
Actor "Bank Staff" as s
Actor "Service Engineer" as e
package "ATM System" {
usecase "View Balance" as vb
usecase "Withdraw Cash" as wc
usecase "Print Statement" as ps
usecase "Check Cash Stock" as ccs
usecase "Download Video Recording" as dvr
usecase "Topup Cash" as tc
}
c --- vb
c --- wc
c --- ps
s --- ccs
s --- dvr
e --- tc
The boundary of the system is defined by the box.
Advanced Use Case Diagrams
- Boundaries - A labelled box can be drawn around a set of use cases to denote the system boundary.
-
Inheritance - Can be used between actors to show that all use cases of one actor are available to the other:
left to right direction
:Bank Staff: --|> :Customer:
-
Include Relations - If several use cases include another use case:
left to right direction
:Bank customer: as bc
package "ATM System" {
(View Balance) as vb
(Withdraw Cash) as wc
(Print Statement) as ps
(Authenticate Customer) as ac
}
bc --- vb
bc --- wc
bc --- ps
vb --> ac:includes
wc --> ac:includes
ps --> ac:includes
-
Extend Relations - If a use case has two or more significantly different outcomes, we can show this by extending the use case to a main use case:
left to right direction
:Bank customer: as bc
package "ATM System" {
(View Balance) as vb
(Withdraw Cash) as wc
(Print Statement) as ps
(Authenticate Customer) as ac
(Re-enter PIN) as pin
(Reject Transaction) as rt
}
bc --- vb
bc --- wc
bc --- ps
vb --> ac:includes
wc --> ac:includes
ps --> ac:includes
pin -up-> ac:extends
rt -up-> ac:extends
Includes is for mandatory behaviour and extends is for optional/conditional behaviour.
Use Case Template
This template should be used for coursework 1.1:
Attribute of Use Case |
Description |
ID |
Short ID, usefull for diagrams and reference. |
Name |
Full name |
Description |
Full Description |
Pre-condition |
What muse be true before the use case can proceed. |
Event flow |
Flow of behaviour that makes up this use case. |
Post-condition |
What should be true if the use case successfully completes. |
Includes |
What other use cases are used. |
Exensions |
Optional behaviour. |
Triggers |
What makes the use case happen. |
Use cases don’t describe internal behaviour and must describe behaviour with external actors.
Example Template
These are some of the use cases for an ATM:
ID |
UC1 |
Name |
Withdraw Cash |
Description |
Bank customer withdraws cash from the machine |
Pre-condition |
ATM in service |
Pre-condition |
ATM has sufficient cash |
Includes |
UC2 (Authenticate Customer) |
Event flow |
Choose quick cash or enter exact amount, choose receipt option, take cash. |
Extensions |
UC4 (Balance too Low) |
Triggers |
Withdraw cash request entered. |
Post-condition |
Balance updated. |
ID |
UC2 |
Name |
Authenticate Customer |
Description |
Bank customer proves their identity to the ATM. |
Pre-condition |
ATM in service |
Event flow |
If user is already authenticated exit from use case, user enters card PIN number, user re-enters PIN if PIN is incorrect. |
Extensions |
UC5 (Card Stolen), UC6 (Pin Entry Failure) |
Triggers |
Authenticated service requested and user not authenticated. |
Post-condition |
User is authenticated if credential are correct. |
ID |
UC3 |
Name |
Check Balance |
Description |
Bank customer retrieves a balance for their account. |
Pre-condition |
ATM in service |
Includes |
UC2 (Authenticate Customer) |
Event flow |
Choose onscreen or paper balance. |
Triggers |
Check balance is requested. |
ID |
UC4 |
Name |
Balance too Low |
Description |
Bank customer cannot make cash withdrawal due to low balance. |
Event flow |
Customer chooses smaller amount or cancels the transaction. |
Triggers |
Cash chosen is grater than available balance. |