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

时间:2013-01-03 10:10:07

标签: java design-patterns

此处的代码会检测mimeType是否等于某种MIME类型,如果是,则会进行某种转换

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
}

我缩短了我的代码,因为它有很多 else if 语句,什么设计模式适合删除许多 if else else if 语句?

7 个答案:

答案 0 :(得分:192)

您可以拥有Converter界面。然后你可以为每个Mimetype创建一个类,如:

public interface Converter {

    public void convertToMp3();
    public void convertToOgg();

}

public class MpegConverter implements Converter {

    public void convertToMp3() {
        //Code here
    }

    public void convertToOgg() {
        //Code here
    }

}

每个转换器都需要这样的类。然后你可以设置这样的地图:

Map<String, Converter> mimeTypeMap = new HashMap<String, Converter>();

mimeTypeMap.put("audio/mpeg", new MpegConverter());

然后你的convertToMp3方法就像这样:

Converter converter = mimeTypeMap.get(mimeType);
converter.convertToMp3();

使用这种方法,您可以在将来轻松添加不同的转换器。

所有未经测试的,可能都没有编译,但你明白了

答案 1 :(得分:23)

如果您使用pre-JDK7,则可以为所有MIME类型添加枚举:

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

并查看有关如何将字符串转换为枚举的Stack Overflow问题 Java - Convert String to enum

答案 2 :(得分:15)

考虑使用策略设计模式和Map来分配适当的策略。除了特定mimeType的转换之外,如果您还需要其他功能,或者转换器是大而复杂的代码,并且您希望将每个转换器放在其自己的.java文件中,则特别有用。

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

答案 3 :(得分:3)

如果您为每个案例运行相同的方法,您应该检查State pattern

答案 4 :(得分:2)

如果您使用的是JDK 7,则可以使用switch-case construct:

请参阅:Why can't I switch on a String?

对于以前的版本,if-else是唯一的选择。

答案 5 :(得分:2)

这绝对是一种战略设计模式。但是你的总体设计存在很大问题。使用String来识别类型并不是一个好的编程习惯。只是因为它很容易编辑,你可以犯一个语法错误,整个下午都在寻找编程错误。您可以避免使用地图&lt;&gt;。

我建议如下:

  1. 扩展类文件。新类将新属性FileType和新方法convertTo(FileType)添加到类File。此属性保持其类型:“audio”,“wav”...并且再次不使用String,Use Enum。在这种情况下,我称之为FileType。尽可能多地扩展文件:WavFile,AudioFile ......
  2. 使用策略dp创建转换器。
  3. 使用Factory dp初始化转换器。
  4. 由于每个文件都知道自己的类型和目标类型(使用convertTo()方法来指定目标类型),它会调用工厂自动获取正确的转换器!!!
  5. 此设计具有可扩展性,您可以根据需要添加FileType和转换器。 你投票的答案是误导!!!! 编码和黑客攻击之间存在很大差异。

答案 6 :(得分:0)

如果您不使用Java 7,则可以创建enum并将该值与switch大小写一起使用。然后你只需要传递枚举值(而不是文件,我不知道你为什么这样做)。它看起来也很整洁。

这些应该有助于您想要做的事情:

 [Java Enum Examples][1] - 
 [Java Switch Case examples][2]