简介
当创建对象的代码多而杂时,可以用工厂模式将对象的创建和使用分离,让代码更加清晰。
比如下面代码根据不同的 rule 创建不同的对象。
java demo
public class Demo {
// 解析文件,返回解析内容
public void load(String rule) {
IParse parse = null;
// 根据不同的文件类型,执行不同的内容
// 分析:如果代码中创建对象的过程很复杂,就需要把这段代码移出去,单独封装成类,封装的类就是工厂类
if ("xml".equals(rule))
parse = new XmlParse();
else if ("json".equals(rule))
parse = new JsonParse();
else if ("excel".equals(rule))
parse = new ExcelParse();
else if ("csv".equals(rule))
parse = new CsvParse();
else
parse = new OtherParse();
// parse 是解析类之一,具体是哪一个,要根据 rule 来决定
parse.parse();
// 省略其它有关 load 的大量操作
}
public static void main(String[] args) {
Demo demo = new Demo();
// 传入 json
demo.load("json");
}
}
// 所有解析类的接口,规定解析类的方法
interface IParse {
// 需要解析类去实现
public void parse();
}
class XmlParse implements IParse {
// 解析结果
public void parse() {
System.out.println("XmlParse");
}
}
class JsonParse implements IParse {
public void parse() {
System.out.println("JsonParse");
}
}
class ExcelParse implements IParse {
public void parse() {
System.out.println("ExcelParse");
}
}
class CsvParse implements IParse {
public void parse() {
System.out.println("CsvParse");
}
}
class OtherParse implements IParse {
public void parse() {
System.out.println("OtherParse");
}
}
python demo
# Demo 用于加载不同的文件,对不同的文件作不同的处理
class Demo:
def load(self, rule):
parse = None
# 根据不同的 rule ,创建不同的对象
if "xml" == rule:
parse = XmlParse()
elif "json" == rule:
parse = JsonParse()
elif "excel" == rule:
parse = ExcelParse()
elif "csv" == rule:
parse = CsvParse()
else:
parse = OtherParse()
# 调用对象的方法进行操作
parse.parse()
# 相当于接口,用于规范各个解析类
# 每个解析类都要实现 parse 方法,否则在调用的时候就会报错
class IParse:
def parse(self):
raise ValueError()
class XmlParse(IParse):
def parse(self):
print("XmlParse")
class JsonParse(IParse):
def parse(self):
print("JsonParse")
class ExcelParse(IParse):
def parse(self):
print("ExcelParse")
class CsvParse(IParse):
def parse(self):
print("CsvParse")
class OtherParse(IParse):
def parse(self):
print("OtherParse")
if __name__ == "__main__":
Demo().load("json")
简单工厂
把创建大量实例的代码放到工厂类中。
java 实现
public class Demo {
// 解析文件,返回解析内容
public void load(String rule) {
IParse parse = ParseFactory.createParse(rule);
// parse 是解析类之一,具体是哪一个,要根据 rule 来决定
parse.parse();
// 省略其它有关 load 的大量操作
}
public static void main(String[] args) {
Demo demo = new Demo();
// 传入 json
demo.load("json");
}
}
// 简单工厂:把创建对象的代码移动到这个类中的一个方法,这个类就叫做简单工厂
// 简单工厂的类名字通常以 Factory 结尾
// 简单工厂的方法,通常叫 createParse
class ParseFactory {
public static IParse createParse(String rule) {
IParse parse = null;
// 根据不同的文件类型,执行不同的内容
if ("xml".equals(rule))
parse = new XmlParse();
else if ("json".equals(rule))
parse = new JsonParse();
else if ("excel".equals(rule))
parse = new ExcelParse();
else if ("csv".equals(rule))
parse = new CsvParse();
else
parse = new OtherParse();
return parse;
}
}
// 所有解析类的接口,规定解析类的方法
interface IParse {
// 需要解析类去实现
public void parse();
}
class XmlParse implements IParse {
// 解析结果
public void parse() {
System.out.println("XmlParse");
}
}
class JsonParse implements IParse {
public void parse() {
System.out.println("JsonParse");
}
}
class ExcelParse implements IParse {
public void parse() {
System.out.println("ExcelParse");
}
}
class CsvParse implements IParse {
public void parse() {
System.out.println("CsvParse");
}
}
class OtherParse implements IParse {
public void parse() {
System.out.println("OtherParse");
}
}
python 实现
# Demo 用于加载不同的文件,对不同的文件作不同的处理
# 问题:如果创建对象的代码比如多,可能还会创建 text ,md,yml 等等
# 简单工厂解决:把对象的创建移动到其它类中, load 方法就会很简洁
class Demo:
def load(self, rule):
parse = ParseRuleFactory().create_parse(rule)
# 调用对象的方法进行操作
parse.parse()
# 简单工厂类:用于实例的创建,根据 rule 创建不同的实例。本质就是把 Demo 中原来创建实例的代码,给迁移过来
class ParseRuleFactory:
def create_parse(self, rule):
parse = None
# 根据不同的 rule ,创建不同的对象
if "xml" == rule:
parse = XmlParse()
elif "json" == rule:
parse = JsonParse()
elif "excel" == rule:
parse = ExcelParse()
elif "csv" == rule:
parse = CsvParse()
else:
parse = OtherParse()
return parse
# 相当于接口,用于规范各个解析类
# 每个解析类都要实现 parse 方法,否则在调用的时候就会报错
class IParse:
def parse(self):
raise ValueError()
class XmlParse(IParse):
def parse(self):
print("XmlParse")
class JsonParse(IParse):
def parse(self):
print("JsonParse")
class ExcelParse(IParse):
def parse(self):
print("ExcelParse")
class CsvParse(IParse):
def parse(self):
print("CsvParse")
class OtherParse(IParse):
def parse(self):
print("OtherParse")
if __name__ == "__main__":
Demo().load("json")
工厂方法
如果创建实例的代码非常复杂,就可以把创建实例的代码单独放入一个类。
比如下面的例子,创建实例代码复杂:
java 实现
public class Demo {
// 如果创建对象时,代码很复杂,简单工厂就不能解决问题,因为即使使用简单工厂,创建实例依旧很复杂
// 此时就需要工厂方法来解决、
// 工厂方法解决方案:将每一个创建过程都封装到工厂类中
// 比如下面的 JsonParseRuleFactory ,将复杂的代码都放到了 JsonParseRuleFactory 类中
public void load(String rule) {
IParse parse = null;
if ("xml".equals(rule))
// 省略了 1000 行代码
parse = new XmlParse();
else if ("json".equals(rule))
parse = new JsonParseRuleFactory().createParse();
else if ("excel".equals(rule))
// 省略了 1000 行代码
parse = new ExcelParse();
else if ("csv".equals(rule))
// 省略了 1000 行代码
parse = new CsvParse();
else
// 省略了 1000 行代码
parse = new OtherParse();
// parse 是解析类之一,具体是哪一个,要根据 rule 来决定
parse.parse();
// 省略其它有关 load 的大量操作
}
public static void main(String[] args) {
Demo demo = new Demo();
// 传入 json
demo.load("json");
}
}
// 工厂方法的接口:要根据不同的调用,实现不同的操作
interface IParseRuleFactory {
// createParse 接口要创建对象以及复杂操作
public IParse createParse();
}
// 把原来 json 处理的所有代码,都迁移过来
class JsonParseRuleFactory implements IParseRuleFactory {
public IParse createParse() {
// 省略了 1000 行代码
return new JsonParse();
}
}
// 所有解析类的接口,规定解析类的方法
interface IParse {
// 需要解析类去实现
public void parse();
}
class XmlParse implements IParse {
// 解析结果
public void parse() {
System.out.println("XmlParse");
}
}
class JsonParse implements IParse {
public void parse() {
System.out.println("JsonParse");
}
}
class ExcelParse implements IParse {
public void parse() {
System.out.println("ExcelParse");
}
}
class CsvParse implements IParse {
public void parse() {
System.out.println("CsvParse");
}
}
class OtherParse implements IParse {
public void parse() {
System.out.println("OtherParse");
}
}
python 实现
# 问题:简单工厂不能解决创建实例的代码可能很复杂,即使迁移到了简单工厂中,复杂的创建过程依旧存在
# 解决:使用工厂方法,把创建过程封装到工厂类
class Demo:
def load(self, rule):
parse = None
if "xml" == rule:
# 省略 1000 行代码
parse = XmlParse()
elif "json" == rule:
parse = JsonParseRuleFactory().create_parse()
elif "excel" == rule:
# 省略 1000 行代码
parse = ExcelParse()
elif "csv" == rule:
# 省略 1000 行代码
parse = CsvParse()
else:
# 省略 1000 行代码
parse = OtherParse()
# 调用对象的方法进行操作
parse.parse()
# 相当于接口,用于规范各个工厂类
class IParseRuleFactory:
def create_parse(self):
raise ValueError()
# 工厂:把 Json 的解析放到此工厂下面
class JsonParseRuleFactory (IParseRuleFactory):
def create_parse(self):
# 省略 1000 行代码
return JsonParse()
# 相当于接口,用于规范各个解析类
# 每个解析类都要实现 parse 方法,否则在调用的时候就会报错
class IParse:
def parse(self):
raise ValueError()
class XmlParse(IParse):
def parse(self):
print("XmlParse")
class JsonParse(IParse):
def parse(self):
print("JsonParse")
class ExcelParse(IParse):
def parse(self):
print("ExcelParse")
class CsvParse(IParse):
def parse(self):
print("CsvParse")
class OtherParse(IParse):
def parse(self):
print("OtherParse")
if __name__ == "__main__":
Demo().load("json")
抽象工厂
假设有 A 公司, B 公司,C 公司… 都要有自己的解析方法,比如:A 公司有 AXmlParseFactory ,B 公司有 BXmlParseFactory ,C 公司有 CXmlParseFactory 。如果此时使用简单工厂和工厂方法,工作量非常大,因为要给每一个公司都创建所有的解析工厂。
此时可以用抽象工厂解决问题。解析工厂返回多个实例,比如,XmlParseFactory 可以返回 A ,B , C 的实例。
java 实现
// 抽象工厂:使工厂类具有返回多个实例的功能
interface IParseRuleFactory {
public IParse AcreateParse();
public IParse BcreateParse();
public IParse CcreateParse();
}
class XmlParseRuleFactory implements IParseRuleFactory{
public IParse AcreateParse() {}
public IParse BcreateParse(){}
public IParse CcreateParse(){}
}
python 实现
# 问题:如果多个公司都要封装工厂,比如 A, B, C ...公司都要封装自己的工厂,就要封装 n 个工厂类
# 解决:可以使用抽象工厂解决问题,每个工厂类可以创建多个实例,比如 JsonParseRuleFactory ,可以创建 A, B, C 公司的实例
# 一个工厂类,可以生成多个公司的解析方法
class IParseRuleFactory:
def a_create_parse(self):
raise ValueError()
def b_create_parse(self):
raise ValueError()
def c_create_parse(self):
raise ValueError()
# 实现时候,一个工厂类就可以生成多个公司的实例
class JsonParseRuleFactory(IParseRuleFactory):
def a_create_parse(self):
"""
"""
def b_create_parse(self):
"""
"""
def c_create_parse(self):
"""
"""