前端校招相关的设计模式小结

1、单例模式

定义:是保证一个类只有一个实例,并且提供一个访问它的全局访问点。

需求:一些对象我们往往只需要一个,比如线程池、全局缓存、浏览器中的window对象、登录浮窗等。

优点:

1、可以用来划分命名空间,减少全局变量的数量

2、可以被实例化,且实例化一次,再次实例化生成的也是第一个实例

class CreateUser{
    constructor(name){
        this.name = name;
        this.getName();
    }
    getName(){
        return this.name;
    }
}
var  ProxyMode = (function(){
    var instance = null;
    return function(name){
        if(!instance){
            instance = new CreateUser(name);
        }
        return instance;
    }
})();
var a= new ProxyMode('aaa');//CreateUser {name: "aaa"}
var b= new ProxyMode('bbb');//CreateUser {name: "aaa"}结果都是第一个对象

2、观察者模式

定义:对象间的一种一对多的依赖关系。

需求:当一个对象的状态发生变化时,所有依赖于他的对象都将得到通知。

优点:时间上的解耦,对象之间的解耦。

var targetObj = {
    name:'aa'
}
var targetObj2 = {
    name:'aa'
}
// 定义值改变时的处理函数(观察者)
function observer(oldVal, newVal) {
    // 其他处理逻辑...
    targetObj2.name = newVal
    console.info(newVal);
}

// 定义name属性及其set和get方法(name属性为被观察者)
Object.defineProperty(targetObj, 'name', {
    enumerable: true,
    configurable: true,
    get: function() {
        return name;
    },
    set: function(val) {
        observer(name, val)
        name = val
    }
});

targetObj.name = '11';
targetObj.name = '22';
console.log(targetObj2.name)

3、发布者/订阅者模式

在网上看到一个对发布者/订阅者模式与观察者模式,比较精辟的总结:

有中间商赚差价的是发布者/订阅者模式,无中间商赚差价的是观察者模式。

function Publish(){
    let s =[];
    this.add= function(sMember){
        let isExist = s.some(function(item){
            if(item == sMember){
                return true;
            }else{
                return false;
            }
        })
        if(!isExist){
            s.push(sMember);
        }
    }
    this.send = function(data){
        s.forEach(function(fn){
            fn(data);
        })
        return this;
    }
}

let a = function(data){
    console.log(data);
}
let b = function(data){
    console.log(data);
}
let p = new Publish();
p.add(a);
p.add(b);
p.send('sadasdsa');

4、工厂模式:

定义:将其成员对象的实例化推迟到子类来实现的类。

需求:创建对象的流程赋值的时候,比如依赖于很多设置文件等 ;处理大量具有相同属性的小对象;注:不能滥用

优点:不暴露创建对象的具体逻辑,而是将将逻辑封装在一个函数中。

function createObject(name ,age){
    var obj = new Object();
    obj.name = name;
    obj.age = age;
    obj.run = function (){
         return this.name + this.age;
    }
    return obj;
}
var a = createObject('lao',22);

5、模块模式

var Person = (function() {
    var name = 'xxx'
    function sayName() {
        console.log(name)
    }
    return{
        name: name,
        sayName: sayName
    }
})()

6、代理模式

使用ES6中的proxy实现

const handler = {
    get: function() {
        console.log('doing');
    }
}

const initialObj = {
    id: 1,
    name: 'cc'
}

const proxiedObj = new Proxy(initialObj, handler);

console.log(proxiedObj.name);

7、策略模式

策略模式的本意将算法的使用与算法的实现分离开来,避免多重判断调用哪些算法。适用于有多个判断分支的场景,如解决表单验证的问题。

// 对于vip客户
function vipPrice() {
    this.discount = 0.5;
}
 
vipPrice.prototype.getPrice = function(price) {
  return price * this.discount;
}
// 对于老客户
function oldPrice() {
    this.discount = 0.3;
}
 
oldPrice.prototype.getPrice = function(price) {
    return price * this.discount;
}
// 对于普通客户
function Price() {
    this.discount = 1;
}
 
Price.prototype.getPrice = function(price) {
    return price ;
}

// 上下文,对于客户端的使用
function Context() {
    this.name = '';
    this.strategy = null;
    this.price = 0;
}
 
Context.prototype.set = function(name, strategy, price) {
    this.name = name;
    this.strategy = strategy;
    this.price = price;
}
Context.prototype.getResult = function() {
    console.log(this.name + ' 的结账价为: ' + this.strategy.getPrice(this.price));
}

var context = new Context();
var vip = new vipPrice();
context.set ('vip客户', vip, 200);
context.getResult();   // vip客户 的结账价为: 100

var old = new oldPrice();
context.set ('老客户', old, 200);
context.getResult();  // 老客户 的结账价为: 60

var Price = new Price();
context.set ('普通客户', Price, 200);
context.getResult();  // 普通客户 的结账价为: 200

接下去的几种模式设计到继承这方面

8、构造函数模式

  function Car(name, year, country){
    this.name = name;
    this.year = year;
    this.country = country;
  }
  Car.prototype.sayName = function(){
    return this.name;
  }
  var mycar = new Car("BMW", 2017, "Germany");
  console.log(mycar);

9、混合模式

function Parent(name){
    this.name = name;
}
Parent.protoType.sayName = function(){
    console.log('parent name:',this.name);
}
Parent.protoType.doSomeThing = function(){
    console.log('parent doSomeThing');
}
function Child(name,fatherName){
    Parent.call(this,faterName);
    this.name = name;
}
Child.protoType = Parent.protoType;
Child.protoType.constructor = Child;
Child.protoType.sayNmae =  function(){
    console.log('child name:',this.name);
}
var child = new Child('son');
child.sayName();
child.doSomeThing();
//通过原型链实现对象属性和方法的继承,而通过构造函数来实现实例属性的继承。

10、中间者模式

function Parent(name){
    this.name = name;
}
Parent.protoType.sayName = function(){
    console.log('parent name:',this.name);
}
Parent.protoType.doSomeThing = function(){
    console.log('parent doSomeThing');
}
function Child(name,fatherName){
    Parent.call(this,faterName);
    this.name = name;
}
function create(proto){
    function F(){}
    F.proto=proto;
    return new F();
}
Child.protoType = create(Parent.protoType);
Child.protoType.sayNmae =  function(){
    console.log('child name:',this.name);
}
Child.protoType.constructor = Child;
//用F(){}去替代父类执行构造函数

参考:https://www.jianshu.com/p/4f3014fb8b8b

https://www.cnblogs.com/smlp/p/9776789.html

https://www.jianshu.com/p/5a3af723ad84

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值