COMP2511
25T3 Week 3
Tuesday 10am-1pm (T10A)
Start 10:05am
Today
- Design by Contract
- Domain Modelling & UML
- JUnit Testing
- Exceptions
Important Notices
- Assignment 1 is out, please start early!
- Go to help sessions if you need help (they get busier towards the due date). Find locations/times on the course website
- No auto generated UMLs of any sort. You will get 0. If you use programs that generate it based on text, please commit this text as a file in your repo.
Design By Contract
Design By Contract
At the design time, responsibilities are clearly assigned to different software elements, clearly documented and enforced during the development and using unit testing and/or language support.
- Clear demarcation of responsibilities helps prevent redundant checks, resulting in simpler code and easier maintenance
Design By Contract
Every software element should define a specification (or a contract) that govern its transaction with the rest of the software components.
A contract should address the following 3 conditions:
- Pre-condition - what does the contract expect?
- Post-condition - what does that contract guarantee?
- Invariant - What does the contract maintain?
Design By Contract
public class Bird {
private int height;
public void fly(int height) {
if (height <= 5) {
throw new IllegalArgumentException("Height must be greater than 5 meters to fly.");
}
this.height = height;
}
}
public class Penguin extends Bird {
@Override
public void fly(int height) {
if (height != 0) {
throw new IllegalArgumentException("Penguins cannot fly! Height must be 0 meters.");
}
// does nothing
}
}- Pre-condition has strengthened - inputs for birds don't apply for penguins
- Post-condition has weakened - additional states/outputs expected
Precondition Weaking
- An implementation or redefinition (method overriding) of an inherited method must comply with the inherited contract for the method
- Preconditions may be weakened (relaxed) in a subclass, but it must comply with the inherited contract
- An implementation or redefinition may lesson the obligation of the client, but not increase it
from 0 <= theta <= 90 to 0 <= theta <= 180 is weakening
[0, 90] => [0, 180]
Why?
Liskov Substitution Principle (more next week). I should be able to use the subclass's implementation in place of my super class.
Domain Modelling
UML
UML

UML
Composition is a specialized form of aggregation. In composition, if the parent object is destroyed, then the child objects also cease to exist. Composition is actually a strong type of aggregation and is sometimes referred to as a "death" relationship.
On the other hand, aggregation still involves one object being a part of another, but if the parent object is destroyed, the child object can still exist.
Examples:
- Aggregation: A classroom has students. If the classroom is removed, the students don't get removed.
- Composition: An online class has breakout rooms. If the class is removed, then the breakout rooms are also removed.
UML

- private attribute
+ static method
# protected attribute
- FINAL_VARIABLE
+ public method
Domain Modelling
Create an OO domain model for a system with the following requirements.
A Car has one or more engines and a producer. The producer is a manufacturing company who has a brand name. Engines are produced by a manufacturer and have a speed. There are only two types of engines within UNSW's cars:
- Thermal Engines, which have a default max speed of 114, although they can be produced with a different max speed, and the max speed can change to any value between 100 and 250.
- Electrical Engines, which have a default max speed of 180. This is the speed at which they are produced, and the max speed can change to any value that is divisible by 6.
Cars are able to drive to a particular location x, y.
Since UNSW is a world-leader in technology innovation, they want you to be able to model the behaviour of Time Travelling for any vehicle, and to model a time travelling car. A vehicle that travels in time stays in the same location but travels to a LocalDateTime.
Domain Modelling
Create an OO domain model for a system with the following requirements.
A Car has one or more engines and a producer. The producer is a manufacturing company who has a brand name. Engines are produced by a manufacturer and have a speed. There are only two types of engines within UNSW's cars:
- Thermal Engines: which have a default max speed of 114, although they can be produced with a different max speed, and the max speed can change to any value between 100 and 250.
- Electrical Engines: which have a default max speed of 180. This is the speed at which they are produced, and the max speed can change to any value that is divisible by 6.
Cars are able to drive to a particular location x, y.
Since UNSW is a world-leader in technology innovation, they want you to be able to model the behaviour of Time Travelling for any vehicle, and to model a time travelling car. A vehicle that travels in time stays in the same location but travels to a LocalDateTime.
Text
- time LocalDateTime

LucidCharts
A generally good diagram maker software that is free for UNSW students:
https://cgi.cse.unsw.edu.au/~cs2511/25T3/setup/lucidchart-setup
Tips for UML Diagrams
- Make it readable (for me please :) )
- Use colours if you wish (but be consistent!)
- E.g. use colours for all trains
- Use purple for a specific design etc.
- Try making a rough one before you start coding your assignments
- Don't worry if it's not perfect to start with, refine over time as you work through large projects!
Code Demo
Wonderous.java
package wondrous;
import java.util.ArrayList;
import java.util.List;
public class Wondrous {
private final int MY_MAGIC_NUMBER = 42;
public List<Integer> wondrous(int start) {
int current = start;
List<Integer> sequence = new ArrayList<Integer>();
while (current != 1) {
sequence.add(current);
if (current % 2 == 0) {
current /= 2;
} else {
current = (current * 3) + 1;
}
}
return sequence;
}
}The Wondrous Sequence is generated by the simple rule:
- If the current term is even, the next term is half the current term.
- If the current term is odd, the next term is three times the current term, plus 1
JUnit Testing
JUnit Testing

Make sure your VSCode is open in the correct folder, otherwise, these buttons wont appear
JUnit Testing
Make sure your VSCode is open in the correct folder, otherwise, these buttons won't appear

JUnit Testing

- Failed test output
- See past history
Debug Mode

- Set a breakpoint, run the test in debug mode
- Stops at a breakpoint it encounters
- See variable values, call stack
Debug Mode

Now let's fix it
package wondrous;
import java.util.ArrayList;
import java.util.List;
// If the current term is even, the next term is half the current term.
// If the current term is odd, the next term is three times the current term, plus 1.
public class Wondrous {
public List<Integer> wondrous(int start) {
int current = start;
List<Integer> sequence = new ArrayList<Integer>();
while (true) {
sequence.add(current);
if (current == 1) {
break;
} else if (current % 2 == 0) {
// Even
current /= 2;
} else {
// odd
current = (current * 3) + 1;
}
}
return sequence;
}
}JUnit Testing
Lets write some more tests
package wondrous.test;
import static org.junit.Assert.assertThrows;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.junit.jupiter.api.Test;
import wondrous.Wondrous;
public class WondrousTest {
@Test
public void testBasic() {
Wondrous w = new Wondrous();
List<Integer> expected = new ArrayList<Integer>(Arrays.asList(3, 10, 5, 16, 8, 4, 2, 1));
assertEquals(expected, w.wondrous(3));
}
@Test
public void testOne() {
Wondrous w = new Wondrous();
List<Integer> expected = new ArrayList<Integer>(Arrays.asList(1));
assertEquals(expected, w.wondrous(1));
}
@Test
public void testInvalid() {
Wondrous w = new Wondrous();
assertThrows(IllegalArgumentException.class, () -> {
w.wondrous(0);
});
}
}Exceptions
Exceptions
What are they?
- An exception is an event, which occurs during the execution of a problem, that disrupt the normal flow of the program's instructions
- When error occurs, an exception object is created and given to the runtime system. This is called throwing an exception
- The runtime system searches the call stack for a method that contains a block of code that can handle the exception
- The exception handler chosen is said to catch the exception
Exceptions
Checked vs Unchecked
- Checked: Must be checked, will result in compilation error if not handled
- Any class that inherits from `Exception` is a checked exception.
- E.g., IOException, SQLException
- Unchecked: Genuine errors that occur at run time
- Any class that inherits from `RuntimeException` is unchecked
- E.g., ArrayIndexOutOfBoundsExceptions, ArithmeticException
Exceptions - Wonderous
How can we use it in Wonderous to make the code better?
Checked or Unchecked?
Exceptions - Wonderous
How can we use it in Wonderous to make the code better?
package wondrous;
import java.util.ArrayList;
import java.util.List;
// If the current term is even, the next term is half the current term.
// If the current term is odd, the next term is three times the current term, plus 1.
public class Wondrous {
public List<Integer> wondrous(int start) {
int current = start;
List<Integer> sequence = new ArrayList<Integer>();
if (start < 1) {
throw new IllegalArgumentException("wondrous start must be >= 1");
}
while (true) {
sequence.add(current);
if (current == 1) {
break;
} else if (current % 2 == 0) {
// Even
current /= 2;
} else {
// odd
current = (current * 3) + 1;
}
}
return sequence;
}
}COMP2511 Week 3 25T3
By Sam Zheng
COMP2511 Week 3 25T3
- 140