立诚勿怠,格物致知
It's all about connecting the dots

Monkey patch

最难看公司代码和redux官方文时了解到monkey patch这个名词的。monkey是猴子的意思,patch是补丁的意思,monkey patch的意思就是你先去抓一只猴子,然后给他们线和针,教他们打补丁,等他们学会了之后就可以自己给自己打补丁了——开个玩笑。Wikipedia上对monkey patch的定义是:

A monkey patch is a way for a program to extend or modify supporting system software locally (affecting only the running instance of the program).

大家在写react native的时候应该会写过类似下面的代码:

import { Stylesheet } from 'react-native'

const styles = StyleSheet.create({
  swiperSlideDot: {
    borderRadius: 3
  }
})

这段代码其实没啥好看的-_-。不过有时候,你可能会根据当前平台是iOS还是android来写一些不一样的样式,然后你可能会写出类似下面这样的代码:

import { StyleSheet, Platform } from 'react-native'

const styles = StyleSheet.create({
  swiperSlideDot: {
    borderRadius: Platform.OS === 'ios' ? 3 : 4
  }
})

但是有些场景下你可能会要这么写(请注意,这是一段错误的代码):

// 请注意,这是一段错误的代码
import { StyleSheet } from 'react-native'

const styles = StyleSheet.create({
  swiperSlideDot: {
    ios: {
      borderRadius: 3,
    },
    android: {
      borderRadius: 4
    }
  }
})

上面这段代码直接跑是会出问题的,因为Stylesheet.create方法的入参对象里面只能包含一层对象,是不允许嵌套第二层对象的。这个时候,我们就可以使用Monkey patch技术了。

1、先编写一个Stylesheet.js文件:

// Stylesheet.js
import { StyleSheet, Platform } from 'react-native'

function create (styles) {
  function styleFor (name) {
    const { ios, android, ...style } = { ...styles[name] }
    if (ios && Platform.OS === 'ios') {
      return { ...style, ...ios }
    } else if (android && Platform.OS === 'android') {
      return { ...style, ...android }
    }
    return style
  }
  const result = Object.keys(styles).map(key => ({ [key]: styleFor(key) }))
    .reduce((loop, next) => ({
      ...loop,
      ...next,
    }), {})
  return StyleSheet.create(result)
}

export default {
  ...StyleSheet,
  create,
}

2、然后就可以上之前那样写代码了:

// 注意,这里不是import { StyleSheet } from 'react-native'
import { StyleSheet } from './StyleSheet'

const styles = StyleSheet.create({
  swiperSlideDot: {
    ios: {
      borderRadius: 3,
    },
    android: {
      borderRadius: 4
    }
  }
})

你看,其实我们并没有修改React Native提供的Stylesheet.create方法,我们只是另外又暴露了一个Stylesheet.create方法,用起来就跟用React Native的Stylesheet方法一样,只是略微增加了一些定制功能。

redux的middleware中间件的实现原理也是monkey patch,具体就不在赘述了,官网上已经写得很明白了(每应用一个中间件,就相当于原先的store.dispatch方法(指的是上一个中间件修改后的store.dispatch方法,只有在未应用任何中间件的情况下才是redux提供的store.dispatch方法)的基础上暴露了新的store.dispatch方法):http://redux.js.org/docs/advanced/Middleware.html。

参考:
  • http://redux.js.org/docs/advanced/Middleware.html
赞(0) 打赏
文章名称:《Monkey patch》
文章链接:https://www.orzzone.com/monkeypatching.html
商业联系:yakima.public@gmail.com

本站大部分文章为原创或编译而来,对于本站版权文章,未经许可不得用于商业目的,非商业性转载请以链接形式标注原文出处。
本站内容仅供个人学习交流,不做为任何投资、建议的参考依据,因此产生的问题需自行承担。

评论 抢沙发

觉得文章有用就打赏一下文章作者

非常感谢你的打赏,我们将继续给力提供更多优质内容!

支付宝扫一扫打赏

微信扫一扫打赏

登录

找回密码

注册