Open ufologist opened 8 years ago
技术
@Monine 同学纯手工打造的 Vue Blog, 和学前班一样也是借用 github issues 做为博客系统 Angular 2.0 Final Release Now Live! 2.0.0 (2016-09-14) 图解7种耦合关系 高内聚与低耦合 内聚是从功能角度来度量模块内的联系,一个好的内聚模块应当恰好做一件事。它描述的是模块内的功能联系。 耦合是软件结构中各模块之间相互连接的一种度量,耦合强弱取决于模块间接口的复杂程度、进入或访问一个模块的点以及通过接口的数据。 要实现的功能。m1和m2是两个独立的模块,其中m2种会显示m1的输入,m1会显示m2的输入。很显然,m1和m2两个模块之间会有一些联系(耦合) 根据耦合程度可以分为7种,耦合度依次变低。 内容耦合: 最紧的耦合程度,一个模块直接访问另一模块的内容 公共耦合: 一组模块都访问同一个全局数据结构 外部耦合: 一组模块都访问同一全局简单变量,而且不通过参数表传递该全局变量的信息。外部耦合和公共耦合很像,区别就是一个是简单变量,一个是复杂数据结构。 控制耦合: 模块之间传递的不是数据信息,而是控制信息例如标志、开关量等,一个模块控制了另一个模块的功能. 从控制耦合开始,模块的数据就放在自己内部了,不同模块之间通过接口互相调用 标记耦合: 调用模块和被调用模块之间传递数据结构而不是简单数据 数据耦合: 调用模块和被调用模块之间只传递简单的数据项参数。相当于高级语言中的值传递 非直接耦合: 两个模块之间没有直接关系,它们之间的联系完全是通过主模块的控制和调用来实现的。耦合度最弱,模块独立性最强。子模块无需知道对方的存在,子模块之间的联系,全部变成子模块和主模块之间的联系。 内聚也分很多种 偶然内聚 逻辑内聚 时间内聚 通信内聚 顺序内聚 功能内聚 为什么我不喜欢「前后端分离」 在 v2ex 引起了热烈的讨论 前后端分离大概的意思就是后端只给前端提供数据,前端负责 HTML 渲染(可以在服务器渲染,也可以在浏览器渲染)和用户交互。 为什么做前后端分离? 如果不分离,前端对网站的控制力太弱,没有话语权。 前端想要扩大势力范围。扩大了势力范围才有晋升的机会。 当时前端能控制的,就是 CSS 和 JS 文件。连 HTML 都是放在后端的仓库的。因为 HTML 是由服务器输出的,用到的模板语言就是后端的。 我认同的是「全栈工程师」 Web 开发不应该这么复杂 回顾下从 2004 年开始, Web 开发经历了怎样的过程。 我们对服务器渲染 HTML 的性能不是很满意,同时浏览器的性能进一步提高了,所以我们觉得可以把渲染放到浏览器上来做。 浏览器从服务器得到一个空的页面,然后用 JS 启动这个页面。 JS 发起很多 API 请求。服务器接收 JSON ,输出 JSON 。所有的 HTML 渲染,由浏览器完成。 但是呢,有两个问题: 所以这些 JS 代码和 API 请求,让首页渲染,非常非常非常慢。 所有内容,都无法被搜索引擎检索到。 所以我们决定不用浏览器来渲染首屏了,让服务器来(回到老路子)。但是由于渲染逻辑我们不想做两遍,所以我们需要在服务器添加一个 JS runtime 来执行 JS 才行,这样浏览器端的渲染逻辑在服务器上也能跑起来了。 康威定律说,软件产品的结构就是其创造团队的组织结构的镜像。 不依赖 Gulp、Babel、WebPack,还能优雅地写代码吗? 前端打包 框架的兴起 MVC 框架(如 Backbone.js) -> MVVM 框架(AngularJS), 此时的库都是不需要额外用 Grunt 做转译的。直到 React 的出现。需要把 JSX 翻译成 JS。此时 Grunt 大概也因为性能太低被 Gulp 取代了。 ECMAScript 的发展 前端开始追新,一定要第一时间用上最新版的 JS 语法。但是即便是 Chrome 和 Firefox 也不可能那么快就支持最新语法。于是前端说,不过就是在 Gulp 里再加一道转译嘛,用 Babel 把 ES 2016 的语法转译成 ES 5 就好了。 DOM 不好用,换成虚拟 DOM CSS 不好用,换成 CSS in JS 浏览器支持的 JS 不好用,换成 ES 最新版语法,然后转译为浏览器支持的 JS DOM Event 不用了,去新造一个 Event 机制。 Gulp 用得太多了 watch 很慢,于是加上了 hot module replacement 实际上这些变化非常适合复杂的 Web 应用,然而 90% 的页面根本不是单页面应用好吗! 能不能让我写一个 CSS 一个 JS 刷新一下就能看到效果!为什么我要花那么多时间来学习转译工具,以及解决转译过程中的各种问题。 总感觉『弊大于利』。甚至有的时候觉得这是『没有问题,创造问题也要上』。 Hybrid APP架构设计思路 Native(以Android为例)和H5通讯,基本原理: Android调用H5:通过webview类的loadUrl方法可以直接执行js代码,类似浏览器地址栏输入一段js一样的效果 webview.loadUrl("javascript: alert('hello world')"); H5调用Android:webview可以拦截H5发起的任意url请求,webview通过约定的规则对拦截到的url进行处理(消费),即可实现H5调用Android var ifm = document.createElement('iframe'); ifm.src = 'jsbridge://namespace.method?[...args]'; JSBridge即我们通常说的桥协议 由于JavaScript语言自身的特殊性(单进程),为了不阻塞主进程并且保证H5调用的有序性,与Native通讯时对于需要获取结果的接口(GET类),采用类似于JSONP的设计理念: 类比HTTP的request和response对象,调用方会将调用的api、参数、以及请求签名(由调用方生成)带上传给被调用方,被调用方处理完之后会吧结果以及请求签名回传调用方,调用方再根据请求签名找到本次请求对应的回调函数并执行,至此完成了一次通讯闭环。 界面与交互(Native与H5职责划分)哪些由Native负责哪些由H5负责? 这个回到原始的问题上来:我们为什么要采用hybrid模式开发?简而言之就是同时利用H5的跨平台、快速迭代能力以及Native的流畅性、系统API调用能力。 总的原则是H5提供内容,Native提供容器 关键界面、安全性要求比较高的界面、交互性强的的界面、UI变更的频率也不高的界面使用Native 导航组件采用Native 导航组件,就是页面的头组件,左上角一般都是一个back键,中间一般都是界面的标题,右边的话有时是一个隐藏的悬浮菜单触发按钮有时则什么也没有。 再者,也是最重要的一点,如果整个界面都是H5的,在H5加载过程中界面将是白屏,在弱网络下用户可能会很疑惑。 所以基于这两点,打开的界面都是Native的导航组件+webview来组成,这样即使H5加载失败或者太慢用户可以选择直接关闭。 系统级UI组件采用Native 默认界面采用Native 设计H5容器 H5离线访问: 顾名思义就是将H5预先放到用户手机,这样访问时就不会再走网络从而做到看起来和Native APP一样的快了。 H5离线动态更新机制: 将H5资源放置到本地离线访问,最大的挑战就是本地资源的动态更新如何设计 Local Url Router 对于H5的请求,线上和离线采用相同的url访问,这就需要H5容器对H5的资源请求进行拦截“映射”到本地,即Local Url Router 哪个蠢蛋写的烂代码? 你既可能是那个吐槽别人给你留下了麻烦,也可能是别人嘴里那个制造麻烦的人。 最难的不是自己写代码,而是维护别人写的代码,在复杂的逻辑中找到某一个隐藏得很深的bug,或者在某个(些)位置添加一些代码以实现新的功能。你需要按照最初实现者的思路去理解,这往往是最难的,这个过程中非常让人容易产生挫败感和不良情绪。 设计太复杂 性能不好 各种无法理解的逻辑 其实有时候我们不理解的,不是人家用的差,而是我们的格调低。我开始收起我的傲慢,不会一上来就指责别人,对不甚了解的领域保持敬畏,以免看起来像个小丑。 好的代码是什么样子的呢? Bjarne Stroustrup(C++之父)说: 逻辑应该是清晰的,bug难以隐藏。 依赖最少,易于维护。 错误处理完全根据一个明确的策略。 性能接近最佳,避免代码混乱和无原则的优化。 整洁的代码只做一件事。 Michael Feathers(《修改代码的艺术》作者)说: 整洁的代码看起来总是像很在乎代码质量的人写的。 没有明显的需要改善的地方。 代码的作者似乎考虑到了所有的事情。 可以感受到,对好的代码的理解有很多共通的地方: 代码简单,代码意图明确,其他人才容易与你协作。 可读性和可维护性要高。 以最合适的方式解决问题。 程序员有三种 拿钱干活,不爽就换 - 程序员只是一份工作。 只要能实现功能就好,学习进步太累了。 热爱程序本身的人, 这些人可能只有1%, 他们有目标的写程序, 他们愿意思考, 愿意听取正确地/更好的方法, 他们会热爱学习新的东西。优秀的工程师在思考、重构 明年的今天「其他」工程师还写一样的代码, 唯一不一样的是Ta老了一岁。 进阶的经验 多看书,多读其他人的博客,阅读优秀的开源项目的代码甚至语言本身的源代码. 看代码要思考别人为什么这样写 想好了再开始写 给自己提要求。实现过程中不断的提高要求,这个要求就是比你现有的能力要高一点点 选择更强的队友。遇见什么样的人,就会变成什么样子的人 对别人吐槽狠 可能有一天, 看到一段代码,骂了句「哪个蠢蛋写的烂代码?」 结果git blame一看原来是自己写的。恭喜你,你进阶了! 一家初创公司的 CTO 应当做什么 像是技术问题,但是当你深入分析问题的本质时,你会发现它们实际上是人的问题 主要工作是确保公司的技术策略服务于它的商业策略 将它分解为五个特定的技能 平台选择与技术方案设计 把控全局(包括一些关键细节) CTO 是整个项目中能够了解整套技术方案能做什么不能做什么的人。这意味着了解什么可行,什么不可行,当前架构能支持什么,做不到什么,以及构建一个新功能在先有架构下要多长时间 提供选择 从不说 “这是不可能的” 或 “我们永远别这样做”。相反找到可选方案并且能够就这些方案与其他人沟通 80/20原则 找到一个获得 80% 好处而只要消耗 20% 成本的折衷方案 培养技术 leader
@Monine 同学纯手工打造的 Vue Blog, 和学前班一样也是借用 github issues 做为博客系统
2.0.0 (2016-09-14)
高内聚与低耦合
内聚是从功能角度来度量模块内的联系,一个好的内聚模块应当恰好做一件事。它描述的是模块内的功能联系。
耦合是软件结构中各模块之间相互连接的一种度量,耦合强弱取决于模块间接口的复杂程度、进入或访问一个模块的点以及通过接口的数据。
要实现的功能。m1和m2是两个独立的模块,其中m2种会显示m1的输入,m1会显示m2的输入。很显然,m1和m2两个模块之间会有一些联系(耦合)
根据耦合程度可以分为7种,耦合度依次变低。
内聚也分很多种
在 v2ex 引起了热烈的讨论
前后端分离大概的意思就是后端只给前端提供数据,前端负责 HTML 渲染(可以在服务器渲染,也可以在浏览器渲染)和用户交互。
为什么做前后端分离?
我认同的是「全栈工程师」
回顾下从 2004 年开始, Web 开发经历了怎样的过程。
我们对服务器渲染 HTML 的性能不是很满意,同时浏览器的性能进一步提高了,所以我们觉得可以把渲染放到浏览器上来做。
浏览器从服务器得到一个空的页面,然后用 JS 启动这个页面。 JS 发起很多 API 请求。服务器接收 JSON ,输出 JSON 。所有的 HTML 渲染,由浏览器完成。
但是呢,有两个问题:
所以我们决定不用浏览器来渲染首屏了,让服务器来(回到老路子)。但是由于渲染逻辑我们不想做两遍,所以我们需要在服务器添加一个 JS runtime 来执行 JS 才行,这样浏览器端的渲染逻辑在服务器上也能跑起来了。
康威定律说,软件产品的结构就是其创造团队的组织结构的镜像。
不依赖 Gulp、Babel、WebPack,还能优雅地写代码吗?
前端打包
框架的兴起
MVC 框架(如 Backbone.js) -> MVVM 框架(AngularJS), 此时的库都是不需要额外用 Grunt 做转译的。直到 React 的出现。需要把 JSX 翻译成 JS。此时 Grunt 大概也因为性能太低被 Gulp 取代了。
ECMAScript 的发展
前端开始追新,一定要第一时间用上最新版的 JS 语法。但是即便是 Chrome 和 Firefox 也不可能那么快就支持最新语法。于是前端说,不过就是在 Gulp 里再加一道转译嘛,用 Babel 把 ES 2016 的语法转译成 ES 5 就好了。
DOM 不好用,换成虚拟 DOM
CSS 不好用,换成 CSS in JS
浏览器支持的 JS 不好用,换成 ES 最新版语法,然后转译为浏览器支持的 JS
DOM Event 不用了,去新造一个 Event 机制。
Gulp 用得太多了 watch 很慢,于是加上了 hot module replacement
实际上这些变化非常适合复杂的 Web 应用,然而 90% 的页面根本不是单页面应用好吗!
能不能让我写一个 CSS 一个 JS 刷新一下就能看到效果!为什么我要花那么多时间来学习转译工具,以及解决转译过程中的各种问题。
总感觉『弊大于利』。甚至有的时候觉得这是『没有问题,创造问题也要上』。
Native(以Android为例)和H5通讯,基本原理:
Android调用H5:通过webview类的loadUrl方法可以直接执行js代码,类似浏览器地址栏输入一段js一样的效果
webview.loadUrl("javascript: alert('hello world')");
H5调用Android:webview可以拦截H5发起的任意url请求,webview通过约定的规则对拦截到的url进行处理(消费),即可实现H5调用Android
var ifm = document.createElement('iframe'); ifm.src = 'jsbridge://namespace.method?[...args]';
JSBridge即我们通常说的桥协议
由于JavaScript语言自身的特殊性(单进程),为了不阻塞主进程并且保证H5调用的有序性,与Native通讯时对于需要获取结果的接口(GET类),采用类似于JSONP的设计理念:
类比HTTP的request和response对象,调用方会将调用的api、参数、以及请求签名(由调用方生成)带上传给被调用方,被调用方处理完之后会吧结果以及请求签名回传调用方,调用方再根据请求签名找到本次请求对应的回调函数并执行,至此完成了一次通讯闭环。
界面与交互(Native与H5职责划分)哪些由Native负责哪些由H5负责?
这个回到原始的问题上来:我们为什么要采用hybrid模式开发?简而言之就是同时利用H5的跨平台、快速迭代能力以及Native的流畅性、系统API调用能力。
导航组件采用Native
导航组件,就是页面的头组件,左上角一般都是一个back键,中间一般都是界面的标题,右边的话有时是一个隐藏的悬浮菜单触发按钮有时则什么也没有。
再者,也是最重要的一点,如果整个界面都是H5的,在H5加载过程中界面将是白屏,在弱网络下用户可能会很疑惑。
所以基于这两点,打开的界面都是Native的导航组件+webview来组成,这样即使H5加载失败或者太慢用户可以选择直接关闭。
设计H5容器
Local Url Router
对于H5的请求,线上和离线采用相同的url访问,这就需要H5容器对H5的资源请求进行拦截“映射”到本地,即Local Url Router
你既可能是那个吐槽别人给你留下了麻烦,也可能是别人嘴里那个制造麻烦的人。
最难的不是自己写代码,而是维护别人写的代码,在复杂的逻辑中找到某一个隐藏得很深的bug,或者在某个(些)位置添加一些代码以实现新的功能。你需要按照最初实现者的思路去理解,这往往是最难的,这个过程中非常让人容易产生挫败感和不良情绪。
其实有时候我们不理解的,不是人家用的差,而是我们的格调低。我开始收起我的傲慢,不会一上来就指责别人,对不甚了解的领域保持敬畏,以免看起来像个小丑。
好的代码是什么样子的呢?
Bjarne Stroustrup(C++之父)说:
Michael Feathers(《修改代码的艺术》作者)说:
可以感受到,对好的代码的理解有很多共通的地方:
程序员有三种
明年的今天「其他」工程师还写一样的代码, 唯一不一样的是Ta老了一岁。
进阶的经验
可能有一天, 看到一段代码,骂了句「哪个蠢蛋写的烂代码?」 结果git blame一看原来是自己写的。恭喜你,你进阶了!
像是技术问题,但是当你深入分析问题的本质时,你会发现它们实际上是人的问题
主要工作是确保公司的技术策略服务于它的商业策略
将它分解为五个特定的技能
把控全局(包括一些关键细节)
CTO 是整个项目中能够了解整套技术方案能做什么不能做什么的人。这意味着了解什么可行,什么不可行,当前架构能支持什么,做不到什么,以及构建一个新功能在先有架构下要多长时间
提供选择
从不说 “这是不可能的” 或 “我们永远别这样做”。相反找到可选方案并且能够就这些方案与其他人沟通
80/20原则
找到一个获得 80% 好处而只要消耗 20% 成本的折衷方案
产品
班会第 10 期分享过一张尺寸的图, 这里的内容更方便查看 UI设计师导航网 UI设计师常用网站收集
班会第 10 期分享过一张尺寸的图, 这里的内容更方便查看
UI设计师常用网站收集
技术
产品