前端设计模式汇总

122 阅读1分钟

构造器+原型模式

定义:开发中常用的组合模式(在构造器中定义实例对象的属性和方法,在原型上定义公有的属性和方法)

function Tabs(selecter) {
    this.selecter = document.querySelector(selecter);
    this.headerItems = this.selecter.querySelectorAll('.header li')
    this.boxItems = this.selecter.querySelectorAll('.box li')
    this.change()

    console.log(this.headerItems, this.boxItems);
}

Tabs.prototype.change = function () {
    for (let i = 0; i < this.headerItems.length; i++) {
        this.headerItems[i].onclick = () => {
            for (let m = 0; m < this.headerItems.length; m++) {
                this.headerItems[m].classList.remove("active");
                this.boxItems[m].classList.remove("active");
            }
            this.headerItems[i].classList.add('active')
            this.boxItems[i].classList.add('active')
        }
    }
}
new Tabs('.container1')

//ES6--class重构
class Tabs1 {
    constructor(selecter) {
        this.selecter = document.querySelector(selecter);
        this.headerItems = this.selecter.querySelectorAll('.header li')
        this.boxItems = this.selecter.querySelectorAll('.box li')
        this.change()

        console.log(this.headerItems, this.boxItems);
    }
    change() {
        for (let i = 0; i < this.headerItems.length; i++) {
            this.headerItems[i].onclick = () => {
                for (let m = 0; m < this.headerItems.length; m++) {
                    this.headerItems[m].classList.remove("active");
                    this.boxItems[m].classList.remove("active");
                }
                this.headerItems[i].classList.add('active')
                this.boxItems[i].classList.add('active')
            }
        }
    }
}
new Tabs1('.container2')

工厂模式

定义:由一个工厂对象决定创建某一种产品类对象的实例,主要用于创建同一类对象。

优点:只需要一个正确的参数,就可以获取到你所需要的对象,而无需知道其创建的具体细节。

缺点:在函数内包含了所有对象的创建逻辑和判断逻辑的代码,每增加新的构造函数还需要修改判断逻辑代码。当我们的对象不是上面的3个而是10个或更多时,这个函数会成为一个庞大的超级函数,变得难以维护。

适用场景:简单工厂只能作用于创建的对象数量较少,对象的创建逻辑不复杂时使用。

class User {
    constructor(role, pages) {
        this.role = role;
        this.pages = pages
    }

    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', 'user-manage', 'news-manage'])
                break;
            default:
                throw Error('参数错误');
        }
    }
}

const user = User.UserFactory('admin');

抽象工厂模式

定义:并不直接生成实例,而是对产品类簇的创建

class User {
    //基类
    constructor(name, role, pages) {
        this.name = name;
        this.role = role;
        this.pages = pages;
    }
    welcome() {
        console.log('欢迎登陆', this.name);
    }
    dataShow() {
        throw new Error('参数错误');
    }
}

class SuperAdmin extends User {
    constructor(name) {
        super(name, 'superadmin', ['home', 'user-manage', 'right-manage', 'news-manage'])
    }
    //重写
    dataShow() {
        console.log('superadmin', this.name);
    }
    addUser() {
        //添加用户
    }
}
class Admin extends User {
    constructor(name) {
        super(name, 'admin', ['home', 'user-manage', 'news-manage'])
    }
    //重写
    dataShow() {
        console.log('admin', this.name);
    }
    deleteEidtor() {
        //删除编辑
    }
}
class Eidtor extends User {
    constructor(name) {
        super(name, 'eidtor', ['home', 'news-manage'])
    }
    //重写
    dataShow() {
        console.log('eidtor', this.name);
    }
}

function getUserFactory(role) {
    switch (role) {
        case 'superadmin':
            return SuperAdmin;
            break;
        case 'admin':
            return Admin;
            break;
        case 'eidtor':
            return Eidtor;
            break;
        default:
            throw new Error('参数错误');
    }
}

let userFactory = getUserFactory('admin');
console.log(userFactory);
let user = new userFactory('曹操');

建造者模式

建造者模式(builder pattern)属于创建型模式的一种,提供一种创建复杂对象的方式。它将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

建造者模式是一步一步的创建一个复杂的对象,它允许用户只通过指定复杂的对象的类型和内容就可以构建它们,用户不需要指定内部的具体构造细节。

建造者模式将一个复杂对象的构建层与其表示层相互分离,同样的构建过程可采用不同的表示。工厂模式主要是为了创建对象实例或者类簇(抽象工厂),关心的是最终产出(创建)的是什么,而不关心创建的过程。而建造者模式关心的是创建这个对象的整个过程,甚至于创建对象的每一个细节。

class Navbar {
    init() {
        console.log('navbar-init')
    }
    getData() {
        console.log('navbar--getData')
    }
    reader() {
        console.log('navbar--reader')
    }
}

class List {
    init() {
        console.log('List-init')
    }
    getData() {
        console.log('List--getData')
    }
    reader() {
        console.log('List--reader')
    }
}

class Creator {
    startBuild(builder) {
        builder.init();
        builder.getData();
        builder.reader();
    }
}

const creator = new Creator();
creator.startBuild(new Navbar());
creator.startBuild(new List());

单例模式

保证一个类仅有一个实例,并提供一个访问它的全局访问点。

主要解决一个全局使用的类频繁地创建和销毁,占用内存

const Modal = (function () {
    let instance = null;
    return function () {
        if (!instance) {
            instance = document.createElement("div");
            instance.innerHTML = "登录对话框";
            instance.className = 'dialog';
            instance.style.display = "none";
            document.body.appendChild(instance);
        }
        return instance;
    }
})();
document.querySelector('.open').onclick = function () {
    //显示modal框
    const modal = Modal();
    modal.style.display = 'block';
}

document.querySelector('.close').onclick = function () {
    //关闭modal框
    const modal = Modal();
    modal.style.display = 'none';
}

装饰器模式

装饰器模式能够很好的对已有功能进行拓展,这样不会更改原有的代码,对其他的业务产生影响,这方便我们在较少的改动下对软件功能进行拓展。

Function.prototype.before = function (beforeFunc) {
    let _this = this;
    return function () {
        beforeFunc.apply(this, arguments);
        return _this.apply(this, arguments);
    }
}

Function.prototype.after = function (afterFunc) {
    let _this = this;
    return function () {
        let result = _this.apply(this, arguments);
        afterFunc.apply(this, arguments);
        return result
    }
}

function test() {
    console.log(11111);
}
// test();

let test1 = test.before(function () {
    console.log('before', 22222);
})
test1();

let test2 = test.after(function () {
    console.log('after', 33333);
})
test2();

适配器模式

将一个类的接口转换为客户想要的另一个接口,适配器模式让那些接口不兼容的类可以一起工作。

class TenXunMap {
    show() {
        console.log('开始渲染1');
    }
}
class BaiduMap {
    display() {
        console.log('开始渲染2');
    }
}
class BaiduAdapter extends BaiduMap {
    constructor() {
        super()
    }
    show() {
        this.display();
    }
}
function reader(map) {
    map.show();
}
reader(new TenXunMap());
reader(new BaiduAdapter());

策略模式

该模式主要解决在有多种算法相似的情况下,使用1f...1se所带来的复杂和难以维护。它的优点是算法可以自由切换,同时可以避免多重1f..e1se判断,且具有良好的扩展性。

let optons = {
    "A": (opt) => {
        return opt * 3
    },
    "B": (opt) => {
        return opt * 2
    },
    "C": (opt) => {
        return opt * 1
    }
}

function run(level, opt) {
    return optons[level](opt)
}

run('A', 5000);