React Native: 三层架构模型

React Native解决了H5的性能问题,Weex本质上也是React Native,发展非常迅速,目前有替代原生开发的趋势。本人原本是iOS Native开发的坚定支持者,原本打算从Objective-C过渡到Swift,就像在Windows平台跟着微软走一样省心省力。无奈形式比人强,省钱省人工对企业由足够的吸引力,养家糊口是现实需求,情怀不能当饭吃,所以作为前端,还是要跟上时代步伐,多学一门技术。
iOS Native开发中,View Controller不容易复用,代码又集中,所以很多聪明人想出了MVVM等架构模型来给View Controller减负。在React Native中,发现这种优势天然存在,比如有一个this.state,天然有界面观察者的作用,只要调用this.setState,就能更新界面,这个相当于View Model的作用了。在iOS Native开发中,需要自定义一个View Model结构体,并用上属性观察者这种特性,Swift才有,才能达到类似效果。
ES6之后,JavaScript引入了class关键字,面向对象的编程方法用起来就方便多了。同时,还有Promiseasync/await,函数式编程的想法也很流行。由于本人iOS Native的编程时间更长,所以很自然地想把MVVM这种想法带过来,形成一个三层架构模型。

简介

简单讲,就是将原来React Native中一个registerComponent,相当于View Controller,能做完的事情,分为功能,逻辑,页面三层。将原来一个js文件能搞定的事情分散到3~4个不同的js文件中。

三层文件夹.png
  • userInterface 用户界面层,这部分按照React Native来划分子模块。这里模块划分的标准是一张的的页面,复用的思路是组件。

  • businessObject业务对象层。这是业务逻辑层,按照面向对象的方法划分子模块,是一个个具体的业务概念,比如信息采集,贷款申请,个人信息管理等。

  • functionModule函数模块层。这是基础函数功能模块,按照函数式编程的思想划分子模块,是一个个具体的功能函数,比如网络取数据,缓存操作等等。

用户界面层

用户对象层.png
  • page:这个代表一个个的页面,一般都是一个registerComponent处理过的,是最顶层的发起者。

  • component:这是可复用的组件。这是React Native的核心思想,框架本身也已经提供了足够丰富的组件供使用。当然这里主要的是对基础组件进行自定义组合,方便page:中的页面调用。

  • image:这是静态资源,比如图片等

  • constant:这是常数集中定义的地方,比如界面共用的颜色,字体,尺寸,文字等等

这一层的主要工作就是集中精力把界面渲染出来,具体的功能和业务尽量都分出去。比如,设置页面标题,虽然很简单,也通过调用下面的逻辑层来实现,不需要自己做。

业务对象层

业务对象层.png
  • service:这是公共服务对象,一般以单例的方式提供。比如页面跳转,主要是url的定义,可以集中写在这里。比如本地缓存,最主要的是key值的定义,可以集中写在一个文件中。比如远程网络访问,主要是一些url和参数的定义,可以集中写在一起。

  • personal, enterprise:这个按照具体的业务划分。比如,这里是企业业务和个人业务来划分文件夹的。

  • Business:这个名字可以固定,当然也可以用其他名字。他的作用是承接页面分出来的工作。打个比方,页面page就像总裁,只要发号施令就可以了,比如响应保存按钮,处理文字录入等等;Business:就像是页面这个总裁的助理,将所有业务都接过来,找人完成。

  • ViewModel:这个是用来替代this.state的,主要保存页面需要展示的信息。需要更新的话,页面调用一下this.setState({});就可以了。相对于this.state,这个已经够好了,他的好处是可以把字段定义从页面中分离出来,并且可以用类的方式,将字段定义的更清晰,还可以提供处理函数,做一些页面逻辑工作。比如,把姓和名拼接成一个字段等。接上面的比方,ViewModel:就相当于Business:这个助理,根据page总裁的指令,给出的具体工作成果。

  • Model:这个一般对应于网络返回数据。JavaScript的网络传输返回的就是对象,字段还可以随时添加,非常灵活。不过没有名字,用起来跟dictionary也差不多,key基本靠猜。Model:可以用类来定义,让大家有一个共同的地方来看字段定义。当然,类可以有成员函数,提供一定的数据处理能力。

  • Business:是按照业务逻辑来分的,跟页面的划分标准都不一样,所以Businesspage之间并没有一一对应的要求。比如,这里的Business:就为三个页面服务,搜索、信息输入、地址选择三个page共用。如果做成单例的话,还可以用成员变量保存状态,省去了页面之间传递数据的麻烦。

  • ViewModel:一般是跟具体的page一一对应的,因为这个本身定位就是相关page显示需求。当然,对于一些比较复杂的page,可能需要多个ViewModel:来共同服务。

  • Model:一般跟具体的网络请求或者缓存对象对应,由Business:来复杂持有和管理。对于page来说是不可见的。page这个总裁只关心需要显示的ViewModel这种看得见的工作成果,至于实际上到底是谁做的,具体怎么做的,只要助理Business清楚就可以了,他作为老总,没有必要知道。

函数模块层

函数功能层.png
  • 这一层是按照函数式的编程思想来做的。对外提供的是一个个能够工作的函数。比如对话框,照相,网络访问,事件,路由等等。
async function actionSheet(title = '标题',
                           buttons = ['第一个按钮', '第二个按钮', '第三个按钮'],
                           cancelButtonText = '取消',
                           destructiveBtnIndex = -1) {
    return new Promise((resolve, reject) => {
        AlipayJSBridge.call('actionSheet',{
            'title': title,
            'btns': buttons,
            'cancelBtn': cancelButtonText,
            'destructiveBtnIndex': destructiveBtnIndex,    // 变红按钮的index
        }, data => {
            const index = data.index;
            const cancelIndex = buttons.length;
            if (index < cancelIndex) {
                return resolve(index);
            } else {
                return reject('选择了取消按钮');
            }
        });
    });
}

export {
    actionSheet,
};

比如这个是iOS开发中常见的action sheet,一般是Native实现,然后提供调用接口。这个是等待用户选择,然后根据选择结果进行相应处理。Native是以回调函数callback来实现异步过程的,在这里用了JavaScript的Promise包装,就可以在后续调用中使用async/await这种最新科技了。

  • 为了方便使用,将输出接口在一个汇总文件中集中一下是个值得推荐的做法。比如:
export {
    showLoading,
    hideLoading,
} from './Loading';

export {
    toast,
} from './Toast';

export {
    alertNative,
    confirm,
} from './Modal';

export {
    actionSheet,
} from './Select';
  • 这一层是具体功能提供者,不涉及具体业务,完成功能后的中间产物怎么组合,那是上面业务层的事,这里只要做好自己的本质工作就好了。接上面的比方,这里就相当开发、测试、运维、平面... ...等等具体干活的。

不足之处

这套架构模型的优点是分工明确,将界面、业务、功能分开来,对于比较成熟的产品是比较好的。并且把现在流行的面向对象编程和面向函数编程都包括进去了。

不过对于初创产品,或者比较简单的产品来说,体现不出优势,反而带来负担。最直白的来说,就是太烦了。
本来要改一点东西,只要找一个js文件,就是那个page总裁页面,就可以了。现在弄得又要找business助理,还要修改function具体干活的,做完了还要转成View Model这种指定的格式... ....
链路这么长,想想都头大,可能我只是修改一个后台返回字段而已啊,要改这么多地方... ...

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容