目录
工厂方法模式属于创建型设计模式。
定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法模式(Factory Method Pattern)使一个类的实例化延迟到其子类。
四个基本要素
名称
- 工厂方法模式
问题
- 在软件开发中,经常会遇到需要根据不同条件创建不同类型的对象的情况。如果直接在客户端代码中创建对象,会导致客户端代码与具体产品类耦合度较高,不利于后续的维护和扩展。
方案
- 定义一个抽象工厂接口或抽象类,其中包含一个用于创建产品的抽象方法。
- 具体的产品由具体的工厂子类实现,每个具体工厂负责创建特定类型的产品。
- 客户端通过调用工厂方法来创建产品,而不直接与具体产品类进行交互。
效果
- 将对象的创建与使用分离,降低了客户端代码与具体产品的耦合度。
- 提高扩展性,新增产品时只需添加新的具体工厂和具体产品,无需修改现有的代码。
- 客户端通过调用工厂方法来创建产品,而不直接与具体产品类进行交互。
模式的结构
构造者
- 是一个接口或抽象类,它包含一个用于创建不同类型产品的抽象方法。
- 客户端通过调用抽象方法来获取产品对象,而不需要知道具体产品的实现细节。
- 通常情况下,抽象工厂是一个接口或者抽象类。
具体构造者
- 实现了抽象工厂(Abstract Factory)定义的接口或者继承了抽象工厂类,并实现了其中定义的方法,用于创建具体的产品对象。
- 每个具体工厂类通常对应一个产品族或者产品等级结构,它包含了一组用于创建具体产品对象的方法。
- 在客户端需要创建产品对象时,通过调用具体工厂的方法来获取对应的产品对象。
抽象产品(Abstract Product)
- 定义了产品对象的接口或抽象类,描述了产品对象应该具有的通用行为和属性。
- 通常作为工厂模式中的一个基类,用于统一表示一组相关的产品对象。
- 抽象产品的存在使得客户端代码可以通过与抽象产品进行交互,而不需要关心具体产品的实现细节,从而实现了客户端与具体产品类的解耦。
具体产品(Concrete Product)
- 具体产品类实现了抽象产品类(或接口)所定义的方法,从而提供了产品对象的具体行为和属性。
- 是工厂方法模式的核心,每个具体产品类对应一个具体工厂类,负责创建该产品的实例。
- 具体产品类的存在使得系统可以根据需求创建不同类型的产品对象,并通过客户端来使用。
工厂方法模式的类图
优点
- 符合开闭原则:修改现有代码的情况下引入新的产品类。
- 高内聚低耦合:将对象的创建与使用分离。
- 符合单一职责原则:每个具体工厂类只负责创建一种产品。
- 灵活性高:客户端代码在运行时动态选择具体工厂类,从而实现了灵活的对象创建方式。
缺点
- 类的数量增加:每个具体产品都需要对应一个具体工厂类,这会增加系统的复杂度和理解难度。
- 增加了系统的抽象程度:工厂方法模式引入了抽象工厂和抽象产品,增加了系统的抽象程度,可能会导致系统的理解和设计难度增加。
模式具体应用
某工厂准备开发一个圆珠笔产品线,目前有一个笔芯类,有红笔芯、蓝笔芯、黑笔芯三个具体产品。该产品线的目的是为用户提供一个圆珠笔实例,分别有红色笔芯的圆珠笔、蓝色笔芯的圆珠笔和黑色笔芯的圆珠笔。
抽象产品(Product) : PenCore.java
public abstract class PenCore {
public String color; // 笔芯颜色
public PenCore(String color) {
this.color = color;
}
public abstract void writeWord(String s);
}
具体产品(ConcreteProduct)_1 : RedPenCore.java
public class RedPenCore extends PenCore {
public RedPenCore() {
super( "红色");
}
@Override
public void writeWord(String s) {
System.out.println("用[" + color + "笔芯]写出{"+color+"}的字: " + s);
}
}
具体产品(ConcreteProduct)_2 : BluePenCore.java
public class BluePenCore extends PenCore{
public BluePenCore() {
super("蓝色");
}
@Override
public void writeWord(String s) {
System.out.println("用[" + color + "笔芯]写出{"+color+"}的字: " + s);
}
}
具体产品(ConcreteProduct)_3: BlackPenCore.java
public class BlackPenCore extends PenCore{
public BlackPenCore() {
super("黑色");
}
@Override
public void writeWord(String s) {
System.out.println("用[" + color + "笔芯]写出{"+color+"}的字: " + s);
}
}
构造者(Creator): BallPen.java
public abstract class BallPen {
public BallPen() {
System.out.println("生产了一只装有"+ getPenCore().color + "笔芯的圆珠笔");
}
public abstract PenCore getPenCore(); //工厂方法
}
具体构造者(ConcreteCreator): BlackBallPen.java
public class BlackBallPen extends BallPen {
@Override
public PenCore getPenCore() {
return new BlackPenCore();
}
}
具体构造者(ConcreteCreator): BlueBallPen.java
public class BlueBallPen extends BallPen{
@Override
public PenCore getPenCore() {
return new BluePenCore();
}
}
具体构造者(ConcreteCreator): RedBallPen.java
public class RedBallPen extends BallPen{
@Override
public PenCore getPenCore() {
return new RedPenCore();
}
}
测试:ApiTest.java
public class ApiTest {
int sharedVariable = 0;
@Test
public void factoryMethodPattern(){
PenCore penCore;
BallPen ballPen;
ballPen = new BlueBallPen();
penCore = ballPen.getPenCore();
penCore.writeWord("hello");
}
@Test
public void test1(){
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
sharedVariable++;
}
});
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
sharedVariable++;
}
});
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Final value of sharedVariable: " + sharedVariable);
}
}