<p>上面代码的问题并不是嵌套太深,而是代码的扩展性太强,不够有意。我的意思是,当你组装机器所需的齿轮、轮子和杠杆已经就位并(大概)起作用时,你能看到的有标签的模块太少了,有太多的问题被“完成”在太多隐含的、未标记的方式上,导致代码难以阅读(对于“完整”部分,你愿意听听吗<a href="http://www.infoq.com/presentations/Simple-Made-Easy" rel="nofollow">http://www.infoq.com/presentations/Simple-Made-Easy</a>-这是一个非常有启发性的谈话,它指出了代码的问题)。在</p>
<p>我举个例子:</p>
<pre><code>...
for msg in self.irc.recv(self.buffer).split(('\r\n').encode()):
...
</code></pre>
<p>我想你说的是“信息”。那么为什么不调用这个变量<code>message</code>?为什么是缩写。那个词?<code>message</code>更清楚了。在</p>
<p>现在是<code>for message in xxx</code>。什么是<code>xxx</code>?你已经知道了。在python英语中,确实,<code>for apple in appples; for pear in pears</code>应该是一种好的、合理的语义书写方式:<code>for ... in</code>循环从元素集合中一次一个地挑出元素,因此{<cd7>}在大多数情况下是可以的。这给了我们</p>
^{pr2}$
<p>这些信息来自哪里?根据您的代码,它们是执行<code>self.irc.recv(self.buffer).split(('\r\n').encode())</code>操作的结果。在</p>
<p>这真是个大麻烦。{{10}绝对是<cd9}中的一个。现在这肯定是一个常数,为什么每次都要重新计算呢?用<code>irc.recv()</code>来解码所有的缓冲区返回,而不是先拆分,然后逐行解码。在</p>
<p>但这是次要的问题。重要的是:无论需要什么低级代码来提供<code>irc</code>中的下一行列表,它可能不应该出现在这里。更确切地说,像</p>
<pre><code>messages = self.irc.get_messages()
</code></pre>
<p>或者也许</p>
<pre><code>messages = <SOME_LIBRARY>.get_irc_messages( self.irc )
</code></pre>
<p>是合适的。当然,这些细节还有很多争议。就我个人而言,我尽量不把我的数据状态对象(主要是泛型类型)与我的库(库中的命名功能的无状态集合)合并在一起。上面链接的<em>简单易用的演示文稿提出了完全相同的观点,顺便说一句,而且还设法令人信服地进行了辩论。(旁白:这当然与当前主流的OOP思想不谋而合,但是google搜索Yegge在名词王国中的执行,如果你相信<code>OOP ≡ good</code><em>n'importe quois</em>)</p>
<p>目前的方法都是关于回复消息,而不是接收消息。把它想象成报纸上的一个真正的专栏:这里我们在办公室里,负责思考并汇编答案,然后发给读者;那些打开收到的报纸邮件、拿起电话、筛选电子邮件的人,在另一个办公室里有着完全不同的工作。因此,如何打开信封应该是你应该在这个地方实现的。需要外包。在</p>
<p>是否要将<code>messages</code>变量显式化或将其合并为内联API调用,取决于可用空间等多个因素,以及是否希望在例程的另一个点循环使用该返回值。我觉得这很好:</p>
<pre><code>...
for message in self.irc.get_messages():
...
</code></pre>
<p><code>for ... in</code>将透明地与生成器和列表返回器一起工作,这很好。在</p>
<p>总是用最一般的、但不松散的、最模块化的、但不是“原子化”的方式来思考代码。在</p>
<p>如果我要针对您的代码编写测试用例,我肯定会挑出<code>irc.recv</code>部分并单独测试。用这样的方式来思考你的代码:什么是好的模块,每个模块都有一个单独的关注点,一个合理的隔离级别,健全的调用参数,这些都有利于良好的可测试性?我的代码部分的合理名称是什么?-如果你坚持这样做,你的代码就不会再嵌套太深了。在</p><p>上面代码的问题并不是嵌套太深,而是代码的扩展性太强,不够有意。我的意思是,当你组装机器所需的齿轮、轮子和杠杆已经就位并(大概)起作用时,你能看到的有标签的模块太少了,有太多的问题被“完成”在太多隐含的、未标记的方式上,导致代码难以阅读(对于“完整”部分,你愿意听听吗<a href="http://www.infoq.com/presentations/Simple-Made-Easy" rel="nofollow">http://www.infoq.com/presentations/Simple-Made-Easy</a>-这是一个非常有启发性的谈话,它指出了代码的问题)。在</p>
<p>我举个例子:</p>
<pre><code>...
for msg in self.irc.recv(self.buffer).split(('\r\n').encode()):
...
</code></pre>
<p>我想你说的是“信息”。那么为什么不调用这个变量<code>message</code>?为什么是缩写。那个词?<code>message</code>更清楚了。在</p>
<p>现在是<code>for message in xxx</code>。什么是<code>xxx</code>?你已经知道了。在python英语中,确实,<code>for apple in appples; for pear in pears</code>应该是一种好的、合理的语义书写方式:<code>for ... in</code>循环从元素集合中一次一个地挑出元素,因此{<cd7>}在大多数情况下是可以的。这给了我们</p>
^{pr2}$
<p>这些信息来自哪里?根据您的代码,它们是执行<code>self.irc.recv(self.buffer).split(('\r\n').encode())</code>操作的结果。在</p>
<p>这真是个大麻烦。{{10}绝对是<cd9}中的一个。现在这肯定是一个常数,为什么每次都要重新计算呢?用<code>irc.recv()</code>来解码所有的缓冲区返回,而不是先拆分,然后逐行解码。在</p>
<p>但这是次要的问题。重要的是:无论需要什么低级代码来提供<code>irc</code>中的下一行列表,它可能不应该出现在这里。更确切地说,像</p>
<pre><code>messages = self.irc.get_messages()
</code></pre>
<p>或者也许</p>
<pre><code>messages = <SOME_LIBRARY>.get_irc_messages( self.irc )
</code></pre>
<p>是合适的。当然,这些细节还有很多争议。就我个人而言,我尽量不把我的数据状态对象(主要是泛型类型)与我的库(库中的命名功能的无状态集合)合并在一起。上面链接的<em>简单易用的演示文稿提出了完全相同的观点,顺便说一句,而且还设法令人信服地进行了辩论。(旁白:这当然与当前主流的OOP思想不谋而合,但是google搜索Yegge在名词王国中的执行,如果你相信<code>OOP ≡ good</code><em>n'importe quois</em>)</p>
<p>目前的方法都是关于回复消息,而不是接收消息。把它想象成报纸上的一个真正的专栏:这里我们在办公室里,负责思考并汇编答案,然后发给读者;那些打开收到的报纸邮件、拿起电话、筛选电子邮件的人,在另一个办公室里有着完全不同的工作。因此,如何打开信封应该是你应该在这个地方实现的。需要外包。在</p>
<p>是否要将<code>messages</code>变量显式化或将其合并为内联API调用,取决于可用空间等多个因素,以及是否希望在例程的另一个点循环使用该返回值。我觉得这很好:</p>
<pre><code>...
for message in self.irc.get_messages():
...
</code></pre>
<p><code>for ... in</code>将透明地与生成器和列表返回器一起工作,这很好。在</p>
<p>总是用最一般的、但不松散的、最模块化的、但不是“原子化”的方式来思考代码。在</p>
<p>如果我要针对您的代码编写测试用例,我肯定会挑出<code>irc.recv</code>部分并单独测试。用这样的方式来思考你的代码:什么是好的模块,每个模块都有一个单独的关注点,一个合理的隔离级别,健全的调用参数,这些都有利于良好的可测试性?我的代码部分的合理名称是什么?-如果你坚持这样做,你的代码就不会再嵌套太深了。在</p>