Reputation: 331
I have a series of switch cases, but it seems a bit too complicated. What is the best way to simplify it? I was thinking of using the strategy design pattern.
My initial thoughts were to make sendReport into a single method, with the method calling sendReport from each of the different classes. However, I am not sure how to implement this. Would anyone give me some guidance, and maybe some suggestions on what I could do to make this switch cases simpler.
Thank you.
public static boolean sendReport(AuthToken token, Student client, List<ContactMethod> bestOptions, String data) {
for (ContactMethod method : bestOptions) {
switch (method) {
case TEXT:
String textMessage = client.getPhoneNumber();
if (null != textMessage) {
TEXT.sendReport(token, client.getFName(), client.getLName(), data, textMessage);
return true;
}
break;
case POST:
String address = client.getAddress();
String suburb = client.getSuburb();
String state = client.getState();
String postcode = client.getPostCode();
if (null != address && null != suburb &&
null != state && null != postcode) {
Mail.sendReport(token, client.getFName(), client.getLName(), data, address, suburb, state, postcode);
return true;
}
break;
case ELECTRONICMAIL:
String email = client.getEmailAddress();
if (null != email) {
Email.sendReport(token, client.getFName(), client.getLName(), data, email);
return true;
}
break;
case VOICECALL:
String number = client.getPhoneNumber();
if (null != number) {
PhoneCall.sendReport(token, client.getFName(), client.getLName(), data, number);
return true;
}
break;
case FACE_TO_FACE:
String face2face = client.getFace2Face();
String personName = client.getPersonName();
if (null != face2face && null != personName) {
Face_To_Face.sendReport(token, client.getFName(), client.getLName(), data, face2face,personName);
return true;
}
break;
case MAGIC:
String magicID = client.getMagic();
if (null != magicID) {
magic.sendReport(token, client.getFName(), client.getLName(), data, magicID);
return true;
}
break;
default:
return false;
}
}
return false;
}
Upvotes: 0
Views: 889
Reputation: 4034
Yes, an implementation of the Strategy/Policy pattern would do the job. And basically, two out of the three already existing answers show a possible implementation for that pattern (Michael's answer and Ali Gelenler's answer), although Michael does not think that his implementation would follow a pattern …
If the set of possible contact methods is fixed, you can even add sendReport()
as a method to the enum, with different implementations for each enum instance. This spares you a dedicated registry for the strategies (and you do not need to define several different classes).
The cleaner path would be (as suggested by the already mentioned answers) to define an interface ContactMethod
and to implement that for each method of contact you need. It has the advantage that you can easily add additional contact methods (in particular if you utilise the java.util.ServiceLoader
API).
The disadvantage is that, if the contact method is an attribute of an externalised entity, you need some kind of a registry for the strategies and a mapping from the name of the strategies to their implementations – as said, something you get for free, when you extend (abuse?) the enums.
Upvotes: 1
Reputation: 241
Define a common interface ContactMethod having a sendReport method and create different implementation classes for each switch case that implement the ContactMethod. For example;
public static boolean sendReport(AuthToken token, Student client, List<ContactMethod> bestOptions, String data) {
for (ContactMethod method : bestOptions) {
if (method.sendReport(token, client, data))
return true;
}
}
public class TextContactMethod implements ContactMethod {
public boolean sendReport(AuthToken token, Student client, String data) {
String textMessage = client.getPhoneNumber();
if (null != textMessage) {
TEXT.sendReport(token, client.getFName(), client.getLName(), data, textMessage);
return true;
}
return false;
}
}
Upvotes: 1
Reputation: 718758
I would simply make the switch "blocks" into methods and call them; e.g.
public static boolean sendReport(AuthToken token, Student client,
List<ContactMethod> bestOptions,
String data) {
for (ContactMethod method : bestOptions) {
boolean res;
switch (method) {
case TEXT:
res = processText(token, client, data);
break;
case POST:
res = processPost(token, client, data);
break;
...
default:
res = false;
}
if (res) {
return true;
}
}
return false;
}
private boolean processText(AuthToken token, Student client) {
String textMessage = client.getPhoneNumber();
if (null != textMessage) {
TEXT.sendReport(token, client.getFName(), client.getLName(),
data, textMessage);
return true;
} else {
return false;
}
}
Sure, you could dress that up with a design pattern, but simple procedural abstraction works just as well.
Upvotes: 2
Reputation: 44110
You don't even need a design pattern, you just need basic polymorphism.
Change ContactMethod
from an enum to an interface. Each case statement becomes an implementation of the interface
public class TextContactMethod implements ContactMethod { ... }
sendReport
becomes
for (ContactMethod method : bestOptions) {
method.fooBar(token, client);
}
Upvotes: 2