简单工厂模式 属于创建型模式,提供创建对象的最佳方式。通过Java的方式来实现简单工厂模式。简单工厂模式的实质:一个工厂类根据传入的参数,动态决定应该创建哪一类产品类(这些产品类均继承自一个父类或接口)实例。
简单工厂模式问题引入
我们在创建对象的时候,用 new 就行了,那为什么要用函数或类将 new 的过程封装起来呢?
这里,为大家引入两个角色来说明这个问题:一个是类的设计者,一个是类的使用者。
类的使用者只关心 “这个对象做这事”、“那个对象做那件事”,而不关心 “这件事如何去做?”,
类的设计者才会去关心 “如何去做”。
举个例子,类的设计者设计了 “阿猫”、“阿狗” 两个类,类的使用者需要创建 “阿猫 1”、“阿狗 2” 两个对象,如果不使用简单工厂模式,类的使用者就需要明确知道 “阿猫”、“阿狗” 两个类,这无疑增加了类使用者的负担。使用工厂来代替创建这两对象,权责分开,比方说,这些动物都有 “吃东西” 的行为,这时,“吃东西” 具体行为是什么样子,这是类的设计者关心的,而何时进行该行为,是类的使用者关心的。
再举个例子,大家经常使用的数据库中间件,无需关心具体的底层实现类,只需将用户名密码等连接信息传过去,就会直接获取到相应的数据库连接实例,这个角度,就可以将数据库中间件看作一个大的工厂。
简单工厂模式优点
一个调用者想创建某个对象,只需知道其名称即可
屏蔽具体行为实现,调用者只需关心产品接口,减轻调用者负担
拓展性高,如果想增加一个产品类,只需拓展一个工厂类即可
简单工厂模式不同实现方式
简单工厂模式分为三种
- 普通简单工厂模式
- 多方法简单工厂模式
- 静态方法简单工厂模式
这三种模式从上到下逐步抽象,并且更具有一般性
普通简单工厂模式
普通简单工厂模式就是建立一个具体工厂类,对实现了同一接口的一些类进行实例的创建,首先看下 uml 类图(这里以发送短信、邮件、快递为例):
首先,创建一个三者共有的接口:
public interface Sender {
public void Send();
}
然后,创建实现类:
public class EmailSender implements Sender{
@Override
public void Send() {
System.out.println("发送邮件");
}
}
public class SmsSender implements Sender{
@Override
public void Send() {
System.out.println("发送短信");
}
}
public class ExpressSender implements Sender {
@Override
public void Send() {
System.out.println("发送快递");
}
}
再然后,我们创建一个工厂类来产出这几种 “产品”:
public class SendFactory {
public Sender produce(String type) {
if (type == null) {
return null;
} else if ("email".equalsIgnoreCase(type)) {
return new EmailSender();
} else if ("sms".equalsIgnoreCase(type)) {
return new SmsSender();
} else if ("express".equalsIgnoreCase(type)) {
return new ExpressSender();
} else {
return null;
}
}
}
接下来,调用下测试:
public class Main {
public static void main(String[] args) {
SendFactory sendFactory = new SendFactory();
Sender senderSms = sendFactory.produce("sms");
senderSms.Send(); // 发送短信
Sender senderEmail = sendFactory.produce("email");
senderEmail.Send(); // 发送邮件
Sender senderExpress = sendFactory.produce("express");
senderExpress.Send(); // 发送快递
}
}
多方法简单工厂模式
多方法简单工厂是在普通简单工厂模式的基础上该进来的,普通简单工厂模式在使用时,如果 type 类型传递错误则不能正确创建对象,多方法直接将 produce 中的逻辑展开到具体的方法中,从而避免该问题。接下来看下我们的改进:
针对上面代码,我们只需调整 SendFactory 类即可:
public class SendFactory {
public Sender produceSms(){
return new SmsSender();
}
public Sender produceEmail(){
return new EmailSender();
}
public Sender produceExpress() {
return new ExpressSender();
}
}
接下来,我们进行如下简单测试:
public class Main {
public static void main(String[] args) {
SendFactory sendFactory = new SendFactory();
Sender senderEmail = sendFactory.produceEmail();
senderEmail.Send(); // 发送邮件
Sender senderSms = sendFactory.produceSms();
senderSms.Send(); // 发送短信
Sender senderExpress = sendFactory.produceExpress();
senderExpress.Send(); // 发送快递
}
}
静态方法简单工厂模式
普通简单工厂模式和多方法简单工厂模式有一个弊端,就是需要频繁的实例化工厂类,一般我们会将 “多方法” 设置为静态的,从而避免类的频繁实例化,拿来即用。
这里我们直接看修改后的 SendFactory 类:
public class Main {
public static void main(String[] args) {
//SendFactory sendFactory = new SendFactory();
Sender senderEmail = SendFactory.produceEmail();
senderEmail.Send(); // 发送邮件
Sender senderSms = SendFactory.produceSms();
senderSms.Send(); // 发送短信
Sender senderExpress = SendFactory.produceExpress();
senderExpress.Send(); // 发送快递
}
}