JavaScript设计模式

80 阅读2分钟

构造器模式

原理:使用构造函数创建对象

function Employee(name,age){
    this.name=name;
    this.age=age;
    this.say = function(){
        console.log(this.name,this.age)
    }
}

var employee1 = new Employee("张三",18);
employee1.say();

var employee2 = new Employee("李四",20);
employee2.say();

优点:创建相同结构的实例可以直接用构造函数,而不是每次都写一段代码来创建。 缺点:构造函数中的方法都是一样的,但是每次创建新的实例都要新开辟一个空间存储函数,使用原型模式优化。

原型模式

function Employee(name,age){
    this.name=name;
    this.age=age;
}

Employee.prototype.say = function(){
    console.log(this.name,this.age)
}

var employee = new Employee("张三",18);
employee.say();

var employee = new Employee("李四",20);
employee.say();

使用类的方式将:构造器模式 & 原型模式 合二为一

class Employee{
    constructor(name,age){
        this.name=name;
        this.age=age;
    }
    say(){
        console.log(this.name,this.age)
    }
}
var employee = new Employee("张三",18);

say 方法已经默认放在原型上了。

QQ20250316-105554.png

工厂模式

根据传入的原料,返回不同的对象

function UserFactory(role) {
    function User(role, page) {
        this.role = role;
        this.page = page;
    }
    switch (role) {
        case "superadmin":
            return new User("superadmin", ["home", "user-manage", "right-manage", "news-manage"]);
            break;
        case "admin":
            return new User("admin", ["home", "user-manage", "news-manage"]);
            break;
        case "editor":
            return new User("editor", ["home", "news-manage"]);
            break;
        default:
            return new Error("参数错误");
    }
}

var user = UserFactory("editor");

es6 实现

class User {
    constructor(role, page) {
        this.role = role;
        this.page = page;
    }
    static UserFactory(role) {
        switch (role) {
            case "superadmin":
                return new User("superadmin", ["home", "user-manage", "right-manage", "news-manage"]);
                break;
            case "admin":
                return new User("admin", ["home", "user-manage", "news-manage"]);
                break;
            case "editor":
                return new User("editor", ["home", "news-manage"]);
                break;
            default:
                return new Error("参数错误");
        }
    }
}

var user = User.UserFactory("editor");

简单工厂的优点是:只要传入一个正确的参数,就可以获取所需要的对象,不需要知道其创建的具体细节。但是在函数内包含了所有对象的创建逻辑和判断逻辑的代码,每增加新的构造函数还需要判断逻辑代码。当我的对象不是上面的3个而是10个时,这个函数会成为一个庞大的超级函数,难以维护。所以简单工厂只能作用于创建的对象数量较少,对象的创建逻辑不复杂时使用。

抽象工厂模式

返回的是具体的类,这个类可能是基于基类的扩展,公共的方法写在基类中。

class User {
    constructor(name, role, page) {
        this.name = name;
        this.role = role;
        this.page = page;
    }
    welcome() {
        console.log("欢迎" + this.name + "进入系统")
    }
    dataShow() {
        // abstract
        throw new Error("抽象方法需要被实现");
    }
}

class SuperAdmin extends User {
    constructor(name) {
        super(name, "superadmin", ["home", "user-manage", "right-manage", "news-manage"]);
    }
    dataShow() { }
    addRight() { }
    addUser() { }
}

class Admin extends User {
    constructor(name) {
        super(name, "admin", ["home", "user-manage", "news-manage"]);
    }
    dataShow() {
        console.log("admin-datashow")
    }
}

class Editor extends User {
    constructor(name) {
        super(name, "editor", ["home", "news-manage"]);
    }
    dataShow() {
        console.log("editor-datashow")
    }
}

function getAbstractClass(role) {
    switch (role) {
        case "superadmin":
            return SuperAdmin;
            break;
        case "admin":
            return Admin;
            break;
        case "editor":
            return Editor;
            break;
        default:
            return new Error("参数错误");
    }
}

var userClass = getAbstractClass("editor");
new userClass("张三")