js 常用设计模式

资料:https://www.runoob.com/design-pattern/observer-pattern.html

单例模式

在执行当前 Single 只获得唯一一个对象
单例模式,是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中,应用该模式的一个类只有一个实例。即一个类只有一个对象实例。

意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
主要解决:一个全局使用的类频繁地创建与销毁。
何时使用:当您想控制实例数目,节省系统资源的时候。
如何解决:判断系统是否已经有这个单例,如果有则返回,如果没有则创建。

  1. var Single = (function(){
  2. var instance;
  3. function init() {
  4. // 定义私有方法和属性
  5. // 操作逻辑
  6. return {
  7. // 定义公共方法和属性
  8. };
  9. }
  10. return {
  11. // 获取实例
  12. getInstance:function(){
  13. if(!instance){
  14. instance = init();
  15. }
  16. return instance;
  17. }
  18. }
  19. })();
  20. var obj1 = Single.getInstance();
  21. var obj2 = Single.getInstance();
  22. console.log(obj1 === obj2);

例子:

比如我现在页面上需要创建一个div的元素,那么我们肯定需要有一个创建 div的函数,而现在我只需要这个函数只负责创建div元素,其他的它不想管,也就是想实现单一职责原则,就好比淘宝的kissy 一样,一开始的时候他们定义kissy只做一件事,并且把这件事做好,具体的单体模式中的实例化类的事情交给代理函数去处理,这样做的好处是具体的业务逻辑分开了,代理只管代理的业务逻辑,在这里代理的作用是实例化对象,并且只实例化一次; 创建div代码只管创建div,其他的不管;如下代码:

代码回收规则如下:

  1.全局变量不会被回收。

  2.局部变量会被回收,也就是函数一旦运行完以后,函数内部的东西都会被销毁。

  3.只要被另外一个作用域所引用就不会被回收

工厂模式

工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。因为工厂模式就相当于创建实例对象的new,我们经常要根据类Class生成实例对象,如A a=new A() 工厂模式也是用来创建实例对象的,所以以后new时就要多个心眼,是否可以考虑使用工厂模式,虽然这样做,可能多做一些工作,但会给你系统带来更大的可扩展性和尽量少的修改量。

意图:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。
主要解决:主要解决接口选择的问题。
何时使用:我们明确地计划不同条件下创建不同实例时。
如何解决:让其子类实现工厂接口,返回的也是一个抽象的产品。

小结:js 工厂模式里面,所有的函数都只是Object的实例,这样的判断没有多大的意义; 而在构造函数里面,构造出来的函数不仅是Object的实例,也是构造函数的实例,而构造函数是我们自己定义的,相当于我们自己定义了一个新的对象类型,可以识别的新的对象类型

  1. function Animal(opts){
  2. var obj = new Object();
  3. obj.name = opts.name;
  4. obj.color = opts.color;
  5. obj.getInfo = function(){
  6. return '名称:'+obj.name +', 颜色:'+ obj.color;
  7. }
  8. return obj;
  9. }
  10. var cat = Animal({name: '波斯猫', color: '白色'});
  11. cat.getInfo();

构造函数模式

 ECMAScript中的构造函数可用来创建特定类型的对象,像Array和Object这样的原生构造函数,在运行时会自动出现在执行环境中。此外,也可以创建自定义的构造函数,从而定义自定义对象的属性和方法。使用构造函数的方法,既解决了重复实例化的问题,又解决了对象识别的问题。

1.没有显式地创建对象;
2.直接将属性和方法赋给了 this 对象;
3.没有 return 语句。

  1. function Animal(name, color){
  2. this.name = name;
  3. this.color = color;
  4. this.getName = function(){
  5. return this.name;
  6. }
  7. }
  8. // 实例一个对象
  9. var cat = new Animal('猫', '白色');
  10. console.log( cat.getName() );

订阅/发布模式(subscribe & publish)

  订阅发布模式又称为观察者模式,定义了一种一对多的关系,让多个观察者同时监听某一个主题对象,这个主题对象的状态发生改变时就会通知所有的观察者对象。

意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
主要解决:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。
何时使用:一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。
如何解决:使用面向对象技术,可以将这种依赖关系弱化。

  发布者发出通知 =>主题对象收到通知并推送给订阅者 => 订阅者执行相应的操作。


思路: 发布者负责发布消息、 订阅者负责接收接收消息,而最重要的是主题对象,他需要记录所有的订阅这特消息的人,然后负责吧发布的消息通知给哪些订阅了消息的人。
所以,当set方法触发后做的第二件事情就是作为发布者发出通知: “我是属性text,我变了”。 文本节点作为订阅者,在接收到消息之后执行相应的更新动作。

二》 VUE组件继承和 VUE的mixins(混入)

与vuex的区别

vuex:用来做状态管理的,里面定义的变量在每个组件中均可以使用和修改,在任一组件中修改此变量的值之后,其他组件中此变量的值也会随之修改。

Mixins:可以定义共用的变量,在每个组件中使用,引入组件中之后,各个变量是相互独立的,值的修改在组件中不会相互影响。

与公共组件的区别

组件:在父组件中引入组件,相当于在父组件中给出一片独立的空间供子组件使用,然后根据props来传值,但本质上两者是相对独立的。

Mixins:则是在引入组件之后与组件中的对象和方法进行合并,相当于扩展了父组件的对象与方法,可以理解为形成了一个新的组件。

1.VUE组件继承

  1. <script>
  2. import baseTabel from '@/views/table.vue'; // vue的普通组件
  3. export default {
  4. extends: baseTabel, // 继承该组件
  5. data () {
  6. return {
  7. text: 222 // 如果没有key就添加,有相同的key就覆盖
  8. }
  9. },
  10. methods: {
  11. okFn(a) { // 如果没有方法名就添加,有相同方法名就重构
  12. // 操作逻辑,重构
  13. // 比如,table组件多处使用,原组件 有个确定按钮 okFn方法 跳转到 /a 路由。
  14. this.$router.push({name:'/b',params:{id:this.text}});
  15. }
  16. }
  17. </script>

继承的子组件通过this.$parent可以更改父组件的data,不推荐直接修改父组件的内容
使用extend的好处是,使用一个拥有多个配置项的组件,通过继承,将不常用到的参数设置默认

2.VUE的mixins(混入)

http://www.cnblogs.com/Ivy-s/p/9937173.html

文档更新时间: 2019-05-17 15:24