Converting many 'if else' statements to a cleaner approach
JavaDesign PatternsJava Problem Overview
My code here detects if the mimeType
is equals to some MIME type, if it is, it will do a certain conversion
public void convertToMp3(File src, File target,String mimeType){
if(mimeType.equals("audio/mpeg")){
...
}else if(mimeType.equals("audio/wav")){
mp3ToWav();
}else if(mimeType.equals("audio/ogg")){
...
}else if(...){
... //More if and else here
}
I have shortened my code, because it has a lot of else if statements, What design pattern is suitable for removing many if and else or else if statements?
Java Solutions
Solution 1 - Java
You could have a Converter
interface. Then you could create a class for each Mimetype like:
public interface Converter {
public void convertToMp3();
public void convertToOgg();
}
public class MpegConverter implements Converter {
public void convertToMp3() {
//Code here
}
public void convertToOgg() {
//Code here
}
}
You would need a class like this for each converter. Then you could set up a map like this:
Map<String, Converter> mimeTypeMap = new HashMap<String, Converter>();
mimeTypeMap.put("audio/mpeg", new MpegConverter());
Then your convertToMp3
method becomes like this:
Converter converter = mimeTypeMap.get(mimeType);
converter.convertToMp3();
Using this approach you could easily add different converters in the future.
All untested, probably doesn't compile, but you get the idea
Solution 2 - Java
If you use pre-JDK7, you may add an enum for all MIME types:
public static enum MimeTypes {
MP3, WAV, OGG
}
public class Stuff {
...
switch (MimeTypes.valueOf(mimeType)) {
case MP3: handleMP3(); break;
case WAV: handleWAV(); break;
case OGG: handleOGG(); break;
}
}
And have a look at the Stack Overflow question Java - Convert String to enum on how to convert Strings to enums.
Solution 3 - Java
Consider using the Strategy design pattern and a Map
to dispatch to the appropriate strategy. Particularly useful if you you will need additional functionality, in addition to a conversion for a particular mimeType
, or the convertors are large and complicated code and you would want to place each convertor in its own .java
file.
interface Convertor {
void convert(File src, File target);
}
private static void convertWav(File src, File target) {
...
}
...
private static final Map< String, Convertor > convertors = new ...;
static {
convertors.put("audio/wav", new Convertor {
void convert(File src, File target) {
convertWav(src, target);
}
});
convertors.put("audio/ogg", new Convertor {
void convert(File src, File target) {
convertOgg(src, target);
}
});
...
}
public void convertToMp3(File src, File target, String mimeType){
final Convertor convertor = convertors.get(mimeType);
if (convertor == null ) {
...
} else {
convertor.convert(src, target);
}
}
Solution 4 - Java
If you run the same methods for each case you should check State pattern
Solution 5 - Java
If you are using JDK 7
, you can use switch-case
construct:
See: https://stackoverflow.com/questions/338206/switch-statement-with-strings-in-java
For prior versions, if-else
is the only choice.
Solution 6 - Java
It's definitely a Strategy design pattern. But you have a big problem in your general design. It's not a good programming habit to use String to identify a type. Simply because it's easily editable and you can make a grammar mistake and spend all the afternoon looking for a programming mistake. You can avoid using map<>.
I suggest the following:
- Extend class File. The new class adds a new attribute FileType and a new method convertTo(FileType) to class File. This attribute holds its type: “audio” , “wav”... and again don't use String, Use Enum. In this case I called it FileType. Extend File as much as you want: WavFile, AudioFile...
- Use a Strategy dp to create your converters.
- Use a Factory dp to initialize the converters.
- Since every File knows its own type and the target type (use convertTo() method to specify the target type) it will call the factory to get the correct Converter automatically!!!
This design is scalable and you can add as much as you need FileType and converters. The answer you vote for is misleading!!!! There is a big difference between coding and hacking.
Solution 7 - Java
If you are not using Java 7 you could create an enum
and use that value with a switch
case. You then only need to pass the enum value (rather than a file, I don't why you are doing that). It would look neater too.
These should help with what you want to do:
[Java Enum Examples][1] -
[Java Switch Case examples][2]