将许多“ if else”语句转换为更清晰的方法

我在这里的代码检测 mimeType是否等于某种 哑剧类型,如果是,它将执行一定的转换

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
}

我已经缩短了我的代码,因为它有很多 否则语句,什么样的设计模式是适合删除很多 如果别的否则语句?

41056 次浏览

If you are using JDK 7, you can use switch-case construct:

See: Why can't I switch on a String?

For prior versions, if-else is the only choice.

If you run the same methods for each case you should check State pattern

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

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.

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]

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);
}
}

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:

  1. 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...
  2. Use a Strategy dp to create your converters.
  3. Use a Factory dp to initialize the converters.
  4. 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.