Rails 如何用代码描述问题而不是过程式思考?

zhangyanan · 2013年11月14日 · 最后由 liwei78 回复于 2013年11月29日 · 3899 次阅读

领导说写代码要转变思维模式,不是过程式的,需要你用代码将问题描述清楚?我想说我的思维一直停留在如何解决问题,解决问题的步骤,请问 rails 高手们,怎么转变思维,用描述性代码实现功能?

其实就是面向对象的意思吧?

你要这样写代码

? 生命、宇宙以及任何事情的終極答案
42

@bhuztez 银河系漫游指南么 - -

假设我已经完成了这个功能

建议你从设计 api 的角度来写 code。比如你要实现一个功能,你希望你的使用 api 是什么样子,先写出你的 api,然后再写测试,从测试的描述中让自己更清楚自己要做什么,测试出错的结果是你想要的结果时,再动手写 code。 比如我想实现所有的 model 按照时间来分组的功能,那么我希望的是:

User.aggregate({created_at.lt: Time.now.....})
Order.aggregate(.....)
Product.aggregate(.....)

那么你就发现你其实希望的是所有的 model 做分组的结构应该是一样,这样你大致能想到自己要做什么了。

难道要来点函数式编程?

多去 stack overflow 问问题,别人能看懂就代表你描述对了

#7 楼 @xds2000 看看你博客左下角的是啥

你说的是函数式编程?

从如何测试的角度

好的代码,他本身的可读性就像是注释一样。像英文那样。人机交流更简便。

#1 楼 是的,发现做了这么多年面向对象,还是不太懂??高手给指点下可以吗?

#2 楼 确实看不懂你说的什么...

4 楼 关键是我不懂得如何思考?我考虑的是解决问题的步骤,但是是过程,我想描述,可是有点困难

#14 楼 @zhangyanan 别管什么面向对象

一开始可以从理解声明式编程和命令式编程的差别入手,#12 楼 @knwang 的回复值得看看。

@knwang 受益!但是有些看到不太懂,没到你那个层次呢,

def grades assignments.map(&:grade).uniq end 这个里面&是什么?

#18 楼 @zhangyanan 这个是 Ruby 的 symbol to proc. 相当于

assignments.map {|assignment| assignment.grade}.uniq

每个语言都有它的惯用法,多参考开源软件的源码。

既然这个问题是领导提出的,我想领导应该有比较合理的答案。

除此之外,我的建议是:

  • 首先,99% 的情况下,不要考虑性能。
  • 把写代码当成写作文。
  • 用函数名 解释 你要做什么?(用 动词 或者 陈述句)
  • 用类名 和 变量名 解释 他是什么?(用名词)
  • 把代码的注释,变成 类名 函数名 变量名。
  • 永远不要写注释。
  • 不停的思考,如何把代码写的更好读。
  • 坚信“解决问题”比“描述解决方案”更容易。
  • 坚信“描述解决方案”比“解决问题”更重要。
  • 如果你不打算写出好的代码,忽略以上所有内容。

很多问题不是只能用面向过程的步骤才能完成的吗...

我觉得应该是对估计会频繁的写的过程式代码做一些归纳, 确定不太改变的几个状态,再用过程式代码去完成这些状态, 这样能避免很多重复性的过程式代码. 至于状态,用类或者用函数去模拟就不一定了.. 而且过程式的代码还是不可少

用人类的思维方式作为指导思想

@ery 当然想写好代码了...不敢忽略!

@knwang 我大致懂得你说的意思,但是这些我理解的不透彻,能麻烦你解释下吗? In comparison, imperative programmers often approach a problem imagining themselves as the computer - "I am going to do this first, then if this condition is true I do x, otherwise I do y.", "I need to use this variable to hold this value, then increment it as I go through this array". Here is the news: we humans are more productive and happier thinking like humans than pretending to be computers.

@knwang inperative programmers 是怎么想的?

如果你手边有《Everyday Scripting with Ruby》,可以看看第 7 章“假设式脚本编写法”。

或者如果有《The RSpec Book》的话,看看第 8 章第 2 小节“The Code You Wish You Had”那一部份。

或者如果你读过《重构》,可以试试把这句话倒过来理解一下“我们应当遵循这样一个原则,每当感觉需要注释来说明一些什么的时候,就将要说明的东西写进独立函数,并以其用途(而不是实现手法)命名。”——既然要把细枝末节的代码写进独立的函数,何不一开始就定义好你要的那个函数(方法)而不是把这些逻辑散落在外面之后再回头整理?

#26 楼 @zhangyanan

过程式的思考方式是想一步步的"实现步骤",然后抽取步骤重构出高的抽象层,是从下而上的;声明式是先勾勒出高层的框架,描述出问题本身或者解决方案的框架,在用具体步骤来实现,是从上而下的。Ruby 的语法很适合这种思维方式,对复杂的问题可以写成 DSL 来描述,然后解决。

#28 楼 @knwang 以前我也很喜欢纯粹自顶向下(分析法)的设计方式,现在觉得自顶向下和自底向上都得用。如果纯粹自顶向下的话,好像有些对象不容易被发现,需要自底向上(归纳法)才能把它们找出来。

`如果你手边有《Everyday Scripting with Ruby》,可以看看第 7 章“假设式脚本编写法”。

或者如果有《The RSpec Book》的话,看看第 8 章第 2 小节“The Code You Wish You Had”那一部份。

或者如果你读过《重构》,可以试试把这句话倒过来理解一下“我们应当遵循这样一个原则,每当感觉需要注释来说明一些什么的时候,就将要说明的东西写进独立函数,并以其用途(而不是实现手法)命名。”——既然要把细枝末节的代码写进独立的函数,何不一开始就定义好你要的那个函数(方法)而不是把这些逻辑散落在外面之后再回头整理?`

#27 楼 @yuan !!!!!!!!!

面向过程的编程是没有错的。它有自身适合的范围,比如面向初学者的教学时,用过程式的编程更容易理解,也更容易理解 if,else,when,case 这种基本得判断。

面向对象的编程是用来解决高级一点的问题,这个时候观点是不一样的。

面向过程是被需求引领着思考,我要做什么,我怎么做。 面向对象是从功能来思考,这个功能给它什么,它给我什么。

以上是我的理解。

@liwei78 我一直在初学者行列混了这么多年,需要进步啊!

@liwei78 我觉得面向对象就是管理代码复杂度的一种方法。我想代码之所以复杂,一是因为逻辑重复、二是因为不好的命名、三是因为过于细节,层次不分明以致于人脑处理不过来。

程序员可以用面向对象语言的封装、多态等机制来去除重复、隐藏细节、良好的命名以表达意图。

那些设计模式、重构手法,讲的都是这些东西。

#32 楼 @zhangyanan 我觉得我也是,即便找工作也是代码力工。

#33 楼 @yuan 写代码和设计模式,就像一个是泥瓦匠,一个是建筑师。建筑师也是从泥瓦匠过来的,只是有些人依旧是当初的泥瓦匠。

这时,我内心的“小人”就会突然冒出来说:你啥也不是,说的话没分量。 好吧,人家说,你说话的时候,后面如果加上 XXX 说,效果会很好,那么。。。。

建筑师是学过拉丁文的泥瓦匠。——阿道夫·路斯

#35 楼 @liwei78 :) 其实我反而不喜欢引用别人说的话来说明道理,感觉这样有些偷懒。经常见到些一直没搞明白也没怎么花精力去搞明白面向对象的,突然看到某“大牛”说面向对象就是个渣,好,那面向对象不用研究了,太好了,顿时轻松了,突然还高你们这些研究面向对象的人一等了。于是拿着真理到处宣传。

我觉得主要还是自己弄清楚了,说话有没分量无所谓,说服不说服得了别人也无所谓,你说是吧?

现在再来回帖主要是因为在公司的群里看到有人转载这两天的某篇文章有感而发。跑题了。

#36 楼 @yuan 哈哈哈,我都忘了我 7 天前说的什么了。。自己想都不知道为啥那么说,忘了。我回帖的时候一般是休息,喝药,吃东西,等 lol 开局的时候,平时不敢上这里了,影响工作思路。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号