业务场景
有这么个场景:供应商需要将把产品通过陆路方式运到目的地,运输的功能非常复杂已经通过代码实现,有客户反应还需要水路运输,这是为了兼容陆路运输的功能增加水路运输,改造代码的工作量则变得异常繁杂,
而且容易出错。在这种场景下在设计运输功能之初,就应该使用工厂方法模式,进行运输方式的解耦。由客户决定运输方式。
工厂方法模式有四个角色
抽象工厂角色,具体工厂角色,抽象产品角色,具体产品角色。不再是由一个工厂类去实例化具体的产品,而是由抽象工厂的子类去实例化产品
// 抽象产品(运输功能)
public interface Moveable {
void run();
}
// 具体产品(空运产品有运输功能)
public class Plane implements Moveable {
@Override
public void run() {
System.out.println("plane....");
}
}
// 具体产品(路运产品有运输功能)
public class Broom implements Moveable {
@Override
public void run() {
System.out.println("broom.....");
}
}
// 抽象工厂(生产运输产品)
public abstract class TransportFactory {
abstract Moveable create();
}
// 具体工厂(空运工厂生产飞机)
public class PlaneFactory extends TransportFactory {
public Moveable create() {
return new Plane();
}
}
// 具体工厂(路运工厂生产车辆)
public class BroomFactory extends TransportFactory {
public Moveable create() {
return new Broom();
}
}
// 测试类
public class Test {
public static void main(String[] args) {
// 客户决定使用运出产品
VehicleFactory factory = new BroomFactory();
Moveable m = factory.create();
m.run();
}
}
使用场景
当你在编写代码的过程中, 如果无法预知对象确切类别及其依赖关系时, 可使用工厂方法。
工厂方法将创建产品的代码与实际使用产品的代码分离, 从而能在不影响其他代码的情况下扩展产品创建部分代码。
如果你希望用户能扩展你软件库或框架的内部组件, 可使用工厂方法。
如果你希望复用现有对象来节省系统资源, 而不是每次都重新创建对象, 可使用工厂方法。
让我们思考复用现有对象的方法:
- 首先, 你需要创建存储空间来存放所有已经创建的对象。
- 当他人请求一个对象时, 程序将在对象池中搜索可用对象。
- 然后将其返回给客户端代码。
- 如果没有可用对象, 程序则创建一个新对象 (并将其添加到对象池中)。