定义
Define an interface for creating an object,but let subclasses decide which class to instantiate.Factory Method lets a class defer instantiation to subclasses.
定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
应用(例子)
我现在做的BIM项目,里面有绘制功能,分为墙体绘制、房间绘制。
BaseDraw负责定义绘制的共性,实现对事物的抽象定义
DrawWall和DrawRoom则是实现具体的操作(称为产品类)
Creator是创建类负责如何创建绘制类
export abstract class BaseDraw {
//公共方法、属性
public startPoint:Point;
public stopPoint:Point;
// 抽象的方法
public abstract draw():void;
}
export class DrawWall extends BaseDraw{
public draw(){
// draw a wall
}
}
export class DrawRoom extends BaseDraw{
public draw(){
// draw a room
}
}
export class Creator{
public readonly DrawType = {
wall:DrawWall,
room:DrawRoom
};
public createDrawObj(c: string): BaseDraw|null {
return this.createObj(this.DrawType[c])
}
private createObj<T extends BaseDraw>(c: new () => T): T|null {
let d = null;
try{
d = new c();
}catch(e){
//error
}
return d;
}
}
}
使用方法
let creator:Creator = new Creator();
let d = creator.createDrawObj(“wall”);//得到一个绘制对象
d.draw(); //绘制墙
好处
首先,良好的封装性性,代码结构清晰。与一个对象相关的职责通常有三类:**对象本身所具有的职责、创建对象的职责和使用对象的职责。**这样写职责分明
其次,易于扩展。比如我现在要新增个绘制标尺,只要新增一个类就好了。
再次,工厂方法模式是典型的解耦框架。我如果要替换墙体绘制类,只要修改工厂方法,不需要一个个文件出new 一个新的对象。
用处
- 像new 一个对象很复杂的情况下,比如创建弹出框,不同的弹出框有不同的布局、不同的组件类,new起来就需要传很多参数给它,这个时候就可以用工厂方法模式。
- 需要灵活的、可扩展的设计,比如你的产品类不固定,或者也可能被替换,只要修改工厂方法就可以了,不用一处处去修改。
- 并行开发,比如你需要类B,但它还没有写好,你就可以先用工厂方法把类B虚拟出来。
参考链接:TS泛型
参考书籍:《设计模式之禅》