常用设计模式

设计模式并非前端独有的技术或者说思维方式,而是软件设计的一种思维方式。在java、C++、C…都有,至于是什么语言来呈现实现,都只是一种思维的呈现方式

设计模式概念

设计模式是软件开发人员在软件开发过程中面临的一些具有代表性问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的;
在我看来设计模式可以看成 “设计” + “模式”

  • 设计:即要遵守的基本的设计原则
  • 模式:即遵循设计原则总结出来的方案(套路)

设计原则

写代码的时候也没必要刻意的要求自己符合每一条原则,这样反而会限制我们,当我们在做技术架构,或者在写代码的时候,尽量避免违反设计原则。这样我们的代码就更加容易被测试,可维护性高,可读性强。

一般来说有SOLID(稳定的)几个原则:

  1. 单一职责原则(Single Responsibility Principle)
  2. 开闭原则(Open Closed Principle)
  3. 里氏替换原则(Liskov Substitution Principle)
  4. 迪米特法则(Law of Demeter)/ 最少知识原则(The Least Knowledge Principle))
  5. 接口隔离原则(Interface Segregation Principle)
  6. 依赖倒置原则(Dependence Inversion Principle)

单一职责原则(Single Responsibility Principle)

类也好,组件也好,把颗粒度降的更低,只有一个因素会影响该类/组件。也就是应该只有一个发生变化的原因。简而言之就是每个类 / 组件只负责一件事,只需要负责自己的那部分,这样类的复杂度就会降低,更容易被测试,可维护性更高,粒度小组合性也更高
比如下面这个Demo

// 设计原则 :不符合单一职责
class Person{
    constructor(){
        // 包含人的姓名
        this.name = "";
        // 不符合单一原则,下面有人技能的名称
        // 有名称和技能的属性,可以考虑把技能的类单独抽离出来
        this.skillName = "";
    }
}

上面的Person的类,如果只有一个name的属性,那么也就只有name会影响到整个Person,可是除了name还有技能这个属性。此时的复杂度就会变高。
比如我们要对这个Person进行测试,如果只有name属性,如果仅以对错(name是否符合预期传入使用)来测试的话,只有两类情况,但现在加入了一个skillName属性,那复杂度就变成2 * 2 = 4累情况了。所以可测试性 、 可维护性就下降了。
此时我们可以考虑将技能的属性单独抽离为一个类。

开闭原则(Open Closed Principle)

一个软件实体,如类、模块和函数应该对外扩展开放,对内修改关闭。
这样设计也是让类 / 模块有更好的维护性。要扩展要修改一些东西要尽可能少的去更改原来的功能。假如代码要是在更新迭代中,对原有的代码要是修改了,可能会对新的功能有一定的影响,一般都会向上兼容。

里氏替换原则(Liskov Substitution Principle)

所有引用基类的地方必须能透明地使用其子类的对象,也就是说子类对象可以替换其父类对象,而程序执行效果不变
看下面这个例子

// 基类
class Animal {
	constructor(name){
        this.name = name;
    }
    fly(){
        console.log("飞");
    }
}

// 子类
class Horse extends Animal{
    constructor(name){
      // 继承父类
        super(name);
    }
    fly(){
      console.log("不能飞");
    }
}
const horse = new Animal('timor')
// 打印出 飞
horse.fly();
const horse1 = new Horse('timor');
// 打印出不能飞
horse1.fly();

上面基类Animail 定义了一个方法fly,可以飞。子类Horse继承了父类并重写了fly这个方法。
导致两个实例horse和horse1分别调用各自的fly打印出的内容不一致,这就不符合历史替换原则了。期望的是引用基类的地方(horse实例化Animal)换成子类(实例化Horse)他们的行为保持一致,而不是子类将父类的方法重写了

迪米特法则(Law of Demeter)/ 最少知识原则(The Least Knowledge Principle))

迪米特法则(Law of Demeter)又叫作最少知识原则(The Least Knowledge Principle),一个类对于其他类知道的越少越好,就是说一个对象应当对其他对象有尽可能少的了解(只和朋友通信,不和陌生人说话)。
比如A和B有关联,B和C有关联。那就避免A和C直接关联
在前端的组件通信中,父子通信,爷爷和孙子辈(跨层级)尽量不要直接通信,基于此原因,我们的解决方案是抽离出一个公共的数据仓库比如Redux来解决。而不是跨级别来通信。

接口隔离原则(Interface Segregation Principle)

多个特定的客户端接口要好于一个通用性的总接口
A类里面有各种方法,B类依赖这个A类的某些方法,那尽可能保证,只提供一些必要的方法和数据。够用即可,也是高内聚的一个体现。而非所有需要或者不需要的数据都一次性返回给B

依赖倒置原则(Dependence Inversion Principle)

  1. 上层模块不应该依赖底层模块,它们都应该依赖于抽象。
  2. 抽象不应该依赖于细节,细节应该依赖于抽象

比如说张三这个实例是依赖一个抽象的类实例化出来得到的具体的人。而不是说我对张三进行抽象才得到一个抽象的人的类。这就反了。
张三是是一个很具象的东西,而人类则是一个宏观的东西。
抽象是把共性的东西抽象,而不是把细节的东西抽象。
一句话,应该从抽象到具体

你可能感兴趣的:(javaScript,设计模式,java,开发语言)