As most Design Patterns, Strategy pattern is an incredibly useful pattern to express polimorphic behaviour.
I don't pretend to explain Strategy pattern on this post. My intention is only to show you a nice way of implementing the pattern using a Java Enum.
Sometimes the difference between strategies is small, and you have control over all the strategies. (There is no intention that a client implements its own strategy).
Also, usually each strategy comes in the form of a Singleton instance.
It would be nice to have all Strategies in a common place, sharing a common namespace.
All the previous can be addressed with the use of the Enum construct in Java 1.5+
Let's suppose a Voice "strategizable" class, with two concrete strategies Screaming Voice and Whisper Voice
This is how we would do this with an Enum.
public enum Voice {
SCREAM(){
@Override
public String say(String say){ return say.toUpperCase()+" !!";}
},
WHISPER(){
@Override
public String say(String say){return say.toLowerCase()+ " please ";}
};
public abstract String say(String say);
}
There we have our two Strategy implementations under the same namespace (the ENUM type), singleton guaranteed. To test the startegy we have the following test case.
package misc;
import org.junit.Test;
import static org.junit.Assert.*;
public class VoiceTest {
@Test
public void testVoice() {
// if in good mood
VoiceUser user = new VoiceUser(Voice.WHISPER);
// if in bad mood
VoiceUser user2 = new VoiceUser(Voice.SCREAM);
assertEquals("do that please", user.askSomeone());
assertEquals("DO THAT !!", user2.askSomeone());
}
}
class VoiceUser {
public VoiceUser(Voice voice) {
this.voice = voice;
}
Voice voice;
String askSomeone() {
String string = "Do that";
return voice.say(string);
}
}