Object oriented
Object-oriented programming is asking objects to do something: a deceptively complex concept to apply correctly.
Goban
Consider a two-dimensional game panel, for example, to play Go (called gobana).
First think about the behavior you need to complete your task. This means listing the behavior for an object, rather than defining the data that manipulates the behavior. For example, a baseboard may have the following types of behavior:
- Place the stone of the Year.
- Remove the Go stone.
- Remove all stones.
For the computer version of Go, it’s convenient to draw attention to specific areas:
- Mark the intersection (e.g. triangle, number, letter, circle, square).
- Remove the mark from the marked intersection.
- Remove all tags.
Please note that gobans should not provide a way to provide customers with links to the stone at a particular intersection. Instead, he can answer questions about his condition. For example, a gobana may answer the following questions:
- Is there a black stone at this intersection?
- Is there a white stone at this intersection?
- Is there a mark at this intersection?
Goban is not responsible for the state of the game: this belongs to the instance of the game (which has the Rules). In real life, a gobana is just a scene for stones.
At this stage, we could write an interface for gobana, not knowing how the basic implementation will work.
public interface Goban { public void place( Stone stone, Point point ); public void removeStone( Point point ); public void removeStones(); public void place( Mark mark, Point point ); public void removeMark( Point point ); public void removeMarks(); public boolean hasWhiteStone( Point point ); public boolean hasBlackStone( Point point ); public boolean hasMark( Point point ); }
Please note that the board is clearly separated from the rules and games. This makes gobans reusable for other games (including stones and intersections). Goban can inherit from a common interface (for example, the Board interface), but this is enough to explain one way of thinking in terms of objects.
Encapsulation
The implementation of the Goban interface does not provide its internal data. At this point, I could ask you to implement this interface, write unit tests, and send me a compiled class when you are done.
I do not need to know which data structures you used. I can use your implementation to play (and portray) Goban. This is an important point when many projects are mistaken. Many, many projects encode the following:
public class Person { private HairColour hairColour = new HairColour( Colour.BROWN ); public Person() { } public HairColour getHairColour() { return hairColour; } public void setHairColour( HairColour hairColour ) { this.hairColour = hairColour; } }
This is ineffective encapsulation. Consider a case where Bob does not like his hair to be pink. We can do the following:
public class HairTrickster { public static void main( String args[] ) { Person bob = new Person(); HairColour hc = bob.getHairColour(); hc.dye( Colour.PINK ); } }
Bob's hair was now pink, and nothing could stop it. There are ways to avoid this situation, but people do not. Instead, encapsulation is broken, resulting in hard, inflexible, distorted errors and unsupported systems.
One possible way to ensure encapsulation is to return the HairColour clone. The revised Person class now makes it difficult to change hair color to Pink.
public class Person { private HairColour hairColour = new HairColour( Colour.BROWN ); public Person() { } public HairColour getHairColour() { return hairColour.clone(); } public void setHairColour( HairColour hairColour ) { if( !hairColour.equals( Colour.PINK ) { this.hairColour = hairColour; } } }
Bob can sleep peacefully, knowing that he will not wake up to the pink paint job.