问题标签 [refactoring]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - 如何处理被认为更改危险但稳定的代码?
处理一个可以访问稳定但没有那么漂亮代码、很容易引入错误的大团队的最佳方法是什么?
我正在寻找类似于 SVN 锁定文件的东西。
language-agnostic - 为什么不在同一行声明多个相同类型的变量?
为什么在一行上声明变量是不好的做法?
例如
代替:
mysql - 终极 MySQL 遗留数据库噩梦
表 1:包括厨房水槽在内的所有物品。日期格式错误(最后一年,因此您无法对该列进行排序),数字存储为 VARCHAR,“街道”列中的完整地址,名字列中的名字和姓氏,姓氏列中的城市,不完整的地址,行根据多年来发生变化的一组规则,重复记录,不完整记录,垃圾记录...通过将数据从一个字段移动到另一个字段来更新前面的行...您可以命名它...哦,当然不是 TIMESTAMP 或 PRIMARY KEY 列在眼前。
表 2:打开这个婴儿后,任何正常化的希望都破灭了。我们在表一中的每个条目和行的更新都有一行。所以重复像没有明天(价值800MB)和像Phone1 Phone2 Phone3 Phone4 ... Phone15这样的列(它们不被称为电话。我用这个来说明)外键是......好吧猜猜。根据表 1 中的行中的数据类型,有 3 个候选项
表 3:它会变得更糟吗?哦是的。“外键是破折号、点、数字和字母的 VARCHAR 列组合!如果不提供匹配项(通常不提供匹配项),则应使用第二列类似的产品代码。具有名称的列与其中的数据没有相关性,以及强制性的 Phone1 Phone2 Phone3 Phone4...Phone15。有从 Table1 复制的列,而不是 TIMESTAMP 或 PRIMARY KEY 列。
表 4:被描述为正在进行中的工作,随时可能发生变化。它与其他人本质上是相似的。
在接近 1m 行时,这是一个大混乱。幸运的是,这不是我的大麻烦。不幸的是,我必须从中提取每个“客户”的复合记录。
最初,我设计了 Table1 的四步翻译,添加了 PRIMARY KEY 并将所有日期转换为可排序格式。然后再执行几个查询步骤,这些查询返回过滤后的数据,直到我有 Table1 到可以使用它从其他表中提取以形成合成的地方。经过数周的工作,我使用一些技巧将其归结为一个步骤。所以现在我可以将我的应用程序指向混乱并拉出一个漂亮干净的复合数据表。幸运的是,我只需要其中一个电话号码就可以了,因此标准化我的桌子不是问题。
然而,这是真正的任务开始的地方,因为每天都有数百名员工以您不想想象的方式添加/更新/删除这个数据库,而且每天晚上我都必须检索新行。
由于可以更改任何表中的现有行,并且由于没有 TIMESTAMP ON UPDATE 列,因此我将不得不求助于日志来了解发生了什么。当然,这假设有一个二进制日志,但实际上没有!
引入这个概念就像铅气球一样下降。我还不如告诉他们,他们的孩子将不得不接受实验性手术。它们并不完全是高科技……万一你没有聚集……
情况有点微妙,因为他们有一些我公司急需的有价值的信息。我被一家大公司的高级管理层(你知道他们是怎么做的)派来“让它发生”。
除了用另一个应用程序解析 bin 日志文件,我想不出任何其他方法来处理夜间更新,以弄清楚他们在白天对该数据库做了什么,然后相应地组合我的表。我真的只需要看看他们的 table1 就可以知道如何处理我的桌子。其他表只提供字段来清除记录。(使用 MASTER SLAVE 将无济于事,因为我会复制一份混乱。)
另一种方法是为其 table1 的每一行创建一个唯一的哈希并构建一个哈希表。然后我会每晚检查整个数据库以查看哈希是否匹配。如果他们不这样做,那么我将读取该记录并检查它是否存在于我的数据库中,如果存在,那么我将在我的数据库中更新它,如果它不存在,那么它是一条新记录,我将插入它。这很难看而且速度不快,但是解析二进制日志文件也不是很漂亮。
我写这篇文章是为了帮助弄清楚这个问题。经常将其告诉其他人有助于澄清问题,从而使解决方案更加明显。在这种情况下,我只是更头疼!
您的想法将不胜感激。
ruby-on-rails - 类似 Rails 的数据库迁移?
是否有任何易于安装/使用(在 unix 上)的数据库迁移工具,例如 Rails Migrations?我真的很喜欢这个想法,但是纯粹为了管理我的数据库迁移而安装 ruby/rails 似乎有点过头了。
python - 在 __iter__ 上对字典进行排序
我正在尝试根据其键对 dict 进行排序,并将迭代器返回到类中重写的 iter 方法中的值。有没有比创建一个新列表、在我对键进行排序时插入到列表中更好、更有效的方法?
database - 重构过时数据库模式的技巧
受困于不再反映您的数据模型的遗留数据库模式是每个开发人员的噩梦。然而,在所有关于重构代码以实现可维护性的讨论中,我并没有听到太多关于重构过时的数据库模式的消息。
关于如何在不破坏所有依赖于旧模式的代码的情况下过渡到更好的模式的技巧有哪些?我将提出一个特定的问题,我必须说明我的观点,但请随时就已证明有用的其他技术提供建议——这些技术也可能会派上用场。
我的例子:
我公司接收和运送产品。现在产品收据和产品发货有一些非常不同的数据与之关联,因此最初的数据库设计者为收据和发货创建了一个单独的表。
在我使用这个系统的一年中,我意识到当前的模式没有一点意义。毕竟收据和发货基本上都是一种交易,它们都涉及更改产品的数量,本质上只是+/-符号不同。事实上,我们经常需要找出产品在一段时间内的变化总量,而这个设计对于这个问题是非常棘手的。
显然,适当的设计是有一个单一的 Transactions 表,其中 Id 是 ReceiptInfo 或 ShipmentInfo 表的外键。不幸的是,错误的模式已经投入生产多年,并且有数百个存储过程和数千行代码。那么我怎样才能将架构转换为正常工作呢?
if-statement - 需要重构 Arrow 反模式的想法
我继承了一个怪物。
它伪装成 .NET 1.1 应用程序处理符合医疗保健索赔支付 (ANSI 835) 标准的文本文件,但它是一个怪物。正在处理的信息涉及医疗保健索赔、EOB 和报销。这些文件由在前几个位置具有标识符的记录和根据该类型记录的规范格式化的数据字段组成。一些记录 ID 是控制段 ID,用于分隔与特定类型事务相关的记录组。
为了处理一个文件,我的小怪物读取第一条记录,确定即将发生的事务类型,然后根据当前正在处理的事务类型开始处理其他记录。为此,它使用嵌套的 if。由于有许多记录类型,因此需要做出许多决定。每个决策都涉及一些处理和 2-3 个其他决策,需要根据之前的决策做出。这意味着嵌套的 if 有很多嵌套。这就是我的问题所在。
这个嵌套的 if 有 715 行长。是的,这是正确的。七百五十条线。我不是代码分析专家,所以我下载了几个免费软件分析工具,得出的 McCabe 循环复杂度等级为 49。他们告诉我这是一个相当高的数字。与亚特兰大地区的花粉计数一样高,其中 100 是高标准,新闻称“今天的花粉计数为 1,523”。这是我有幸看到的箭头反模式最好的例子之一。在其最高处,缩进深度为 15 个制表符。
我的问题是,你会建议用什么方法来重构或重组这样的东西?
我花了一些时间寻找想法,但没有什么能让我站稳脚跟。例如,用保护条件代替级别是一种方法。我只有其中一个。一窝下来,十四走。
也许有一种设计模式可能会有所帮助。指挥链会是解决这个问题的一种方式吗?请记住,它必须保留在 .NET 1.1 中。
感谢您的任何想法。
c# - 如何以编程方式识别对 C# 方法的引用数量
我最近继承了需要修剪和清理的 C# 控制台应用程序。长话短说,该应用程序由一个包含超过 110,000 行代码的类组成。是的,一个类中超过 110,000 行。当然,该应用程序是我们业务的核心,它全天候运行更新动态网站上使用的数据。尽管有人告诉我我的前任是“一个非常优秀的程序员”,但很明显他根本不喜欢 OOP(或版本控制)。
无论如何......在熟悉代码的同时,我发现了很多声明但从未引用过的方法。看起来好像复制/粘贴用于对代码进行版本控制,例如说我有一个名为 getSomethingImportant() 的方法,很可能还有另一个名为 getSomethingImortant_July2007() 的方法(在大多数情况下,模式是 functionName_[dateamp])。看起来当程序员被要求对 getSomethingImportant() 进行更改时,他会复制/粘贴然后重命名为 getSomethingImortant_Date,对 getSomethingImortant_Date 进行更改,然后将代码中的任何方法调用更改为新方法名称,将旧方法留在代码,但从未被引用。
我想编写一个简单的控制台应用程序,它爬过一个巨大的类并返回所有方法的列表以及每个方法被引用的次数。据我估计,有超过 1000 种方法,所以手工完成需要一段时间。
.NET 框架中是否有可用于检查此代码的类?或者任何其他有用的工具可以帮助识别已声明但从未引用的方法?
(附带问题:有没有其他人见过这样的 C# 应用程序,一个非常大的类?这或多或少是一个巨大的程序过程,我知道这是我见过的第一个,至少是这个大小。)
asp.net - 是否有任何实用程序可以帮助我重构 CSS
我正在使用一些写得很糟糕的 CSS,至少可以这么说。我不是设计/CSS 专家,但我至少了解CSS 中的C。虽然 VS-2008 内部的内置 CSS 支持比以前的版本有了很大改进,但它仍然不能完全满足我的要求。
我想知道是否有人知道一个好的程序或实用程序可以帮助我重构和清理我的 CSS,就像 ReSharper 允许用 C# 做的那样。
一些很不错的功能:
- 检查 CSS 文件并确定提取常用样式(如字体样式、颜色等)的方法...
- VS-2008 的插件会很棒!
- 检查标记文件并就改进当前使用的类和样式提出一些建议。
database - 最佳实践:将项目的工作流状态存储在数据库中?
我有一个关于如何存储复杂工作流状态以在数据库中处理任务的最佳实践的问题。我一直在网上寻找无济于事,所以我想我会问社区他们认为什么是最好的。
这个问题来自我在上一个问题中给出的同一个“BoxItem”示例。这个“BoxItem”在我的系统中被跟踪,因为它执行了各种任务。该任务可能会持续数天并需要人工交互,因此必须保持 BoxItem 的状态。还必须跟踪谁完成了任务(如果适用)以及任务完成的时间。
起初,我通过在“BoxItems”表中为每个需要完成的人工交互任务添加三个字段来解决这个问题:
任务名称是否完整
日期TaskName完成
用户任务名完成
当工作流程很简单时,这很有效……但现在它已经发展成为一个复杂的流程(流程中可能有 10 个以上的人机交互……其中大约一半是可选的,可能会或可能不会针对 BoxItem 完成,这导致我开始为那些可选任务添加“Do TaskName ”字段),我发现应该是一个简单的表现在有 40 个左右的字段完全用于保留此状态信息。
我发现自己在问是否有更好的方法来做到这一点......但我不知所措。
我的第一个想法是制作一个通用的“BoxItemTasks”表,它定义了可以在给定盒子上完成的任务,但我仍然需要单独保存日期和用户信息,所以它并没有真正帮助。
我的第二个想法是,也许这无关紧要,如果这张表有 40 个或更多用于状态保留的字段,我不应该担心......也许我只是偏执。但感觉要保留很多信息。
无论如何,我不知道第三种选择可能是什么,或者上述两种选择中的一种是否真的合理。我可以看到这个工作流程在未来可能会变得更加复杂,对于每一个新任务,我需要添加 3-4 个字段来支持它的跟踪......感觉就像它正在失控。
在这个情况下,你会怎么做?
我应该注意,这是对现有系统的维护,它是在没有 ORM 的情况下构建的,所以我不能把它留给 ORM 来处理。
编辑:
凯夫,你是在谈论做这样的事情:
盒子物品
(PK) BoxItemID
(其他无关的东西)
BoxItemActions
(PK) BoxItemID
(PK) BoxItemTaskID
完成了
完成日期
用户已完成
BoxItemTasks
(PK) 任务类型
描述(如果有必要)
嗯......这会起作用......它代表需要改变我目前执行 SQL 查询的方式以查看哪些项目处于什么状态,但从长远来看,这样的事情看起来会更好(没有进行像序列化想法所代表的基本设计更改......虽然如果我有时间,我想按照我的想法去做。)。
这就是你提到的Kin,还是我不同意?
编辑:啊,我也看到了你的想法,用“最后一个动作”来确定当前状态......我喜欢它!我认为这可能对我有用......我可能需要稍微改变一下(因为在某些时候任务会同时发生),但这个想法似乎是个好主意!
编辑最后:总而言之,如果其他人在未来用同样的问题来查找这个......听起来如果您的系统将信息预加载到某个可查询的界面中(即不直接调用数据库本身,就像我正在处理的临时系统那样),但如果你没有那个,附加表的想法似乎应该很好用!谢谢大家的回复!