# Programming 2.2 exercise solutions
## UML diagrams
```mermaid
stateDiagram
SequenceDiagram --> InteractionDiagrams
CommunicationDiagram --> InteractionDiagrams
InteractionDiagrams --> Behavioural
ClassDiagram --> Structural
PackageDiagram --> Structural
```
***
## M1 Iterative, evolutionary and agile
### Agile manifesto
- Individuals and interactions over processes and tools
- Working software over comprehensive documentation
- Customer collaboration over contract negotiation
- Responding to change over following a plan
### EX2 Process consultant
To Gaston, because a team with agile approach has a better chance to finish everything.
Also to Rita, because agile produces business value quicker than waterfall. However, because of the iterative process, unexpected costs can arise.
***
## M2 Inception
### EX2 Drill glossary
> Make a glossary for the Grill mini case. Separate in a domain and technical section and order each alphabetically.
> Include concepts, their definition and aliases.
#### Domain
|Concept|Definition|Synonims|Remarks|Values
|-|-|-|-|-|
|Administrator|A contributor with increased platform privileges||E.g. teachers, developers
|Answer|user input for a Question|
|Badge|Grants access to contribution priviliges||Acquired by collecting reputation|Mentor, Reviewer
|Course|Courses in participaint institution's programmes|class, subject|
|Exam|Trial questionnaires in the system|test|Can be based on any real-life assessment from the participating universities
|Hint|Additional help to answer a question|||Level 1, 2, 3
|Point|Reward for a correct answer to a question that counts to the exam score
|Programme|Programmes of a participating institution
|User|Student with or without badges|Student
|Question|Atomic assessment in exam||Multiple choice or open answer|
|Reputation|Reward for succeeded exam scores, distributed per course|karma|Visible on user profile|
|Reward|Advantages users can earn by collecting reputation||e.g. vouchers, film tickets
|Score|Final mark received on a test|exam result|calculated by points and used up hints||
|Subscription|Describes a student's enrollment in a course||
|Vote|Positive or negative feedback on a hint submitted by a mentor||numerical
#### Technical
|Concept|Definition|Synonims|Remarks
|-|-|-|-|
|External Administrative System|The participating universities inner administrative system|EAS|Accessed by APIs
|System|The Drill platform as a whole||E.g. *students quit if the system is unresponsive*
> Are there any words in the domain that have another meaning for KdG outside the scope of the project?
Plenty.
***
## M3 Requirements
Definition of Ready (DoR): INVEST
**I**ndependent: dependencies are available
**N**egotiable: stakeholders understand and agree on the content
**V**aluable: a priority has been assigned
**E**stimable: sufficient details available to estimate effort
**S**mall: can be implemented in 1 sprint
**T**estable: acceptance criteria has been defined, test data available
Definition of Done (DoD):
- features implemented
- acceptance criteria fulfilled
- code has been peer reviewed
- code has 85% test coverage
- all tests succeed
- accepted by stakeholders
***
## M4 Domain Model
```mermaid
classDiagram
A --|> B: Inheritance
C --* D: Aggregation
E ..> F: Dependency
G "0..1" -- "*" H: Relation
I --> J: Association
```
### Exercise 1
> The Belgian National Registration Number is a Value Object (UML datatype). Write a Java class for it that respects the Value Object conventions.
```java
public final class RegistryNumber {
private final String value;
public RegistryNumber(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
```
### Exercise 2
1. Entity
2.
- code: primitive
- destination: value object
- hotel: entity
- maxParticipants: primitive
- hosts: collection
### Exercise 3
> Extend the Money class with an add method, adding an amount (in the same currency) to the Money object. Respect the immutability of the class.
```java
@EqualsAndHashCode
public final class Money {
private final double amount;
private final Currency currency;
public Money(double amount, Currency currency) {
this.amount = amount;
this.currency = currency;
}
public double getAmount() {
return amount;
}
public Currency getCurrency() {
return currency;
}
public Money add(double amount) {
this = new Money(this.amount + amount, this.currency);
return this;
}
}
```
### Exercise 4
> A country is divided into provinces. A province is divided into cities. A country has neighbouring countries, a province has neighbouring provinces and a city has neighbouring cities. Countries, provinces and cities have all names and sizes (in square km).
> 1. Make a domain model to handle this information.
```mermaid
classDiagram
class Area {
<<abstract>>
name: String
size: double
}
class Country
class Province
class City
Country --|> Area
Province --|> Area
City --|> Area
Area "*" -- "*" Area: neighbours
Country "1" -- "*" Province
Province "1" -- "*" City
```
Disadvantages: circular reference.
> 2. What would be the most generic domain model you can make? What are advantages/disadvantage of a more generic model?
```mermaid
classDiagram
class AreaType {
<<enum>>
COUNTRY,
PROVINCE,
CITY
}
class Area {
name: String
size: double
type: AreaType
}
Area "1" -- "*" Area: contains
Area "*" -- "*" Area: neighbours
```
***
## M5 - From analysis to design
### Exercise 1
**1.**
**User Story**
As a traveler,
I want to see the fee breakdown before I pay
So that I know how much the base price and the zone price cost
**Given** the traveler selected a ticket and pressed on pay
**When** the ticket is valid through 3 zones
**Then** the dispenser displays £2 + £1.5
**2**
As a ticket dispenser,
I want to be returned to the main menu if the latest transaction is idle for 1 minute
So that the next buyer don't have to press on cancel if the previous left before finalizing
**Given** the traveler selected a ticket, but didn't press on finalize
**Given** the traveler selected a ticket, pressed on finalize but didn't pay
**When** the system is in this state for 1 minute
**Then** the purchase is automatically cancelled and the dispenser displays the main menu again
**Sequence diagram**
```mermaid
sequenceDiagram
autonumber
actor T as Traveler
participant TD as :TicketDispenser
participant PS as :PaymentService
T->>+TD: enters zone count
Note over T,TD: 3
TD--)-T: displays price
Note over TD,T: £2 + 3 * £0.5
T->>+TD: presses on pay
TD--)-T: prompts for card
T->>+TD: presents card
TD->>+PS: sends card data
PS--)-TD: verifies payment
TD--)-T: prints ticket
Note over TD,T: Valid for zones A, B, C<br>£3.5
```
**Operation contracts**
| **No** | **Operation** | **Cross reference** | **Pre-conditions** | **Post-conditions** |
| -------| ------------------| ------------- | -----| -----------------------|
| 1 | Enters zone count | Zone selection| None | `TicketSale ts` (instance creation)|
|2|Displays price||Existing `TicketSale` with number of zones|Calculated price displayed|
|3|Presses on pay||
## M6 Interaction diagrams
### Exercise 1: XFrame interaction diagram
> We have a class XFrame with attributes nameField of type JTextField and helloLabel of type JLabel with a method nameAction
```java
class XFrame {
JTextField nameField = new JTextField();
JLabel helloLabel = new JLabel();
void nameAction() {
String name= nameField.getText();
String hello = "Hello " + name;
helloLabel.setText(hello);
}
}
```
> Make an interaction diagram for a call to nameAction on an XFrame. Is the value of variable hello specified in the sequence diagram?
```mermaid
sequenceDiagram
actor A as Actor
participant XF as :XFrame
participant JTF as :JTextField
participant JL as :JLabel
A ->>+ XF: nameAction()
XF ->>+ JTF: getText()
JTF ->>- XF: text
XF ->>+ JL: setText(text)
```
> How does the interaction diagram change if we write the method nameAction like this?
```java
public void nameAction() {
helloLabel.setText("Hello " + nameField.getText());
}
```
It doesn't.
>How does the interaction diagram change if we write the method nameAction like this (happy is en attribute of XFrame )?
```java
void nameAction() {
String name = nameField.getText();
String hello;
if(happy) hello = "Nice to meet you " + name;
else hello = "Hello " + name;
helloLabel.setText(hello);
}
```
```mermaid
sequenceDiagram
actor A as Actor
participant XF as :XFrame
participant JTF as :JTextField
participant JL as :JLabel
A ->>+ XF: nameAction()
XF ->>+ JTF: getText()
JTF ->>- XF: text
alt happy
XF ->>+ JL: setText("Nice to meet you" + text)
else
XF ->>+ JL: setText("Hello" + text)
end
```
### Exercise 2: Printer
> Make an interaction diagram for a computer receiving a request from a user to print a file. The computer contacts a print server which sends it to the printer. If the printer is busy the print job should be queued by the print server.
```mermaid
sequenceDiagram
Actor U as User
participant C as Computer
participant PS as PrintServer
participant P as Printer
U ->>+ C: print
C ->>+ PS: print(:File)
alt printerBusy
loop printerBusy
PS ->>+ PS: queue(:File)
end
else
PS ->>+ P: print(:File)
end
P ->>- PS: done
PS ->>- C: done
C ->>- U: done
```
### Exercise 3: flights interaction diagram
> Class Airline manages multiple instances of class Flight (with attributes: flightNumber, price and destination). Each Flight instance has a unique number. Draw a domain model and an interaction diagram for these actions:
> 1. Raise the price for a flight with a given flightNumber.
> 2. Raise the price of all flights.
> 3. Raise the price of all flights with a given destination.
> 4. Remove a flight with a given flightNumber
```mermaid
classDiagram
class Airline {
name: String
}
class Flight {
flightNr: long
price: double
destination: String
}
Airline "1" -- "*" Flight
```
#### 1.
```mermaid
sequenceDiagram
actor M as Manager
participant A as :Airline
participant Fs as :Flight[*]
participant F as :Flight
M ->>+ A: raiseByFlightNr(flightNr:long, percent:double)
A ->>+ Fs: getByFlightNr(:long)
Fs ->>- A: :Flight
A ->>+ F: raisePrice(:double)
```
#### 2.
```mermaid
sequenceDiagram
actor M as Manager
participant A as :Airline
participant Fs as :Flight[*]
participant F as :Flight
M ->>+ A: raiseAll(percent:double)
loop i < Flight.size
A ->>+ Fs: get(i)
Fs ->>- A: :Flight
A ->>+ F: raisePrice(percent:double)
end
```
#### 3.
```mermaid
sequenceDiagram
actor M as Manager
participant A as :Airline
participant Fs as :Flight[*]
participant F as :Flight
M ->>+ A: raiseByDestination(destination: String, percent:double)
loop i < Flight.size
A ->>+ Fs: get(i)
Fs ->>- A: f:Flight
opt f.destination == destination
A ->>+ F: raisePrice(percent:double)
end
end
```
#### 4.
```mermaid
sequenceDiagram
actor M as Manager
participant A as :Airline
participant Fs as :Flight[*]
M ->>+ A: removeByFlightNr(flightNr:long)
A ->>+ Fs: getByFlightNr(:long)
Fs ->>- A: f:Flight
A ->>+ Fs: remove(f:Flight)
```
### Exercise 4: `Team::getPlayerNames():String[]`
## M7 Design Class Diagrams
Also called Evolved Domain Model.
### Exercise 1: bidirectional navigation
> For the class diagram below, add a method to link a person to another dog. Make sure that the bidirectional navigation remains consistent. Also, add a method to link a Dog to another person. Show how the methods work in an interaction diagram.
```mermaid
classDiagram
class Person {
name:String
birthday:Date
setDog(:Dog)
}
class Dog {
name:String
breed:String
setPerson(:Person)
}
Person "0 .. 1" <--> "0..1" Dog : has
```
`setDog():`
```mermaid
sequenceDiagram
actor U as User
participant P as :Person
participant OD as old:Dog
participant ND as new:Dog
U ->>+ P: setDog(new:Dog)
opt this.dog != new
opt old != null
P ->>+ OD: setDog(null)
Note over P,OD: old = this.dog
end
opt new != null
P ->>- ND: setDog(this)
end
end
```
`setPerson():`
Same, but reversed.
```mermaid
sequenceDiagram
actor U as User
participant D as :Dog
participant OP as old:Person
participant NP as new:Person
U ->>+ D: setPerson(new:Person)
opt this.person != new
opt old != null
D ->>+ OP: setPerson(null)
Note over D,OP: old = this.person
end
opt new != null
D ->>- NP: setPerson(this)
end
end
```
> How would your solution change if a Person can have multiple dogs? Provide an interaction diagram.
### Exercise 2: movie roles
> Write the classes using roles as concepts in a package a. Initialise your system with the objects in the above example. Is the model a good solution for this business context?
```java
package a;
import java.util.List;
import java.util.ArrayList;
import java.time.LocalTime;
abstract class User {
String name;
User(String name) {
this.name = name;
}
}
class Planner extends User {
List<Show> managedShows = new ArrayList();
Planner(String name) {
super(name);
}
}
class ContentManager extends User {
List<Movie> managedMovies = new ArrayList();
ContentManager(String name) {
super(name);
}
}
class Show {
Movie movie;
LocalTime start;
Show(Movie movie, LocalTime start) {
this.movie = movie;
this.start = start;
}
}
class Movie {
String title;
Movie(String title) {
this.title = title;
}
}
class Main {
public static void main(String[] args) {
/* This roles as concept model is not a good solution for this context,
* because it introduces double effort if we want to update Josh.
*/
Planner planner = new Planner("Josh");
ContentManager manager = new ContentManager("Josh");
Movie dune = new Movie("Dune");
Movie spiderman = new Movie("Spiderman");
Movie brokenCircle = new Movie("The Broken Circle Breakdown");
Show s1 = new Show(dune, LocalTime.of(16, 0));
Show s2 = new Show(brokenCircle, LocalTime.of(20, 0));
manager.managedMovies.add(spiderman);
planner.managedShows.add(s1);
planner.managedShows.add(s2);
}
}
```
> Copy your code to a package b. Write the classes using roles as associations. Initialise your system with the objects in the above example. Is the model a good solution for this business context?
```java
package b;
import java.util.List;
import java.util.ArrayList;
import java.time.LocalTime;
class User {
String name;
List<Show> plannedShows = new ArrayList();
List<Movie> plannedMovies = new ArrayList();
User(String name) {
this.name = name;
}
}
class Show {
Movie movie;
LocalTime start;
Show(Movie movie, LocalTime start) {
this.movie = movie;
this.start = start
}
}
class Movie {
String title;
Movie(String title) {
this.title = title;
}
}
class Main {
static void main(Strin[] args) {
/* This model is a better solution, because we don't have to
* double manage Josh
*/
User u = new User("Josh");
Movie dune = new Movie("Dune");
Movie spiderman = new Movie("Spiderman");
Movie brokenCircle = new Movie("The Broken Circle Breakdown");
Show s1 = new Show(dune, LocalTime.of(16, 0));
Show s2 = new Show(brokenCircle, LocalTime.of(20, 0));
}
}
```
### Exercise 3: student inheritance
> Our developers have indicated a problem with this design: when a student becomes a MasterStudent, the object needs to be removed and recreated. Change the design to solve this. Do you need to add business rules to guarantee that your new design keeps the same semantics as the original design?
In this design, there are is no extra business logic. `StudentStatus` could also be an enumeration that each `Student` has an attribute of, and then extra rules are needed to enforce the fact bachelor students don't have a thesis.
```mermaid
classDiagram
class Student {
number: long
name: String
}
class StudentStatus {
<<abstract>>
start: LocalDate
}
class Institute {
location: String
}
class BachelorStatus
class MasterStatus
class Thesis {
title: String
}
Student "*" -- "1" Institute
Student "1" -- "1" StudentStatus
MasterStatus "1" -- "1" Thesis
BachelorStatus --|> StudentStatus
MasterStatus --|> StudentStatus
```
## M8 GRASP
Part of Responsibility-Driven Design.
Generalized Responsibility Assignment Software Patterns
Important patterns:
- low coupling
- high cohesion
- controller
- creator
- information expert
### Exercise 1: communication diagram to class diagram, coupling
> Given the above communication diagram:
> 1. Make an (evolved) domain model
```mermaid
classDiagram
class B {
bCode
getE()
}
class C {
m1()
}
class E {
doQ(:D)
}
C --> "*" B
B --> "1" E
```
> 2. Change the communication diagram to lower coupling, if possible.
```mermaid
flowchart LR
Start -- "m1(bCode, d)" --> :C
:C -- "1: b = getCode(bCode)" --> :B[":B[*]"]
:C -- "2: doQ(d)" --> b:B
b:B -- "3: e = getE()" --> b:B
b:B -- "4: doQ(d)" --> e:E
```
### Exercise 2: Contacts
GRASP patterns:
```mermaid
classDiagram
class Contacts
class Person {
name: String
}
class Phone {
type
countryCode: int
number: int
}
Contacts "1" -- "*" Person
Person "1" -- "*" Phone
```
> Study the above domain model.
> 1. Make an interaction diagram for a user story where a new user with one phone is added.
```mermaid
flowchart
Start -- "addNew(name, type, countryCode, number)" --> :Contacts
:Contacts -- "<< create >>(name, type, countryCode, number)" --> :Person
:Person --"<< create >> (type, countryCode, number)" --> :Phone
```
**Low coupling**, because `Contacts` needn't create `Phone`.
> 2. Make an interaction diagram for a user story to retrieve all phones with a given countryCode.
### Exercise 3: Enrollment
1.
```mermaid
classDiagram
class Enrollment
class Course {
durationInDays: int
}
class CourseEnrollment {
start: Date
end: Date
}
class EnrollmentController {
getGraduationDate(:Enrollment)
}
class EnrollmentService {
getGraduationDate(:Enrollment)
}
Course "1" -- "*" CourseEnrollment
CourseEnrollment --* Enrollment
EnrollmentController --> EnrollmentService
```
3.
```mermaid
sequenceDiagram
actor U as UI
participant EC as :EnrollmentController
participant ES as :EnrollmentService
participant E as e:Enrollment
participant CE as :CourseEnrollment
U ->>+ EC: getGraduationDate(e:Enrollment)
Note over U, EC: e could be the result of automatic parameter<br>parsing, as in e.g. Java Sprint
EC ->>+ ES: getGraduationDate(e:Enrollment)
ES ->>+ E: getGraduationDate()
loop courseEnrollments:CourseEnrollment[*]
ES ->>+ CE: d=getEnd()
Note over ES, CE: finding latest endDate not elaborated
end
ES ->>- EC: d:Date
EC ->>- U: d:Date
```
GRASP patterns:
**Controller**, because `EnrollmentController` is the only point of interaction from the UI.
**Information expert**, because `EnrollmentService` has the information to obtain the graduation date.
**High cohesion**, because all objects do one thing, and they do that well, in order to fulfill the query.
#
**Low couplnig**, because not all objects have knowledge about each other.
## M14 Logical architecture
### EX2 Convert addressbook application to layered architecture
> Adapt the interaction diagrams to fit a 3 layer architecture. Addressbook controller should be stateless.
```mermaid
flowchart TD
ABC[:AddressBookController]
ABS[:AddressBookService]
ABR[:AddressBookRepository]
PS[:PersonService]
PR[:PersonRepository]
AS[:AddressService]
AR[:AddressRepository]
AB[AddressBook]
P[Person]
A[Address]
Start -- "1. addPerson(nm, str, hNr, zip, city)" --> ABC
ABC -- "2. addPerson(nm, str, hNr, zip, city)" --> ABS
ABS -- "3. p=addPerson(nm)" --> PS
PS --"3.1 p=create(nm)" --> PR
PR --"3.2 p=<< create >> (nm) " --> P
ABS -- "4. a=addAddress(str, hNr, zip, city)" --> AS
AS --"3.1 a=create(str, hNr, zip, city)" --> AR
AR --"3.2 a=<< create >>(str, hNr, zip, city)" --> A
ABS -- "5. create(p, a)" --> ABR
ABR -- "5.1 << create >>(p, a)" --> AB
```
> 2. Adapt the design class diagram based on the modified interaction diagrams
> 3. Add a package diagram based on the above diagrams
nah
DDD, RDD, GoF, GRASP, INVEST