今天主要讲解的是工厂方法模式。内容参考自java_my_life 博主的博客。但是拒绝粘贴复制,全部手打
工厂方法模式是类的创建模式。工厂方法模式的用意是定义一个创建产品对象的工厂接口,将实际创建工作,推迟到子类中。
案例说明
大家很多时候都做过导出功能,比如一个系统,需要导出的格式包括html、pdf等。但是财务系统导出的格式和其他普通的格式又不一样,
此时如果用我们上篇学到的简单工厂模式,势必会让工厂类很繁琐,各种if判断。日后增加导出的格式,又会对工厂类进行增加逻辑编写。 此时我们采用 工厂方法模式进行实现。核心的工厂类不再负责所有对象的创建,它只是声明看一个工厂接口,具体的对象创建交给了子类。
下面针对这个程序,我画的uml图
从上图可以看出,一共有4个角色
- 抽象工厂角色:担任这个角色的工厂方法模式的核心,在模式中创建对象的工厂类必须实现该接口。
- 具体工厂角色:实现 抽象工厂接口的具体类,与业务逻辑密不可分。
- 抽象导出角色:工厂方法模式所创建的对象的父类,也就是所有导出类的父类。
- 具体导出角色:这个角色实现了抽象导出角色的接口。
具体代码
1.抽象导出角色
public interface ExportFile {
public boolean export(String data);
}
2.具体导出角色
public class ExportFinancialHtmlFile implements ExportFile {
@Override
public boolean export(String data) {
System.out.println("导出财务版HTML文件");
return true;
}
}
public class ExportFinancialPdfFile implements ExportFile {
@Override
public boolean export(String data) {
System.out.println("导出财务版PDF文件");
return true;
}
}
public class ExportStandardHtmlFile implements ExportFile {
@Override
public boolean export(String data) {
System.out.println("导出标准版HTML文件");
return true;
}
}
public class ExportStandardPdfFile implements ExportFile {
@Override
public boolean export(String data) {
System.out.println("导出财务版PDF文件");
return true;
}
}
3.抽象工厂角色
public interface ExportFactory {
public ExportFile factory(String type);
}
- 具体工厂角色
public class ExportHtmlFactory implements ExportFactory {
@Override
public ExportFile factory(String type) {
if("standard".equals(type)){
return new ExportStandardHtmlFile();
}else if("financial".equals(type)){
return new ExportFinancialHtmlFile();
}else{
throw new RuntimeException("没有找到对象");
}
}
}
public class ExportPdfFactory implements ExportFactory {
@Override
public ExportFile factory(String type) {
if("standard".equals(type)){
return new ExportStandardPdfFile();
}else if("financial".equals(type)){
return new ExportFinancialPdfFile();
}else{
throw new RuntimeException("没有找到对象");
}
}
}
测试
public static void main(String[] args) {
String data = "";
ExportFactory exportFactory = new ExportHtmlFactory();
ExportFile exportFile = exportFactory.factory("financial");
exportFile.export(data);
}
执行结果
导出财务版HTML文件
总结
- 工厂方法模式和简单工厂模式明显的不同在结构上,工厂方法的核心是抽象工厂类,简单工厂模式的核心是一个具体的类
- 如果系统新增一个导出类型,此时只需要增加一个导出类和对应的工厂类,客户端不需要改动,更符合开闭原则。
需要注意一点,设计模式是一种设计思想,并不是一成不变的 ,不要为了套设计思想让代码变得复杂,反而是一种画蛇添足的做法。
所有设计模式的代码已经放到github上。