Software Modelling and Design Notes

Note: These notes are a mixture of lecture material, textbook material and private research. All credit to the University of Melbourne.

Software Modelling and Design

Modelling and Design

Aim is to learn about Software Modelling and Software Design

Software Design

Purposefully choosing the structure and behaviour of the software system. Behaviour is about how the system responds to inputs and events, and choosing how parts of the system collaborate to achieve goals.

Software Modelling

Creation of tangible, but abstract, representations of a system so that design ideas can be communicated and critiqued, and alternatives explored.

Analysis and Design

Analysis

Analysis - investigation of the problem and requirements

Object-Oriented Analysis - finding and describing objects and concepts in the problem domain

Design

Design - conceptual solution to a problem that meets the requirements

Object-Oriented Design - defining software objects and their collaboration

Implementation

Implementation - a concrete solution to a problem that meets the requirements

Object-Oriented Implementation - implementation in object-oriented languages and technologies

Object-orientation emphasises the representation of objects.

Representation of objects

We want to understand the domainrepresent itdefine solutionimplement it

(all in terms of objects)

Should be able to:

  • apply principles and patterns to create better designs
    • assign responsibilities to SW objects with emphasis on the 9 GRASP principles
  • iteratively follow a set of common analysis and design activities (based on Agile/Unified Process)
  • create frequently used models in UML

Domain Model

Used to visualise real-world concepts. Includes domain objects, attributes, responsibilities and multiplicities.

Domain Model

Design Class Diagram

Used to visualise software elements. Includes classes, attributes, methods and multiplicities.

Design Class Diagram

Structure:

  1. System
  2. Build
  3. Subsystem
  4. Package
  5. Cluster

If packages are highly dependent on each other, they are highly coupled. High coupling is usually bad and hard to understand.

Developers tend to add complexity unnecessarily if unconstrained. Important to ensure developers think through implications of a structure/design change to maintain good design (particularly important in large projects).

This subject focusses on the object-oriented design method, with object-oriented modelling and modelling heuristics.

Sidenote: Heuristic - any approach to problem solving that employs a practical method not guaranteed to be optimal but sufficient for immediate goals. Used when classic methods are too slow, or for finding an approximate solution when classic methods fail to find any exact solution.

UML - Unified Modelling Language

Domain Models

Should be able to:

  • Identify conceptual classes related to the current iteration
  • Create an initial domain model
  • Model appropriate attributes and associations

Domain models look at the role that use cases play in relation to modelling. The purpose is understanding the problem space (not talking about software yet). The domain objects will be familiar to experts in the problem space.

Artefacts

This diagram shows the relationship between artefacts.

Associations and Attributes

Associations - model the relationships between the objects

Attributes - give information about the domain objects beyond the relationships

A domain model should not include:

  • software artefacts/classes (such as a database)
  • methods

Conceptual Class

An idea, thing, or object in the real world

A Conceptual class C is a combination of:

  • Symbol - words or images representing C
  • Intension - the definition of C
  • Extension - a set of instances represented by C

Conceptual Class

Representation Gap

Ideal to keep the “representation gap” between domain and design model as small as possible. This helps stakeholders to understand the software. The domain model should inspire objects and names in the design model.

Steps to creating a domain model:

  1. Find the conceptual classes
    1. Reuse or modify existing models
    2. Use a category list
    3. Identify noun phrases
  2. Draw them as classes in a UML class diagram Make a list of candidate conceptual classes in domain based on commonly occurring categories e.g:
    • Business transactions - Sale, Payment
    • Physical objects - Item, Register, Board, Piece
    • Containers of things - Store, Bin, Aeroplane
    • Recording transactions - Register, Ledger
  3. Add associations and attributes

Modelling is highly iterative, need to keep adding, removing and adjusting.

Attributes vs Classes

If something is not considered a number or text in the real world, it’s probably a conceptual class, not an attribute.

Description Classes

A description class contains information that describes something else. Should be used when:

  • groups of items share the same description
  • items need to be described even when there are currently no examples
  • it reduces redundant or duplicated information
  • deleting instances results in losing required info

We should clearly distinguish between items and their descriptions to avoid duplication.

Item Descriptions

Flight Description Example

Associations

An association represents some meaningful and significant relationship between classes. Guidelines:

  • significant in domain (don’t have to model all associations)
  • knowledge of the relationship needs to be preserved
  • derived from common associations list

Association category list:

  • A is a member of B - Cashier-Store, Player-MonopolyGame, Pilot-Airline
  • A is a role related to a transaction B - Customer-Payment, Passenger-Ticket
  • A is physically or logically contained in/on B - Register-Store, Item-Shelf, Square-Board
  • A is known/logged/recorded/reported/captured in B - Sale-Register, Piece-Square

Association

Association name - User verbs

Multiplicity - 0..1 → “optionally-one”. Multiplicities will be dependent on the context and what rules we want to enforce.

Multiplicities

Multiple Associations on Flight

UML Attribute Notation (not all relevant to domain model)

Modelling Standard Attributes

Incorrect use of foreign key as attribute

Modelling Quantities. Need the unit to be useful.

Use Cases

Use Cases - Textual representations of how particular users or actors interact with the system to achieve a goal

Use Case Diagrams - Give an overview of the use cases and the relationships between them

SuD - system under discussion (what we’re aiming to develop)

Actor - something with behaviour, such as a person, computer system or organisation (e.g. a cashier). Interacts with the SuD (can be people or other systems). Can trigger behaviour in the system and react to output.

Scenario (use case instance) - a specific sequence of actions and interactions between actors and the SuD

Use Case - a collection of related success and failure scenarios that describe an actor using the SuD to support a goal. Non-conditional (a specific sequence). Use Cases are text, not diagrams, and are not object-oriented constructs.

A use case can be brief, casual or fully dressed.

With use cases don’t say anything about how the user interacts with the system, just what information is going in or out.

Define the main success scenario and any alternate scenarios.

Fully dressed use cases

Use Case Diagrams

Types of Actors:

  1. Primary - uses services of the SuD
  2. Supporting - provides a service to the SuD (often a computer system, but not necessarily)
  3. Offstage - has an interest in behaviour of the use case, but is not primary or supporting

Use Case

Tests for “Useful” Use Cases:

  1. Boss Test - would your boss be happy if you told them the use case you’ve been working on all day?
  2. Elementary Business Process Test - should be a task performed by one person in one place at one time, in response to a business event, which adds measurable business value and leaves the data in a consistent state
  3. Size Test - very seldom a single action/step; often 3-10 pages of text for a fully dressed use case

Object-Oriented Layers

An example of layers can be:

  • User Interface
  • Application Logic - our primary focus → explore how to design objects (other layers can be technology/platform dependent)
  • Other layers/components

System Sequence Diagrams

A form of dynamic modelling. They capture the dynamic context of the system.

Treats the system as a black box.

Derived from use cases.

Objectives:

  • identify system events
  • create system sequence diagrams for use case scenarios

System Sequence Diagrams (SSDs) try to work out what events the system needs to handle by going through the use case diagrams and extracting the sequence of events.

Basic SSD

A SSD analyses the “external” behaviour of the system.

Sometimes show what’s going inside the system “black box” if it’s necessary to understand what is going on.

Multiple Actors

Multiple Actor SSD

Mobile user is the primary user. Can have secondary actors like ProductInventory and MappingService.

Both indicate a return, just different notation (explicit vs implicit):

  1. closestToMe(storeLocations): storeLocation
  2. :store

Choose abstract naming e.g. enterItem(...) is better than scan(...)

Interaction Diagrams

Sequence Diagrams (SD)

Different to SSD

Sequence Diagram

  1. External source generates the method call doOne
  2. A now has control of execution of the system
  3. A asks B to doTwo and passes control to B
  4. Control returned to A
  5. A asks B to doThree and passes control to B
  6. Control returned to A

Communication Diagram

Not constrained by layout like a sequence diagram → more like a class diagram

Communication Diagram

public class A {
    private B myB = new B();

    public void doOne() {
        myB.doTwo();
        myB.doThree();
    }
}
  • Instance of Class A
  • A has access to B through a private variable called myB
  • When doOne() is invoked in A
  • Ask B to doTwo()
  • Ask B to doThree()

**SD** of `makePayment`

**CD** of `makePayment` {:class=”image fit-small”}

CD message to **this**

CD **Object Creation** - 1. *Nature of Message*

CD **Object Creation** - 2. *Annotation*

CD **Object Creation** - 3. *Stereotype*

**Sequence numbers** - use legal numbering

**Conditional messages** - use guard style notation

**Mutually Exclusive Messages**

**Static (Class) Messages**

Accessing a static variable through a static method:

public class Bicycle {
    private static int numberOfBicycles = 0;

    public static int getNumberOfBicycles() {
        return numberOfBicycles;
    }
}

**Iteration**

**Iteration over a collection**

**Polymorphic Messages/Cases** - T representation

**Asynchronous/Synchronous Calls**

**SD Notation**

**Singleton Pattern in Interaction Diagram**

**Execution Specification Bar**

Messages to **Self (this)**

**Object Creation**

**Object Destruction**

A frame is a mechanism for more complex computational constructs.

UML Frames: **Opt**

UML Frames: **Alt**

Note: Polymorphism is often a better choice than an alt frame.

UML Frames: **Loop**

**Collections (Formal)** - indexed object `lineItems` indexed by `i`

**Collection (Shorthand)**

UML Frames: **Nesting**

UML Frames: **ref** - *reference frame*

Polymorphism

Subclasses of a class can define their own unique behaviours and yet share some of the functionality of the parent class.

In Java, the JVM calls the appropriate method for the object that is referred to in each variable. It does not call the method that is defined by the variables type. This behaviour is referred to as virtual method invocation.

Payment → abstract superclass

CreditPayment and DebitPayment → concrete subclasses

Both subclasses have to implement the authorize() abstract method.

Polymorphism in `Payment`. Both subclasses have to implement the
`ahttps://s3-ap-southeast-2.amazonaws.com//uni-notes/smd/e()` abstract method

A “T diagram” showing **polymorphic variants**

Asynchronous Calls & Active Objects

Synchronous → wait for executed statement to finish before executing next statement

Asynchronous → can move onto another task before the previous one has finished

SD

Strengths:

  • Time Ordering
  • Shows detail between objects

Weaknesses:

  • Linear Layout can obscure relationships
  • Consumes horizontal space

CD

Strengths:

  • More layout options
  • Shows relationships b/w objects
  • Combines scenarios to provide complete picture

Weaknesses:

  • More difficult to see message sequencing
  • Fewer notation options to express patterns

GRASP Responsibilities

GRASP - General Responsibility Assignment Software Patterns/Principles

Responsibility: A contract or obligation of a classifier

A classifier is a class/interface or other component of the software system.

We want to make components responsible for some part of the system.

Doing responsibilities:

  • Direct - create object, perform calculation
  • Initiate action in other objects
  • Control and coordinates activities in other objects

Knowing responsibilities (informational knowledge):

  • Private, encapsulated data (made available through methods)
  • Related objects
  • Derivable or calculable items

Responsibilities and Methods are related but not the same:

  • Responsibility → abstract concept
  • Methods → concrete ways of meeting responsibilities

Responsibility driven design sees an OO design as a community of collaborating, responsible objects.

Involves assigning responsibilities to classes based on proven principles.

9 GRASP principles are:

  1. Creator
  2. Information Expert
  3. Low Coupling
  4. Controller
  5. High Cohesion
  6. Polymorphism
  7. Indirection
  8. Pure Fabrication
  9. Protected Variations

1. Creator

Deals with problem of which class is responsible for creating a new instance of a class. The action of creating another class is an assignment of responsibility.

We want to ensure low coupling, increased clarity, encapsulation and reusability.

B should be responsible for creating A if:

  • B contains or compositely aggregates A (most important)

  • B records A

  • B has the initialising data for A (B is an expert)

Dynamic example of Creator pattern

When board is created, the board is assigned the responsibility of creating squares.

Static example of Creator pattern

Contraindications

May decide against the creator pattern in the case of:

  • Creation of significant complexity e.g.
    • When recycling instances for performance (taking objects from a pool before creating new ones)
    • Only retrieving specific instances based on property

In these cases we can delegate to a helper class in the form of a Concrete Factory or Abstract Factory.

2. Information expert

A general principle to assign responsibilities to objects to achieve outcomes that are easier to understand, maintain, extend and reuse.

Assign responsibility to the class that has the information necessary to fulfil the responsibility.

Example of Information Expert

Contraindications

Don’t use expert if the suggested solution results in poor coupling or cohesion.

3. Low Coupling

Coupling is a measure of how strongly one element is connected to, has knowledge of, or relies on others.

It relates to the connections between components in a software system. More connections → harder to maintain.

Low coupling suggests assigning responsibility so that the design supports low dependency, low change impact and increased reuse. The lower the dependency the less changes propagate through the system.

Contraindications

  • High coupling to stable elements like Standard Java Libraries is not an issue
  • Coupling is actually essential, so we are just choosing to keep it low where we can without compromising other design aspects.

4. Controller

Relates to which object receives the first message from an external system and coordinates/controls a system operation (major input event, appears on SSD).

Assign responsibility to a class representing one of:

  • the overall system, a “root” object, a device the system is running in, or a major subsystem
    • a facade controller → representation of system as a whole with routing point where all messages go through
  • a use case scenario or session controller that deals with the event in complex systems

The controller lives just under the UI layer in the domain layer. The UI layer needs to know where to route the message to.

Example of Facade Controller

Contraindications

Can sometimes get a bloated controller with too many responsibilities and low cohesion. The controller becomes too complicated with too much logic and duplicated information. Solutions:

  • May need to add more controllers based on use case.
  • Delegate to responsibility

5. High cohesion

Keeping objects focussed, understandable and manageable. A measure of how strongly (functionally) related and focussed the responsibilities of an element are.

Example of High Cohesion

Contraindications

  • Lower cohesion sometimes required to meet non-functional requirements such as performance.
  • Coupling and cohesion are fundamental design properties that are interdependent and must be considered together.

6. Polymorphism

If we purely use if-else’s, we get a proliferation of them. Need a better way of handling alternatives based on type.

Allows us to handle alternatives based on type by giving a single interface to entities of different types. When related alternatives differ by type (class):

  • Use operations with the same interface to assign responsibilities for the behaviour to the types for which the behaviour varies

Polymorphism helps us to create pluggable software components.

Polymorphic → “giving a single interface to entities of different types”

Adapters → objects responsible for handling varying interfaces.

Example of Polymorphism - Adapter

If the superclass doesn’t have any default behaviour, declare it {abstract}.

Example of Polymorphism - Abstract

7. Pure Fabrication

Which object should have responsibility when solutions offered (say, by Expert) violate High Cohesion and Low Coupling?

Can fabricate an object not in the domain to give a better design. Required when a low representation gap/ solution offered by expert causes high coupling/low cohesion.

Only to be used when other techniques don’t work.

Example: Creating a PersistentStore for saving DB related transactions like a Sale.

Contraindications

  • Sometimes driven by behavioural decomposition into functions, resulting in functions being group into objects. Don’t just create an object when looking for a place to put a quick set of functions.

8. Indirection

Where to assign responsibility to avoid direct coupling between two or more software elements?

Example of Poor Coupling

De-coupling components so that low coupling is supported and reuse potential remains high by assigning the responsibility to an intermediate object. The intermediary creates an indirection between the other components.

Example of Indirection

Coupling isn’t about the number of links but the nature of those links.

Adaptor pattern is an example of indirection

9. Protected Variations

A way of designing objects/systems so that variations/instability in these elements do not have an undesirable impact on other elements.

Identify known or predicted variation/instability and assign responsibilities to create a stable interface around them. An interface refers to a means of access, it’s not just a programming language interface.

Points of change include:

  • variation points: variations in existing system - e.g. multiple tax calculators
  • evolution points: speculative variations that may arise in the future

Open-Closed Principle (OCP) - strongly related to protected variation

Modules should be both open (for extension; adaptable) and closed (to modification that affects clients) e.g. define a class and only use access methods → can change field definitions without impacting clients

Contraindications

Cost of speculative “future-proofing” at evolution points can outweigh the benefits. Can be cheaper/easier to rework a simple “brittle” design.

Relationship between GRASP Principles

GRASP Examples

1. Creating payment from `:Sale` or `:Register` - *Low coupling* or *Creator*

2. Controller choices - Cashier interaction

2. Controller choices - System Wide Controller or Use Case Handler

3. Low cohesion, high coupling (*worse option*)

3. High cohesion, low coupling (*better option*)

Here makePayment() is delegated to Sale, and Sale creates Payment.

Visibility

Object Oriented Analysis and Design (OOAD) applies encapsulation (through objects and classes).

  • High cohesion → encourages grouping highly related responsibilities
  • Low coupling → encourages minimising dependency on other elements
  • Design → requires assigning responsibilities and objects cooperating to achieve required outcomes
  • Objects → require visibility of each other to cooperate

How does Register gain visibility of ProductCatalog?

Visibility - `:Register` and `:ProductCatalog` example

Accessing objects can be done in a few ways:

  • Create new object
  • Access existing object
    • Global object
    • Made available at some point
      • Passed in as a constructor
      • By calling one of our own methods
      • Is an attribute of class

The different ways in which we access objects has an impact on the coupling of the design.

What is visibility?

The ability of an object to see or refer to another object.

For A to send a message to B, B must be visible to A.

Being in scope or visible:

  1. B is an attribute of A
  2. B is a parameter of a method of A
  3. B is a local object in a method of A
  4. B has in some way global visibility

1. Attribute Visibility

Attribute visibility is considered a tight form of coupling.

Attribute Visibility

Here we can make ProductCatalog an attribute of Register:

class Register {
    ...
    private ProductCatalog catalog;
    ...
    public void enterItem(int itemID, int qty) {
        ...
        desc = catalog.getProductDesc(itemID)
        ...
    }
}

2. Parameter Visibility

Looser form of coupling than attribute visibility.

Parameter visibility

Register already needs to know about ProductCatalog, so it gets it and passes to Sale as a parameter of makeLineItem(...)

A worse option with higher coupling would be passing the item id into makeLineItem(...) and making ProductCatalog visible to Sale in some way.

Parameter to attribute visibility → pass a parameter in to a constructor and save it as an attribute. This gives higher coupling.

e.g.

SalesLineItem(ProductDescription desc, int qty) {
    ...
    ProductDescription description = desc;
    ...
}

3. Local Visibility

Where we provide access through scope of declaration (temporary visibility).

enterItem(int id, int qty) {
    ...
    ProductDescription desc = catalog.getProductDesc(id);
    ...
}

desc has limited context → not available outside of enterItem

This is weak, localised coupling.

Note: even if catalog wasn’t stored as an attribute, if we were to somehow access the catalog e.g. other.getCatalog().getProductDesc(id) that is still a dependency (still coupling) as there is implicitly a catalog object there.

4. Global Visibility

Strong form of coupling → needs to be used in a controlled way.

Java doesn’t strictly have global visibility, but it is achievable through static attributes (but use Singleton). e.g.

public class Global {
    public static int v = 1;
}
public static void main(String[] args) {
    Global g = new Global();
    int n1 = g.v; // can access through object
    int n2 = Global.v; // can access through class
}

v will be the same regardless of it’s access (through object or class) as it is a static variable.

UML Visibility Marks

UML Visibility Marks

  • + → public
  • - → private
  • # → protected
  • / → derived

Mapping Designs to Code

Objective is to map design artefacts to code in an object oriented language.

OO implementation requires:

  • Class and Interface definitions
  • Method definitions

`SalesLineItem` and `ProductDescription` example

As SalesLineItem only has 1 ProductDescription, can make it an attribute.

public class SalesLineItem {
    private int quantity;
    private ProductDescription description;

    public SalesLineItem(ProductDescription description, int qty) {...}

    public Money getSubTotal() {...}
}

Need to consider who will be making the SalesLineItem and hence where the constructor lives. Also need to consider which attributes are to be included in the constructor (there may be default values). Need to look at the dynamic models.

`Register` class in DCD

public class Register {
    private ProductCatalog catalog;
    private Sale currentSale;

    public Register(ProductCatalog catalog) {...}

    public void endSale() {...}
    public void enterItem(ItemID id, int qty) {...}
    public void makeNewSale() {...}
    public void makePayment(Money cashTendered) {...}
}

Creating `Register.enterItem(...)` method

public void enterItem(ItemID id, int qty) {
    ProductDescription desc = catalog.getProductDescription(id);
    currentSale.makeLineItem(desc, qty);
}

Multiplicity: Adding a Collection

Adding a collection

public class Sale {
    ...
    private List lineItems = new ArrayList();
    ...
}

Collections class is necessary to maintain visibility to all of the SalesLineItems.

Choice of the collections class depends on the operations we want to perform on the items:

  • Key-based lookup → Map
  • Growing ordered list → List

If implementing an interface, declare in terms of the interface:

Map<String, Integer> map = new HashMap<String, Integer>();

Map is the interface, HashMap is the concrete instance (can change initialisation without having to change variable type)

Creating `Sale.makeLineItem(...)` method

public void makeLineItem(ProductDescription desc, int qty) {
    lineItems.add(new SalesLineItem(desc, qty));
}

When implementing, move from least-coupled to most-coupled.

State Machine Diagrams

Note: State machines relate to compiler theory.

A state machine describes the behaviour of an object in terms of:

  • events that affect the object
  • the state of the object between the events

State machine for a telephone

  • Event - a significant or noteworthy occurrence
  • State - condition of the object at a moment in time
  • Transition - directed relationship between two states such that an event can cause the object to change from the prior to the subsequent state

State-dependent object → reacts differently to events depending on their state (interested in these for state machines)

Applying State Machines

Consider them when:

  1. Object is state-dependent and has complex behaviour
  2. Developing a communications or control application (very common, more so than business information systems)

Examples

  • Complex Reactive Objects
    • Physical device controllers - e.g. state of a lift
    • Transactions and related business objects - e.g. e-commerce transaction
    • Role mutators (objects that change roles) - e.g. employee from contractor to permanent
  • Protocols and Legal Sequences
    • Communications protocols
    • UI Page/Window Flow, Navigation
    • Use Case Operation Sequencing

Web-page navigation example

Process Sale Operation Sequencing example

State Machine Notation

State Machine Notation

When** the object is in State A, if trigger event occurs, and guard is true, perform behaviour action and transition the object to State B

Telephone example

Browser example

Choice Pseudostate

  • Can have more than two choice states
  • Can use [else] guard
  • States don’t have to be mutually exclusive (nondeterministic state machine)

Choice PseudoState

Nested States

  • Transition into Active via off hook, which transitions into PlayingDialTone (or Active.PlayingDialTone)
  • All substates of Active inherit the on hook transition

Nested States

Decision must be made as to what behaviour we want to model and at what level of abstraction.

Domain Model Refinement

Refine with:

  • generalisations
  • specialisations
  • association classes
  • time intervals
  • composition
  • packages

Generalisation-Specialisation Class Hierarchy

Payment Hierarchy - Conceptual

Payment Hierarchy - Class Diagram

Payment Hierarchy - Class Diagram

Being {abstract} indicates that the subclasses are disjoint and complete. Every Payment can only be one of Cash Payment, Credit Payment, or Check Payment.

Each subclass conforms to all of the properties of the superclass.

Abstract v Concrete

Abstract vs Concrete Superclasses

Generalisation:

  • Identify commonality among concepts
  • Define superclass (general concept)
  • Define relationships with subclasses (specialised concepts)

Enables:

  • Economy of expression
  • Reduction in repeated information → less chance of errors
  • Improved cohesion → domain model that matches intuition

These are all separate but related concepts.

Specialisation Hierarchy

  • The top associations are power types
  • The bottom inheritance sets are specialisation hierarchies

Here we have two specialisation hierarchies for coverage type and insurance plan.

Guideline for creating subclasses:

  1. Subclass has additional attributes of interest
  2. Subclass has additional associations of interest
  3. Subclass is operated on, handled, reacted to, or manipulated differently to other classes in noteworthy ways

Modelling guidelines:

  1. Declare superclasses abstract
  2. Append the superclass name to the subclass