简单工厂模式(Simple Factory Pattern)不属于 GoF 的 23 种经典设计模式的范围,
简单工厂一般分为:普通简单工厂、多方法简单工厂、静态方法简单工厂。
一、模式定义
简单工厂模式(Simple Factory Pattern)提供创建对象的最佳方式,又称为静态工厂方法(Static Factory Method)模式,它属于创建型模式。
工厂模式,顾名思义,用来创建大规模的同类产品。提供一个创建对象实例的功能,而无须关心其具体创建过程。被创建对象实例的类型可以是接口、抽象类,也可以是具体的类。
简单工厂模式的实质:一个工厂类根据传入的参数不同动态决定应该创建哪一类产品类(这些产品类均有相同父类或实现相同的接口)实例,这也是多态的思想。
简单工厂模式有以下优点:
-
帮助封装
只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程,组件外部能够面向接口编程。 -
解耦
通过简单工厂,客户端仅仅“消费”产品,免除了直接创建产品对象的责任。
二、模式动机
工厂模式适合:凡是出现了大量的产品需要创建,并且具有共同的接口时,可以通过工厂方法模式进行创建。
其主要关键点有:
- 大量的具有相同父类或接口的产品需要创建
- 需要统一的创建该类对象的入口
例如:
1、客户在餐厅吃饭,根据客户性质不同,需要采取不同的折扣结算方案
2、根据消息通知的及时性不同,采取不同的消息发送方式(邮件/短信)
3、根据外部传入的标识不同,进行系统不同缓存的类型刷新操作
三、模式结构
简单工厂模式包含如下角色:
-
Factory:工厂角色
工厂角色负责创建所有实例的内部逻辑 -
Product:抽象产品角色
抽象产品角色是所创建的具体对象的父类或者共同接口 -
ConcreteProduct:具体产品角色
具体产品角色是创建目标,所有创建的对象都充当这个角色的某个具体类的实例。
四、代码实现
简单工厂一般分为:普通简单工厂、多方法简单工厂、静态方法简单工厂
1、普通简单工厂
建立一个工厂类,对实现了同一接口的类进行实例的创建;
Sender.java
package com.design.demo.simplefactory;
/**
* @author administrator
* @date 2020-05-16 14:21
*/
public interface Sender {
/**
* 信息发送
*/
public void Send(String message);
}
EmailSender.java
package com.design.demo.simplefactory;
/**
* 邮箱发送信息实现类
* @author administrator
* @date 2020-05-16 14:22
*/
public class EmailSender implements Sender {
@Override
public void Send(String message) {
System.out.println("通过邮件发送信息:" + message);
}
}
SmsSender.java
package com.design.demo.simplefactory;
/**
* 短信发送信息实现类
* @author administrator
* @date 2020-05-16 14:22
*/
public class SmsSender implements Sender {
@Override
public void Send(String message) {
System.out.println("通过短信发送信息:" + message);
}
}
SenderFactory.java
package com.design.demo.simplefactory;
/**
* Sender对象工厂类
* @author administrator
* @date 2020-05-16 14:23
*/
public class SenderFactory {
/**
* 根据type入参,返回对应的实现
* @param type
* @return
*/
public Sender getSender(String type) {
if ("mail".equals(type)) {
return new EmailSender();
} else if ("sms".equals(type)) {
return new SmsSender();
} else {
System.out.println("请输入正确的类型!");
return null;
}
}
}
FactoryTest.java
package com.design.demo.simplefactory;
/**
* @author administrator
* @date 2020-05-16 14:43
*/
public class FactoryTest {
public static void main(String[] args) {
SenderFactory senderFactory = new SenderFactory();
Sender sender = senderFactory.getSender("mail");
if(null != sender) {
sender.Send("message abc ...");
}
}
}
2、多方法简单工厂
是对普通工厂方法模式的改进,在普通工厂方法模式中,如果传递的字符串出错,则不能正确创建对象;而多个工厂方法模式是提供多个工厂方法,分别创建对应对象。
将上面的代码做下修改,仅改动下SenderFactory类就行
package com.design.demo.simplefactory;
/**
* Sender对象工厂类
* @author administrator
* @date 2020-05-16 14:23
*/
public class SenderFactory {
public static Sender getEmailSender() {
return new EmailSender();
}
public static Sender getSmsSender() {
return new SmsSender();
}
}
3、静态方法简单工厂
将工厂方法里的方法置为静态的,不需要创建工厂实例,直接调用即可。
由于静态方法简单工厂不需要实例化工厂类,所以大多数情况下,我们会选用此模式。
SenderFactory.java
package com.design.demo.simplefactory;
/**
* Sender对象工厂类
* @author administrator
* @date 2020-05-16 14:23
*/
public class SenderFactory {
/**
* 根据type入参,返回对应的实现
* @param type
* @return
*/
public static Sender getSender(String type) {
if ("mail".equals(type)) {
return new EmailSender();
} else if ("sms".equals(type)) {
return new SmsSender();
} else {
System.out.println("请输入正确的类型!");
return null;
}
}
}
FactoryTest.java
package com.design.demo.simplefactory;
/**
* @author administrator
* @date 2020-05-16 14:43
*/
public class FactoryTest {
public static void main(String[] args) {
Sender sender = SenderFactory.getSender("mail");
if(null != sender) {
sender.Send("message abc ...");
}
}
}
五、缺点
-
工厂类职责过重
由于工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。 -
违反了“开闭原则”
系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在if语言中加上创建新产品的逻辑。
六、工厂模式和策略模式的区别
- 工厂模式,是创建型设计模式,关注对象的创建。目的是在工厂类中为调用者创建产品对象,其主要封装了创建产品对象的逻辑过程,调用者不关心创建的过程细节(对调用者来说相当于黑盒),但是仍然由调用者来使用产品对象的属性和方法。
- 策略模式,是行为型设计模式,关注行为的封装。目的是实现多个不同算法的策略类,由调用者传递不同的参数给Context类来选择执行不同的算法流程(对调用者来说相当于白盒)。策略模式的优点让策略的变化独立于使用策略的客户。