前端开发中常用的几种设计模式
单列模式
构造函数每次被创建对象,只有一个被创建
单例模式是JavaScript最简单的设计模式之一。属于创建型模式,提供看一种创建对象的最佳方式
简单来说
就是没有就创建,有就使用,只有一个
- 私有构造函数
- 声明静态单列对象
- 构造单列之前要加锁
- 需要二次检查单例实例是否为空,分别在锁之前和锁之后
var single = (function(){
var demo;
return function(name){
if(demo){
return demo
}
this.name = name
demo = this
}
})
//es6实现方式
class Singleton{
constructor(name){
this.name=name
this.instance = null
}
//构造一个广为人知的接口,供用户对该类进行实例化
static getInstance(name){
if(!this.instance){
this.instance = new Singleton(name)
}
return this.instance
}
}
单例模式分为二种
懒汉模式 ,饿汉模式
懒汉模式
比较慢,在类加载的时候,不创建实例,因此类加载速度快,但是运行获取对象的速度慢
class Ddd{
constructor(){
this.init();
this.Instance=null
}
init(){
console.log("我是懒汉,我有点懒")
}
sayName(){
console.log("我是懒汉")
}
static getInstance(){
if(!this.Instance){
this.Instance = new Ddd()
}
return this.Instance
}
}
Ddd.getInstance().sayName()
//我是懒汉,我有点懒
//我是懒汉
class Ddd{
static EvilMan = new Ddd()
sayName(){
console.log("我是恶汉")
}
sayAge(){
console.log("我比他大一岁")
}
constructor(){
console.log("我是恶汉ES6写法")
}
}
Ddd.EvilMan.sayName();
我是恶汉ES6写法
我是恶汉
简单工厂模式
运用场景:
你去购买汉堡,直接点餐,取餐,没必要自己亲手做(初始化实例封装)
商店要‘封装’做汉堡的工作,做好直接给买者
实现:
从上面的代码中我们可以知道,所谓简单工厂模式技术一个工厂类和一个工厂函数,通过传入参数的不同,返回不同的实例
适用场景:
举一个生活中实际的使用场合,假如我们上体育课需要去拿篮球,足球和排球,我们可以自己去一个一个找对应的球(类似于上面通过自己来创建对象),也可以通过管理员,告诉管理员需要什么样的球,至于管理员是怎么找到这个相对应的球,就与我们不相关了。这个管理员就是工厂类。
特点:
- 需要创建的类较少,因为需要根据传入的参数来判断返回的实例,如果类太多,那么就会导致逻辑复杂。
-
- 不需要关注实例的创建过程,只需要传入相对应的值即可。
缺点:
从简单工厂模式的特点中我们可以知道,简单工厂模式适合于创建的类较少,一旦需要的类较多,逻辑就会复杂。而且一旦需要添加新的类,就得重新修改工厂类,这样显得非常不方便。
//封装买东西的动作
class Product{
constructor(name){
this.name=name
}
init(){
console.log("点餐")
}
fn1(){
console.log("取餐")
}
fn2(){
console.log("取餐人:"+ this.name)
}
}
//创建一个产品对象
class Creator{
create(name){
return new Product(name)
}
}
let creator = new Creator();
let p = creator.create('p1');
观察者模式
当对象见存在一对多关系,使用观察者模式观察者模式属于行为型模式
发布订阅
- 发布
- 订阅
- 取消订阅
- 当状态发生改变的时候,执行一段代码
模拟场景:有一个饭馆前台接受客户订单,当食物做好了,喊一声,客户确认是自己的食物,就来控制台取餐
class Platform{
constructor(){
this.orders = []
}
submit(order){
this.orders.push(order)
}
notify(good){
this.orders.forEach(item =>{
item.callMe(good)
})
}
}
class customer{
constructor(name,good){
this.name = name
this.good = good
}
callMe(good){
if(good == this.good){
console.log(this.name+'的'+this.good+"做好了!!!")
}
}
}
var meituan = new Platform()
meituan.submit(new customer("张三","奶茶"))
meituan.submit(new customer("李四","麻辣烫"))
meituan.notify("麻辣烫")
(未完待续…)