ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

前端 IoC 理念

2020-06-07 11:56:57  阅读:241  来源: 互联网

标签:理念 App showMsg options 模块 new IoC 前端 otherA


背景

在前端项目中,随着项目越来越复杂,模块块之间的高耦合性导致项目越来越难以复用

简介

IoC 的全称叫做 Inversion of Control,可翻译为为「控制反转」或「依赖倒置」,它主要包含了三个准则

  • 高层次的模块不应该依赖于低层次的模块,它们都应该依赖于抽象
  • 抽象不应该依赖于具体实现,具体实现应该依赖于抽象
  • 面向接口编程 而不要面向实现编程
 class App {
            constructor(options) {
                this.options = options;
                this.otherA = new OtherA();
                this.otherB = new OtherB();
                this.init();
            }

            init() {
                window.addEventListener('DOMContentLoaded', () => {
                    this.otherA.showMsg('otherA');
                    this.otherB.showMsg('otherB');
                });
            }
        }
        class OtherA {
            showMsg(msg) {
                console.log(msg)
            }
        }
        class OtherB {
            showMsg(msg) {
                console.log(msg)
            }
        }
        new App({
            onReady() {
                // do something here...
            },
        });

从上面代码可以看出,如果在需求多变的情况下,如果子模块 OtherA 有变动需要传参数, App 这个高层次的模块也要改变,对于之前测试通过了的 App 来说,也必须重新测试,造成了高层次的模块依赖于低层次的模块,代码出现了耦合

依赖注入

依赖注入,也就把高层模块所依赖的模块通过传参的方式把依赖「注入」到模块内部,实现松耦合,代码改造一下:

    class App {
            constructor(options) {
                this.options = options;
                this.otherA = options.otherA;
                this.otherB = options.OtherB;
                this.init();
            }

            init() {
                window.addEventListener('DOMContentLoaded', () => {
                    this.otherA.showMsg('otherA');
                    this.otherB.showMsg('otherB');
                });
            }
        }
        class OtherA {
            showMsg(msg) {
                console.log(msg)
            }
        }
        class OtherB {
            showMsg(msg) {
                console.log(msg)
            }
        }
        new App({
            otherA: new OtherA(),
            otherB: new OtherB(),
            onReady() {
                // do something here...
            },
        });

但是这样改造还是会有一些问题,如果再增加一个模块otherC的情况下,还是需要修改高层次的模块 App,需要进一步抽象 App 模块,代码改动如下:

            constructor(options) {
                this.options = options;
                this.otherA = options.otherA;
                this.otherB = options.OtherB;
                this.onReady = options.onReady;
                this.init();
            }
            static modules = []
            init() {
                window.addEventListener('DOMContentLoaded', () => {
                    this.registerModules();
                    this.onReady();
                });
            }
            static use(module) {
                Array.isArray(module) ? module.map(item => App.use(item)) : App.modules.push(module);
            }
            registerModules() {
                App.modules.map(module => module.showMsg && typeof module.showMsg == 'function' && module.showMsg(
                    this));
            }
        }
        class OtherA {
            showMsg(app) {
                console.log('OtherA')
            }
        }
        class OtherB {
            showMsg(app) {
                console.log('OtherB')
            }
        }
        class OtherC {
            showMsg(app) {
                console.log('OtherC')
            }
        }
        App.use([new OtherA(), new OtherB(), new OtherC()]);
        new App({
            onReady() {
                // do something here...
            },
        });

从上面代码可以看出, App.use 把所有的模块都存在 App 中的 static modules = [] 中, 在 App 模块加载之后,通过 registerModules 函数取出 modules 中的模块,依次执行各个低层次的子模块,依次调用他们的方法执行

概括

App 模块此时应该称之为「容器」比较合适了,跟业务已经没有任何关系了,它仅仅只是提供了一些方法来辅助管理注入的依赖和控制模块如何执行

App 作为一个核心模块,负责控制各个子模块,不实现具体业务,面向抽象编程

标签:理念,App,showMsg,options,模块,new,IoC,前端,otherA
来源: https://www.cnblogs.com/fuGuy/p/13060020.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有