我们正在升级FutureStack的注册,仅到4月30日。条款和条件适用。 现在注册

9件你永远不会编码自己的事情

读取9分钟

这篇文章最初于2014年7月8日发布为“你应该永远不会编码的七件事”。它于2019年3月12日更新并扩展。

作为程序员,我们喜欢解决问题。我们喜欢它的想法春天从我们的头部春天,穿过我们的指尖来创造神奇的解决方案。亚博直播平台

但有时,为了解决问题,我们可能过早地开始编写代码。我们可能会立即卷起袖子投入其中——从不考虑是否有人已经解决了类似的问题,并发布了已经编写、测试和调试过的代码。

有时候,我们需要停下来想一想,然后再开始打字。

例如,这九个通常遇到的编码问题几乎总是使用现有解决方案更好地解决,而不是尝试编写自己的代码:

1.解析HTML或XML

基于编码器的次数询问Stackoverflow上的这个主题许多人显然低估了解析HTML或XML的复杂性。从任意HTML中提取数据看似简单,但实际上这是一项应该留给库的工作。

假设您希望从中提取一个URLsrc属性的一个< img >标签:

最快的解决方案是使用一个简单的正则表达式(regex)和一个捕获来匹配模式:

/  /

字符串foo.jpg将在捕获组#1中,可以分配给a

字符串。但是,如果标签有其他属性怎么办?

< img id = "棒" src = " foo.jpg”>

它会处理备用引号吗?

< img src = ' foo.jpg ' >

还是没有引用?

如果标签跨越多条线,那么是常何种方式?

你的代码知道忽略这个注释掉的标签吗?

< !——关于stackoverflow的常见问题涉及从Web API从JSON文件中提取数据的有人好奇的人。例如,“我怎样才能才能只得到麦克亨利电话号码?”

{“姓名”:“Tacos El Norte”,“标签”:[“Tacos”,“墨西哥”,“电话”:{“MCHENRY”:“815-759-9227”,“Libertyville”:“847-837-3488“,”Waukegan“:”847-263-9001“}}

在这种情况下,正常表达式不会起作用,因为JSON是结构化的,并且您无法轻易地用简单的正则表达式解析数据。您不能只搜索“MCHENRY”并采取任何遵循的内容,因为“MCHENRY”可能出现在多个领域。

另一个复杂因素是您可以将JSON倒入多行。正如多行标签可能导致从XML和HTML的数据带有正则表达式时造成问题,您可能对JSON具有相同的问题。

如果您在命令行中使用JSON,有一个非常有用的工具叫做JQ.为您解释和重新格式化JSON。

将我们的JSON文件传递给jq立即为我们格式化它:

金桥美元。炸玉米饼。json {"name": "Tacos El Norte", "tags": ["Tacos", "Mexican"], "phone": {"McHenry": "815-759-9227", "Libertyville": "847-837-3488", "Waukegan": "847-263-9001"}}

然后,我们可以使用简单的查询来仅显示电话号码部分

数据结构:

$ JQ.phone Tacos.json {“MCHENRY”:“Libertyville”:“847-837-3488”,“Waukegan”:“847-263-9001”}

然后只是一个电话号码:

$ JQ.PHONE.PHONE.MCHENRY TACOS.JSON“815-759-9227”

对于从命令行提取数据来说,这是没问题的,但大多数情况下,您将使用编程语言。幸运的是,JSON是如此普遍,以至于每种编程语言都至少有一个库或模块来解析它。例如,在Python中,你可以这样写:

import json restaurant = json.load(open('tacos.json')) print(restaurant['phone']['McHenry'])

在PHP中,你会写:

$ restaurant = json_decode(file_get_contents('tacos.json'));打印$ Restaurant-> Phone-> MCHENRY;

使用您可以使用这么多工具,从JSON中提取数据所需的代码是您不需要写自己的代码。

4.电子邮件地址验证

有两种方法可以验证电子邮件地址:您可以通过简单的检查来实现,也可以根据规则验证RFC 2822.

假设您想要一个简单的检查,验证电子邮件地址是否具有非空白字符,@符号,然后是更多的非空白字符。您可以使用此正则表达式:

/ ^ \ s + @ \ s + $ /

这个正则表达式是不完整的,它允许无效的东西通过,但至少它会确认@符号在中间的存在。

您还可以对RFC 2822中的规则验证电子邮件地址,该规则定义了电子邮件地址的标准格式。这些规则比您实现的更复杂。即使您知道RFC中的所有规则,简单的正则表达式也不会进行这项工作。您需要使用解释和正确应用规则的库。

如果你是不是将全部验证RFC 2822,然后您至少可以验证规则的合理子集。这是许多情况下有效的设计权衡,但不要欺骗自己认为您已经涵盖了所有案例,除非您返回完整的RFC,或者使用由拥有的人写的图书馆使用。

5.处理URL.

URL与电子邮件地址几乎是可恶的,但它们仍然充满了您必须记住的令人讨厌的规则:您需要编码哪些字符?你如何处理空间?你用+迹象做什么?#sign后的字符有效了?

无论使用哪种语言,您都可以找到可以将url分解为所需组件的库,然后将它们重新组合,并进行正确的格式设置。您还将找到可以验证url的代码。

说你有网址:

https://beta.example.com:8000/r/example.

为了只提取主机名,您可能会使用regex,或者使用您语言的标准函数。例如,使用PHP的内置parse_url.功能:

$ url = https://beta.example.com: 8000 / r /例子的;$host = parse_url($url, PHP_URL_HOST);

每种语言都有URL操作函数。使用它们。

6.日期/时间操作

起初,围绕日期/时间操纵的所有规则似乎容易包装。但事情很快就会变得复杂;您可能必须考虑多个时区,夏令时,闰年,甚至闰秒。例如,您可能必须弄清楚当前日期后10天或计算两次之间的分钟数。

在与美国时区交易时,这很难。在全球工作时,它会变得更加复杂。(你知道吗有些时区与相邻的时区相差几分钟,不是全部?)

即使是验证日期的简单也可能有角落案例。这不仅仅是“九月三十天......”的问题,以弄清楚一个月有多少天。你知道2000年是2月29日的闰年,但2100年不会是闰年吗?

为什么当现有库已经为您完成了它时,为什么会追踪所有这些变量?无论您是执行日期算术要计算日历上的特定时间,还是您验证输入字符串实际上是有效日期,请使用现有库。

7.模板系统

创建样板文本几乎是程序员的必经之路:

亲爱的#用户#,谢谢您对#product#的兴趣#...

您的第一个版本的模板,如此可以工作一段时间。但是,您必须添加多种输出格式和数字格式,然后您必须在表中输出结构化数据,然后在和on-to-tehinal中输出结构,您建立了一个需要无尽的护理和喂养的ad hoc怪物。

如果您正在进行比简单的字符串字符串替换更复杂,请退后并找到一个好的模板库。为了使事情更加简单,如果您在PHP中编写,语言本身就是模板系统(尽管这通常不是它的主要用例)。

8.记录框架

在许多情况下,伐木工具开始小并成长为庞然大物。您编写了一个简单的函数来记录文件,但是您必须修改它,以便它可以记录到多个文件,或在完成时发送电子邮件通知,或者具有不同的日志级别,或者依此类推。

幸运的是,大多数语言至少有三个日志套餐已经存在,并且不会拯救你的恶化结束。开发的一个次要标准是log4(langageName)公约。早在2001年,发布了一个名为log4j的Java日志库。它开始流行,并被改编成其他语言。现在有一些库,比如log4php、log4py和log4go(分别用于PHP、Python和Go)。如果您正在寻找一个日志框架,可以从搜索开始log4(langageName)

9.安全与加密

在案件中,我们向前看,我推荐使用现有代码来拯救自己的时间和麻烦。然而,在安全性和加密代码的情况下,还有一个更重要的原因:你不太可能自己做对。

根据施奈尔的法律,“任何人都可以发明一个加密算法,他们自己不能破裂;发明一个没有其他人可以破裂的更难更难。”通过比您更好的专家测试并攻击加密算法并攻击。(有关为什么要重用现有代码的安全性和加密的更多示例,请参阅“我们为什么不自己卷呢“在安全堆栈交换中。)

无论您是使用数据库绑定变量,避免在创建哈希时SQL注入或腌制密码,这是关键的不采取快捷方式。遵循推荐的实践。即使你认为你的方式和那么好,也可能不是。相信专业人士:将安全性和加密留给专家,并做他们所说的。

这不是矫枉过正吗?

有时,程序员不想使用现有的代码。我们为自己的技能感到自豪,我们喜欢编写代码来解决问题的过程。这很好,但通常解决问题的最佳方法是编写尽可能少的代码。在软件领域,最昂贵的时间是程序员的时间。在软件中包含一个额外的库可能会增加几毫秒的程序执行时间,而没有人会注意到这一点。值得注意的是,您花费了数小时或数天的时间从您编写的代码中寻找错误——但不需要这样做。