我在做 iOS 开发的时候,发现自己在写程序的时候,常常处于两种状态的切换,我把这两种状态称为软件开发的上帝模式与农民模式。我先给大家介绍一下这两种模式的特点。

上帝模式

处于上帝模式时,我需要构思整个应用的架构设计,如何进行类之间的组织和信息的传递。我有可能会在纸上画一些类图,把关键的几个类之间关系构思清楚。这就类似于建筑师画设计图纸一样。

在这个阶段,我的大脑是努力工作的,我会利用我学到的《设计模式》、《重构》、《代码大全》中的架构知识,先把类的关系组织好。然后我会深入到每一类的实现细节,构思好每个类大概怎么实现,这个过程又会利用了如何命名、DRY 原则、单一职责原则等编程知识。

而这一切的行为,都是在纸上完成的,我甚至会关掉电脑屏幕,因为电脑屏幕前有很多影响注意力的信息(例如 QQ、微信、邮件等)。

农民模式

当一切构思基本完成,我就会打开 Xcode,开始我的农民模式工作。

在农民模式,我会专心于将我刚刚构思好的内容变成一行行真实的代码。由于已经想得比较清楚,这个过程通常更多是一种体力活,或者好听一点,是一个手艺人的体力活。对于农民模式的我来说,我需要知道 iOS 开发的各种基本知识,以及一些常见的提升效率的工作方式,以便我能够更快地完成编码工作。

在农民模式中,我会注意集中精力,因为虽然实现代码是偏体力活的事情,但是思路如果断掉,接上的话还是会花费不少时间。有一些同事会喜欢戴上耳机,以避免干扰,也是这个道理。

一个例子

举一个具体的例子,下图是小猿搜题的发现页面,它明显是用一个 Group Style 的 UITableView 来实现的,每个 Cell 的样式也非常简单:左边有一张 UIImageView,接着是一个 UILabel,然后是靠右侧的 UILabel(可能内容为空)以及最右侧的一张右剪头的 UIImageView。

由于这个发现页面可以由服务器来定制,所以我在上帝模式的时候,先构思好我需要实现:

一个 View Controller 类(DiscoveryViewController),用于展示整个界面

一个 TableViewCell 类(DiscoveryTableViewCell),用于描述一个条目

一个 ViewModel 类(DiscoveryConfig),用于描述发现页的内容

一个网络请求类(GetDiscoveryApi),用于获得服务器的定制信息

在持久化层(StorageAgent)增加两个方法,用于获取上次缓存的定制内容(getDiscoveryConfig)以及保存最新的定制内容 (saveDiscoveryConfig)

一个负责更新的类(ConfigUpdateAgent),用于处理更新的时机选择(checkUpdate)

我还会把每个类大概的成员变量和成员方法名想好。构思完成之后,我脱下上帝的黄袍(别问我上帝为什么要穿黄袍,我也不知道),换上农民干活的麻布衣服,开始搬代码了。我先把这些类都建好,方法名命名好。接着我开始填一个一个的方法名的实现。

每一个类的实现过程都可以看作一个阶段性的成果,这个时候我会稍微休息一下,然后继续搬砖。

最终,我完成了所有代码,然后开始运行。咦,为什么运行效果不对?我赶紧打起精神,开始调试起代码来。这个时候,我一会儿切换成上帝模式,审视自己的架构是否有漏洞。一会儿切换成农民模式,看自己是不是不小心敲错了一些代码细节。

最终,代码被全部编写完成并且运行正常了。

一些技巧

上帝模式的技巧

上帝模式中,切忌不应该过于着急动手,把一切的细节都想清楚,看看有没有特殊情况没有考虑到。如果一开始设计得不好,那么真正实现到最后才发现,那么农民模式下写的代码就白白浪费了。

上帝模式的工作是可以脱离电脑来实施的,这意味着我们可以拉上同事,找个白板讨论。我们也可以在上下班的路上思考。

经过讨论的上帝模式的产出会更加靠谱,在我们公司,我们会在 Scrum 的计划会议的后半程,用出牌的方式估计每一个工作的 Story Point,而具体的估计方式,就是以上帝模式将整个工作细化,使得我们大家能够明确出农民模式下的编码工作量到底是多少。

软件开发能力的提高,上帝模式会比农民模式更难,在上帝模式下工作得出色的同学,会进一步成为架构师,成为更复杂架构的设计规划者。

在软件开发书籍中,涉及上帝模式的图书也有很多,例如《设计模式》和《重构》,但是好的架构都是无法脱离实际业务的,所以大多数程序员都无法通过简单地看书就提高自己的上帝模式的能力,更多的提高方式是工作一段时间,有一些实际体会之后再看书,就能够理解书中的道理。

农民模式的技巧

农民模式中,效率是第一要素。所以,保证自己的专注力是非常重要的。在这方面,「番茄工作法」是一个不错的实践方式。

农民模式中,应该尽量采用「宽度优先搜索」的方式来完成任务,而不是「深度优先搜索」的方式。在上面的例子中,我先将各种类的类名和方法名填好,然后再完善细节就是一种「宽度优先搜索」的方式。这种方式下,我们不需要额外的「栈空间」来保存工作的上下文。

为了更容易理解,我来举一个「深度优先搜索」的工作方式,在上面的例子中,我先写界面的 Controller 类,写到一半发现需要 TableViewCell,于是就去写 TableViewCell。TableViewCell 写到一半发现需要先实现 ViewModel,然后就跑去实现 ViewModel,ViewModel 实现完发现需要缓存起来,于是就跑去写缓存逻辑。这种工作方式下,我就需要分别记住:Controller 的进度和 TableViewCell 的进度,以便我之后继续完善它们。这种方式其实就相当于一次「打断」,因为我把 Controller 的编写硬生生拆成了两次,这样就使得我需要更多时间回记上次的思路。

农民模式中,我们应该尽量提升自己的代码输入效率。比如将常用的代码片段保存在 Xcode 的 Snippets 中或者 Dash 中,在组织内规范好统一的命名约定和规则,熟悉 iOS 的各种调试技巧,都可以使自己更快把上帝模式下的蓝图转换成实际代码。

相对于上帝模式,大部分同学都会轻视农民模式下的效率。比如写一会儿代码聊一会儿 QQ。比如由于自己事先积累不够,很多基本的 iOS 开发知识还需要查资料和文档。农民模式下的效率低下,使得一个人看起来工作了很久,却没有什么产出。

在 iOS 领域,我个人的经验表明,我在一整天的农民模式中,最高可以产出 1000 行左右的代码。2012 年猿题库创业初期时,我在 4 个月的紧张工作中,平均每天的代码产出约为 500 行。

一些问题

提升上帝模式能力

很多 iOS 开发新手对于提升自己上帝模式的能力感觉到无从下手,建议这部分同学可以多分析一些优秀的开源软件的架构,同时阅读一些相关的书籍。另外,每一次恶心的重构都是一次难得的经验,说明之前的架构设计不够优雅,结合自身的业务特点,多思考多讨论,慢慢地就会培养出自己对于架构的一些心得了。

提升农民模式效率

很多 iOS 开发新手对于农民模式不够重视。一个程序员大部分时间都应该是处于农民模式的,农民模式决定了我们产出的效率,而很多人只重视工作时间,不重视工作效率,使得自己的产出非常低下。

提升自己的农民模式能力,建议使用「番茄工作法」并且做一些时间记录,平时多学习一些最新的 iOS 开发知识,以便减少自己的知识盲区。专注于自己的精力是否集中,如果觉得太累,就活动一下或者适当休息,不应该强迫自己 Coding。

警惕混搭模式

混搭模式,类似于练功人士的「走火入魔」,专指那些在上帝模式没有想清楚,就马上切入农民模式写代码,写到一半代码又切到上帝模式思考。边写边想的混搭模式使得自己想的时候不够清晰,写的时候又不够专注,两边都不讨好。通常刚刚入行的人都处于这种混搭的模式,不但写出来的代码容易有逻辑错误,而且速度很慢。

结语

上帝模式与农民模式这个叫法是我自己发明出来的,你喜欢这个世界观设定吗?

我们在程序的世界里,一会儿是高高在上的上帝,一会儿又是埋头干苦活的农民,想想也挺奇妙的。

愿大家在这个世界中玩得开心!

如果你感兴趣,这儿还有我的另一个世界观设定:《打开你的脑洞》

转自:http://blog.devtang.com/2016/07/20/programming-worlds-farmer-and-god/

IOS开发设计思路的更多相关文章

  1. 100个iOS开发/设计面试题汇总

    常见问题 你昨天/这周学习了什么? 你为什么热衷于软件开发? 你对哪一种控制系统比较熟悉? 是否参与过GitHub项目? 是否参与过GitHub或其他同类型网站的iOS开源项目? 请描述一下你的iOS ...

  2. iOS 开发设计常用软件及工具整理

    1, xCode 2, AppCode 3, Skech 原型设计软件 4, Hype 动画设计工具 5, fontawsome 免费图表 6, Prepo icon, images.catlog 生 ...

  3. 100个iOS开发/设计面试题汇总,你将如何作答?

    原文: http://www.csdn.net/article/2015-01-19/2823604-ios-interview-questions 常见问题 你昨天/这周学习了什么? 你为什么热衷于 ...

  4. Activiti 工作流会签开发设计思路

    http://man1900.iteye.com/blog/1607753 在流程业务管理中,任务是通常都是由一个人去处理的,而多个人同时处理一个任务,这种任务我们称之为会签任务.这种业务需求也很常见 ...

  5. iOS开发设计多个target

    创建target有两种方式, 1>.是通过新建target可以通过File-->New-->Target,然后选择其中一个模板来创建,app类型的target进行创建 2>.另 ...

  6. iOS开发:代码通用性以及其规范 第二篇(猜想iOS中实现TableView内部设计思路(附代码),以类似的思想实现一个通用的进度条)

    在iOS开发中,经常是要用到UITableView的,我曾经思考过这样一个问题,为什么任何种类的model放到TableView和所需的cell里面,都可以正常显示?而我自己写的很多view却只是能放 ...

  7. iOS 组件化 —— 路由设计思路分析

    原文 前言 随着用户的需求越来越多,对App的用户体验也变的要求越来越高.为了更好的应对各种需求,开发人员从软件工程的角度,将App架构由原来简单的MVC变成MVVM,VIPER等复杂架构.更换适合业 ...

  8. iOS开发之浅谈MVVM的架构设计与团队协作

    今天写这篇博客是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇博客的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦 ...

  9. 李洪强iOS开发-网络新闻获取数据思路回顾

    李洪强iOS开发-网络新闻获取数据思路回顾 01 创建一个继承自AFHTTPSessionManager的工具类:LHQNetworkTool 用来发送网络请求获取数据  1.1 定义类方法返回单例对 ...

随机推荐

  1. MySQL做练习时总结的一些知识点

    MySQL做练习时总结的一些知识点     0:mysql有三种注释方法 上午插入记录的时候一直没有成功,郁闷不知道为什么.因为是很多条记录一起插入,中间一些不用的数据就用"--" ...

  2. 情报收集:Metasploit命令、查询网站和测试网站

    外围信息收集: testfire.com IBM建立的测试网站 http://www.maxmind.com 查找一些网站的地理位置 http://searchdns.netcraft.com/ 查询 ...

  3. Struts2配置详解_配置Action

    Struts2的核心功能是action,对于开发人员来说,使用Struts2主要就是编写action,action类通常都要实现com.opensymphony.xwork2.Action接口,并实现 ...

  4. 用iconv指令解决utf8和gb18030编码间转换

    Linux显示在Windows编辑过的中文就会显示乱码是由于两个操作系统使用的编码不同所致.Linux下使用的编码是utf8,而Windows使用的是gb18030.  解决方案:  在终端中,进入到 ...

  5. HDU 5038 Grade(分级)

    Description 题目描述 Ted is a employee of Always Cook Mushroom (ACM). His boss Matt gives him a pack of ...

  6. SQL - 批量修改表中所有行数据某字段的部分内容

    UPDATE 表名 SET 字段名 = REPLACE (字段名, 'old', 'new');

  7. ASP.Net MVC4中封装CSS和js冗余代码(不让其大篇的显示在前台上)

    (1)封装CSS和JS代码,使用调用的方式在前台进行调用.是开发看起来简洁和易于管理,可达到重用.   由于asp.netMVC4 框架 ,在封装js和CSS的时候,有如下规范: using Syst ...

  8. chubu

    python解释型语言,不需要编译成机器认可的二进制码,而是直接从源代码运行程序. python是基于c语言开发的. python很容易嵌入到其他语言. 中文注释,必须在前边加上注释说明 : #_*_ ...

  9. create table xxx as select 与 create table xxx like

    create table xxx )       | NO   | PRI | NULL    | auto_increment | | Name       | varchar() | NO   | ...

  10. 三种实例化bean的方式

    在spring中有三中实例化bean的方式: 一.使用构造器实例化:(90%通常使用的一个方法) 二.使用静态工厂方法实例化: 三.使用实例化工厂方法实例化. 每种实例化所采用的配置是不一样的: 一. ...