Zhengrenzhe

(°∀°)ノ 老打杂了

用户工具

站点工具


设计模式:模式:建造者模式

建造者模式(Builder Pattern)

Separate the construction of a complex object from its representation so that the same construction process can create different representations

如果一个对象构建过程比较复杂,并且构建部分有些过程是可选的,那么就可以使用建造者模式。建造者模式将复杂对象的构建与其表示(实例)分离,使同样的构建过程可以创建不同的表示(实例)。

概念有点晦涩,简而言之,你要创建一个复杂对象,创建的过程就好像汽车生产流水线一样繁琐,同时这个复杂对象会被不同的地方用到,而且并不是所有属性都用到,也就是说创建对象中间的几个步骤是可选的。对于这种情况,使用建造者模式可以轻松处理。

典型的,在前端中,表单面板一直是一个比较麻烦的东西,在不同的场景下,表单可能会需要不同的输入类型。例如登陆表单需要用户名与密码,而重置密码表单则只需要密码,为这一点差异新做一个表单显然是划不来的。

现在使用TypeScript实现一个使用建造者模式的表单生成器:

abstract class FormCls {
    static allItemsType: Exclude<keyof FormCls, "render">;

    username(): string {
        return `<input name="username" />`;
    }

    password(): string {
        return `<input type="password" name="password" />`;
    }

    email(): string {
        return `<input type="email" />`;
    }

    color(): string {
        return `<input type="color"/>`;
    }

    date(): string {
        return `<input type="date"/>`;
    }

    render(order: (typeof FormCls.allItemsType)[]): string {
        return order.map(type => this[type]()).join("\n");
    }
}

class Form extends FormCls {
};

abstract class FormBuilderCls {
    private order: (typeof FormCls.allItemsType)[] = [];

    addItem(item: typeof FormCls.allItemsType) {
        this.order.push(item);
        return this;
    }

    getForm() {
        const form = new Form();
        return form.render(this.order);
    }
}

class FormBuilder extends FormBuilderCls {
}

const form = new FormBuilder();
form.addItem("username").addItem("password");

console.log(form.getForm());

在抽象类FormCls中,定义了几种表单的“零件”,例如用户名、密码、邮件。render方法接收一个类型为(typeof FormCls.allItemsType)[]数组,也就是Exclude<keyof FormCls, “render”>,它枚举了FormCls中除了render之外的所有方法。

抽象类FormBuilderCls是一个建造者类,addItem向order添加一个“零件”,调用getForm则返回根据当前order建造的form表单。

从此我们使用表单时,根据所需字段就能建造出符合我们需求的表单。

设计模式/模式/建造者模式.txt · 最后更改: 2020/02/28 05:49 由 zhengrenzhe