interface
1. 概述
定义一个用于创建对象的接口, 让实现类决定实例化哪一个类. 工厂方法使一个类的实例化延迟到其接口实现类.
2. 适用性
- 当一个类不知道它所必须创建的对象的类的时候;
2. 当一个类希望由它的子类来指定它所创建的对象的时候;
3. 当类将创建对象的职责委托给多个帮助子类中的某一个, 并且你希望将哪一个帮助子类是代理者这一信息局部化的时候.
3. 代码实现
比如我们现在想要创建 Worker
接口的实例 Teacher
和 Farmer
:
interface Worker {
void work();
}
class Teacher implements Worker {
@Override
public void work() {
System.out.println("老师在工作");
}
}
class Farmer implements Worker {
@Override
public void work() {
System.out.println("农民在耕地");
}
}
现在我们回顾适用性第一条和第二条, 我们要创建一个 Factory 类, 这个类可以创建 Teacher
和 Farmer
, 但我们不知道到底创建的是 Teacher
还是 Farmer
, 我们将判断创建的对象类型交给子类来判断, 那么我们需要这样一个抽象类和具体子类:
abstract class Factory{
public abstract Worker getWorker();
}
class TeacherFactory extends Factory {
@Override
public Worker getWorker() {
...
return new Teacher();
}
}
class FarmerFactory extends Factory {
@Override
public Worker getWorker() {
...
return new Farmer();
}
}
这样我们就可以通过调用具体子类重写的 getWorker()
的方法来创建对象:
Factory factory = new TeacherFacoty();
Worker worker = factory.getWorker();
以上其实就是很多文章中提到的抽象方法模式.
也可以将抽象类换为一个自定义的新的接口, 通过接口实现类来创建, 比如:
interface Factory{
Worker getWorker();
}
但回看实用性的第三点, “将哪一个帮助子类是代理者这一信息局部化的时候“, 也就是说不如我们直接根据要求得到一个 factory
, 这个 factory
就能创建我们要的类型的 worker
, 所以最好再将其封装, 外层加上一个 AbstractFacoty
, 只留一个静态的方法:
class AbastractFactory{
@FunctionalInterface
interface WorkerFactory{
public Worker createWorker();
}
static class TeacherFactory implements WorkerFactory {
@Override
public Worker createWorker() {
return new Teacher();
}
}
static class FarmerFactory implements WorkerFactory {
@Override
public Worker createWorker() {
return new Farmer();
}
}
public static WorkerFactory factory(String str) {
switch(str) {
case "teacher":
return new TeacherFactory();
case "farmer":
return new FarmerFactory();
default:
break;
}
return null;
}
}
这样我们就可以直接传入 "teacher"
这样的参数来得到相应的工厂, 调用工厂的 .createWorker()
方法来创建对象:
AbastractFactory.WorkerFactory workerFactory = AbastractFactory.factory("teacher");
Worker worker = workerFactory.createWorker();
worker.work(); // 输出老师在工作
4. 总结
Factory Method 模式是设计模式中应用最为广泛的模式, 在面向对象的编程中, 对象的创建工作非常简单, 对象的创建时机却很重要. Factory Method 解决的就是这个问题, 它通过面向对象的手法, 将所要创建的具体对象的创建工作延迟到了子类(或接口实现类),从而提供了一种扩展的策略, 较好的解决了这种紧耦合 (close coupling) 的关系.
参考文章
- https://www.liaoxuefeng.com/wiki/1252599548343744/1281319170474017
- https://www.tutorialspoint.com/design_pattern/factory_pattern.htm
- https://en.wikipedia.org/wiki/Design_Patterns
- https://en.wikipedia.org/wiki/Factory_method_pattern#Java
- https://en.wikipedia.org/wiki/Abstract_factory_pattern#Java_example
- https://www.javatpoint.com/factory-method-design-pattern
- https://juejin.im/entry/58f5e080b123db2fa2b3c4c6
- https://blog.csdn.net/carson_ho/article/details/52343584
- https://www.jianshu.com/p/e55fbddc071c