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?

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


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:

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