设计模式------工厂方法模式
前言
工厂方法模式(Factory Method Pattern):定义一个用于创建对象的接口,让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。工厂方法模式又简称为工厂模式(Factory Pattern),又可称作虚拟构造器模式(Virtual Constructor Pattern)或多态工厂模式(Polymorphic Factory Pattern)。工厂方法模式是一种类创建型模式。
一、UML图
抽象工厂角色(Creator):是工厂方法模板的核心,与应用程序无关。任何在模式中创建的对象的工厂类必须实现这个接口。
具体工厂角色(Concrete Creator)角色:这是实现抽象工厂接口的具体工厂类,包含与应用程序相关的逻辑,并且受到应用程序调用以创建产品对象。
抽象产品角色(Product):工厂方法模式所创建的对象的超类型,也就是对象的共同父类或共同拥有的接口。
具体产品角色(Concrete Product)角色:这个角色实现了抽象产品角色所定义的接口。某具体产品有专门的具体工厂船舰,他们之间往往一一对应。
二、优点
- 当系统扩展需要添加新的产品对象时,仅仅需要添加一个具体对象以及一个具体工厂对象,原有工厂对象不需要进行任何修改,也不需要(尽量小的)修改客户端,较好的符合了“开放–封闭”原则。而简单工厂模式在添加新产品对象后不得不修改工厂方法,扩展性不好。
三、缺点
- 具体产品对象与工厂方法的耦合性:工厂方法时要创建产品对象的,也就是需要选择具体的产品对象,并创建他们的实例。因此具体产品对象与工厂方法是耦合的。
四、实质
- 延迟到子类来选择实现
五、体现的原则
- 工厂方法模式很好的体现了“依赖倒转原则”
- 依赖倒置原则告诉我们“要依赖抽象,不要依赖于具体类”,简单点说就是:不能让高层组件依赖于低层组件,而且不管高层组件还是低层组件,都应该依赖于抽象。
六、应用场景
- 如果一个类需要创建某个接口对象,但又不知道具体的实现,这种情况可以选用工厂方法模式,把创建对象的工作延迟到子类中实现。
- 如果一个类本身就希望由他的子类来创建所需要的对象的时候,应该使用工厂方法模式
七、相关模式
1、工厂方法模式和抽象工厂模式
这两个模式既有区别,又有联系,可以组合使用。
工厂方法模式一般针对单独的产品对象创建,而抽象工厂模式注重产品簇对象的创建,这是他们的区别。
如果把抽象工厂创建的产品簇简化,这个产品簇就只有一个产品,那么这个时候的抽象工厂跟工厂方法是差不多的,也就是抽象工厂可以退化成工厂方法,而工厂方法又可以退化成简单工厂,这是他们的联系。
在抽象工厂的实现中,还可以使用工厂方法来提供抽象工厂的具体实现,也就是说他们可以组合使用。
2、工厂方法模式和模板方法模式
这两个模式外观类似,都有一个抽象类,然后由子类来提供一些实现,但工厂方法模式的子类专注的是创建产品对象,而模板方法模式的子类专注的是为了固定的算法骨架提供某些步骤的实现。
这两个模式可以组合使用,通常在模板方法模式里面,使用工厂方法来创建模板方法需要的对象
八、示例代码
要求简述:
在实际的企业应用中,一个公司的系统往往分散在很多不同的地方运行。公司既没有建立全公司专网的实力,又不愿意让业务数据实时地在广域网上传递。折中的方案是各分公司内运行系统独立,每天业务结束时,各分公司导出业务数据、打包、传送给总公司。
导出数据格式会有不同要求
文本格式、数据库备份格式、Excel格式、Xml格式
分清哪是产品类、哪是工厂类
//产品类接口
public interface ExportFileApi{
public boolean export(String data);
}
//具体产品类
public class ExportDB implements ExportFileApi{
public boolean export(String data){
System.out.println("导出数据"+data+"到数据库备份文件");
return true;
}
}
public class ExportTxtFile implements ExportFileApi{
public boolean export(String data){
System.out.println("导出数据"+data+"到文本文件");
return true;
}
}
//抽象工厂类
public abstract class ExportOperate {
public boolean export(String data){
ExportFileApi api=factoryMethod();
return api.export(data);
}
protected abstract ExportFileApi factoryMethod();
}
//具体工厂类
public class ExportDBOperate extends ExportOperate {
protected ExportFileApi factoryMethod() {
return new ExportDB();
}
}
public class ExportTxtFileOperate extends ExportOperate {
protected ExportFileApi factoryMethod(){
return new ExportTxtFile();
}
}
//客户端
public class Client {
public static void main(String[] args) {
ExportOperate operate =new
ExportDBOperate();
operate.export("测试数据");
}
}