SDA SE Wiki

Software Engineering for Smart Data Analytics & Smart Data Analytics for Software Engineering

User Tools

Site Tools


Assignment 6

  • For additional information on OCL see the reference from the OMG.

Task 21: Database Schema

A Drink To Remember

The CoffeeMaker keeps track of all the refillable supplies like paper cups or drink ingredients. For each of these, it has to know the available amount. For particular supplies, it also remembers other details. E.g. for drink ingredients, it needs to know the temperature at which the ingredient needs to be stored. On the other hand, the CoffeeMaker also needs to remember recipes for the individual drinks.

Here is a simplified class model of the relevant entities:

Of course, all of this entities should be persistent - if the CM2K is shutdown and restarted again, it should still remember them. We decided to use a relational DBMS for this job.

Your task:

Give a database schema that represents the above structure.

Notes:

  • Your schema should contain all required table names, colum names, column types, primary indexes, and foreign indexes.
  • You know from the lecture that there are different ways to map inheritance to a database schema. Give a reason for you choice.
  • Please use the SQL syntax described below to specify the schema.
CREATE TABLE tbl_name
    (create_definition,...)

create_definition:
    col_name data_type 
  | PRIMARY KEY (col_name,...)
  | FOREIGN KEY (col_name,...) REFERENCES tbl_name [(col_name,...)]

data_type:
    INT[(length)] 
  | FLOAT[(length,decimals)] 
  | CHAR(length)

BTW: This is a simplified version of the CREATE TABLE syntax used by MySQL. If you are interested in the syntax actually used by MySQL, you can find it in the MySQL reference manual


Task 22: OCL-Warmup (exam style task)

A. Strengthen the given domain model by formulating OCL invarinats which specify the following:

  1. totalPrice can’t be negative
  2. totalPrice will be zero if no items are ordered.
  3. totalPrice really describe the price of the ordered items.
  4. Different items have different ids.

B. Returning back to the example given in the lecture, Express the OCL invariants Inv1 and Inv2 in natural language:

context TournamentControl inv Inv1:
    tournament.players->forAll(p|
        p.tournaments->forAll(t|
            t <> tournament implies
                not t.overlap(tournament)))
 
context Match inv Inv2:
    players->forAll(p|
        p.tournaments->exists(t|
        t.matches->includes(self)))

Task 23:OCL Again (Mousetrap Example)

Setup mousetrap

Actors: MouseExterminator

Flow of events:

  1. Invariant for bar:
    • let f be the restoring force of the spring driving the bar,
    • let D be the spring constant, and x the current angle
    • f = -D * x
    • Precondition: The bar of the mousetrap is released, no bait on trip, previous victim(s) removed
  • Pull back the spring-loaded bar
  • Postcondition: bar is under maximum tension
  • Precondition: the bar is under maximum tension, no bait on trip
  • Invariant: the bar is under maximum tension
  • snap in the trip
  • Postcondition: trip snapped in, bar locked
  • Precondition: trip is snapped in
  • Put bait on trip
  • Postcondition: bait on trip

Successfully trap mice

Actors: Mouse

Flow of Events:

    • Precondition: mousetrap is armed
    • One mouse steps on the trip.
    • Precondition: One or at most two mice are located on the trip/bail
    • The spring-loaded bar is released and kills all mouse on the trap
    • Postcondition: All mice on the trap have been killed

Task

Annotate the classes / operations in the given UML class diagram with corresponding OCL constraints. The diagram should be enough to come up with a valid solution. You may add methods if you want to give the diagram more structure and if you can't figure out how to map the steps otherwise.


Task 24: Refactoring

Check out the project A6T24_ThreeKeyCupApp. We think this code could need some improvement. We have at least eight suggestions. Find four locations, where the code needs improvement. For each of these locations do the following:

  1. Describe what needs to be improved. If there is a smell that corresponds to the situation, name it.
  2. Name the refactoring that can solve the problem.
  3. Execute the refactoring. Make use of the power of the automated refactorings in Eclipse.

We have compiled a list of hints. Feel free to use them, if you don't prefer to explore the code first on your own.


Task 25: Testing

Have a look at the following JUnit test case:


package geometry;
import junit.framework.TestCase;

public class RectangleTest extends TestCase {

  public void testCreation() {
    Rectangle rect1 = new Rectangle();
    assertNull(rect1.getBottomLeft());
    assertNull(rect1.getTopRight());
    Rectangle rect2 = new Rectangle(1, 2, 3, 4);
    assertEquals(new Vertice(1, 2), rect2.getBottomLeft());
    assertEquals(new Vertice(3, 4), rect2.getTopRight());
  }

  public void testGetCenter() {
    Rectangle rect1 = new Rectangle();
    assertNull(rect1.getCenter());
    Rectangle rect2 = new Rectangle(0, 0, 2, 2);
    assertEquals(new Vertice(1, 1), rect2.getCenter());
    Rectangle rect3 = new Rectangle(1, 2, 3, 4);
    assertEquals(new Vertice(2, 3), rect3.getCenter());
  }
  
  public void testContains() {
    //      +-----------+   +---+
    //      |         r |   | s |
    //  +---+---+---+   |   |   |
    //  | l |   | m |   |   |   |
    //  |   |   +---+   |   |   |
    //  |   |       |   |   |   |
    //  +---+-------+   |   +---+
    //      |           |
    //      +-----------+
    Rectangle left = new Rectangle(0, 1, 3, 3);
    Rectangle middle = new Rectangle(2, 2, 3, 3);
    Rectangle right = new Rectangle(1, 0, 4, 4);
    Rectangle somewhere = new Rectangle(4, 1, 6, 4);
    // [ your code for subtask a. would come here ]
  }

  public void testContainsEmptyRectangle(){
    Rectangle somewhere = new Rectangle(4, 4, 8, 8);
    Rectangle nowhere = new Rectangle();
    assertTrue(!somewhere.contains(nowhere));
    assertTrue(!nowhere.contains(somewhere));
  }
  
  public void testAccommodateVertice() {
    Rectangle rect = new Rectangle();
    rect.accommodate(new Vertice(1, 2));
    assertEquals(new Rectangle(1, 2, 1, 2), rect);
    rect.accommodate(new Vertice(-3, -4));
    assertEquals(new Rectangle(-3, -4, 1, 2), rect);
    rect.accommodate(new Vertice(-4, 4));
    assertEquals(new Rectangle(-4, -4, 1, 4), rect);
  }

  public void testAccommodateRectangle() {
    //                      +---+
    //                      | r |
    //      +-----------+   |   |
    //      |         m |   |   |
    //  +---+-------+   |   |   |
    //  | l |       |   |   |   |
    //  +---+-------+   |   +---+
    //      |           |
    //      +-----------+
    Rectangle left = new Rectangle(0, 1, 3, 2);
    Rectangle middle = new Rectangle(1, 0, 4, 3);
    Rectangle right = new Rectangle(4, 1, 6, 4);
    Rectangle rect = new Rectangle();
    rect.accommodate(middle);
    assertEquals(new Rectangle(1, 0, 4, 3), rect);
    rect.accommodate(left);
    assertEquals(new Rectangle(0, 0, 4, 3), rect);
    rect.accommodate(right);
    assertEquals(new Rectangle(0, 0, 6, 4), rect);
  }
  
  public void testCreationWithInvalidArguments(){
    // [ your code for subtask d. would come here ] 
      Rectangle nothing = new Rectangle(2, 2, 1, 1);
    // [ your code for subtask d. would come here ] 
  }
}
 

The RectangleTest test case was written in a test-first manner to define the functionality of a class Rectangle. Read through the methods testCreation() and testGetCenter(). One can see from the test methods how to interpret the constructor parameters and that the getCenter() method really calculates the coordinates of the center of the rectangle (e.g. 2 = (1 + 3) / 2 and 3 = (2 + 4) / 2).

  1. The contains(Rectangle) method should have the natural meaning, i.e. a.contains(b) should return true, if all points of b are in the rectangle a. We already prepared test data in the method testContains(). Write down all possible assertions about these test data that check the implementation of contains(Rectangle).
  2. Comment on the quality of the test data in testContains().
  3. Read through the methods testAccommodateVertice() and testAccommodateRectangle() and explain in one or two sentences what the methods accommodate(Vertice) and accommodate(Rectangle) should do regarding to the test method.
  4. The constructor should throw an InvalidArgumentException with the message “The left bottom vertice must be below and on the left of the right top vertice.“, if called with invalid (see message) arguments. Add the missing code in testCreationWithInvalidArguments() to ensure this at least in one case.
  5. What is “white box” testing? When do we apply it? What are the leading criteria for test case creation?
  6. What is “black box” testing? When do we apply it? What are the leading criteria for test case creation?
  7. Is JUnit mainly used for white or for black box tests? Does it make a difference if we develop the test cases test-first?
teaching/lectures/oosc/2008/exercises/assignment6.txt · Last modified: 2018/05/09 01:59 (external edit)

SEWiki, © 2020