工厂模式(上)

本文探讨了如何通过简单工厂、工厂方法和抽象工厂模式优化 RuleConfigSource 类,实现了文件格式解析的灵活性和代码结构的清晰。通过工厂类,减少了if-else条件判断,提高了代码的可扩展性和维护性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简单工厂(Simple Factory)

public class RuleConfigSource { 
  public RuleConfig load(
  String ruleConfigFilePath) { 
  String ruleConfigFileExtension =getFileExtension(ruleConfigFilePath); 
  IRuleConfigParser parser = null; 
  if ("json".equalsIgnoreCase(ruleConfigFileExtension)) { 
  parser = new JsonRuleConfigParser(); 
  } else if ("xml".equalsIgnoreCase(ruleConfigFileExtension)) { 
  parser = new XmlRuleConfigParser(); 
  } else if ("yaml".equalsIgnoreCase(ruleConfigFileExtension)) {    parser = new YamlRuleConfigParser(); 
  } else if ("properties".equalsIgnoreCase(ruleConfigFileExtension)) { parser = new PropertiesRuleConfigParser(); 
  } else { throw new InvalidRuleConfigException( "Rule config file format is not supported: " + ruleConfigFilePath) } 
  String configText = ""; 
  //从ruleConfigFilePath文件中读取配置文本到configText中 
  RuleConfig ruleConfig = parser.parse(configText); 
  return ruleConfig; } 
  private String getFileExtension(String filePath) {
  //...解析文件名获取扩展名,比如rule.json,返回json return "json"; 
  }
}

我们可以将代码中涉及 parser 创建的部分逻辑剥离出来,抽象成 createParser() 函数。
重构之后的代码如下所示:

public RuleConfig load(String ruleConfigFilePath) { 
String ruleConfigFileExtension = getFileExtension(ruleConfigFilePath); IRuleConfigParser parser = createParser(ruleConfigFileExtension); 
if (parser == null) { 
throw new InvalidRuleConfigException( "Rule config file format is not supported: " + ruleConfigFilePath } 
String configText = ""; 
//从ruleConfigFilePath文件中读取配置文本到configText中 
RuleConfig ruleConfig = parser.parse(configText); 
return ruleConfig; } 
private String getFileExtension(String filePath) { 
//...解析文件名获取扩展名,比如rule.json,返回json return "json"; 
} 
private IRuleConfigParser createParser(String configFormat) { IRuleConfigParser parser = null; 
if ("json".equalsIgnoreCase(configFormat)) { 
  parser = new JsonRuleConfigParser(); 
} else if ("xml".equalsIgnoreCase(configFormat)) { 
  parser = new XmlRuleConfigParser(); 
} else if ("yaml".equalsIgnoreCase(configFormat)) { 
  parser = new YamlRuleConfigParser(); 
} else if ("properties".equalsIgnoreCase(configFormat)) { 
  parser = new PropertiesRuleConfigParser(); 
}
 return parser; 
}
}

为了让类的职责更加单一、代码更加清晰,我们还可以进一步将 createParser() 函数剥离 到一个独立的类中,让这个类只负责对象的创建。而这个类就是我们现在要讲的简单工厂模 式类。

public class RuleConfigSource { 
public RuleConfig load(String ruleConfigFilePath) { 
String ruleConfigFileExtension = getFileExtension(ruleConfigFilePath); IRuleConfigParser parser =RuleConfigParserFactory.createParser(ruleConfig)
if (parser == null) { 
throw new InvalidRuleConfigException( "Rule config file format is not supported: " + ruleConfigFilePath } 
String configText = ""; 
//从ruleConfigFilePath文件中读取配置文本到configText中
 RuleConfig ruleConfig = parser.parse(configText); 
 return ruleConfig; } 
 private String getFileExtension(String filePath) { 
 //...解析文件名获取扩展名,比如rule.json,返回json return "json"; 
 } }
  public class RuleConfigParserFactory { 
  public static IRuleConfigParser createParser(String configFormat) { IRuleConfigParser parser = null; 
  if ("json".equalsIgnoreCase(configFormat)) { 
  parser = new JsonRuleConfigParser(); 
  } else if ("xml".equalsIgnoreCase(configFormat)) { 
  parser = new XmlRuleConfigParser(); 
  } else if ("yaml".equalsIgnoreCase(configFormat)) { 
  parser = new YamlRuleConfigParser(); 
  } else if ("properties".equalsIgnoreCase(configFormat)) { 
  parser = new PropertiesRuleConfigParser(); 
  } 
  return parser; 
  } 
}

另外我们可以将 parser 事先创建好缓存起来。当调用 createParser() 函数的时候,我 们从缓存中取出 parser 对象直接使用。

public class RuleConfigParserFactory { 
private static final Map cachedParsers = new HashMa static { cachedParsers.put("json", new JsonRuleConfigParser()); cachedParsers.put("xml", new XmlRuleConfigParser()); cachedParsers.put("yaml", new YamlRuleConfigParser()); cachedParsers.put("properties", new PropertiesRuleConfigParser()); 
} 
public static IRuleConfigParser createParser(String configFormat) { 
if (configFormat == null || configFormat.isEmpty()) {
 return null;
 //返回null还是IllegalArgumentException全凭你自己说了算 
 } 
 IRuleConfigParser parser = cachedParsers.get(configFormat.toLowerCase()); return parser; } }

工厂方法(Factory Method)
要将 if 分支逻辑去掉,比较经典处理方法就是利用多态。

public interface IRuleConfigParserFactory { 
IRuleConfigParser createParser(); 
} 
public class JsonRuleConfigParserFactory implements IRuleConfigParserFactory { 
@Override public IRuleConfigParser createParser() { 
return new JsonRuleConfigParser(); 
} 
}
public class XmlRuleConfigParserFactory implements IRuleConfigParserFactory { 
@Override public IRuleConfigParser createParser() { 
return new XmlRuleConfigParser(); 
   } 
} 
public class YamlRuleConfigParserFactory implements IRuleConfigParserFactory { 
@Override 
public IRuleConfigParser createParser() { 
   return new YamlRuleConfigParser(); 
 } 
} 
public class PropertiesRuleConfigParserFactory implements IRuleConfigParserFact{
@Override 
public IRuleConfigParser createParser() {
 return new PropertiesRuleConfigParser(); 
 } 
}

工厂方法模式比起简单工厂模式更加符合开闭原则。

public class RuleConfigSource { 
public RuleConfig load(String ruleConfigFilePath) { 
String ruleConfigFileExtension = getFileExtension(ruleConfigFilePath); IRuleConfigParserFactory parserFactory = null; 
  if ("json".equalsIgnoreCase(ruleConfigFileExtension)) { 
  parserFactory = new JsonRuleConfigParserFactory(); 
  } else if ("xml".equalsIgnoreCase(ruleConfigFileExtension)) { parserFactory = new XmlRuleConfigParserFactory(); 
  } else if ("yaml".equalsIgnoreCase(ruleConfigFileExtension)) { parserFactory = new YamlRuleConfigParserFactory(); 
  } else if ("properties".equalsIgnoreCase(ruleConfigFileExtension)) { parserFactory = new PropertiesRuleConfigParserFactory(); 
  } else { 
  throw new InvalidRuleConfigException("Rule config file format is not supp } IRuleConfigParser parser = parserFactory.createParser(); String configText = ""; 
  //从ruleConfigFilePath文件中读取配置文本到configText中 
  RuleConfig ruleConfig = parser.parse(configText);
  return ruleConfig; } 
 private String getFileExtension(String filePath) { 
 //...解析文件名获取扩展名,比如rule.json,返回json return "json";
  } 
 }

工厂类对象的创建逻辑又耦合进了 load() 函数中,我们可以为工厂类再创建一个简单工厂,也就是工厂的工厂,用来创建工厂类对象。
RuleConfigParserFactoryMap 类是创建工厂对象的工厂类,getParserFactory() 返回的 是缓存好的单例工厂对象。

public class RuleConfigSource { 
public RuleConfig load(String ruleConfigFilePath) { 
String ruleConfigFileExtension = getFileExtension(ruleConfigFilePath); IRuleConfigParserFactory parserFactory = RuleConfigParserFactoryMap.getPars 
  if (parserFactory == null) { 
  throw new InvalidRuleConfigException("Rule config file format is not supp 
  } 
   IRuleConfigParser parser = parserFactory.createParser();
   String configText = ""; 
   //从ruleConfigFilePath文件中读取配置文本到configText中 
   RuleConfig ruleConfig = parser.parse(configText); 
   return ruleConfig; } 
 private String getFileExtension(String filePath) { 
 //...解析文件名获取扩展名,比如rule.json,返回json return "json"; 
 } 
} 
//因为工厂类只包含方法,不包含成员变量,完全可以复用, 
//不需要每次都创建新的工厂类对象,所以,简单工厂模式的第二种实现思路更加合适。 
public class RuleConfigParserFactoryMap { 
//工厂的工厂 
private static final Map cachedFactories = static { cachedFactories.put("json", new JsonRuleConfigParserFactory()); cachedFactories.put("xml", new XmlRuleConfigParserFactory()); cachedFactories.put("yaml", new YamlRuleConfigParserFactory()); cachedFactories.put("properties", new PropertiesRuleConfigParserFactory()) } 
public static IRuleConfigParserFactory getParserFactory(String type) {   if (type == null || type.isEmpty()) 
{ return null; 
} 
IRuleConfigParserFactory parserFactory = cachedFactories.get(type.toLowerCa return parserFactory; } }

那什么时候该用工厂方法模式,而非简单工厂模式呢?

要组合其他类对象,做各种初始化操作的时候,我们推荐使用工厂方法模式,将复杂的创建逻 辑拆分到多个工厂类中,让每个工厂类都不至于过于复杂。

抽象工厂(Abstract Factory)

针对规则配置的解析器:基于接口
IRuleConfigParser JsonRuleConfigParser XmlRuleConfigParser YamlRuleConfigParser PropertiesRuleConfigParser
针对系统配置的解析器:
基于接口
ISystemConfigParser
JsonSystemConfigParser
XmlSystemConfigParser
YamlSystemConfigParser
PropertiesSystemConfigParser

我们可以让一个工厂负责创建多个不同类 型的对象(IRuleConfigParser、ISystemConfigParser 等),而不是只创建一种 parser 对象。这样就可以有效地减少工厂类的个数。

public interface IConfigParserFactory { 
IRuleConfigParser createRuleParser(); 
ISystemConfigParser createSystemParser(); 
//此处可以扩展新的parser类型,比如IBizConfigParser 
} 
public class JsonConfigParserFactory implements IConfigParserFactory { @Override 
public IRuleConfigParser createRuleParser() { 
return new JsonRuleConfigParser(); 
} 
@Override 
public ISystemConfigParser createSystemParser() { 
return new JsonSystemConfigParser(); 
}
} 
public class XmlConfigParserFactory implements IConfigParserFactory { @Override 
public IRuleConfigParser createRuleParser() { 
return new XmlRuleConfigParser();
} 
@Override public ISystemConfigParser createSystemParser() { 
return new XmlSystemConfigParser(); 
} 
} 
// 省略YamlConfigParserFactory和PropertiesConfigParserFactory代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值