前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Thinking--IOC思想在前端中的应用

Thinking--IOC思想在前端中的应用

作者头像
奋飛
发布2019-08-14 18:01:31
6400
发布2019-08-14 18:01:31
举报
文章被收录于专栏:Super 前端

Thinking系列,旨在利用10分钟的时间传达一种可落地的编程思想。

IOC

系统中,经常会出现 A 模块,依赖 B 模块,同时也依赖 C 模块的情况。我们通常的处理方式是将 B、C 模块直接引入到 A 模块中,这个获取过程都在 A 模块中实现,随着业务的扩充,A 模块可能还需要 D、E、F… 等等模块,这将导致代码高度耦合并且难以维护和调试。且未来想要删除某模块,需要删除模块的代码,同时需要删除在 A 模块中的引用。

代码语言:javascript
复制
/* A.js */
import B from 'B'
import C from 'C'
import ...

IOC(Inversion Of Control):控制反转 组件之间的依赖关系由容器在应用系统运行期来决定,也就是由容器动态地将某种依赖关系的目标对象实例注入到应用系统中的各个关联的组件之中。

  • 高层次的模块不应该依赖于低层次的模块,应该依赖于抽象;
  • 抽象不应该依赖于具体实现,具体实现应该依赖于抽象。

其背后的核心思想:针对接口编程,不针对实现编程!接口驱动,使得其可以供不同灵活的子类实现

实现

IOC 有两种实现方式:依赖查找和依赖注入。

依赖查找(Dependency Lookup):容器提供接口和上下文条件给组件,组件需要实现接口,该接口提供了一个对象,可以重用这个对象查找依赖。

依赖注入(Dependency Injection):内置对象是通过注入的方式进行创建。依赖注入有两种实现方式:Setter方式(传值方式)和构造器方式(引用方式)。

现实问题陈述

页面刷新,刷新按钮隶属于 Header 模块,页面 A 中点击刷新按钮。 常规思路:需要再 Header 中依赖 A 页面,然后调用 A 模块的刷新方法。这里 Header 模块属于高层模块 ,A 页面属于低层模块

代码语言:javascript
复制
/* Header */
import A from './A'
import B from './B'

现在如果需要在 B 页面增加刷新,则 Header 同时也要依赖 B 模块。整个流程会非常复杂,随着业务扩大,整体模块耦合度也会很大。

解决方案

将 Header 模块修改为依赖接口,页面 A 和 页面 B 各自实现接口。大大降低了 Header 模块的修改几率。

Header 模块

代码语言:javascript
复制
<template>
	...
    <li class="refresh" @click="refreshTag">
        <idss-icon-svg name="circle-refresh-outline"></idss-icon-svg>刷新
    </li>
	...
</template>	

<script>
    export default {
        ...
        methods: {
            refreshTag () {
                let initFn = this.getComponents().init
      			initFn && (typeof initFn) === 'function' && initFn()
            },
            getComponents () {
                // 这里this.$route 相当于了传统IOC中的容器角色
     			let matchedArray = this.$route.matched
      			return matchedArray[matchedArray.length - 1].instances.default.$parent.$refs['router-view']
    		}
        }
    }
</script>

这里我们抽象了接口 init 方法,每个模块各自实现 init() 即可。

A 模块

代码语言:javascript
复制
export default {
    name: 'A',
    methods: {
        init () {
            // A模块的刷新逻辑
        }
    }
}
IOC
IOC

典型IOC的实现(伪代码)

代码语言:javascript
复制
// Header
import contianer
contianer.getInstance('name').refresh()

// contianer
let contianer = []
function register (name, vm) {}
function getInstance() ()

// A
import contianer
register('A', vm)

// B
import contianer
register('A', vm)

优势:模块之间靠接口规则约束,完全解耦。增加模块只需按要求注册和提供相关 refresh 方法即可;未来想删除 B 模块,同样只需将 B 模块代码删除即可,Header和Container模块无需做任何修改!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019年06月02日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • IOC
    • 实现
      • 现实问题陈述
        • 解决方案
          • 典型IOC的实现(伪代码)
          相关产品与服务
          容器服务
          腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档