public class Game {
private char[][] board;
}
Is that the best we can do?
public class Book {
private String authorName;
private String publicationDate;
private String ISBN;
}
public class Book {
private Author author;
private YearMonth publication; // Java 8
private ISBN isbn;
}
public class Triangle {
private Side[] sides = new Side[3];
private Angle[] angles = new Angle[3];
}
Is this what you were thinking?
public class Board {
private Tile[][] tile;
}
Pretty simple, right?
public interface Tile {
boolean isSolid();
}
public enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY,
FRIDAY, SATURDAY, SUNDAY;
}
If each day is a constant,
it will be a big waste to have more
than one instance of each!
public enum Cell {
DEAD {
@Override
public Cell nextGeneration(int aliveNeighbors) {
if (aliveNeighbors == 3) {
return ALIVE;
}
return this;
}
},
ALIVE {
@Override
public Cell nextGeneration(int aliveNeighbors) {
if (aliveNeighbors == 2 || aliveNeighbors == 3) {
return this;
}
return DEAD;
}
};
public abstract Cell nextGeneration(int aliveNeighbors);
}
If the JVM can do it for you, why you
would try to do it yourself!
But the biggest problem is understanding
when to use a Singleton
public enum Tile {
EMPTY {
public String toString() {
return " ";
}
},
WALL {
public boolean isSolid() {
return true;
}
public String toString() {
return "#";
}
},
PILL {
public String toString() {
return ".";
}
},
SUPER_PILL {
public String toString() {
return "o";
}
};
public boolean isSolid() {
return false;
}
}
Ship ship = new BattleShip();
public class Ships {
public static Ship build(String type) {
switch(type) {
case "BattleShip":
return new BattleShip();
case "AirCraft":
return new Aircraft();
case "Submarine":
return new Submarine();
case "Destroyer":
return new Destroyer();
case "Patrol":
return new PatrolBoat();
default:
return null;
}
}
}
public class Ships {
public static Ship build(String type) {
switch(type) {
case "BattleShip":
return new BattleShip();
case "AirCraft":
return new Aircraft();
case "Submarine":
return new Submarine();
case "Destroyer":
return new Destroyer();
case "Patrol":
return new PatrolBoat();
default:
return null;
}
}
}
public enum Type {
BATTLESHIP, AIRCRAFT, SUBMARINE, DESTROYER, PATROL;
}
public class Ships {
public static Ship build(Type type) {
switch(type) {
case BATLLESHIP:
return new BattleShip();
case AIRCRAFT:
return new Aircraft();
case SUBMARINE:
return new Submarine();
case DESTROYER:
return new Destroyer();
case PATROL:
return new PatrolBoat();
default:
return null;
}
}
}
public class Ships {
public static Ship build(Type type) {
switch(type) {
case BATLLESHIP:
return new BattleShip();
case AIRCRAFT:
return new Aircraft();
case SUBMARINE:
return new Submarine();
case DESTROYER:
return new Destroyer();
case PATROL:
return new PatrolBoat();
}
}
}
public class Ships {
public static Ship build(Type type) {
switch(type) {
case BATLLESHIP:
return new BattleShip();
case AIRCRAFT:
return new Aircraft();
case SUBMARINE:
return new Submarine();
case DESTROYER:
return new Destroyer();
default:
return new PatrolBoat();
}
}
}
public class Ships {
public static Ship build(Type type) {
switch(type) {
case BATLLESHIP:
return new BattleShip();
case AIRCRAFT:
return new Aircraft();
case SUBMARINE:
return new Submarine();
case DESTROYER:
return new Destroyer();
case PATROL:
return new PatrolBoat();
default:
throw new AssertionError(String.format("Unrecognised type %s", type));
}
}
}
public class Board {
Ship[] ships = { Ships.build(BATTLESHIP),
Ships.build(AIRCRAFT), Ships.build(SUBMARINE),
Ships.build(DESTROYER), Ships.build(PATROL)};
}
How code would use the Factory?
public class Ships {
public static Ship build(Type type) {
return new BaseShip(type.getHitPoints());
}
}
public enum Type {
EMPTY, WALL, PILL, SUPER_PILL;
public static Tile of(char representation) {
switch (representation) {
case ' ':
return EMPTY;
case '#':
return WALL;
case '.':
return PILL;
case 'o':
return SUPER_PILL;
default:
throw new AssertionError(String.format(
"Unsupported cell representation %s", representation));
}
}
}
public class Board {
private final int height;
private final int width;
private final Map<Coordinate, Tile> board;
}
public class Coordinate {
private final int row;
private final int column;
private Coordinate(int row, int column) {
this.row = builder.row;
this.column = builder.column;
}
public int getRow() {
return row;
}
public int getColumn() {
return column;
}
}
Coordinate coordinate = new Coordinate(2, 1);
public class Triangle {
private final Side[] sides;
public static class Builder {
private final Side[] sides = new Side[3];
public Builder withA(Side a) {
side[0] = a;
return this;
}
public Builder withB(Side b) {
side[1] = b;
return this;
}
public Builder withC(Side c) {
side[2] = c;
return this;
}
public Triangle build() {
return new Triangle(this);
}
}
public Triangle(Builder builder) {
this.sides = builder.sides;
}
}
Triangle t1 = new Triangle.Builder()
.withA(Side.of(3.0))
.withB(Side.of(4.0))
.withC(Side.of(5.0))
.build();
Triangle t2 = new Triangle.Builder()
.withAlpha(Angle.degrees(60.0))
.withC(Side.of(5.0))
.withBeta(Angle.degrees(60.0))
.build();
Triangle t3 = new Triangle.Builder()
.withA(Side.of(10.0))
.withGamma(Angle.degrees(90.0))
.withB(Side.of(10.0))
.build();
public class Coordinate {
private final int row;
private final int column;
public static class Builder {
private int row;
private int column;
public Builder withRow(int row) {
this.row = row;
return this;
}
public Builder withColumn(int column) {
this.column = column;
return this;
}
public Coordinate build() {
return new Coordinate(this);
}
}
private Coordinate(Builder builder) {
this.row = builder.row;
this.column = builder.column;
}
}
Coordinate c1 = new Coordinate.Builder()
.withRow(1)
.withColumn(2)
.build();
but is it too much verbose for
just two attributes?
public class Coordinate {
private static final int[] dx = {-1, 0, 0, 1};
private static final int[] dy = { 0,-1, 1, 0};
private static final int totalNeighbors = dx.length;
private final int row;
private final int column;
// more code
public List<Coordinate> neighbors() {
List<Coordinate> neighbors = new ArrayList<>(totalNeighbors);
for (int i = 0; i < totalNeighbors; ++i) {
Coordinate neighbor = new Coordinate.Builder()
.withRow(row + dx[i])
.withColumn(column + dy[i])
.build();
neighbors.add(neighbor);
}
return Collections.unmodifiableList(neighbors);
}
}
Collections.unmodifiableList(neighbors);
public class UnmodifiableList<E> implements List<E> {
private List<E> data:
public UnmodifiableList(List<E> component) {
this.data = component;
}
@Override
public int size() { // delegated
return data.size();
}
@Override
public boolean add(E e) { // decorated
throw new UnsupportedOperationException();
}
// more code
}
BufferedReader br =
new BufferedReader(new InputStreamReader(System.in));
BufferedReader br2 =
new BufferedReader(new FileReader("foo.txt"));
public static <T> List<T> unmodifiableList(List<? extends T> list)
It works by the magic of Polymorphism!
Try to explain that with the typical definitions of polymorphism!
List<String> data = new ArrayList<>();
That's not the best example!
public Coordinate move() {
if (this.escaping) {
// code to escape
} else {
// code to move normally
}
}
public class ChaserGhost {
public Coordinate move() {
// code to chase
}
}
public class Inky extends ChaserGhost {
}
public class GhostBehavior {
Coordinate move(Coordinate paceman, Board board);
}
public class AmbushBehavior implements GhostBehavior {
@Override
public Coordinate move(Ghost ghost, Pacman pacman, Board board) {
// code to ambush
}
}
public class ChaseBehavior implements GhostBehavior {
@Override
public Coordinate move(Ghost ghost, Pacman pacman, Board board) {
// code to chase
}
}
public abstract class CommonGhost {
private GhostBehavior behavior;
public CommonGhost(GhostBehavior behavior) {
setBehavior(behavior);
}
public Coordinate move(Pacman paceman, Board board) {
return behavior.move(paceman, board);
}
public void setBehavior(GhostBehavior behavior) {
this.behavior = Objects.requireNotNull(behavior);
}
}
public class Inky {
public Inky() {
super(new ChaseBehavior());
}
}
public class Binky {
public Binky() {
super(new AmbushBehavior());
}
}
public class Game {
private Ghost[] ghosts = {new Inky(), new Blinky,
new Pinky(), new Clyde()};
public void run() {
// code
if (tile == Tile.SUPER_PILL) {
for (Ghost ghost: ghosts) {
ghost.setBehavior(new EscapeBehavior());
}
}
// code
}
}
public class ButtonDemo extends JPanel
implements ActionListener {
protected JButton b1, b2, b3;
public ButtonDemo() {
b1 = new JButton("Disable middle button", leftButtonIcon);
b1.setActionCommand("disable");
b2 = new JButton("Middle button", middleButtonIcon);
b3 = new JButton("Enable middle button", rightButtonIcon);
//Listen for actions on buttons 1 and 3.
b1.addActionListener(this);
b3.addActionListener(this);
//Add Components to this container, using the default FlowLayout.
add(b1);
add(b2);
add(b3);
}
public void actionPerformed(ActionEvent e) {
if ("disable".equals(e.getActionCommand())) {
b2.setEnabled(false);
b1.setEnabled(false);
b3.setEnabled(true);
} else {
b2.setEnabled(true);
b1.setEnabled(true);
b3.setEnabled(false);
}
}
}
int bfs(Node source, Node destination) {
Queue<Coordinate> moves = new ArrayDeque<>();
Map<Coordinate, Coordinate> antecessor = new HashMap<>();
Map<Coordinate, Integer> distance = new HashMap<>();
moves.add(origin);
antecessor.put(origin, null);
distance.put(origin, 0);
while (!moves.isEmpty()) {
Node current = moves.poll();
if (current.equals(destination)) {
return distance.get(current);
}
for (Node neighbor: current.neighbors()) {
if (!antecessor.containsKey(neighbor)) {
moves.add(neighbor);
antecesor.put(neighbor, current);
distance.put(neighbor, distance.get(current) + 1);
} }
}
}
return -1;
}