<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>组件化 on prometheus</title><link>https://new.halfrost.com/zh/tags/%E7%BB%84%E4%BB%B6%E5%8C%96/</link><description>Recent content in 组件化 on prometheus</description><generator>Hugo -- gohugo.io</generator><language>zh-CN</language><copyright>halfrost</copyright><lastBuildDate>Sat, 08 Jul 2017 09:51:00 +0000</lastBuildDate><atom:link href="https://new.halfrost.com/zh/tags/%E7%BB%84%E4%BB%B6%E5%8C%96/index.xml" rel="self" type="application/rss+xml"/><item><title>大话大前端时代(一) —— Vue 与 iOS 的组件化</title><link>https://new.halfrost.com/zh/vue_ios_modularization/</link><pubDate>Sat, 08 Jul 2017 09:51:00 +0000</pubDate><guid>https://new.halfrost.com/zh/vue_ios_modularization/</guid><description>序 今年大前端的概念一而再再而三的被提及，那么大前端时代究竟是什么呢？大前端这个词最早是因为在阿里内部有很多前端开发人员既写前端又写 Java 的 Velocity 模板而得来，不过现在大前端的范围已经越来越大了，包含前端 + 移动端，前端、CDN、Nginx、Node、Hybrid、Weex、React Native、Native App。笔者是一名普通的全职 iOS 开发者，在接触到了前端开发以后，发现了前端有些值得移动端学习的地方，于是便有了这个大前端时代系列的文章，希望两者能相互借鉴优秀的思想。谈及到大前端，常常被提及的话题有：组件化，路由与解耦，工程化（打包工具，脚手架，包管理工具），MVC 和 MVVM 架构，埋点和性能监控。笔者就先从组件化方面谈起。网上关于前端框架对比的文章也非常多（对比 React，Vue，Angular），不过跨端对比的文章好像不多？笔者就打算以前端和移动端（以 iOS 平台为主）对比为主，看看这两端的不同做法，并讨论讨论有无相互借鉴学习的地方。
本文前端的部分也许前端大神看了会觉得比较基础，如有错误还请各位大神不吝赐教。
Vue 篇 一. 组件化的需求 为了提高代码复用性，减少重复性的开发，我们就把相关的代码按照 template、style、script 拆分，封装成一个个的组件。组件可以扩展 HTML 元素，封装可重用的 HTML 代码，我们可以将组件看作自定义的 HTML 元素。在 Vue 里面，每个封装好的组件可以看成一个个的 ViewModel。
二. 如何封装组件 谈到如何封装的问题，就要先说说怎么去组织组件的问题。
如果在简单的 SPA 项目中，可以直接用 Vue.component 去定义一个全局组件，项目一旦复杂以后，就会出现弊端了：
全局定义(Global definitions) 强制要求每个 component 中的命名不得重复 字符串模板(String templates) 缺乏语法高亮，在 HTML 有多行的时候，需要用到丑陋的 \ 不支持 CSS(No CSS support) 意味着当 HTML 和 JavaScript 组件化时，CSS 明显被遗漏 没有构建步骤(No build step) 限制只能使用 HTML 和 ES5 JavaScript, 而不能使用预处理器，如 Pug (formerly Jade) 和 Babel 而且现在公司级的项目，大多数都会引入工程化的管理，用包管理工具去管理，npm 或者 yarn。所以 Vue 在复杂的项目中用 Vue.</description></item><item><title>BeeHive —— 一个优雅但还在完善中的解耦框架</title><link>https://new.halfrost.com/zh/beehive/</link><pubDate>Sat, 04 Mar 2017 10:44:00 +0000</pubDate><guid>https://new.halfrost.com/zh/beehive/</guid><description>前言 BeeHive是阿里巴巴公司开源的一个iOS框架，这个框架是App模块化编程的框架一种实现方案，吸收了Spring框架Service的理念来实现模块间的API解耦。
BeeHive这个名字灵感来源于蜂窝。蜂窝是世界上高度模块化的工程结构，六边形的设计能带来无限扩张的可能。所以就用了这个名字作为开源项目的名字。
在前一篇文章iOS 组件化 —— 路由设计思路分析中，我们分析了App组件之间可以通过路由来解除耦合。那么这篇文章就来看看利用模块化的思想如何解除耦合的。
(看到这里一定会很多人有疑问，那就看看这篇文章组件和模块的区别)
说明：本文是基于BeeHive v1.2.0版本进行解析的。
目录 1.BeeHive概述 2.BeeHive模块注册 3.BeeHive模块事件 4.BeeHive模块调用 5.其他的一些辅助类 6.可能还在完善中的功能 一. BeeHive概述 由于BeeHive是基于Spring的Service理念，虽然可以使模块间的具体实现与接口解耦，但无法避免模块对接口类的依赖关系。
暂时BeeHive没有采用invoke和performSelector:action withObject: params的方法。主要原因还是考虑学习成本难度以及动态调用实现无法在编译检查阶段检测接口参数变更等问题。
目前BeeHive v1.2.0 全部是利用Protocol的方式，实现了模块间解耦的目的：
1.各个模块以插件的形式存在。每个都可独立，相互解耦。 2.各个模块具体实现与接口调用分离 3.各个模块也有生命周期，也可以进行管理。
官方也给出了一个架构图：
接下来就依次分析模块注册，模块事件，模块调用是如何实现解耦的。
二. BeeHive模块注册 先从模块的注册开始分析，来看看BeeHive是如何给各个模块进行注册的。
在BeeHive中是通过BHModuleManager来管理各个模块的。BHModuleManager中只会管理已经被注册过的模块。
注册Module的方式总共有三种：
1. Annotation方式注册 通过BeeHiveMod宏进行Annotation标记。
BeeHiveMod(ShopModule) BeeHiveMod宏定义如下：
#define BeeHiveMod(name) \ char * k##name##_mod BeeHiveDATA(BeehiveMods) = &amp;#34;&amp;#34;#name&amp;#34;&amp;#34;; BeeHiveDATA又是一个宏：
#define BeeHiveDATA(sectname) __attribute((used, section(&amp;#34;__DATA,&amp;#34;#sectname&amp;#34; &amp;#34;))) 最终BeeHiveMod宏会在预编译结束会完全展开成下面的样子：
char * kShopModule_mod __attribute((used, section(&amp;#34;__DATA,&amp;#34;&amp;#34;BeehiveMods&amp;#34;&amp;#34; &amp;#34;))) = &amp;#34;&amp;#34;&amp;#34;ShopModule&amp;#34;&amp;#34;&amp;#34;; 注意双引号的总对数。</description></item><item><title>iOS 组件化 —— 路由设计思路分析</title><link>https://new.halfrost.com/zh/ios_router/</link><pubDate>Sat, 25 Feb 2017 03:39:00 +0000</pubDate><guid>https://new.halfrost.com/zh/ios_router/</guid><description>前言 随着用户的需求越来越多，对App的用户体验也变的要求越来越高。为了更好的应对各种需求，开发人员从软件工程的角度，将App架构由原来简单的MVC变成MVVM，VIPER等复杂架构。更换适合业务的架构，是为了后期能更好的维护项目。
但是用户依旧不满意，继续对开发人员提出了更多更高的要求，不仅需要高质量的用户体验，还要求快速迭代，最好一天出一个新功能，而且用户还要求不更新就能体验到新功能。为了满足用户需求，于是开发人员就用H5，ReactNative，Weex等技术对已有的项目进行改造。项目架构也变得更加的复杂，纵向的会进行分层，网络层，UI层，数据持久层。每一层横向的也会根据业务进行组件化。尽管这样做了以后会让开发更加有效率，更加好维护，但是如何解耦各层，解耦各个界面和各个组件，降低各个组件之间的耦合度，如何能让整个系统不管多么复杂的情况下都能保持“高内聚，低耦合”的特点？这一系列的问题都摆在开发人员面前，亟待解决。今天就来谈谈解决这个问题的一些思路。
目录 1.引子 2.App路由能解决哪些问题 3.App之间跳转实现 4.App内组件间路由设计 5.各个方案优缺点 6.最好的方案 一. 引子 大前端发展这么多年了，相信也一定会遇到相似的问题。近两年SPA发展极其迅猛，React 和 Vue一直处于风口浪尖，那我们就看看他们是如何处理好这一问题的。
在SPA单页面应用，路由起到了很关键的作用。路由的作用主要是保证视图和 URL 的同步。在前端的眼里看来，视图是被看成是资源的一种表现。当用户在页面中进行操作时，应用会在若干个交互状态中切换，路由则可以记录下某些重要的状态，比如用户查看一个网站，用户是否登录、在访问网站的哪一个页面。而这些变化同样会被记录在浏览器的历史中，用户可以通过浏览器的前进、后退按钮切换状态。总的来说，用户可以通过手动输入或者与页面进行交互来改变 URL，然后通过同步或者异步的方式向服务端发送请求获取资源，成功后重新绘制 UI，原理如下图所示：
react-router通过传入的location到最终渲染新的UI，流程如下：
location的来源有2种，一种是浏览器的回退和前进，另外一种是直接点了一个链接。新的 location 对象后，路由内部的 matchRoutes 方法会匹配出 Route 组件树中与当前 location 对象匹配的一个子集，并且得到了 nextState，在this.setState(nextState) 时就可以实现重新渲染 Router 组件。
大前端的做法大概是这样的，我们可以把这些思想借鉴到iOS这边来。上图中的Back / Forward 在iOS这边很多情况下都可以被UINavgation所管理。所以iOS的Router主要处理绿色的那一块。
二. App路由能解决哪些问题 既然前端能在SPA上解决URL和UI的同步问题，那这种思想可以在App上解决哪些问题呢？
思考如下的问题，平时我们开发中是如何优雅的解决的：
1.3D-Touch功能或者点击推送消息，要求外部跳转到App内部一个很深层次的一个界面。
比如微信的3D-Touch可以直接跳转到“我的二维码”。“我的二维码”界面在我的里面的第三级界面。或者再极端一点，产品需求给了更加变态的需求，要求跳转到App内部第十层的界面，怎么处理？
2.自家的一系列App之间如何相互跳转？
如果自己App有几个，相互之间还想相互跳转，怎么处理？
3.如何解除App组件之间和App页面之间的耦合性？
随着项目越来越复杂，各个组件，各个页面之间的跳转逻辑关联性越来越多，如何能优雅的解除各个组件和页面之间的耦合性？
4.如何能统一iOS和Android两端的页面跳转逻辑？甚至如何能统一三端的请求资源的方式？
项目里面某些模块会混合ReactNative，Weex，H5界面，这些界面还会调用Native的界面，以及Native的组件。那么，如何能统一Web端和Native端请求资源的方式？
5.如果使用了动态下发配置文件来配置App的跳转逻辑，那么如果做到iOS和Android两边只要共用一套配置文件？
6.如果App出现bug了，如何不用JSPatch，就能做到简单的热修复功能？
比如App上线突然遇到了紧急bug，能否把页面动态降级成H5，ReactNative，Weex？或者是直接换成一个本地的错误界面？
7.如何在每个组件间调用和页面跳转时都进行埋点统计？每个跳转的地方都手写代码埋点？利用Runtime AOP ？
8.如何在每个组件间调用的过程中，加入调用的逻辑检查，令牌机制，配合灰度进行风控逻辑？
9.如何在App任何界面都可以调用同一个界面或者同一个组件？只能在AppDelegate里面注册单例来实现？
比如App出现问题了，用户可能在任何界面，如何随时随地的让用户强制登出？或者强制都跳转到同一个本地的error界面？或者跳转到相应的H5，ReactNative，Weex界面？如何让用户在任何界面，随时随地的弹出一个View ？
以上这些问题其实都可以通过在App端设计一个路由来解决。那么我们怎么设计一个路由呢？
三. App之间跳转实现 在谈App内部的路由之前，先来谈谈在iOS系统间，不同App之间是怎么实现跳转的。
1. URL Scheme方式 iOS系统是默认支持URL Scheme的，具体见官方文档。</description></item></channel></rss>