简单工厂模式有个比较明显的弊端:工厂类集中了所有实例的创建逻辑,明显违背开闭原则。基于前面介绍的简单工厂模式Java,我们来看如何通过Java语言实现工厂方法模式。
工厂方法模式则是对该问题的进一步延伸解决,差异就是将原先存在于一个工厂类中的逻辑抽调出来,创建一个接口和多个工厂类。这样,一旦功能有新增,比如说我们要加一个 “发送导弹” 的功能,只需要加一个 “导弹发送工厂类”,该类实现 produce 接口返回实例化的 “导弹发送类”,再在 “导弹发送类” 中,实现具体的发送逻辑即可,无需修改之前的业务代码,拓展性较好。
首先,我们还是创建一个 Sender 接口:
public interface Sender {
public void Send();
}
然后我们创建几个具体的实现类:
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 EmailSender implements Sender{
@Override
public void Send() {
System.out.println("发送邮件");
}
}
然后,我们统一一下工厂类的接口行为:
public interface Provider {
public Sender produce();
}
继续,定义几个工厂实现上面这种 “行为约束”:
public class ExpressSendFactory implements Provider {
@Override
public Sender produce() {
return new ExpressSender();
}
}
public class EmailSendFactory implements Provider{
@Override
public Sender produce() {
return new EmailSender();
}
}
public class SmsSendFactory implements Provider {
@Override
public Sender produce() {
return new SmsSender();
}
}
测试类:
public class Main {
public static void main(String[] args) {
Provider providerSms = new SmsSendFactory();
Sender senderSms = providerSms.produce();
senderSms.Send(); // 发送短信
Provider providerEmail = new EmailSendFactory();
Sender senderEmail = providerEmail.produce();
senderEmail.Send(); // 发送邮件
Provider providerExpress = new ExpressSendFactory();
Sender senderExpress = providerExpress.produce();
senderExpress.Send(); // 发送快递
}
}
工厂方法模式中,核心的工厂类(这里为 Provider 接口)不再负责所有产品的创建,而是将具体创建的工作交给子类去做,该核心类仅扮演抽象工厂的角色,负责给出具体工厂子类必须实现的接口,而不接触哪一个产品类应该被实例化的细节,拓展性较简单工厂模式提升明显。