一、模式定义
工厂方法模式(Factory Method Pattern)又称为工厂模式,也叫虚拟构造器(Virtual Constructor)模式或者多态工厂(Polymorphic Factory)模式,它属于创建型模式。
在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类。
工厂方法模式,是对简单工厂模式的进一步抽象化,其好处是可以使系统在不修改原来代码的情况下引进新的产品,即满足开闭原则。
二、模式动机
请先阅读《Java 设计模式-创建型模式-简单工厂模式(Simple Factory Pattern)》
简单来说是来为了解决简单工厂模式所出现的一些缺点而进行的改进。
现在对该系统进行修改,不再设计一个消息发送者工厂类来统一负责所有消息发送者的创建,而是将具体消息发送者的创建过程交给专门的工厂子类去完成;
我们先定义一个抽象的消息发送者工厂类,再定义具体的工厂类来生产邮箱发送者、短信发送者等,它们实现在抽象消息发送者工厂类中定义的方法。
这种抽象化的结果使这种结构可以在不修改具体工厂类的情况下引进新的产品,如果出现新的消息发送者类型,只需要为这种新类型的消息发送者创建一个具体的工厂类就可以获得该新消息发送者的实例,这一特点使得工厂方法模式具有超越简单工厂模式的优越性,更加符合“开闭原则”。
三、模式结构
工厂方法模式包含如下角色:
- Product:抽象产品,是工厂方法模式所创建的产品的抽象
- ConcreteProduct:具体产品,是抽象产品的具体实现
- Factory:抽象工厂,抽象工厂类中声明了工厂方法
- ConcreteFactory:具体的工厂方法,实现了抽象工厂,用来生产具体的产品
四、代码实现
Sender.java
package com.design.demo.factorymethod;
/**
* @author administrator
* @date 2020-05-16 14:21
*/
public interface Sender {
/**
* 信息发送
*/
public void send(String message);
}
SmsSender.java
package com.design.demo.factorymethod;
/**
* 短信发送信息实现类
* @author administrator
* @date 2020-05-16 14:22
*/
public class SmsSender implements Sender {
@Override
public void send(String message) {
System.out.println("通过短信发送信息:" + message);
}
}
EmailSender.java
package com.design.demo.factorymethod;
/**
* 邮箱发送信息实现类
* @author administrator
* @date 2020-05-16 14:22
*/
public class EmailSender implements Sender {
@Override
public void send(String message) {
System.out.println("通过邮件发送信息:" + message);
}
}
SenderFactory.java
package com.design.demo.factorymethod;
/**
* 抽象工厂
* @author administrator
* @date 2020-05-16 15:44
*/
public interface SenderFactory {
public Sender newSender();
}
EmailSenderFactory.java
package com.design.demo.factorymethod;
/**
* @author administrator
* @date 2020-05-16 16:16
*/
public class EmailSenderFactory implements SenderFactory {
@Override
public Sender newSender() {
return new EmailSender();
}
}
SmsSenderFactory.java
package com.design.demo.factorymethod;
/**
* @author administrator
* @date 2020-05-16 16:16
*/
public class SmsSenderFactory implements SenderFactory {
@Override
public Sender newSender() {
return new SmsSender();
}
}
ClientTest.java
package com.design.demo.factorymethod;
/**
* @author administrator
* @date 2020-05-16 16:18
*/
public class ClientTest {
public static void main(String[] args) {
//发送邮件
SenderFactory emailSenderFactory = new EmailSenderFactory();
Sender emailSender = emailSenderFactory.newSender();
emailSender.send("message abc ...");
//发送短信
SenderFactory smsSenderFactory = new SmsSenderFactory();
Sender smsSender = smsSenderFactory.newSender();
smsSender.send("message abc ...");
}
}
五、缺点
-
增加程序的复杂度
一旦添加新产品,既要创建产品类,又要创建工厂类,增加了一大波类。 -
更加难以理解
由于考虑到系统的可用性,需要引入抽象层,在客户端代码中均用抽象定义,客户端代码更加抽象难以理解。