清洁代码:职责 — Janos Pasztor

栏目: 数据库 · 发布时间: 5年前

内容简介:我听说你想成为一个更好的程序员。您希望使用可重用的部分,并希望更轻松地维护旧代码。您可能还希望在团队中更好地工作并确保减少错误。对更好代码的渴望通常会让人们发现“清洁代码”这个术语。这很可能是由您可能已经注意到,我使用了名称“module”而不是“class”或“object”。那是因为干净的代码不是特定于面向对象的编程。您可以将干净的代码原则与您喜欢的任何编程范例一起使用,例如,经典的过程编程。

我听说你想成为一个更好的程序员。您希望使用可重用的部分,并希望更轻松地维护旧代码。您可能还希望在团队中更好地工作并确保减少错误。

对更好代码的渴望通常会让人们发现“清洁代码”这个术语。这很可能是由 罗伯特C.“鲍勃叔叔”马丁 创造的 ,他写了一本同名的书。你可能想给它一个阅读,但是,我发现它非常冗长。本书介绍了一些基本原则,这些原则可以帮助您编写模块化代码,以便以后可以重用这些模块。在本系列中,我们将介绍他的原则和想法,以及清洁代码运动的其他一些作者的原则和想法。

您可能已经注意到,我使用了名称“module”而不是“class”或“object”。那是因为干净的代码不是特定于面向对象的编程。您可以将干净的代码原则与您喜欢的任何编程范例一起使用,例如,经典的过程编程。

那么让我们开始讨论我们议程上的第一个主题:何时是拆分模块的好时机?

责任

编写代码时,必须以某种方式对其进行分段。组织单位可以是类或模块,具体取决于您的编程范例。一般的想法是,一段代码应该只处理一个责任。换句话说,做一件事,做得好。

但是责任是什么?让我们上一节课,例如,与学校的学生打交道。该课程将保留一个学生的数据。像这样:

<b>class</b> Student {
  <b>private</b> string name;
  
  <b>public</b> <b>void</b> setName(string name) {
    <b>this</b>.name = name;
  }
  
  <b>public</b> string getName() {
    <b>return</b> <b>this</b>.name;
  }
}

您需要将数据保存在某个位置,例如,在数据库中。问题出现了:实现save()存储此学生记录的方法是一个好主意吗?毕竟,这将非常方便:

Student joe = <b>new</b> Student();
joe.setName('Joe');
joe.save();

想象一下以下情况。您在考虑 MySQL 的情况下实现此类,这是Web世界中相当标准的数据库引擎。一个忠实的日子,你的老板来找你并告诉你系统管理员一直抱怨,服务器超载。在短暂的搜索之后,您发现您的students桌子非常庞大而且速度很慢,因此您现在决定为您的学生数据实施缓存。数据从MySQL读取并写入例如Memcache。

所以现在你的Student类需要知道MySQL和Memcache。到目前为止Student,只能让您轻松访问学生数据的简单类已经发展到相当大的规模,现在出现了维护问题。有很多代码甚至无法测试。但是,嘿,这就是生活吧?

接下来的一周,似曾相识,你的老板又回到了你的办公桌前。系统管理员再次抱怨。(他们不能只购买更多的硬件吗?来吧。)现在这是你的courses桌子造成的问题。您决定使用相同的路径并将Memcache的代码复制到您的Courses班级。

是的,是的,我可以听到你尖叫,你永远不会那样做。您总是决定重构代码以避免重复。但相信我,其他人不会。除非您单独工作,否则您将不得不与那些对重复代码具有更高容忍度的人打交道。

那么我们怎样才能避免这种情况呢?即使不是您编辑代码,我们怎样才能确保不会发生这种情况?答案在于责任这个词。用我们的save()方法我们犯了一个错误。我们在一个班级中承担了不止一项责任。该Student班负责保存学生记录并将其保存到数据库。

用伟大的鲍勃叔叔的话来说,如果一个类只有一个改变的原因,那么它就有一个责任。

前面的例子很清楚:有两个职责,存储/检索数据和数据结构本身。这些应该解耦,以便我们可以独立地改变它们。

那么我们如何解决这个问题呢?记住,我们说过我们想让一个班级只有一个责任。所以让我们把它分成两部分。让我们按原样保留原始Student类,并创建第二个类来存储和检索Student对象。

<b>class</b> MySQLStudentStorage {
  <b>public</b> Student getById(<b>int</b> id) {
    <font><i>//...</i></font><font>
  }
  
  <b>public</b> <b>void</b> store(Student Student) {
    </font><font><i>//...</i></font><font>
  }
}
</font>

当然,当你几乎没有代码时,这很容易。但是如果你已经拥有大量依赖save()函数的代码,你会怎么做?那么,你处境艰难,没有完美的解决方案。

例如,您可以通过Student类中的调用代理:

<b>class</b> Student {
  <font><i>//...</i></font><font>
  
  <b>public</b> <b>void</b> save() {
    storage = <b>new</b> MySQLStudentStorage();
    storage.store(<b>this</b>);
  }
}
</font>

使用此代理解决方案将极大地帮助您,因为您可以一次重写一个模块的代码,并且您不需要对生产环境进行大的更改。当您需要拆分类时,几乎可以在所有情况下使用代理策略。

重构

让我们看一个不同的例子。想象一下处理财务数据的系统。你知道,这是无聊的东西。您很可能拥有某种类型的数据库,并且您必须向使用它的人员提供一些报告。这些报告将是Excel表格或某些描述的CSV文件。

其中一份报告可能是每月收入/支出表。最初,您为财务人员构建了此表,以便他们可以根据您提供的数据运行他们的奇特报告软件。有一天,令你惊讶的是,首席执行官走进你的房间,并要求你改变报告的一栏。她希望你很好地格式化数字,这样她就更容易阅读。当然,您希望让您的首席执行官感到高兴,因此您需要改变这一栏。

一切都很顺利,直到本月末,财务人员再次尝试使用该报告并将其导入到他们的软件中。一切都崩溃了。他们希望修复报告。我不知道你是否遇到了财务人员,但如果他们说他们希望他们的报告得到修复,那就意味着他们现在想要修复它。毕竟,这是本月底,他们需要提供自己的报告,如果因为你迟到,没有人会诅咒。

你是做什么?显然,你还原了之前的改变。然后你给首席执行官写了一封抱歉的信,下次你想要加薪时,你的记分卡肯定不会好看。或者您可以花时间重构代码以提供两个单独的报告而不是一个报告,并将其作为两个功能出售给CEO。毋庸置疑,你必须花一些时间在上面,但拥有专门的CEO报告比在你的记录上留下黑色标记要好得多。此外,下次首席执行官要求您更改某些内容时,您可以自由地这样做,因为您确保一个模块只负责一件事,只有一个改变的理由。

结论

如您所见,本文中概述的单一责任原则非常符合商业业务利益。让您编写遵循此想法的代码符合公司的长远利益。将变化压缩到不属于的类中将导致更大和更大的类,并导致巨大的维护难题。复杂的代码也意味着您需要进行的任何更改都需要数月而不是数天,因为您必须解决代码中有机发展的混乱。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

人工智能

人工智能

李开复、王咏刚 / 文化发展出版社 / 2017-5-10 / CNY 55.00

人工智能已经来了,它就在我们身边,几乎无处不在。 人工智能技术正在彻底改变人类的认知,重建人机相互协作的关系。史无前例的自动驾驶正在重构我们头脑中的出行地图和人类生活图景,今天的人工智能技术也正在翻译、写作、绘画等人文和艺术领域进行大胆的尝试。 我们真的知道什么是人工智能吗? 我们真的准备好与人工智能共同发展了吗? 我们该如何在心理上将人和机器摆在正确的位置? 我们该......一起来看看 《人工智能》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具