Java 转换多个';否则';以更干净的方式发言
这里我的代码检测Java 转换多个';否则';以更干净的方式发言,java,design-patterns,Java,Design Patterns,这里我的代码检测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("a
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
}
我缩短了我的代码,因为它有很多else-if语句,什么设计模式适合删除许多if-and-else或else-if语句?如果您使用的是
JDK 7
,您可以使用switch-case
构造:
见:
对于以前的版本,
if-else
是唯一的选择。如果对每种情况运行相同的方法,您应该检查您可能有一个转换器
接口。然后可以为每个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());
Converter converter = mimeTypeMap.get(mimeType);
converter.convertToMp3();
使用这种方法,您可以在将来轻松添加不同的转换器
所有未经测试的,可能不会编译,但您得到的想法是如果您使用pre-JDK7,您可以为所有类型添加枚举:
看看如何将字符串转换为枚举的堆栈溢出问题。如果您不使用Java 7,您可以创建一个
enum
,并将该值与开关一起使用。然后只需要传递枚举值(而不是文件,我不知道为什么要这样做)。它看起来也会更整洁
这些应该有助于您想做的事情:
[Java Enum Examples][1] -
[Java Switch Case examples][2]
考虑使用策略设计模式和映射
来分配适当的策略。如果您需要额外的功能,除了转换特定的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);
}
}
接口转换器{
无效转换(文件src、文件目标);
}
私有静态void convertWav(文件src,文件目标){
...
}
...
私有静态最终映射<字符串,转换器>转换器=新。。。;
静止的{
转换器。输入(“音频/wav”,新转换器{
无效转换(文件src、文件目标){
convertWav(src,目标);
}
});
转换器。put(“音频/ogg”),新转换器{
无效转换(文件src、文件目标){
convertOgg(src,target);
}
});
...
}
public void convertToMp3(文件src、文件目标、字符串mimeType){
最终转换器Convertor=convertors.get(mimeType);
if(转换器==null){
...
}否则{
convertor.convert(src,target);
}
}
这绝对是一种策略设计模式。但是你的总体设计有一个大问题。使用字符串来标识类型不是一个好的编程习惯。这仅仅是因为它很容易编辑,而且你可能会犯语法错误,花整个下午寻找编程错误。你可以避免使用地图
我建议如下:
扩展类文件。新类向类文件中添加了一个新属性FileType和一个新方法convertTo(FileType)。此属性保留其类型:“音频”、“wav”。。。同样,不要使用字符串,请使用枚举。在本例中,我称之为FileType。扩展文件,如您所需:WavFile,AudioFile
使用策略dp创建转换器
使用出厂dp初始化转换器
由于每个文件都知道自己的类型和目标类型(使用convertTo()方法指定目标类型),因此它将调用工厂自动获取正确的转换器李>
这种设计是可扩展的,您可以根据需要添加任意多的文件类型和转换器。
你投票的答案有误导性!!!!
编码和黑客有很大区别。枚举和开关如何?工厂设计模式不适合您的需要?@RomanC我为什么要使用工厂设计模式?您想简化代码删除许多if-else语句,我使用了工厂模式。允许多态性为您工作。if/else语句是否有问题?当然,它不是一个漂亮的、过度设计的OOP模式,但它简单易懂,易于维护。任何阅读它的人都能理解它,那么为什么要尝试将它转换为其他东西呢?我运行不同的方法。这里不需要状态模式,这不是对有限状态机建模,而是根据输入类型选择不同的转换策略,因此策略模式更合适。但是如果我有不同的转换器而不是ConvertingComp3呢?我也有Ogg和Wav的转换器。不过我觉得有点迷茫,如果我想添加Ogg转换器,您可以向接口添加其他方法。e、 g.convertToOgg()我更新了答案在本例中,MPEGConverter上使用convertToOgg方法将MPG转换为MP3,convertToOgg用于将MPG转换为OGG。因此,不,他们做的工作不同。可能与namingGood想法混淆,对我来说,这似乎是一个非常干净的解决方案。只是不要忘记检查是否确实存在处理程序,如果找不到处理程序,则给出错误消息。对于那些可能不知道的人,这称为。为什么不在枚举本身放置一个handle方法?然后是MimeTypes.valueOf(mimeType.handle()
@SpaceTrucker:好建议,它会比我的想法更干净。事实上,这将是cowls想法的一个很好的实现,因为不需要使用不同的实现来处理映射。我不相信建议使用开关作为重构多个if else if
的一种方式的响应得到了23票的支持。吼叫声当我想到什么样的开发人员时,这让我感到害怕。@Daniel嗯,我猜太多的开发人员认为“行数越少越好”,尽管新代码与旧代码有相同的缺点。@Daniel,你能更明确地表达你对这种方法的担忧吗?问题中提供的用例归结为“执行一个且仅执行一个代码”
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);
}
}