JS的设计模式(笔记)

一、构造器模式

需求:录入员工信息。
原始方法:

const employee1 = {
	name: "张三",
	age: 18
}

const employee2 = {
	name: "李四",
	age: 20
}

按以上方法,如员工如要录入多个信息或多个员工就会显得十分臃肿复杂,这时我们可以用到构造器模式:

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

const e1 = new Employee("张三", 18)
const e2 = new Employee("李四", 20)

二、原型模式

按照以上方法,如想在构造函数Employee上加上一个say方法,则

function Employee(name, age) {
	this.name = name
	this.age = age
	this.say = function() {
		console.log("我的名字叫" + name + ",我今年" +  age + "岁。")
	}
}

但是,这样添加会有一个问题,每次在new一个Employee实例的时候都要重新开辟一个空间去存储say方法,会占用大量空间,不符合代码的可复用性,此时我们可以用到原型模式:

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

Employee.prototype.say = function() {
	console.log("我的名字叫" + this.name + ",我今年" +  this.age + "岁。")
}

我们可以把代码提升一下,使用ES6中的class来构造函数:

class Employee {
	constructor(name, age) {
		this.name = name
		this.age = age
	}
	say() {
		console.log("我的名字叫" + this.name + ",我今年" +  this.age + "岁。")
	}
}

以上代码中,我们可以发现,class这种写法是兼顾构造器模式和原型模式的,constructor中放构造器所写的变量,在Employee中写原型上的变量和方法。

三、工厂模式

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

如在后台管理系统中我们需要根据登录的用户信息去获取该用户对应的权限:

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

    static Userfactory(role) {
        switch (role) {
            case "superadmin":
                return new User("superadmin", ["home", "user-manage", "goods-manage", "news-manage"])
                break
            case "admin":
                return new User("admin", ["home", "goods-manage", "news-manage"])
                break
            case "aditor":
                return new User("aditor", ["home"])
                break
            default:
                throw new Error("参数错误!")
        }
    }
}
console.log(User.Userfactory("aditor"));

缺点:当我们需要创建更多类型的对象时,工厂函数就会成为一个超级庞大的函数,难以维护,所以工厂函数只适用于创建的对象数量少、对象的创建逻辑不复杂时使用。

四、抽象工厂模式

抽象工厂模式并不直接生成实例,而是用于对产品类的创建。

class User {
  constructor(name, role, permission) {
      this.name = name
      this.role = role
      this.permission = permission
  }

  welcome() {
      console.log("欢迎回来," + this.name);
  }

  showData() {
      throw new Error("抽象方法需要被实现")
  }
}

class SuperAdmin extends User {
  constructor(name) {
      super(name, "superadmin", ["home", "user-manage", "goods-manage", "news-manage"])
  }

  showData() {
      console.log("superadmin-show-data");
  }

  addUser() { }
}

class Admin extends User {
  constructor(name) {
      super(name, "admin", ["home", "goods-manage", "news-manage"])
  }

  showData() {
      console.log("admin-show-data");
  }
}

class Aditor extends User {
  constructor(name) {
      super(name, "aditor", ["home"])
  }

  showData() {
      console.log("aditor-show-data");
  }
}

function getAbstactUserFactory(role) {
  switch (role) {
      case "superadmin":
          return SuperAdmin
      case "admin":
          return Admin
      case "aditor":
          return Aditor
  }
}

const UserClass = getAbstactUserFactory("admin")
const user = new UserClass("张三")
console.log(user.welcome()); // 欢迎回来,张三

区别:工厂模式返回的是具体的对象,而抽象工厂模式返回的是具体的

五、建造者模式

定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
举例:例如网页上获取导航栏以及导航栏所对应的数据列表。

class Navbar {
	init() { console.log("navbar-init") }
	getData() {
		return new Promise(resolve => {
			setTimeout(() => {
				resolve()
				console.log("navbar-getdata")
			})
		}, 1000)
	}
	render() { console.log("navbar-render") }
}

class List{
	init() { console.log("list-init") }
	getData() {
		return new Promise(resolve => {
			setTimeout(() => {
				resolve()
				console.log("list-getdata")
			})
		}, 1000)
	}
	render() { console.log("list-render") }
}

class Creator {
	async startBuild(builder) {
		await builder.init()
		await builder.getData()
		await builder.render()
	}
}

const op = new Creator()
op.startBuild(new NavBar())
op.startBuild(new List())

建造者模式关心的是创建这个对象的整个过程,甚至创建对象的每一个细节。

六、单例模式

定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。主要解决一个全局使用的类频繁地创建销毁,占用内存(例如vue中的store)。
(1)ES5的写法(闭包)

const Singleton = (function() {
	let instance
	function User(name, age) {
		this.name = name
		this.age = age
	}
	return function(name, age) {
		if (!instanace) {
			instance = new User(name, age)
		}
		return instance
	}
})()

(2)ES6的写法

class Singleton = {
	constructor(name, age) {
		if (!Singleton.instance) {
			this.name = name
			this.age = age
			Singleton.instance = this
		}
		return Singleton.instance
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值