Encapsulation
CS 3500, Fall 2015
Back to Connect $N$
Our model’s interface
static enum Status { Playing, Stalemate, Won, }
Status getStatus();
boolean isGameOver();
int getNextPlayer();
int getWinner();
Integer getPlayerAt(int x, int y);
boolean isColumnFull(int which);
int move(int who, int where);
int getWidth(); int getHeight();
int getGoal(); int getPlayers();
What fields do we need?
int width;
int height;
int goal;
int players;
Status status;
int turn;
List<List<Integer>> columns;
How about some more flexibility‽
Why commit to players being int
s?
int width;
int height;
int goal;
int players;
Status status;
int turn;
List<List<Integer>> columns;
More flexibility!
int width;
int height;
int goal;
int players;
Status status;
Object turn;
List<List<Object>> columns;
What if we want 3-D Connect $N$?
int width;
int height;
int goal;
int players;
Status status;
Object turn;
List<List<Object>> columns;
Or $k$-D Connect $N$?
int width;
int height;
int goal;
int players;
Status status;
Object turn;
List<List<Object>> columns;
That’s better
int width;
int height;
int goal;
int players;
Status status;
Object turn;
Object hypercolumns;
Width and height are only 2-D
int width;
int height;
int goal;
int players;
Status status;
Object turn;
Object hypercolumns;
Ah, this is more general
Map<String, Integer> dimensions;
int goal;
int players;
Status status;
Object turn;
Object hypercolumns;
But what about goal & players?
Map<String, Integer> dimensions;
int goal;
int players;
Status status;
Object turn;
Object hypercolumns;
Into the Map
with them!
Map<String, Integer> configuration;
Status status;
Object turn;
Object hypercolumns;
In $k$-D, status might get interesting
Map<String, Integer> configuration;
Status status;
Object turn;
Object hypercolumns;
Better not limit it
Map<String, Object> properties;
Object turn;
Object hypercolumns;
Hmm, I dunno about turn
Map<String, Object> properties;
Object turn;
Object hypercolumns;
The Map
means we decide later!
Map<String, Object> properties;
Object hypercolumns;
Go big or go home
Map<String, Object> properties;
Our model representation is now as flexible as can be
Do we like it?
ಠ_ಠ
What’s the trade-off here?
We gained flexibility
We lost meaning and intent
Let’s try the other direction
Does this representation allow too much freedom?
int width;
int height;
int goal;
int players;
Status status;
int turn;
List<List<Integer>> columns;
Bad freedoms
width
orheight
orgoal
orplayers
might change mid-gamestatus
orcolumns
might benull
width
orheight
orgoal
orplayers
might be zero or negativethe shape of the list-of-lists in
columns
might not match the dimensions inwidth
andheight
or it might contain
Integer
s that don’t stand for actual playersand the client can look at or change whatever it pleases
Use final
wherever you can
If it shouldn't change, let the compiler check for you that it doesn't
final int width;
final int height;
final int goal;
final int players;
Status status;
int turn;
List<List<Integer>> columns;
Use final
wherever you can
If it shouldn't change, let the compiler check for you that it doesn't
final int width;
final int height;
final int goal;
final int players;
Status status;
int turn;
final List<List<Integer>> columns;
Use private
whenever you can
As soon as a client depends on a field, you support that field forever
private final int width;
private final int height;
private final int goal;
private final int players;
private Status status;
private int turn;
private List<List<Integer>> columns;
Principle of least privilege
Every program and every privileged user of the system should operate using the least amount of privilege necessary to complete the job.—Jerome Saltzer
Encapsulation
Any pair of integers looks like any other
Methods give meaning to the data
Hiding the fields preserves meaning and adds flexibility
Access levels
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 |
Where can it be seen from?
Modifier | class | package | subclass | world |
---|---|---|---|---|
private | ✓ | ✗ | ✗ | ✗ |
default | ✓ | ✓ | ✗ | ✗ |
protected | ✓ | ✓ | ✓ | ✗ |
public | ✓ | ✓ | ✓ | ✓ |
Who can see members of Base
?
package left; package right;
public class Base { ... } public class Derived
extends Base { ... }
public class lefthelper { ... } public class righthelper { ... }
Modifier | Base | LeftHelper | Derived | RightHelper |
---|---|---|---|---|
private | ✓ | ✗ | ✗ | ✗ |
default | ✓ | ✓ | ✗ | ✗ |
protected | ✓ | ✓ | ✓ | ✗ |
public | ✓ | ✓ | ✓ | ✓ |