当Dijkstra写关于关注点分离的文章时,他是否打算进行代码模块化?


9

首先,我阅读了摘自Edsger W. Dijkstra 1974年的论文“关于科学思想的作用”:

让我尝试向您解释,我的品味是所有明智思维的特征。就是说,一个人出于自己的一致性而愿意独立地深入研究其主题的一个方面,一直都知道一个人只在其中一个方面中占据一席之地。我们知道一个程序必须是正确的,我们只能从那个角度研究它;我们也知道它应该是有效的,可以这么说,我们可以在另一天研究它的效率。在另一种情况下,我们可能会问自己,是否这样做:为什么,该程序是理想的。但是,通过同时处理这些各个方面,则无济于事!这就是我有时所说的“关注点分离”,即使不是完全可能,据我所知,这是有效地整理思想的唯一可用技术。这就是我所说的“将注意力集中在某个方面”的意思:这并不意味着忽略其他方面,这只是正视这个事实,即从该方面的观点来看,另一方面是无关紧要的。它同时是一轨和多轨。

我看到关注点的现代分离正在谈论将代码模块化。但是,阅读上面的引用后,我理解这是一次将您的注意力集中在一项特定的任务上,而不是将精力集中在其他方面。在我看来,这并不意味着必须将代码分成模块化的块。

也就是说,在您面前有一个代码,即在一个文件中的所有文件都包含视图,存储库,控制器,事件处理,工厂等概念。

作为一个简短的示例,下面是一些具有数据访问权限并查看(输出)的代码:

$sql = "SELECT * FROM product WHERE id = " . db_input($id);
$row = db_fetch_array(db_query($sql)); 
<option value="<?=$row['id']?>"<?= $row['ver'] == $row['ver'] ? '  selected="selected"' : '' ?>>Version <?=$row['ver']?></option>

使用现代的OO,我可以使用Repository模式将数据访问放在其自己的文件中,View代码可以进入其自己的文件模板,并且可以将它们连接在一起以通过控制器(或Action或Request Handler)进行通信,并且我可以添加一个工厂来创建和连接各种依赖项。我可以有一个定义这些工厂的配置文件。当然,这与单一文件的一切相去甚远。

我关于关注点分离的问题是这样的:阅读Dijkstra的报价,我有一个想法,即他不一定意味着关注点分离是“代码的模块化分离(到文件或它们自己的函数/方法/等)中”,而且他的意思还在于让人们将注意力集中在程序的某个方面,而不用专心于其他重要但目前尚未考虑的方面,而无论它们是否在代码中物理上分开。

那么为什么我们要负担物理模块化代码分离和设计模式呢?不管代码的结构如何,仅将精力集中在一个方面是否足够?

我不是在谈论编写最可怕的意大利面条代码,然后只考虑它的一个方面,这很可能是一种负担。但是最后,我要解决的是,当不需要在精神上专注于某个方面时,为什么要执行物理代码分离,为什么要将代码拆分为分离的文件或块(方法)?

关注点分离应该仍然是一种心理锻炼,而不是身体锻炼吗?
换句话说,编程的精神(专注)和物理(纸上代码)方面是否应该脱节?


5
我可以肯定的是,到1974年,他只是将模块化编程视为显而易见的东西,这就是为什么他在那篇论文中没有明确讨论它。帕纳斯(Parnas )在1972年发表有关如何模块化的论文,到那时是否已经模块化已经不再是一个问题。实际上,您所描述的甚至不是模块化编程,而是结构化编程,Dijkstra本人本人在1968年的经典著作《考虑到有害》中强烈主张支持这种编程
约尔格W¯¯米塔格

好吧,所以也许我可以将“关注点分离”更多地理解为一种精神集中的练习,而模块化则是一种在纸上封装代码方面的方式。但是,我现在将关注点的分离和模块化更多地看作是独立的概念。
丹尼斯

@JörgWMittag,您可以定义结构化和模块化编程之间的区别吗?Google上的某些链接表明它们是相同的。
丹尼斯,

构造= IFWHILEFOR而不是GOTO。模块化=具有明确定义的公共API的模块与隐藏的内部实现和表示形式严格分开。(例如Modula,Mesa,Modula-2,Modula-3,后来的Pascal方言(UNIT)。)
JörgW Mittag,

Answers:


2

迪克斯特拉(Dijkstra)就如何思考发表了明确的声明。程序(和过程)模块化及其可取性可能是这种想法的结果,但是他提出的关键点是如何评估问题。该程序通常是解决问题的方法,通过提倡“关注点分离”,他提供了明智的建议。最好的例子就是“优化”。笑话是:“在计划优化程序时,您的第一个策略应该是:不要。” 换句话说,您首先要专注于使程序正确。快速而有趣是一个值得关注的问题,但也不能完全消除。


14

关注点分离是一种抽象的思维方式,它包括分别考虑不必关联的事物。

模块化(将不相关的功能组分离为模块),封装(隐藏模块的内部细节)和抽象(将通用与特定以及其实现隔离)都是在领域中实现这种思维方式的手段。软件设计。


9

我建议,尽管本文具有历史意义,但40年前Dijkstra所称的“关注分离”一词在今天并不特别重要。如今,它已广泛用于调制。

有大量证据表明,调制技术具有极大的好处,而这些好处远远超过了它给我们带来的“负担”。不管Dijkstra当时的意思是什么,都不会改变这样的事实:一小段代码(每个代码仅专注于一件事)会导致代码更易于编写,阅读,理解,维护和测试。


5
我认为应该指出,有关关注点分离的许多现代思想都来自早期论文,这些论文最终催生了IBM的“面向方面的编程”。我认为最初的论文(90年代末至2000年代初)是最大的影响力。已经有一段时间了,网站都变了。不知道我是否还能找到他们。
Berin Loritsch

2
困难的部分是试图定义“一件事”的含义。否则,该想法对实际代码编写将毫无用处,而错误地对编写,阅读,理解,维护和测试代码的难度将立即产生有害影响。
jpmc26

1
如果您能够(a)解释您认为Dijkstra“关注点分离”的意思,并且(b)解释为什么您认为他的意思不再相关,那么这将真正帮助我们理解您的立场。
John R. Strohm

2

我可以举一个个人的例子来说明关注点分离,我认为这与Dijkstra的概念相当。当我分析软件中的特定主题时,我会构建三个视图。

  1. 首先,我考虑数据。数据表示问题的逻辑谓词。类被构造为抽象现实世界中的实体,它们的属性是抽象的参数。类之间的关联表示类实例之间的功能映射。在这一点上,尚无代码涉及任何思考,也没有任何处理的概念。只是该主题所涉及逻辑的静态视图。
  2. 其次,我考虑动力。具有非平凡生命周期的任何类都将建模为有限状态机。这涉及到顺序执行和同步的考虑。同样,没有代码可以确定事物之间的相互作用和顺序。
  3. 第三,我考虑处理。在此,必须在状态转换或其他同步操作中完成的实际算法工作。

最后,获得主题的三个方面的视图,然后可以将该主题以便于代码本身及其维护的任何分组形式表述为代码。这三个方面不仅是一项精神锻炼。我提供所有方面的书面说明。为什么?因为如果主题足够大,那么我在短期记忆中甚至无法保留一个完整的方面。如果主题很小,那么几乎所有方法都可以用,因为您可以将其全部掌握在脑海中。

分离关注点的动机是为了适应人类的短期记忆限制。尽管计算机程序员在短期记忆中可以操纵的概念数量上比大多数其他人更胜任,但我们根本无法一下子掌握一切。为了有效,必须系统地分离关注点排除问题的一个或多个方面,以便专注于某些其他特定方面。当然,排除一个方面并不会使它从考虑中消失。必须有一种方法可以结合所有问题来实现解决方案。经验表明,分离和重组的最终结果通常比一个可能跨越多个方面混杂在一起的巨大飞跃提供了一种更易于理解的解决方案。当问题的规模很大或错综复杂时,尤其如此。


1

关注点分离是一个逻辑概念,无论您如何实现,它都会传播到代码组织模型中。的确,代码文件只是技术细节,是使软件易于管理的一种方法。具有良好编辑器的单个文件允许折叠区域的扩展可能也对您而言(一段时间)。或者将以父子方式在单独的表中存储类和方法的关系数据库可以用作存储介质。但是在需要源代码的世界中,文本文件很难被击败

  • 随身携带
  • 可通过许多不同的外部工具访问
  • 可被多个程序员访问
  • 可版本化和可比
  • 恰好可以很好地处理文件的操作系统可以很好地扩展

最重要的是,我们人类不是很擅长同时考虑或处理不同的事物。因此,我们需要一个模型,该模型允许一次思考和处理一件事情,而不会破坏我们当时未考虑的其他部分。因此,我们进行构建,一次放置一块砖,确保我们之前放置的砖不会干扰后来放置的砖。而且,如果我们以后要更换一块砖,那么事情一定不能崩溃。这是一种适用于我们的单轨思维的模型。

但是,这不是真菌或藻类的生长方式。。。


-1

我相信对Dijkstra的报价的具体答案已经解决了,但是,因为您声明“使用现代OO,我可以将数据访问放在其自己的文件中”并询问“关注点分离应该仍然是一种心理锻炼,而不是身体锻炼吗?” 让我提请您注意现代OO负责人指导我们的地方。

在使用OO进行开发时,应遵循SOLID原则。这对他们来说是一个很好的链接,但是有关“关注点分离”的TLDR主要在SOLID中的S:“ 单一职责原则”或SRP中。

这绝对是一种体育锻炼,而不是一种精神锻炼。对于您的特定示例,MVC(或其同级MVVM和MVP)指示一个人将Model,View和Controller / Presenter / ViewModel的协调区物理上分开到单独的文件中。我已经看到了一些MVVM实现,其中将它们实现为单独的程序集,以进一步限制人们“混淆概念”的趋势。

但。如果您遵循Bob叔叔的观点,它不只是简单的“这是一个视图,这是一个模型” 。

还需要考虑任何特定的OO元素的需求来源。例如,如果您将客户想要的东西与操作人员想要的东西混在一起,那么您还将违反SRP。或者,像鲍勃叔叔所做的那样:班级应该只有一个并且只有一个改变的理由。

我强烈建议您使用提供的链接进行进一步研究,或者在网络上搜索“可靠原则”。


到目前为止,SOLID原理与实际编写代码(=哲学)的现实是脱节的,以至于只有在您已经知道如何编写良好的代码之后,才能以任何远程有用的方式来理解它们,此时,它们充其量是多余的。在没有经验和能力的情况下将它们用作指导原则会产生极其糟糕的代码。
jpmc26
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.