核心作用
实现了创建者和调用者的分离。
实例化对象,用工厂方法代替new操作。将选择实现类、创建对象统一管理和控制。从而将调用者跟我们的实现类解耦。
其中工厂模式又分为:
- 简单工厂模式(静态方法工厂模式)
用来生产同一等级结构中的任意产品。(对于增加新的产品,需要修改已有代码)。在简单工厂模式中,我们定义一个专门的类用来创建其他的实例。这个类会根据不同的参数返回不同的实例,这些不同的实例一般有一个共同的分类。需要注意的是,简单工厂模式不属于GOF定义的23种设计模式 - 工厂方法模式
用来生产同一等级结构中的固定产品。(支持增加任意产品)是对简单工厂的一个升级
简单工厂模式
要点
简单工厂模式也叫静态工厂模式,就是工厂类一般是使用静态方法,通过接收的参数的不同来返回不同的对象实例。
对于增加新产品无能为力!不修改代码的话,是无法扩展的。
实例分析
例如现在有两辆车,一台比亚迪,一台奥迪。两台车子都有一个启动方法。如下
public class AudiCar {
public void run() {
System.out.println("奥迪汽车启动了");
}
}
public class BydCar{
public void run() {
System.out.println("比亚迪启动了");
}
}
如果我打算启动奥迪,那我就需要按照如下方式启动
AudiCar car = new AudiCar();
car.run();
如果我打算启动比亚迪,那我就需要按照如下方式启动
BydCar car = new BydCar();
car.run();
上面的代码看着是没什么问题的,不过我们可以用工厂模式,把代码被的更加容易扩展。首先,奥迪和比亚迪都是汽车,都有一个启动方法。于是,我们先定义一个接口,如下:
public interface Car {
/**
* 汽车启动方法
*/
void run();
}
然后让比亚迪和奥迪分别实现这个接口,重新启动方法,如下:
public class AudiCar implements Car {
@Override
public void run() {
System.out.println("奥迪汽车启动了");
}
}
public class BydCar implements Car {
@Override
public void run() {
System.out.println("比亚迪启动了");
}
}
最后我们在通过一个工厂类来提供具体汽车的实例:
public class CarFactory {
public static Car createCar(String type){
if ("A".equals(type)) {
return new AudiCar();
}else if ("B".equals(type)){
return new BydCar();
}else{
return null;
}
}
}
这样,当用户需要获取奥迪和比亚迪的实例时,只需要通过给工厂方法传入不同的参数,就可以获取到对应的实例。如下:
public static void main(String[] args) {
Car carOne = CarFactory.createCar("A");
carOne.run();
Car carTwo = CarFactory.createCar("B");
carTwo.run();
}
这就是一个简单工厂,那么这么做到底有什么好处呢?
优点
在简单工厂模式,有三个重要的元素,就是UML图中的抽象产品,具体产品,具体工厂。三个元素中,最重要的当属于工厂类,工厂类根据不同的参数构建不同的实例,需求方只需要告诉工厂它需要什么,剩下的脏活累活都是工厂类去干。从而实现一个解耦
缺点
有优点,当然就会有缺点,最大的缺点就是这个工厂类不够灵活,当产品增加的时候,我们就得修改这个工厂类,不够友好;并且由于我们使用了静态方法,导致简单工厂也没法形成继承结构
UML图
最终的类结构如下图:
这就是简单工厂模式,接下来我们将在工厂模式中对此做进一步的优化
工厂方法模式
工程方法模式是对简单工厂的一个升级。我们具体看下
模式定义
工程方法模式也属于创建型模式,又名工厂模式,虚拟构造器模式,多态工厂模式。在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的实例化操作,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工程子类来确定应该实例化那一个具体产品
在简单工厂模式中,实例的创建都是在工厂类中完成的,如果添加了新的产品就得修改工厂方法,现在,我们对工厂类也进行抽象,抽出一个接口,然后创建多个工厂类,实现工厂抽象接口,在不同的工厂类创建不同的产品,这样,如果添加新的产品线,我们只需要提供一个相应的工厂类即可
实例分析
我们在汽车的案例上,继续完善
奥迪类和比亚迪类就不需要变了,我们只需要重新定义CarFactory,首先我们定义CarFactory;
public interface Factory {
Car crateCar();
}
再来定义CarFactory的实现类
public class AudiFactory implements Factory{
@Override
public Car crateCar() {
return new AudiCar();
}
}
public class BydFactory implements Factory{
@Override
public Car crateCar() {
return new BydCar();
}
}
在这里我们定义了两个实现类,不同的实现类,用来创建不同的Car实例。最终,通过如下方式来创建实例
public class ClientTwo {
public static void main(String[] args) {
Car carOne = new AudiFactory().crateCar();
carOne.run();
Car carTwo = new BydFactory().crateCar();
carTwo.run();
}
}
这就是我们说的工厂方法模式,就比上面的多了一个工厂类的抽象,以后如果有新的产品上线,我们只需要提供一个相关工厂类即可
优点
- 工厂类满足单一职责,一个工厂类只创建一个类
- 符合开闭原则
- 实例方法,可以形成工厂类的等级结构
缺点
- 每次添加新的产品,都需要提供对应的工厂类
- 一个具体的工厂只能创建一种产品
UML图
总结
本文主要和大家分享了工厂模式,工厂模式主要说的就是方法工厂,简单工厂模式并不属于GOF23模式,只是一个特殊的工厂模式
代码案例文件下载地址
http://pvyob7cem.bkt.clouddn.com/factory.rar