Published on

CS 3500 Day 10

Authors
  • avatar
    Name
    Jacob Aronoff
    Twitter

Object Oriented Design

Today we're talking about mocks. Mocks are components that can replace an actual componeny. They are very useful for testing purposes. We call these components 'stubs'.

Now back to the rest of the lecture:

We're talking about encapsulation, specifically in the context of connect N:

When we're using multiple dimensions, it's easiest to use a map:

Map<String, Integer> configuration;




Status status;
Object turn;

Object hypercolumns;

But what about status? To add it into our generalization, we simply change Integer to Object. If we keep abstracting, we get:

Map<String, Object> properties;

By doing so, we lost meaning and intent. We gained flexibility though! aWe also basically threw out the type system. If we bring back everything:

int width;
int height;
int goal;
int players;

Status status;
int turn;

List<List<Integer>> columns;

What's bad?

  • width or height or goal or players might change mid-game
  • status or columns might be null
  • width or height or goal or players might be zero or negative
  • the shape of the list-of-lists in columns might not match the dimensions in width and height
  • or it might contain Integers that don’t stand for actual players
  • and the client can look at or change whatever it pleases

To fix this, use final as much as possible! Ensure correct initialization! Also use the proper access level modifiers:

Modifier Scope

private same class only

default ...and everything else in the package

protected ...and subclasses

public ...and the rest of the world

Invariance

Preserving the “validity” of an object Don’t let outsiders access it If possible make it final so that once valid, always valid What about mutable objects?

final class Even {
  public Even(int value) {
    if (value % 2 != 0) {
      throw IllegalArgumentException("value must be even");
    }

    this.value = value;
  }

  public int getValue() {
    return value;
  }
  private final int value;
}

An invariant is:

a logical statement about the instantaneous state of an object that is ensured by the constructors and preserved by the methods.

If these are met, it's an invariant:

  • logical statement: a claim that is true or false
  • the instantaneous state of an object: meaning the values in its fields at a point in time
  • ensured by the constructors: when a constructor finishes normally then the claim is true
  • preserved by the methods: if the claim is true before a method is called then it is true afterward

Examples of invariants:

private final int width;
// INVARIANT (1): width is not null
// INVARIANT (2): width > 0
// INVARIANT (3): width > height
// INVARIANT (4): width never changes
private int turn;
// INVARIANT (5): turn only increases
// INVARIANT (6): turn > 0
// INVARIANT (7): turn < players
private List<List<Integer>> columns;
// INVARIANT (1): columns != null
// INVARIANT (2): columns.size() == width
// INVARIANT (3): columns.get(col) != null if 0 <= col < width
// INVARIANT (4): every column in columns has size <= height
// INVARIANT (5): every Integer in columns is a valid player
//                in (0, players]
// NOT AN INVARIANT: columns
// NOT AN INVARIANT: columns agrees with width
// NOT AN INVARIANT: columns always refers to the same list
// INVARIANT BUT VACUOUS: columns is a list