什么是工厂设计模式?
将工厂提取成一个接口或抽象类,具体生产什么产品由子类决定,工厂设计模式是将拥有共性的产品抽象封装到工厂类中统一进行管理和创建,以达到降低使用者与产品之间的耦合度的目的一种手段。在java中,万物皆对象,这些对象都需要创建,如果创建的时候直接new该对象,就会对该对象耦合严重,假如我们要更换对象,所有new对象的地方都需要修改一遍,这显然违背了软件设计的开闭原则,如果我们使用工厂来生产对象,我们就只和工厂打交道就可以了,彻底和对象解耦,如果要更换对象,直接在工厂里更换该对象即可,达到了与对象解耦的目的;所以说,工厂模式最大的优点就是:解耦
本篇主要介绍三种工厂设计模式的使用:
1、简单工厂
2、工厂方法
3、抽象工厂
参考文章:
https://www.jianshu.com/p/38493eb4ffbd
https://blog.csdn.net/bruceleenumberone/article/details/73888726
1、简单工厂
定义:一个工厂方法,依据传入的参数,生成对应的产品对象;
我们以汽车为例讲解工厂模式。
Car.java源码如下:
public interface Car {
void run();
}
Audi.java源码如下:
public class Audi implements Car {
@Override
public void run() {
System.out.println(getClass().getSimpleName() + " run...");
}
}
BMW.java源码如下:
public class BMW implements Car {
@Override
public void run() {
System.out.println(getClass().getSimpleName() + " run...");
}
}
CarFactory.java源码,这个类专门负责创建对象:
public class CarFactory {
public static Car create(String type) {
if ("audi".equals(type)) {
return new Audi();
} else if ("bmw".equals(type)) {
return new BMW();
} else {
return null;
}
}
}
Client.java源码如下:
public class Client {
public static void main(String[] args) {
Car car1 = CarFactory.create("audi");
Car car2 = CarFactory.create("bmw");
car1.run();
car2.run();
}
}
控制台输出:
Audi run...
BMW run...
要点:
- 1 简单工厂模式也叫静态工厂模式,就是工厂类一般使用静态方法,通过接收的参数的不同的对象的不同来返回不同的对象实例。
- 2 对于增加新产品无能为力!不修改代码的话,是无法扩展的。需要修改CarFactory这个类
- 3 一般使用较多还是简单工厂模式。
2、工厂方法
工厂方法模式要点:
1)为了避免简单工厂模式的缺点,不完全满足OCP(开闭原则)。
2)工厂方法模式和简单工厂模式最大的不同在于,简单工厂模式只有一个(对于一个项目或者一个独立模块而言)工厂类,而工厂方法模式有一组实现了相同接口的工厂类。
修改汽车工厂CarFactory.java接口的源码:
public interface CarFactory {
Car createCar();
}
新增AudiFactory类源码:
public class AudiFactory implements CarFactory {
@Override
public Car createCar() {
return new Audi();
}
}
新增BMWFactory类源码:
public class BWMFactory implements CarFactory {
@Override
public Car createCar() {
return new BMW();
}
}
Client.java源码如下:
public class Client {
public static void main(String[] args) {
AudiFactory audiFactory = new AudiFactory();
BWMFactory bwmFactory = new BWMFactory();
Car car1 = audiFactory.createCar();
Car car2 = bwmFactory.createCar();
car1.run();
car2.run();
}
}
控制台输出:
Audi run...
BMW run...
工厂方法模式更加符合开闭原则。弊端是每次扩展都会增加新的类。
3、抽象工厂
1)用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)。
2)抽象工厂模式是工厂方法模式的升级版本,在有多个业务品种、业务分类时,通过抽象工厂模式产生需要的对象是一种非常好的解决方式。
抽象工厂和工厂方法的模式基本一样,区别在于,工厂方法是生产一个具体的产品,而抽象工厂可以用来生产一组相同,有相对关系的产品;重点在于一组,一批,一系列;举个例子,假如生产小米手机,小米手机有很多系列,小米note、红米note等;假如小米note生产需要的配件有825的处理器,6英寸屏幕,而红米只需要650的处理器和5寸的屏幕就可以了;用抽象工厂来实现:
Cpu源码:
public interface Cpu {
void run();
class Cpu650 implements Cpu {
@Override
public void run() {
System.out.println("这是Cpu650在跑...");
}
}
class Cpu825 implements Cpu {
@Override
public void run() {
System.out.println("这是Cpu825在跑...");
}
}
}
Screen源码:
public interface Screen {
void size();
class Screen5 implements Screen {
@Override
public void size() {
System.out.println("这是5寸显示屏...");
}
}
class Screen6 implements Screen {
@Override
public void size() {
System.out.println("这是6寸显示屏...");
}
}
}
PhoneFactory 源码:
public interface PhoneFactory {
Cpu getCpu();
Screen getScreen();
}
XiaoMiFactory源码:
public class XiaoMiFactory implements PhoneFactory {
@Override
public Cpu getCpu() {
return new Cpu.Cpu825();
}
@Override
public Screen getScreen() {
return new Screen.Screen6();
}
}
RedMiFactory源码:
public class RedMiFactory implements PhoneFactory {
@Override
public Cpu getCpu() {
return new Cpu.Cpu650();
}
@Override
public Screen getScreen() {
return new Screen.Screen5();
}
}
Client源码:
public class Client {
public static void main(String[] args) {
XiaoMiFactory factory = new XiaoMiFactory();
factory.getCpu().run();
factory.getScreen().size();
RedMiFactory redMiFactory = new RedMiFactory();
redMiFactory.getCpu().run();
redMiFactory.getScreen().size();
}
}
控制台输出:
这是Cpu825在跑...
这是6寸显示屏...
这是Cpu650在跑...
这是5寸显示屏...
如果小米手机出了845的CPU则只需新增Cpu845实现Cpu接口方法,然后在XiaoMiFactory工厂里面返回Cpu.Cpu845()即可。
参考文章:
https://www.jianshu.com/p/33f9301fb8fe
总结:
- 工厂设计模式分为三类。简单工厂,工厂方法,抽象工厂。
- 三种模式没有高下之分。
- 简单工厂模式适合用于项目需求简单,产品很少并且几乎没有扩展可能性的情况。
- 工厂方法模式适合用于产品簇单一,但却经常发生改变的情况。
- 抽象工厂适合用于项目拥有多个产品簇,且产品等级经常发生改变,并且还需要尽可能控制项目体积的情况。
- 笔者倾向于简单工厂方法>抽象工厂模式>工厂方法模式的思考方式。原因在于简单的问题用简单工厂方法已经足够,而稍微复杂的问题则几乎会面临扩展和工厂类大量增多的情况,用抽象工厂模式更能有效的解决问题。
END.