• 2015-12-10

    关于移动端应用开发的一些想法

    Views: 12911 | 1 Comment

    根据移动端开发的短短历史来看, 很多移动端开发者在内部比较缺少分工. 相对比, 对于某些上规模的系统, 即使后端工程师这样的一个细分领域的角色, 也会进行分工上的再细分, 例如一般会分成基础服务开发工程师, 业务逻辑开发工程师.

    随着移动端应用的复杂度不断增长, 移动端开发工程师这个角色还需要再进行更细的分工. 我们可以参考一些游戏开发行业的分工方式. 我根据自己的理解, 做一下分工.

    对于移动端工程师岗位的划分, 我觉得可以分为: 1, 界面工程师; 2, 逻辑工程师.

    下面, 根据工作职责和内容划分, 然后结合岗位划分来介绍.

    职责1: 界面实现

    界面实现这项工作属于界面工程师的职责. 具体来说, 此项工作包括:

    1. 使用代码来编写静态的界面UI, 这部分是UI设计图的直接实现, 除去自定义控件部分.
    2. 编写自定义控件, 如动画效果控件. 自定义控件可以是通用的, 和业务无关的, 也可以是业务相关的.

    职责2: 界面交互

    界面实现这项工作也属于界面工程师的职责. 此项工作内容为:

    1. 处理界面交互, 如动画效果, 页面内 Tab 切换, 控件的出现和隐藏等.
    2. 处理页面之间的跳转.
    3. 在界面交互和页面跳转的过程中, 向数据逻辑模块请求数据.
    4. 在数据逻辑模块返回数据后, 对界面进行改变, 如组装数据, 启用动效等.

    职责3: 数据逻辑

    数据逻辑模块是业务逻辑在终端的一种体现, 属于逻辑工程师的工作职责. 逻辑工程师根据业务特点, 从服务器请求数据和将数据保存到服务器(网络交互), 或者从本地请求数据和将数据保存到本地(客户端缓存).

    数据逻辑模块一方面和服务端接口进行交互, 另一方面处理用户手机的数据存取(本地存储, 可统称为客户端缓存).

    关于内嵌 WebView 控件的代码逻辑

    内嵌 WebView 这种技术方案有一些特殊, 因为它既由网页本身实现了界面, 又实现了数据逻辑中的网络交互部分. 如果采用内嵌 WebView 控件的方案, 那么界面程序员的工作就变成:

    1. 处理网页跳转与原生(宿主)页面之间的跳转关系
    2. 向网页暴露数据逻辑接口

    关于页面跳转的实现, 有两种方式:

    1. 原生向网页暴露 js 接口, 由网页自主控制页面间的跳转
    2. 原生拦截 WebView 的 URL, 改变页面跳转流程

    Posted by ideawu at 2015-12-10 17:07:31
  • 2015-10-11

    低级程序员和高级程序员的区别

    Views: 15438 | 3 Comments

    低级程序员认为自己与高级程序员的区别, 主要是高级程序员任何功能都能编码实现, 编码速度快, 代码无 bug. 正如一惯的那样, 低级程序员之所以低级, 正是因为他们勉强能看到(或者根本看不到)事物的表象而看不到本质. 所以, 低级程序员总结出的一切东西, 你都可以大胆地忽略.

    所以, 我们来听听高级程序认为自己与低级程序员的区别是什么. 高级程序员之所以高级, 在于他们认识到代码 bug 是不可避免的, 有千万种理由可以导致 bug, 但他们可以在设计和逻辑上保证(追求)滴水不漏, 并用逻辑的百分之百准确性来减少代码 bug. 没错, 严谨的逻辑能力是高级程序员区别于低级程序员的最主要原因.

    可以举一个简单常见例子: 网络购票终端的开发. 当然, 比低级程序员还低级的程序员做不出来. 我们先看看低级程序员是怎么做:
    Continue reading »

    Posted by ideawu at 2015-10-11 13:03:02
  • 2015-03-25

    流式布局的原理和代码实现

    Views: 26101 | 2 Comments

    最简单的流式布局模型, 其实就是: 靠左, 靠右, 或者堆叠. 根据这个简单的理论, 可以用两个栈(Stack)数据结构, 一个表示靠左边的控件列表, 另一个表示靠右边的控件列表, 即可实现流式布局模型.

    用伪代码表示如下:

    // 视图控件
    class View{
        private FlowLayouter layouter;
        
        // 当控件发生 frame 改变后, 调用此方法标记为需要重新布局
        void setNeedsLayout(){
            View view = this;
            while(view){
                view.markNeedsLayout();
                // 当控件需要重新布局时, 一般地, 它的父节点也需要重新布局
                view = view.parent;
            }
        }
        
        void layout(){
            for(View child in this.children){
                this.layouter.place(child);
            }
        }
    }
    
    // 流式布局管理器
    class FlowLayouter{
        private Stack leftViews;
        private Stack rightViews;
        
        void place(View child){
            Position pos;
            child.layout(); // 子节点先进行布局
            while(!this.spaceFits(child)){
                if(child.floatLeft){
                    View view = this.leftViews.pop();
                    pos = view.pos;
                    // 当被移除的节点比其它节点更高时, 继续移除
                    while(pos.y > this.leftViews.last.y){
                        View view = this.leftViews.pop();
                        pos = view.pos;
                    }
                }
                if(child.floatRight){
                    View view = this.rightViews.pop();
                    pos = view.pos;
                    // 当被移除的节点比其它节点更高时, 继续移除
                    while(pos.y > this.rightViews.last.y){
                        View view = this.rightViews.pop();
                        pos = view.pos;
                    }
                }
            }
            
            // place child here
            child.pos = pos;
            
            if(child.floatLeft){
                this.leftViews.push(child.pos);
            }
            if(child.floatRight){
                this.rightViews.push(child.pos);
            }
        }
    }
    

    这段代码最重要的是两点:

    1. 当某个控件发生改变时, 它需要重新布局. 同时, 它的父节点, 以及父节点的父节点, 一直到节点树的根节点, 都需要重新布局. 当然, 这是性能最差的方案, 优化的思路就是减少需要重新布局的节点的数量, 这需要发动每个人的聪明才智来想.

    2. 用两个 Stack 来分别表示靠左的和靠右节点列表. 如果当前的空白空间不足以放下一个控件, 那么, 尝试从节点列表中移除一个节点, 这样, 这个布局区域就空出来了一些空间. 当然, 这个空间应该往下移, 不能和被移除的节点所占据的空间重叠. 因为流式布局的基本原理就是不重叠(除非通过特殊设定, 如负数的偏移量).

    有了这个简单的流式布局模型, 你可以在所有最基本的绝对定位的 GUI 库上面实现功能强大的流式布局, 例如, iOS 的 UIKit 不支持流式布局, 你可以根据上面的代码扩展, 给 iOS 界面开发加上流式布局功能.

    流式布局其实是非常有趣的一项功能, 它的模型很简洁, 但功能强大且应用广泛. GUI 界面的本质是树, 树是简洁而优美的, 而流式布局使用的数据结构是 Stack, 又是一种非常基础的数据结构.

    说句题外话, 我已经实现了 iOS 系统上面的 UI 流式布局 - CocoaUI, 你可以试用下.

    Posted by ideawu at 2015-03-25 14:33:48 Tags: ,
  • 2014-10-25

    谈谈普通程序员的技术问题

    Views: 12756 | 2 Comments

    我见过不少优秀的程序员, 也见过很多普通的程序员. 那么程序员怎么叫普通, 怎么叫优秀呢? 我认为一个程序员是优秀的还是普通的, 关键要看其思路和逻辑.

    普通的程序员常常具有跟些不好的品质呢? 或者说改掉了哪些不好的品质, 就能成为优秀的程序员呢? 下面我说说看.

    1. 技术浮于表面

    普通的程序员大多是没有看透技术本质的程序员, 看待技术只浮于表面, 特别对某些具有一丁点特性的新东西特别惊奇, 例如有些普通程序员对于 Python 的缩进方式特别"惊奇", 仅仅因为此便产生了过度的心理应激反应, 而不是去关注编程语言的本质.

    另一方面, 对某些技术又特别绝望, 感觉学不懂, 害怕, 不知道技术是相通的.
    Continue reading »

    Posted by ideawu at 2014-10-25 18:03:53
  • 2014-09-23

    国内云主机省钱秘籍

    Views: 33004 | 2 Comments

    我之前对比过亚马逊AWS, Linode, 阿里云等云服务(云主机), 发现美国的 Linode 其实是最合算的, 国内的云主机的价格一般能达到 Linode 的 10 倍! 这其实是非常恐怖的!

    不过, Linode 虽好, 但毕竟是美国的东西, 跨越大洋的阻隔, 物理距离决定了网络延时, 所以国内用户使用 Linode 用户体验不太好. 而且还有可能有其它的致命阻隔. 所以, 有时不得不使用国内的云主机.

    Continue reading »

    Posted by ideawu at 2014-09-23 10:14:45 Tags: , , , ,
  • 2014-08-10

    如何更好地提问技术问题?

    Views: 10882 | 2 Comments

    简单的技术问题, 通过搜索引擎即可得出答案, 不要问人.

    对于开放性的问题, 一定要提供详细的信息, 一定要有自己的见解和分析, 否则不要问. 这里给出提问的模板:

    对于某某东西, 我认为它应该这样, 理由是xxx, 但我却发现它那样, 为什么呢? 我的理解错了? 还是我观察错了?

    千万不要只问一句"某某东西为什么那样?" 这种没有信息的问题.

    Posted by ideawu at 2014-08-10 21:04:00
|<<<123456789>>>| 5/15 Pages, 86 Results.