js设计模式:简单工厂和单例

写在前面:
一些关于自己在代码设计思维方面的学习记录

面向对象的一些理解

实例代码就不上了, 就写一些总结

封装: 提供属性和方法的权限管理, 只对外暴露接口, 具体的功能在内部实现
继承: 子类继承父类的方法和属性, 可以抽离公共代码,减少代码冗余
多态: 同一个接口在子类中的不同的实现, 可以对父类中方法进行扩展

ES6中类的设计分析

锻炼自己的抽象设计能力, 通过UML类图来展示类之间的关系

  • 一般步骤

    梳理各给类之间的关联关系:

    抽离父类, 抽象子类, 分析关联类(相互引用的关系)
    

    要理解以下几点:
    // 每个独立的对象都可以抽象为一个类
    // 每个类都 要干自己该干的事(方法), 都有自己的特性(属性)
    // 关联类: 一个类 需要用到 另一个类中的东西; 或者说一个类 它可以作为另一个类的属性来用

简单工厂模式

我们不需要关心业务的具体实现过程, 最后只需要给你一个模型,你输入参数就可以套用了;下面都是结合实例来展示我的理解

// 举个栗子
// 食品实例生成的详细过程
class Food {
    constructor(name, type) {
        this.name = name // 食品
        this.type = type // 食品类型
    }

    desc() {
        console.log(`我是${this.name},属于${this.type}类型`);
    }
    
}

class FoodFactory {
    // ES6中静态方法不会被实例调用,可以被类调用
    static create(name, type) {
        // 创建一种食品实例
        return new Food(name, type)
    }
}

// 工厂开始生产食品实例了
FoodFactory.create('核桃', '坚果').desc() // 我是核桃, 属于坚果类型
FoodFactory.create('旺仔', '饮品').desc() // 我是旺仔, 属于饮品类型
// 这样我们就可以 生成出我们想要的食品, 只要你给我们 一个名称和类型

单例模式

就是保证全局只有一个对象可以访问; 像全局缓存、全局状态管理时,都可以使用, 实现数据共享

我们要确保一个类 只能初始化 一个实例, 有就直接返回, 没有就初始化

如购物车, 登录框只有一个, jQuery的 $, vuex的store都是单例模式的思想

class Singleton {
    // js模拟
    constructor() {}

    login() {
        console.log('login...');
    }
}

// 给类挂载一个静态方法, 只有一个
// 自执行函数: 只是为了将变量保存在 函数的作用域中, 避免污染而已
Singleton.singleInstance = (function () {
            // 通过闭包实现: 类似通过一个全局变量来存储这个实例
            let instance;  // 保存创建好的实例
            return function() {
                if (!instance) {
                    // 如果没有创建, 就创建一个
                    instance = new Singleton()
                }
                return instance
            }
        })()
// 通过调用静态方法来创建单实例
let single11 = Singleton.singleInstance()
let single22 = Singleton.singleInstance()
// 通过调用类 初始化的实例
let single3333 = new Singleton()
single11.login();
single22.login();
console.log(single11 === single22);  // ture
console.log(single11 === single3333); // false

demo演示, 页面登录框

class LoginForm {

    constructor() {
        this.state = 'hide' // 初始状态
    }

    // 显示
    show() {
        if (this.state === 'show') {
            console.log('登录框已经显示');
            return ;
        }
        this.state = 'show';
        console.log('登录框显示了, 请输入');
    }
    // 隐藏
    hide() {
        if (this.state === 'hide') {
            console.log('登录框已隐藏');
            return ;
        }
        this.state = 'hide';
        console.log('登录框隐藏');
    }
}

// 添加单例方法
// 通过这个方法, 我初始化出来的 都是指向同一个实例对象
LoginForm.initSingle = (function () {
    let instance; // 存储实例对象
    return function () {
        if (!instance) {
            instance = new LoginForm()
        }
        return instance
    }
})()

// 当同时对一个实例进行操作时:

// 页面1的登陆操作
let login1 = LoginForm.initSingle()
login1.show()

// 页面2的登陆操作
let login2 = LoginForm.initSingle()
login2.show() // 登陆框已经显示, 页面2也是对同一实例进行访问,就会弹出错误
login2.hide()

// 单例模式 就是实例化出来的对象 都指向同一实例, 对同一实例进行操作, 
// 实现了 数据共享
    原文作者:前端
    原文地址: https://segmentfault.com/a/1190000018525570
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞