5. Numeric Processing Examples

5.4. OBJECT-ORIENTED DESIGN: Information Hiding

The fact that our new versions of OneRowNim – we've developed two new versions in this chapter – are backward compatible with the previous version is due in large part to the way we have divided up its public and private elements. Because the new versions still present the same public interface, programs that use the OneRowNim class, such as the OneRowNimApp from Chapter 4 (Fig. 4.24), can continue to use the class without changing a single line of their own code. To confirm this, see the Self-Study Exercise at the end of this section.

public class OneRowNim 

{ public static final int PLAYER.ONE = 1; 

public static final int PLAYER:IWO= 2; 

public static final int MAX_PICKUP= 3; 

public static final int MAXSTICKS = 11; 

public static final boolean GAMEDVER = false; 

private int nSticks = MAX_SIICKS;

private boolean onePlaysNext = true;                     

public OneRowl'Sm() { //OneRowNim() constructorl 

public OneRowlstun(int sticks)

{ nSticks = sticks;

} // OneRowNim() constructor2 

public OneRowbrun(int sticks, int starter)

{ nSticks = sticks;

onePlaysNext = (starter == PLAYERDNE);

} // OneRowNim() constructor3 

public boolean takeSticks(int num)

{ if (num < 1 I num > MA)U'ICKUP I I num > nSticks )

return false; // Error else // Valid move

{ nSticks = nSticks — rum;

onePlaysNext = !onePlaysNext;

return true;

} //else

} // takeSticks() 

public int getSticks()

{ return nSticks; }

}//getSticks 

public int getPlayer()

{ if (onePlaysNext)

return PLAYER_ONE;

else return PLAYER_TWO;

} //getPlayer() 

public boolean gameOver()

{ return (nSticks <= 0); }

} // gameOver () 

public int getWinner()

{ if (nSticks < 1)

return getPlayer ();

else return 0; // Came is not over

} // getWinner() 

public String report()

{ return ("Number of sticks left : " + getSticks()

+ "\ nNext turn by player " + getPlayer () + " \ n" );

} // report ()

} // OneRowNim class 

Figure 5.8: This version of OneRowNim uses named constants.

Although we have made significant changes to the underlying representation of OneRowNim, the implementation details – its data and algorithms – are hidden from other objects. As long as OneRowNim's public interface remains compatible with the old version, changes to its private elements won't cause any inconvenience to those objects that were dependent on the old version. This ability to change the underlying implementation without affecting the outward functionality of a class is one of the great benefits of the information hiding principle.

JAVA EFFECTIVE DESIGN

Information Hiding. In designing a class, other objects should be given access just to the information they need and nothing more.


The lesson to be learned here is that the public parts of a class should be restricted to just those parts that must be accessible to other objects. Everything else should be private. Things work better, in Java programming and in the real world, when objects are designed with the principle of information hiding in mind.


SELF-STUDY EXERCISE 

EXERCISE 5.4 To confirm that our new version of OneRowNim still works correctly with the user interfaces we developed in Chapter 4, compile and run it with OneRowNimApp (Fig. 4.24).