阅读更多

1顶
0踩

研发管理

转载新闻 写好软件的诀窍

2013-05-07 09:54 by 副主编 WnouM 评论(4) 有9479人浏览
程序员身上的一个好笑的事情是,我们在毕生的职业生涯中都相信:我们的工作是告诉计算机如何去做。

真实情况

真实情况是,计算机能正确的按照命令去运行。无论你写的是“Hello World”,还是用无人飞机去杀死一个人。计算机都能精确的按照你的命令去做。

可我们的工作,我们的真正工作是:告诉程序员和我们自己:我们让计算机做什么了。现代的软件编程思想就是结构化的、清楚的描述计算机将要执行的任务。

事实上,计算机并不去阅读你在程序里写了什么,而人会。计算机把程序员写的代码编译成字节比特,真正会去看你写的是什么的只有人类。

写软件要像讲故事

如果你对你的工作和你写的代码的行为有了新的认识,你会马上很清楚的发现,编程工作更像讲故事。

想一想。你是如何知道一个人讲故事没人爱听的?这很简单,他老跑题,他老是纠结在不重要的细节上,他老是在故事场景中挑来跳去,等等。你立刻能知道故事被他讲烂了。

虽然在最后你能明白故事里发生了什么,你甚至能复述它,但你会喜欢这样的故事吗?你会有兴趣转述给别人或丰富故事内容吗?

相同的事情也发生在软件开发中。如果你的代码写的含糊不清,乱七八糟,没有人会愿意欣赏它。没有人会愿意看它第二次。并且你是第一个受它折磨的人。

诀窍

那么,现在你想要知道这个简单的秘诀,不是吗?下面就是:

代码里的干扰因素越少越好

注意,我不是在讨论明晰的代码vs隐晦的代码,不是在讨论约定优先,不是在讨论元数据编程有害或其它类似的东西。

写出好的软件的诀窍是代码里只写那些能让你的代码讲出的故事更有意义的内容。如果它能让你的代码更清楚,那就这样写它。如果这个东西对故事没有任何意义,那就扔了它。扔了它能让故事更好。如果代码耦合模块不清,就用元数据编程和约定。

例子

有一些经典的例子可以证明这一点。比如,描述一篇帖子和它的作者的关系。

class Post < ActiveRecord::Base
 belongs_to :author, class_name: 'User', foreign_key: :authored_by
end


看见了没?所有关于类名,外键的信息都是干扰。去掉它们。

class Post < ActiveRecord::Base
 belongs_to :user
end


第二版中没有好听的“作者”字眼,但却是更优的,因为它直奔主题,用最简短的语句告诉所有你想知道的。

另外一个例子,说一个类需要关联那些创建/修改它的信息的用户:

class Setting < ActiveRecord::Base
  belongs_to :creator
  belongs_to :editor

  attr_accessor :editing_user

  before_create :set_creator
  before_update :set_editor

private

  def set_creator
    self.creator = @editing_user
  end

  def set_editor
    self.editor = @editing_user
  end

end


干扰,所有的这些回调和attr_acessors都是干扰,都是垃圾信息,没有任何价值体现在你想完成的任务中。更简洁更好的方法是下面这样写:

class Setting < ActiveRecord::Base
  belongs_to :creator
  belongs_to :editor

  def editing_user=(user)
    if new_record?
      self.creator = user
    else
      self.editor = user
    end
  end
end


你可以看到它精炼的告诉了我们发生了什么。这段代码说,这个类有一个记录创建者,一个编辑者,我们用editing_user赋给它们值。没有回调干扰。没有几个private方法的无用信息。

一个更经典的例子,在controller里管理数据:

class PostsController < ApplicationController
  def create
    if params[:post][:text].present?
      if params[:post][:text] =~ /fuc k|cock|shi t/
        flash[:error] = "Be nice"
        @achtung = true
      end
    end

    if !@achtung
      @post = Post.new(params[:post])

      if @post.save
        flash[:success] = "Yoo hoo!"
        redirect_to :index
      else
        render :new
      end
    else
      redirect_to :index
    end
  end
end


所有的这些条件逻辑跟你的controller实际上没有任何关系。所有的这些逻辑判断并不属于controller层负责。当然,你可以这样做,而其能正常的运行,但这不是好的软件。

试试这样写:

class PostsController < ApplicationController
  def create
    @post = Post.new(params[:post])

    if @post.save
      flash[:success] = "Yoo hoo!"
      redirect_to :index
    else
      render :new
    end
  end
end

class Post < ActiveRecord::Base
  validate :bad_language_check

private

  def bad_language_check
    if text =~ /fuc k|shi t|cock/
      errors.add(:text, "has some pretty bad language")
    end
  end
end


现在你的controller能清楚的说明白发生了什么。你可以清楚的看明白当记录可以创建和不能创建时会发生什么。跟Post类一样,你可以清楚的理解它在过滤那些不干净的文字。而且校验器有自己单独的地方。它的实现方式不会影响Post本身。

结论

其实很简单。想写出好的软件吗?别再给机器写代码,从此后为人写代码。

就这么简单。

英文原文:The Trick To Good Software / 译:外刊IT评论
来自: 外刊IT评论
1
0
评论 共 4 条 请登录后发表评论
4 楼 dohkoos 2013-08-10 11:04
非常好的几个例子
3 楼 夜神月 2013-05-08 12:37
影响软件质量的因素主要还是看软件管理方面
2 楼 diggywang 2013-05-07 20:09
freezingsky 写道
我觉得前提是,完整而清晰的需求是一切软件的基础!再好的软件架构也顶不住层出不穷的奇怪需求。

这只是程序员的乌托邦,现实中不可能存在。否则也不会有那么多软件开发模型了,只要一个线性模型就行了。
1 楼 freezingsky 2013-05-07 13:40
我觉得前提是,完整而清晰的需求是一切软件的基础!再好的软件架构也顶不住层出不穷的奇怪需求。

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • 作为程序员写好软件的诀窍

    作为程序员写好软件的诀窍。程序员身上的一个好笑的事情是,我们在毕生的职业生涯中都相信:我们的工作是告诉计算机如何去做。真实情况  程序员身上的一个好笑的事情是,我们在毕生的职业生涯中都相信:我们的工作...

  • 软件架构设计说明书该怎么写?

    如果你无从下手,这里有个小窍门可以利用, 找一个出现率很高的业务,在该业务处理前尽可能多的记录一些可能与该业务相关的数据状态,待业务处理完成后,再次记录,并与之前的数据进行比较, 那些发生了变化的往往...

  • 软件测试工程师如何写好一个BUG报告?

    为什么是好的Bug报告? 如果您的错误报告是有效的,那么它得到修复的机会就会更高。因此,修复bug取决于您如何有效地报告它。报告错误只是一种技能,我将解释如何实现这一技能。 “编写问题报告(bug报告...一个好的软件

  • 怎样才能写好软件

    无论你写的是“Hello World”,还是用无人飞机去杀死一个人。计算机都能精确的按照你的命令去做。 可我们的工作,我们的真正工作是:告诉程序员和我们自己:我们让计算机做什么了。现代的软件编程思想就是结构化的...

  • 如何写好一个BUG报告?

    为什么是好的Bug报告? 如果您的错误报告是有效的,那么它得到修复的机会就会更高。因此,修复bug取决于您如何有效地报告它。报告错误只是一种技能,我将解释如何实现这一技能。 “编写问题报告(bug报告)的目的是...

  • 台达EH ES EV SV等系列PLC解密软件

    可以区分大小写,可以勾选不同的字符,这样解密速度就快多了,一般字母与数字组合的几小时搞定。 4、最近增加了直读功能,当然只能直读早期的老版本PLC,最新版本的只能穷举。 使用窍门:此次升级重点是支持485通讯...

  • 好的软件架构设计

    什么是软件架构 前言:软体设计师中有一些技术水平较高、经验较为丰富的人,他们需要承担软件系统的架构设计,也就是需要设计系统的元件如何划分、元件之间如何发生相互作用,以及系统中逻辑的、物理的、系统的...

  • 湖南软件工程自考本科总结

    湖南软件工程自考

  • mcu比较器技巧和诀窍_软件开发技巧和窍门

    mcu比较器技巧和诀窍 这些只是我想分享的职业生涯中的一些技巧和窍门。 此列表不包含银弹,也不假装是完整的或绝对的。 这只是一个列表,希望对某人有所帮助。 1)将编码推到最后 这一点也可以理解为编码前的思考...

  • 什么是软件测试工程师

    软件测试工程师(Software Testing Engineer)指理解产品的功能要求,并对其进行测试,检查软件有没有缺陷(Bug),测试软件是否具有稳定性(Robustness)、安全性、易操作性等性能,写出相应的测试规范和测试用例...

  • 写给程序员的软件测试指南:人人都可以开发无Bug代码

    一年之后,还是端午节,两位译者一起为不一样风格的软件测试译著《程序开发人员测试指南:构建高质量的软件》(后简称《程序开发人员测试指南》)写序,依旧充满诗意,享受着成功的喜悦,并郑重推荐本书...

  • 软件测试工程师的自我认识和定位!!

    在谈论软件测试之前,我作为一个有一定工作经验的工程师,我想发表一些自己的想法和观点,这些观点虽然不是完全 正确的,但是确实是我在工作中不断的去沉淀,去理解,去思考才得来的一些看法。希望作为刚入行的你,...

  • 通过隐喻更充分地理解软件开发

    然而随着时间的推移,与那些不善于运用隐喻的人相比,人们普遍认为,那些使用隐喻来指明软件开发过程的人明显更能理解编程并能更快地写出更好的代码; 3、常见的软件隐喻 软件中的“书法”:编写代码 关于软件开发,...

  • 如何写出好的产品帮助文档?

    早前我也这么认为,究其原因,一则自己不喜欢也不擅长写文档,代码是给机器读的,只要语法和逻辑没问题,计算机就会听命执行,而文档是写给人看的,除了语法和逻辑,好文档还要照顾读者的心理;二则传统软件的客户对...

  • 软件架构设计

    什么是软件架构前言:软体设计师中有一些技术水平较高、经验较为丰富的人,他们需要承担软件系统的架构设计,也就是需要设计系统的元件如何划分、元件之间如何发生相互作用,以及系统中逻辑的、物理的、系统的重要...

  • 基于ssm的网络教学平台(有报告)。Javaee项目,ssm项目。

    重点:所有项目均附赠详尽的SQL文件,这一细节的处理,让我们的项目相比其他博主的作品,严谨性提升了不止一个量级!更重要的是,所有项目源码均经过我亲自的严格测试与验证,确保能够无障碍地正常运行。 1.项目适用场景:本项目特别适用于计算机领域的毕业设计课题、课程作业等场合。对于计算机科学与技术等相关专业的学生而言,这些项目无疑是一个绝佳的选择,既能满足学术要求,又能锻炼实际操作能力。 2.超值福利:所有定价为9.9元的项目,均包含完整的SQL文件。如需远程部署可随时联系我,我将竭诚为您提供满意的服务。在此,也想对一直以来支持我的朋友们表示由衷的感谢,你们的支持是我不断前行的动力! 3.求关注:如果觉得我的项目对你有帮助,请别忘了点个关注哦!你的支持对我意义重大,也是我持续分享优质资源的动力源泉。再次感谢大家的支持与厚爱! 4.资源详情:https://blog.csdn.net/2301_78888169/article/details/144929660 更多关于项目的详细信息与精彩内容,请访问我的CSDN博客!

  • 2024年AI代码平台及产品发展简报-V11.pdf

    2024年AI代码平台及产品发展简报-V11

  • 蓝桥杯JAVA代码.zip

    蓝桥杯算法学习冲刺(主要以题目为主)

  • QPSK调制解调技术研究与FPGA实现:详细实验文档的探索与实践,基于FPGA实现的QPSK调制解调技术:实验文档详细解读与验证,QPSK调制解调 FPGA设计,有详细实验文档 ,QPSK调制解调;

    QPSK调制解调技术研究与FPGA实现:详细实验文档的探索与实践,基于FPGA实现的QPSK调制解调技术:实验文档详细解读与验证,QPSK调制解调 FPGA设计,有详细实验文档 ,QPSK调制解调; FPGA设计; 详细实验文档,基于QPSK调制的FPGA设计与实验文档

Global site tag (gtag.js) - Google Analytics