设计模式之工厂模式
1、概念
(1)什么是工厂模式?
工厂顾名思义就是创建产品,根据产品是具体产品还是具体工厂可分为简单工厂模式和工厂方法模式,根据工厂的抽象程度可分为工厂方法模式和抽象工厂模式。该模式用于封装和管理对象的创建,是一种创建型模式。
(2)为什么用工厂模式?
可以让调用方不需要负责对象的创建,明确了各个类的职责。
实现了调用方和工厂的解耦,后期维护容易。
2、工厂模式的三种模式
(1):简单(静态)工厂模式
该模式对对象创建管理方式最为简单,因为其仅仅简单的对不同类对象的创建进行了一层薄薄的封装。该模式通过向工厂传递类型来指定要创建的对象。
package com.example.designmode.factory;
public class SimpleFactory {
private SimpleFactory() {
}
public static Worker getWorkerBy(String workerType) {
if ("teacher".equals(workerType)) {
return new Teacher();
} else if ("wanderer".equals(workerType)) {
return new Wanderer();
}
return null;
}
public static void main(String[] args) {
SimpleFactory.getWorkerBy("teacher");//获取教师对象
SimpleFactory.getWorkerBy("wanderer");//获取流浪者对象
}
}
class Worker {
}
class Teacher extends Worker {
}
class Wanderer extends Worker {
}
简单(静态)工厂模式:
优点:只需要维护一个工厂。
缺点:每增加一个对象,要同步修改工厂代码。
(2):工厂方法模式
和简单工厂模式中工厂负责生产所有产品相比,工厂方法模式将生成具体产品的任务分发给具体的产品工厂,也就是定义一个抽象工厂,其定义了产品的生产接口,但不负责具体的产品,将生产任务交给不同的派生类工厂。这样不用通过指定类型来创建对象了。
package com.example.designmode.factory;
public class FactoryMethod {
public static void main(String[] args) {
new NotebookFactory().getElectronicEquipmentFactory();// 获取笔记本对象
new SpeakerFactory().getElectronicEquipmentFactory();// 获取音箱对象
}
}
abstract class ElectronicEquipmentactory {
abstract ElectronicEquipment getElectronicEquipmentFactory();
}
class NotebookFactory extends ElectronicEquipmentactory {
@Override
public ElectronicEquipment getElectronicEquipmentFactory() {
return new Notebook();
}
}
class SpeakerFactory extends ElectronicEquipmentactory {
@Override
public ElectronicEquipment getElectronicEquipmentFactory() {
return new Speaker();
}
}
class ElectronicEquipment {
}
class Notebook extends ElectronicEquipment {
}
class Speaker extends ElectronicEquipment {
}
工厂方法模式:
优点:如果有新的对象增加,只需要增加一个具体的类和具体的工厂类即可。
不会有已有代码产生影响,便于后期维护。
缺点:每增加一个对象,要增加一个对象类和工厂类,增加代码量。
(3):抽象工厂模式
抽象工厂模式通过在AbstarctFactory中增加创建产品的接口,并在具体子工厂中实现新加产品的创建,当然前提是子工厂支持生产该产品。
package com.example.designmode.factory;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class AbstractFactory {
public static void main(String[] args) {
Factory2077 psFactory = new PsFactory();
psFactory.HighFrameRate2077();
psFactory.LowFrameRate2077();
Factory2077 pcFactory = new PcFactory();
pcFactory.HighFrameRate2077();
pcFactory.LowFrameRate2077();
}
}
abstract class Factory2077{
abstract Game2077 HighFrameRate2077();
abstract Game2077 LowFrameRate2077();
}
@Slf4j
class PsFactory extends Factory2077 {
@Override
Game2077 HighFrameRate2077() {
log.info("PS5高帧率低画质2077");
return new Ps5Game2077();
}
@Override
Game2077 LowFrameRate2077() {
log.info("PS4低帧率低画质2077");
return new Ps5Game2077();
}
}
@Slf4j
class PcFactory extends Factory2077 {
@Override
Game2077 HighFrameRate2077() {
log.info("Rtx3090高帧率高画质2077");
return new Rtx3090Game2077();
}
@Override
Game2077 LowFrameRate2077() {
log.info("Rtx3060高帧率高画质2077");
return new Rtx3060Game2077();
}
}
class Game2077{
}
class Ps4Game2077 extends Game2077 {
}
class Ps5Game2077 extends Game2077 {
}
class Rtx3090Game2077 extends Game2077 {
}
class Rtx3060Game2077 extends Game2077 {
}
工厂方法模式:
优点:增加一层抽象类,减少了工厂的数量。
缺点:需要新产品时,必须要修改多个工厂类。
3、总结
上面介绍的三种工厂模式有各自的应用场景,实际应用时能解决问题满足需求即可,可灵活变通,无所谓高级与低级。
此外无论哪种模式,由于可能封装了大量对象和工厂创建,新加产品需要修改已定义好的工厂相关的类,因此对于产品和工厂的扩展不太友好,利弊需要权衡一下。
总的来说,简单工厂模式还是用的比较多,工厂方式模式的代码量稍微有点多,抽象工厂模式一般用于业务场景比较大的情况下。
参考博客: