设计模式
  8CtDmU74qicX 2023年11月24日 23 0

设计原则

  1. 开放封闭原则
    对扩展开放,对修改关闭
  2. 例子1 - axios 设计符合开闭原则(通过axios.interceptors 对外部扩展进行开放)、以及redux中间件设计方式
  3. 例子2
1. enum MemberName {

normal:'normal',

vip:'vip',

vipPlus:'vipPlus'

}

// 不符合开闭原则,因为如果新增了会员类型,则需要修改Production类里面的代码去适配

class Member{

public name:MemberName;

constructor(name){

this.name = name;

}

}

class Production {

constructor(private member:Member,private myPrice:number){

this.member = member;

this.myPrice = myPrice;

}get price(){
    switch(this.member.name){
       case Member.normal:return myPrice;
       case Meber.vip: return this.myPrice*0.8;
       case Meber.vipPluse: return this.myPrice*0.6;
       default:return myPrice;
    }
}};

const p = new Production(new Meber(Member.vip),800);// 符合开闭原则 , 将折扣 - discount 写入到member中,然后在Production 中调取计算即可

class Member{

public name:MemberName;

public discount:number;

constructor(name,discount){

this.name = name;

this.discount = discount;

}

}

class Production {

constructor(private member:Member,private myPrice:number){

this.member = member;

this.myPrice = myPrice;

}get price(){
    return this.myPrice* member.discount;
}};


2. 单一职责原则
思想:一个类或者函数的功能要尽可能的单一,不要太杂
一般性原则:如果一个类代码超过100行或方法超过10个或内部有其他功能代码,则选择进行拆分
好处:同前端模块化类似。更好的责任划分,如果涉及修改能保证更少的改动,以及减少对整个系统其他代码的影响。
a. 例子

// 不符合单一职责

// 1. product 和 category 属于两个分类,应该拆开

// 2. updateProduct 应该拆分成单独的功能

class Product{

public name:string;

public price:number;

public categoryName:string;

public categoryIcon:string;

updateProduct(propertyName,value){

this[propertyName] = value;

}

}// 符合单一职责

class Category {

public name:string;

public icon: string;

updateName(value){

this.name = value;

}

updateIcon(){}

}class Product {

public name:string;

public price:number;

public category:Category;

updateName(name){}

updatePrice(price){}

}


3. L 里氏替换原则

  1. 所有引用基类的地方必须能透明地使用其子类的对象
  2. 子类能替换掉父类,使用者可能根本就不需要知道是父类还是子类,反之则不行
  3. 里氏替换原则 是开闭原则 实现的基础,程序设计的时候尽量使用基类定义及引用,运行时再决定使用哪个子类
  4. 里氏替换原则可以提高代码的复用性,提高代码的可扩展性,也增加了耦合度
  5. 当对于多态,这个原则是讲的是类如何设计,子类如果违反了父类的功能则表示违反了里氏替换原则
  6. 原则:要求子类不能违反父类的功能和规定
    例子
  7. 接口隔离原则
  8. 保持接口的单一独立,避免出现胖接口
  9. js中没有接口,使用较少
  10. 类似于单一职责原则,更关注接口
  11. 依赖倒置原则
  12. 面向接口编程,依赖于抽象而不依赖于具体实现
  13. 使用方只关注接口而不关注具体类的实现
  14. js中使用较少(没有接口、弱类型)

一 单例模式
单例模式的核心是确保只有一个实例, 并提供全局访问

  1. 直接使用一个数据
  2. Class 中定义 一个静态属性 getInstance 返回一个实例,每次通过getInstance 去创建对象,就会是单例
    二 工厂模式
    工厂模式定义一个用于创建对象的接口,这个接口由子类决定实例化哪一个类。该模式使一个类的实例化延迟到了子类。而子类可以重写接口方法以便创建的时候指定自己的对象类型。
  3. 用于不直接操作原对象的创建(可能参数很多),使用工厂模型,用一个新的class 去默认一些参数
    三 适配器模式
    适配器与代理模式相似
  • 适配器模式: 提供一个不同的接口(如不同版本的插头)
  • 代理模式: 提供一模一样的接口
    装饰者模式是“新增行为”,代理模式是“控制访问行为”,适配器模式是"转换行为"

自己理解,适配器模式,相当于利用一个新的class 重写了原来class的方法,使得这个方法得到重构 - 适配一些新的功能。
四 代理模式
自己理解,代理模式,是利用一个新的class ,代理原来class的重名的方法,使该方法的使用,输出都和原来保持一致,但是可以在代理方法中新增一些 不影响原功能使用的功能。
不支持操控原对象,而是利用代理对象对远对象进行操作。代理对象的属性和方法和原对象保持一致,只是对原对象中的方法进行了增强。

ES6中 的Proxy ,可以代理对象 (set, get),也可以代理函数(apply)
应用

  1. 代理缓存 - 代理函数,缓存函数的结果(针对于一些比较复杂的计算进行缓存)。利用的的是 Proxy 的 apply 函数的代理
  2. 表单验证代理 - 代理对象的set,在set内部进行表单校验
    虚拟代理,也就是延迟创建对象。在需要时候再进行对象的创建。图片加载前 提供loading效果,http 缓存加载。
    缓存代理,利用缓存代理函数,对一些复杂的函数的结果进行缓存。

五 装饰器模式
自己理解,装饰器模式,是利用一个新的class,对原来class功能的增加,比如新增一个方法什么的。
ES6装饰器

  • 类的属性
  • 类的方法
  • 属性存取器(accessor)
    六 策略模式
    自己理解,当出现大量的if else 语句的时候,就该考虑策略模式了。
    策略对象,也就是 对象的key 对应的是 策略名称,对应的value 表示策略函数。
    七 发布订阅模式 - eventBus

八观察者模式 - rxjs
数据生产者 (observable、subject)
数据观察者(observer)

发布订阅和观察者模式都是用来处理异步的方案
九 迭代器模式
迭代器模式是指提供一种方法顺序访问一个聚合对象中各个元素,而不需要暴露该对象的具体表示,常见的为部署 Symbol.iterator 属性,调用对应 Symbol.iterator 的方法返回一个迭代器对象,然后就可以以统一的方式进行遍历:

let arr = ['a', 'b', 'c'];

let iterator = arrSymbol.iteratoriterator.next();

// { value: 'a', done: false }iterator.next();

// { value: 'b', done: false }iterator.next();

// { value: 'c', done: false }iterator.next();

// { value: undefined, done: true }
【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

上一篇: webpack 下一篇: es6
  1. 分享:
最后一次编辑于 2023年11月24日 0

暂无评论

推荐阅读
8CtDmU74qicX