• 2016-05-10

    一个 GUI 系统的组成部分

    Views: 15952 | No Comments

    在做 iOS 上的 XML+CSS UI 布局框架 CocoaUI 的过程中, 我体会到了 Apple 技术的强大之处, Apple 的底层框架和库提供了强大的功能和友好的 API, 我在开发 GUI 框架(上层 UI 框架)时用到的许多技术功能点都是信手拈来.

    现在总结, 有不少想法, 记下来分享一下.

    首先, iOS 系统为什么那么"好"? 不仅开发者觉得好, 最终用户用起来也觉得棒! 对比看 Android 的软件界面, 毛毛糙糙, 生硬, 总是缺了很多神韵. 这当然有屏幕硬件的功能, 但软件技术的作用更多, 因为从公开的资料上看, 不少 Android 厂商使用了和苹果同类的硬件.

    Continue reading »

    Posted by ideawu at 2016-05-10 16:31:03
  • 2015-12-10

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

    Views: 7958 | 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: 10835 | 3 Comments

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

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

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

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

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

    Views: 14550 | 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: 9085 | 2 Comments

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

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

    1. 技术浮于表面

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

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

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

    国内云主机省钱秘籍

    Views: 19718 | 2 Comments

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

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

    Continue reading »

    Posted by ideawu at 2014-09-23 10:14:45 Tags: , , , ,
|<<<123456789>>>| 3/13 Pages, 75 Results.