Vue.js的IoC容器模式探索

IoC概念阐述

  • IoC(Inversion of Control),意为控制反转,不是什么技术,而是一种设计思想。==Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制==。
  • 借用《spring 揭秘》的一张图对IOC的概念阐述
  • 下面我们将尝试在Vue.js中实现IoC容器模式,他的基本构造如下图

代码实现

- service-container容器

<!--service-container.js-->
const RepositoryInterface = {
  find () {},
  list () {}
}

function bind (repositoryFactory, Interface) {
  return {
    ...Object.keys(Interface).reduce((prev, method) => {
      const resolveableMethod = async (...args) => {
        const repository = await repositoryFactory()
        return repository.default[method](...args)
      }
      return { ...prev, [method]: resolveableMethod }
    }, {})
  }
}

export default {
  get productRepository () {
    // Delay loading until a method of the repository is called.
    return bind(() => import('@/views/ioc/product'), RepositoryInterface)
  },
  get userRepository () {
    // Load the repository immediately when it's injected.
    const userRepositoryPromise = import('@/views/ioc/user')
    return bind(() => userRepositoryPromise, RepositoryInterface)
  }
}

复制代码
  • 如上代码所示,有一个bind()辅助函数,该函数接受一个接口(这是一个普通的对象,其中包含我们真实存储库的每个方法的伪方法)以及要动态解析的存储库的生成方法,以及它返回一个包含原始存储库的所有方法的对象。
  • 实现了按需加载服务,不会一次加载所有的服务,想象一下,我只使用A服务,结果将A服务以外的其他服务都加载了,这是不合理的。

UserListing接口模拟

// Usually a third party API.
const api = Promise.resolve([
  {
    id: 1,
    name: 'Antonia'
  },
  {
    id: 2,
    name: 'Anton'
  }
])

export default {
  async find (id) {
    const result = await api
    return result.find(x => x.id === id)
  },
  async list () {
    return api
  }
}

复制代码

product 接口模拟

// Usually a third party API.
const api = Promise.resolve([
  {
    id: 1,
    title: 'Some stuff'
  },
  {
    id: 2,
    title: 'Some other stuff'
  }
])

export default {
  async find (id) {
    const result = await api
    return result.find(x => x.id === id)
  },
  async list () {
    return api
  }
}

复制代码

UserListing组件

<template>
  <ul>
    <li v-for="user in users" :key="user.id">{{ user.name }}</li>
  </ul>
</template>

<script>
  export default {
    name: 'UserListing',
    inject: ['userRepository'],
    data () {
      return { users: [] }
    },
    async created () {
      this.users = await this.userRepository.list()
    }
  }
</script>

复制代码

ProductListing组件

<template>
  <ul>
    <li v-for="product in products" :key="product.id">{{ product.title }}</li>
  </ul>
</template>

<script>
  export default {
    name: 'ProductListing',
    inject: ['productRepository'],
    data () {
      return { products: [] }
    },
    async created () {
      this.products = await this.productRepository.list()
    }
  }
</script>

复制代码

IOC 测试页面

<template>
  <div id="app">
    <h2>Products</h2>
    <ProductListing/>

    <h2>Users</h2>
    <UserListing/>
  </div>
</template>

<script>
  import ProductListing from './ProductListing'
  import UserListing from './UserListing'

  export default {
    components: {
      ProductListing,
      UserListing
    }
  }
</script>

复制代码

总结

  • 通常来讲,IoC容器模式在JavaScript这样的语言中实际上没那么有用。为什么?因为你不需要它来获得许多其他语言如Java、PHP所带来的好处。例如。我们可以使用高阶函数的概念通过参数将依赖关系传递给函数(或通过Vue.js组件中的props)。
  • 使用JavaScript和Vue.js构建可伸缩应用程序可能也不需要IoC,但它仍然是一种有趣的模式,探索它的实现也是有现实意义(前端后端化条件下),可以更好的理解其含义,把握好使用的场景。

参考链接

转载于:https://juejin.im/post/5d034012f265da1bab29aa91

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值