我们能否使在大型代码库的不同部分之间添加数据流更容易?


10

在对大型系统进行更改时,我经常会遇到一个问题,即某些功能需要从另一部分中获取一些数据,但是它们位于深度和分支调用树的不同部分中,可能流经事件侦听器,延迟调用,等。这样,简单的更改就会迅速膨胀。

Yossi Kreinin的博客文章(http://www.yosefk.com/blog/i-want-a-struct-linker.html)的相关引用:

您有很多传递的数据结构。很快,关于该结构的最有价值的事情不是它保留的数据,而是通过一些繁琐的控制流程一直可用的事实。

全局变量是让代码“呼喊”到遥远的代码的一种经典方法,但众所周知它们存在问题。动态范围变量是一种更受限制的方法,但它们也存在问题。

是否有旨在解决此问题的编程语言研究?我们是否可以更轻松地将意外的数据流添加到大型代码库中,同时仍具有静态检查,简便的单元测试和其他优点?


表达问题的方式我想您应该记住单个流程中的数据流,而没有进程间的通信。那么,您看到哪种类型的问题无法通过标准事件发送器/侦听器机制解决?
Doc Brown

一个人为的例子:想象一下,在系统的深处,有一些代码向用户发送文本消息。并且您获得了一个新的要求,即消息文本应取决于用户所在时区中的当前时间。调用堆栈看起来像这样:一些知道用户时区的代码,调用一个方法,该方法调用一种方法(重复15次),该方法调用生成消息文本的方法。按照我的标准,这是一个简单的示例,因为它仅涉及向下的通信,但是仍然必须更改15种方法的签名才能进行细微的更改。
Vladimir Slepnev

好吧,我想可能有帮助的是对数据流进行显式建模,并将组件与数据流分离。德国软件工程师为此主题写了很多文章,大多数文章都是德语的。下面是英文的他的条目文章:geekswithblogs.net/theArchitectsNapkin/archive/2011/03/19/...
布朗博士

我认为单例内部API可能会有所帮助。它可以在整个应用程序中访问,并将封装所有数据检索逻辑。
superM 2013年

Answers:


1

您指的是CDI(上下文依赖注入)AKA IoC(控制反转)。Java JSF和Spring Framework是一些示例。ASP.NET MVC具有Unity等插件。Java语言开始使用诸如RequireJS之类的库来组织结构,该库具有在许多现代JS框架中可见的注入行为。那是用于连接本地和远程应用程序。

为了跨网络进行松散耦合,公司喜欢将Web Services与SOAP,REST,AJAX或通过RPC进行常规远程方法调用一起使用。在Java中,可以使用JAX-WS或.NET WCF来构建分布式服务。然后,您可以将它们以任何语言或平台从服务总线或“数据流”中排列为客户端。Ruby,Python,Scala,Java,C#等。

松散耦合使您可以划分和解决问题,并且服务通常是数据库中提取数据的入口点。加紧阶梯,我们有了名为Message Queue的野兽。那条路通往企业和基础架构类型的框架。

但是,如果您的项目坚持不使用任何网络,则可以使用诸如Scala,Akka,NodeJS等之类的语言来设计,以在单个应用程序中实现大量数据流。他们还可以使用一些或所有前面提到的用于复杂项目的技术。例如,Scala可与JAX-RS REST服务一起使用,以从数据源中提取某种“全局数据”,并具有用于IoC内部接线的Spring。JBoss,.NET和GUI工具(例如MuleESB)中也有许多业务执行或工作流框架。在开发中,Eclipse和Netbeans使您可以在可视流程图屏幕中拖放服务。

最后,Java仍然具有Singleton bean。要在运行时调整方法,请使用代理或反射框架。但老实说,1999年是如此。

我认为,如果您要打很多电话,以根据用户所在的时区向用户发送消息,则可能有一种两步方式来实现与用户看到的效果相同的效果。但是,是的,现有语言已经使用了CDI框架,就像外套一样,赋予它们您提到的所有灵活功能。我喜欢称它为程序的潜意识,无缝处理脏活。


消息队列可能会过大,但是消息传递是使事件全面触发的理想方式。Java使用消息驱动Bean(Message Driven Bean,MDB),这应该允许您的程序相互发送或接收“对话”。您可以通过这种方式获得异步红利。
Senor Developer

感谢您的指点!这绝对使我想知道一种语言如果从头开始设计以支持依赖项注入和类似的模式会是什么样子。
Vladimir Slepnev

0

实际上,最简单的方法是使用某种数据封装API。这可能是NoSQL存储,也可能是封装的RDBMS(或者实际上可能在同一应用程序中的不同时间和位置)–没有任何理由使您无法长期处理RDBMS存储和NoSQL数据库处理短期状态控制)。它甚至可能是一系列单例对象。

然后可以以某种可管理的方式在某种中性空间中使用您的数据结构。这是我们对LedgerSMB采取的方法(但是对于一些基本隐蔽的单身人士,它具有一些半全局变量,但是又对这些变量进行了管理,我们选择直接存储对象,因为它使变量的管理更容易一些,但是存在全部4个)。

当然,任何方法都需要权衡,您无法绕开这些权衡。关键是要看一下权衡(管理vs性能vs代码清洁度vs潜在的编码陷阱),然后根据最适合您的应用程序来做出决定。


感谢您的回答!在我看来,编程语言研究可以解决这个问题。例如,如果代码从全局数据库或隐藏的单例中读取某些数据,则可能需要有关其所需数据的静态/声明性保证。
Vladimir Slepnev

-1

如果您使用(或引用)这些词

hairy flow of control

那么我认为您的代码确实是一团糟。您应该立即将其删除。如果使用关注点的模块化/分离,则没有“麻烦的控制流”之类的东西。您的代码只是缺乏简单性,这也可以通过引用全局变量:-)来推断。


为什么要下票?引号中缺少恰好支持我观点的引言:“(可能被归类为“反模式”或“代码气味”,因此在相应的圈子中都有一个名称,但我不知道,所以我将留下它的
名字

2
这并不是问题的真正答案,这可能是投票否决的原因
Daniel Gratzer

然后让我重新表述一个问题:是否有任何魔术技巧可以消除违反软件设计最基本原则之一的代码混乱:KISS(保持简单,愚蠢)?诀窍不是魔术,要么是因为程序员知道所有不太明显的细节(长此以往将杀死公司),要么就无法被替换,或者是重组代码库。不幸的是,许多公司起初并不关心正确的代码设计,甚至根本不了解后果,然后不得不至少重写一次代码,很多甚至甚至多次重写它……
user127749 2013年
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.