The learning goals for Week 37 are:
Mon: (at 8.15) The Strategy pattern derived. Wed: Refactoring and Integration Testing. Mandatory Reflections. Definitions of Design Patterns.
Literature:
Slides:
Notes for this weekplan:
The UML presentation (W3-3) is one of those boring 'then-there-is-X-and-Y-and-Z' lectures so it is replaced by a screencast. But do not skip it, because it is important and you will use UML a lot for documenting design in your mandatory project ! While rather boring to remember the difference between a dashed and a full line, or the shape of a diamond and which end it should be at, it is vital that you get it right. It makes a huge difference if you say "The ocean is in the fish" but wanted to say "The fish is in the ocean". I see students at the exam describing their designs using incorrect UML ("The PayStation inherits from Receipt" kind of stuff), and it is not good.
Several modern languages avoid implementation inheritance but keeps (aspects) of the essential 'interface' and 'object implements interface' constructs that are essential to the Strategy pattern. If you want to see one way of implementing PayStation's RateStrategy in Go and Rust, you may have a look at my own katas:
Spend the first 15-20 minutes of the TØ/Lab class in plenum discussing...
The Card
and Hero
interfaces only
have methods to access/read data, not to mutate/write
data. The argument is of course that of 'strong
encapsulation'---we do not want anyone to cheat by modifying
the health value of a card.
To see this, consider the Game method:
public interface Game { Card getCardInField(Player who, int indexInField); ... }
When a client calls:
Card c = game.getCardInField(Player.FINDUS, 0);
... then the returned object is of type Card
, and
only methods mentioned in the interface Card
can
be called. Beware you Python folks: Java is radically more
insisting here than Python is. (Java is 'strongly typed').
There is, however, a problem, as a HotStone game is all about
changing state as the game play progresses---getting that
opponent hero's health to zero. That is, the object
implementing Game
must be able to mutate
objects that represents cards and heroes. So - what to do?
We could consider:
public interface Card {
int getHealth();
void setHealth(int newValue); // ADDED
}
public interface Card { int getHealth(); }
public class StandardCard implements Card {
int getHealth() { return health; }
void setHealth(int newValue) { health = newHealth; }
}
public class StandardGame implements Game {
private StandardCard[][] hand; // Just an example datastructure
}
public class StandardGame implements Game {
private Card[][] hand; // Just an example datastructure
}
StandardCard asStdCard = (StandardCard) card;
asStdCard.setHealth(7);
StandardCard asStdCard = asStandardCard(card);
asStdCard.setHealth(7);
I strongly advice against option 1. Argue why option 1 is a problematic idea.
Next, discuss benefits and liabilities of the other options. (And we will later in the course discuss a fifth option, which solves many of the liabilities of all these options.)
Next, consider mutating the health of a card with either of these two methods:
void setHealth(int newValue);
// Set to
specific health
void changeHealthBy(int delta);
//
Add 'delta' to health
The first method will set health to the given value
'newValue'; whereas the second method will add the given delta
to the current health value, so you will normally use negative
delta values ala
card.changeHealthBy(-2);
Given the specifications and 'feel' of HearthStone which of the two types of methods would you prefer? Argue why.
Optional Exercises:
These are optional exercises. Be sure to solve the mandatory project first, and only if you have a lot of spare time, try having a look at the exercises below.
7.5 7.6 9.1 9.3Rehearse a TDD exam situation. Spend 20-25 minutes to read and prepare a 10 minute oral presentation of one of the TDD exercises in the example exam question set: demo-question-final-2023.pdf.
Next, do a 10 minute presentation at the whiteboard in front of your team.
The team provides constructive feedback on the presentation: Is your presentation clear and understandable, do you discuss the concepts and terms correctly, is you Java example code correct, etc. Swap and ensure all in the team gets a chance to rehearse the situation.