We're sunsetting PodQuest on 2025-07-28. Thank you for your support!
Export Podcast Subscriptions
People
J
Jeff
使用ChatGPT来改善关系和解决争论
P
Peter
Topics
Peter: 我最近一直在做一个游戏项目,最初用Unity和视觉脚本语言编写。随着项目发展,我意识到代码库已经难以维护,许多功能用视觉脚本语言难以实现。因此,我决定重新开始,选择更合适的引擎和编程语言,并运用我学到的新技术。我认为,当代码库过于复杂或技术栈过时时,重新开始可能是更好的选择,可以提高效率并避免陷入技术债务的泥潭。 我理解重写代码需要时间和精力,但有时这比在混乱的代码库中挣扎更有效率。重新开始也让我有机会尝试不同的游戏引擎,选择最适合项目的工具。 当然,这并非总是最佳选择,需要根据具体情况权衡利弊。对于一些简单的项目或时间紧迫的项目,逐步改进可能更合适。 Jeff: 我认为几乎不应该完全重写代码。我过去多次尝试完全重写,结果都不理想。我更倾向于逐步改进现有代码。即使代码存在问题,也应该尽量保留现有功能,并逐步改进。 以我去年重写Kineo应用为例,虽然我移植到新平台并使用了新的UI设计,但事后看来,我本应该逐步迁移,而不是完全重写。 完全重写会浪费时间,因为你需要重新实现已经存在的功能。即使现有代码不够理想,它至少是可运行的。我们可以通过模块化,逐步改进,并添加单元测试来提高代码质量。 当然,如果代码库过于混乱,难以模块化,那么重新开始可能也是一种选择。但即使如此,我们也应该尽量保留业务逻辑,并在新的代码库中重新实现。

Deep Dive

Chapters
Peter and Jeff discuss the pros and cons of starting over on an app versus continuing to work with an existing codebase. Peter recently started over on a game he'd been working on for a couple of years, while Jeff generally advises against it.
  • Peter started over on his game, Project Hack, due to problems with his original Unity codebase.
  • Jeff advises against completely rewriting an app from scratch, citing past experiences.
  • The discussion focuses on the tradeoffs between starting over and working with an existing codebase, considering factors like technical debt, modularity, and available resources.

Shownotes Transcript

在本集中,我们讨论了 Peter 重新开始使用新代码库的决定。他认为有时这是正确的做法。Geoff 分享了他的观点,这引发了热烈的讨论,并为开发人员在处理现有项目和技术债务时提供了一些思考。(00:00) - 介绍 (10:13) - 成为支持会员 (20:19) - 获取超过 200 个 Mac 应用 (27:02) - 支持播客 链接:你永远不应该做的事情,第一部分 与遗留代码有效合作 成为支持会员 https://patreon.com/compileswift 感谢我们每月的支持者

Adam Wulf bitSpectre Arclite

★ 支持这个播客在 Patreon 上 ★ </context> <raw_text>0 大家好!欢迎收听另一集播客。我是你的主持人 Peter。Jeff 也在今天,你的另一位主持人。Jeff,你好吗?我很好。我一直在做很多不同的项目,

试图同时发布很多东西。太棒了。这总是很有趣,对吧?因为一切总是按计划进行。从不出错,对吧?100%。是的。有趣的是,我认为在这一集中,我们将会有不同的意见,我认为这总是能带来最好的对话,人们也喜欢听到我们意见相左。然后他们可以选择立场,对吧?我只希望有人能一次选择我的立场。这就是我想要的全部。是的。

在本集中,我将讨论我最近一直在做的事情,这引发了一个想法。那就是这个想法:好吧,你知道,我有一个应用程序,一个游戏。你有一些你正在构建的东西,对吧?你意识到你对自己说:你知道吗?

也许这里最好的办法是从头开始。所以我想讨论一下我如何走到现在这个地步以及我做出的决定,然后我们将对此进行讨论。所以你们中的一些人可能知道,我已经开发一款游戏了,天哪,我不知道,到现在为止已经几年了。

断断续续地。这纯粹是我和我的朋友想要的游戏,他们有这个想法。它叫做 Project Hack。Projecthack.net 是你可以找到它的网站。并且……

我浏览了一遍,我会稍微分解一下。我构建了第一个版本。它很棒,完成了我的所有期望,但它只打算作为第一个版本来查看,首先,这个想法是否可行?其次,我能实现更大的计划吗?现在,这是一个单人游戏。这是一种闲置风格的游戏。我不会详细介绍所有细节。你可以访问 projecthack.net 查看。你会明白的。

但是当要构建我所谓的“更大、更合适的版本”时,我一直希望它成为多人游戏,因为这是驱动想法之一。我面临着这个决定。我最初是在学习 Unity 时用 Unity 构建这个游戏的。我就是这样学习用 Unity 制作游戏的。所以你可以想象,我做错了很多事情。

当我回到代码库并查看它时,我想,好吧,你知道吗?我无法保存这个代码库。或者我可以,但我必须基本上理解一年前我做了什么,然后才能开始重建它并构建新内容。那时,我可能应该从头开始的想法就出现了。现在,我决定从头开始。

这还给了我一个机会去尝试很多不同的游戏引擎来制作同一个游戏,以找出我最舒服的引擎,哪个引擎最适合这个游戏。同样,这可以应用于应用程序,所有东西,对吧?我知道我有了,我学习了新的技术。我学会了如何做事情,很多事情做得更好,因为在那段时间里我也成为了一名更好的程序员。

因此,你知道,我又想,好吧,你知道吗,在这个时候,我可以花几个月的时间试图重新学习我用可视化脚本语言编写的旧代码库,并用 C# 重建它,因为这就是 Unity 使用的语言。这就是我想要走的路线,以便让它适用于很多基本上用可视化脚本很难完成的事情。所以是的,

这就是我决定从头开始的原因。这让我们今天在这里讨论了这样做的一些优缺点,对于你们中的一些人来说,你们可能也在同一条船上,对吧?你遇到了一些问题,一些障碍或其他什么。也许你继承了一个应用程序。也许你从其他人那里购买了一个应用程序。你现在正在查看这个代码库,这个陌生的代码库,说,我应该做什么?我应该从头开始还是应该……

继续尝试使现有的代码库工作。这就是这里的背景故事。很明显,我对这个问题的看法是,有时从头开始是好方法。但是 Jeff,我认为你对这个问题有不同的看法。你怎么看?

是的,我的看法恰恰相反。从头开始完全重写,我将用“几乎”这个词来补充说明,但我感觉这个“几乎”是完全微不足道的,很小,中学水平的。不是正确的方法。好的。你几乎,几乎,几乎,几乎永远不应该完全重写某些东西。让我说,你知道,我将……

在这里稍微食言一下,并说,你知道,我从经验中吸取了教训,我已经多次完全重写了东西,而且它从未奏效。我坐在那里,我想,嘿,你知道,这似乎是那些我应该回去重写的时候之一。而且它几乎总是错误的。嗯,

我认为我将在本次对话中提到最多的一个将是我去年对 Kineo 进行的大规模重写。我认为这

似乎符合你可能想要进行大规模重写的各个方面。我将其移植到不同的平台。我在使用 Apple 最新的用户界面设计方面使用了 SwiftUI 而不是 UI Kit。我为该应用程序添加了许多新功能,但事后看来,

我不应该进行干净的重写。我应该改为逐步迁移,根据需要将其分解,而不是为 VisionOS 创建应用程序的全新版本。好的。我可以问一个问题吗?因为我觉得我需要一点澄清。因为我听到你说,我认为我听到你说你正在为一个新平台做这件事,对吧?我正在为一个新平台做这件事。所以……

我的问题是,为新平台做这件事怎么能不是从该平台的底层开始呢?你明白我的意思吗?

好吧,好的,所以它仍然是 Apple 平台。哦,好的,好的,所以它不像 Android。我可以重用,是的。我将其从 iOS 和 iPadOS 移植到 Visual OS。明白了,因为那将是我的后续问题,好吧,等等,当然你使用了不同的技术?这里的答案是否定的,相同的平台。好的,明白了。老实说,对于很多这些事情来说,它可能仍然是正确的。你可能仍然能够迁移现有内容,但我感觉这比我们在这里想要讨论的要复杂得多。

好的,这就是答案,朋友们,对吧?我们有两种不同的意见,这将带来一场精彩的对话。那么,你为什么认为最好是,你知道,利用你现有的东西并进行改进呢?我不想用“重构”这个词,因为我认为这是错误的。但是,为什么最好是利用你现有的东西并继续使用它呢?你知道,无论是错误、糟糕的……

任何代码,糟糕的模式,以及继续使用它。因为对我来说,这听起来像是,你知道,你正在浪费时间去做一些事情,好吧,你可能在那里拥有所有逻辑。你可能拥有应用程序的功能,对吧?所以你基本上拥有应用程序的骨架,你将用新的、新的代码、新的任何你想要的东西来刷新它。那么,你为什么认为这是可行的方法呢?

我认为你已经为我做了我的论证。哦,该死。是的。所有这些东西都已经存在。是的,你可能已经学习了更好的方法。你可能已经学习了一种更好的方法。但是你拥有的……

大概至少在某种程度上是有效的。因此,你可以将其保留在那里,并在其周围构建支架。你可以说,好吧,我需要添加这个新功能,或者我需要改进它的一些现有部分。你可以在构建它时将其他所有内容保留在那里。你曾经用过一个术语,你说你正在浪费时间。但我感觉

完全抛弃它的方法是它本身就是在浪费时间。你正在浪费时间重新实现你已经拥有、你已经完成的事情。为此,是的,它们可能并不理想。没有什么东西是完美的。没有代码是完美的。你可以坐在那里,你可以把它放在墙后面。你可以坐在那里说,这段代码,我们知道这段代码很糟糕。

并尽量避免尽可能多地接触它。但它仍然在那里。它在某种程度上仍然有效。因此,拥有你无需花费时间从头开始重写的代码是值得的。好的,我们聊天室里有人,我们在录制这段视频时,我们的 Discord 上有一个聊天室。嘿,如果你想参与其中,请加入我们的 Discord。我们将在节目说明中添加我们的链接。但他们指出,哦,好吧,你可以采用这种模块化方法。

但我认为这只有在你一开始就采用了良好的模块化方法的情况下才能奏效,对吧?这就是我为什么认为从头开始是好方法的原因之一,因为你的代码库可能如此交织在一起,像意大利面条一样,你根本无法解开这团乱麻。我不是说,你知道,不要破坏一切,因为你很有可能会破坏一切。

但这在某种程度上就是重点,我想,对吧?

但我所说的想法是,是的,你正在抛弃代码,但你并没有抛弃你已经解决的所有问题,这意味着你最初应用程序中的业务逻辑和规则以及所有内容仍然存在。你只是将它们用作模板,用新的技术构建新的应用程序,对吧?我的意思是,我认为……

我会说,我认为用相同的技术重建是不值得的,对吧?我觉得这有点像,好吧,你最终会回到你之前所在的位置。你为什么要这样做呢,对吧?但我认为这就是我从某些方面得出的结论,有时试图解开意大利面条比……

承认它在那里并构建它,构建它背后的想法和理念,但以一种更新、更清晰的方式。是的。让我一次解决几个问题。你说你正在抛弃代码,但你并没有抛弃业务逻辑。我认为对于很多人来说,……

业务逻辑就是你的代码。你可能没有像对错误进行逐一匹配那样详细地记录你的代码,这里是我做出的每一个选择,这里是我做出的每一个决定,这里就是这种程度。当你重新创建这样的软件时,你将进行更改。你将做出不同的事情,除非你完全理解你的代码,达到

为了重新创建你已经创建的业务逻辑,你必须理解你根本不想做的代码的程度。好的。解开那团意大利面条。当然。我应该在这里说,是的,我同意,如果唯一的规则或……

无论你想称之为什么是,你必须遵循的文档是关于这个应用程序是什么、它是如何工作的以及它是如何构建的,那就是没有文档的代码。那么,你知道,从我的角度来看,你知道,无论哪种方式你都处于困境中,对吧?你必须在修复或重新启动之前进行反向工程。

不幸的是,很容易坐在那里说,当然,我们没有人会这样做,对吧?但是是的,我们都会。我们都做过。我想在这里补充一点,我现在很好奇,无论它是你构建的应用程序,也就是说你,你的团队,无论对你来说这意味着什么,

还是你从其他人那里继承的应用程序,你的意见是否相同?你会说对两者来说意见都一样吗?鉴于此……我会说……对不起。鉴于你可能继承的应用程序,代码是你拥有的所有关于这个东西的功能的东西?是的。我会说,如果代码是你继承的所有东西,那就几乎要加倍强调,你不应该重写它,因为你已经拥有了它。但我认为没有人……

能够如此好地理解他们自己多久以前写的代码。嗯,有句老话,呃,意识到当你编写代码时,以后必须维护它的人知道你住在哪里。是的。是的,这是真的,因为是你。是的。而且,就像我一样,我感觉,

这将是一个问题。无论是谁写的,还是你写的,过去的你都是其他人写的。绝对的。他们是一个完全不同的人。显然,你谈论重写这个的全部原因是因为你当时做出了现在不会做出的决定。所以我认为没有多少理由……

将这两件事区别对待,说,嘿,你知道,无论我是否重写了这个,对不起,无论我最初是否写了这个,或者其他人最初是否写了这个,我之后只是在维护它,我觉得这些东西足够相似,不,在这两种情况下,我都会避免重写。好的,所以。

对我来说,这也会——我明白你在说什么,对吧?因为如果我理解正确的话,我们可以说,嘿,无论我选择哪条路径,六个月后的我仍然会——会用现在我审视六个月前的我的同样的眼光来看待现在的我,对吧?对。

是的,不,我完全明白。是的,不,我理解。而且,嘿,你知道,无论我现在决定什么,六个月后都会像六个月前一样错误,只是原因不同。我认为这就是你所说的,对吧?现在,回到模块化的想法以及解开意大利面条,就像那样,我

我同意这通常是你应该朝着这个方向前进的方法,并且使事情更模块化确实使你在进行这些重构时更容易进行。但我认为这不是一个理由……

如果它没有模块化,你应该完全抛弃已经存在的东西,我将参考一本很棒的书,呃,我用马丁·福勒的重构编写,我用迈克尔·费瑟斯的有效使用遗留代码编写,这很有趣,你知道有效使用遗留代码是我的亚马逊阅读清单上的一本书,有一天我会读的,它是一本非常棒的书,你绝对应该阅读这本书,我们将让大家……每个人都应该知道这一点,是的

这两本书都强烈推荐。你应该阅读这两本书。好了。句号。我试图记住哪一本特别提到了我想提到的内容。是的,它是有效使用遗留代码。在我的副本的第 30 页。在书的开头。似乎。好的。是的。所以这个想法是,你所做的是获取该代码,你已经拥有的那大块意大利面条代码。

你获取该代码,你将其放入模块中。这就是你的一个模块。你可以将这个模块称为任何你想要的东西。在我的项目中,当我回去做这样的事情时,我倾向于将其称为核心或遗留或类似的东西。你,你把它放在一边,你把它隔离起来。然后你对该代码所做的操作是,当你需要该代码的部分时,当你需要将其引入你的现代架构、你的现代重写、你的现代任何东西时,嗯,

你进去找到接缝。你找到你可以说,哦,我可以在此处插入一个注入点的地方。注入是指依赖注入或类似的东西。我可以使用我的新代码连接到这段代码。我可以在这里插入。这是我的入口点。你进去找到它。然后一旦你在那里找到了接缝,它就会非常像一个……

我不知道,雕刻一块石头,从大理石中雕刻出一些东西。你在那里有你的凿子。一旦你在那里有了你的凿子,你就可以开始挑选了。你可以取下一块。这就是你解决这段意大利面条代码的方法。你一次取下少量。你进去,你说,哦,这段业务逻辑,我可以将其分离出来。我可以在那里建立一个连接。然后使用该连接,我可以开始撬开这一部分。现在这一部分……

再次,仍然是一种自包含的模块,可能在其内部。它并不漂亮。这不是你想要的,但你可以将这小部分提取到你的新架构中。

然后一旦你将这小部分提取到你的新架构中,你就会有一个更小的界面来与之交互。你有一个更小的事情需要与之通信。你知道当你有一件小事情需要与之通信时你会得到什么吗?你可以为它编写测试。你可以围绕它编写单元测试。然后一旦你围绕它编写了单元测试,你就知道你可以用它做什么了吗?然后你可以重写这小部分。你重写这小部分,你使这小部分更好。你已经完全对其进行了单元测试。你已经

你已经能够在整个项目上取得进展。哦,所以你已经能够构建你仍在做的一切,并且你能够随着时间的推移进行改进。

好的。好的。

你已经,你已经能够在整个项目上取得进展。哦,所以你已经能够构建你仍在做的一切,并且你能够随着时间的推移进行改进。

无需后退,花费大量时间重写所有这些部分。休息时间到了。大家好。我是 CompileSuite 播客的 Peter Whittem。我想告诉你关于 Setapp 的信息。Setapp 是一项服务,每月只需支付 10 美元的订阅费,你就可以访问超过 200 个 Mac 应用程序,现在它也作为该交易的一部分在 iOS 上可用。

我使用这项服务,因为它有很多我经常使用的真正优秀的一流应用程序。对我来说,作为一名开发人员,能够访问用于 API、项目规划、编写电子邮件、编写文档的工具非常宝贵,你还可以获得所有这些东西,包括数据库应用程序,所有这些都在 Setapps 服务上,每月只需 10 美元。你可以根据需要使用任意数量的应用程序。

如果你有兴趣查看此内容,请访问 peterwhitam.com,P-E-T-E-R-W-I-T-H-A-M.com/setapps,S-E-T-A-P-P。你可以在那里查看详细信息。它有一个链接,你可以通过它开始使用这项服务,并查看它对你来说是否有效。我强烈推荐给每个 Mac 用户。休息时间结束。一次全部。好的。好的。这听起来……

与他们在聊天室里所说的非常相似。你知道,就,哦,是的,让我们把它隔离起来,然后……看,你知道,对我来说,就像在聊天室里他们说的那样,稍后重构它。这让我对这件事感到困扰的部分是,不,如果你现在要费这个劲,那就现在重构它。对吧?但是……

但是你正在谈论的部分,对吧?模块,无论你如何表达它,对任何人的意义是什么。我不同意这一点。我认为,公平地说,这是否是我们在迁移到 Swift 时所做的大部分事情?

好的,好吧,我将把这个控制器从 Objective-C 重写为 Swift。我将用 SwiftUI 重写这个视图,而不是它是什么,故事板地狱,对吧?一个接一个地挑选它们,因为这也是一种允许我们这样做的技术,对吧?但我认为,对于很多人来说,回去说,你知道吗?

Swift 是新事物。Swift 是新的热门事物。Swift 很酷。我们需要做的是完全抛弃我们所有的 Objective-C 代码,不要查看它,并根据我们之前的内容从头开始用 Swift 构建一个新的应用程序。好的。我认为,人们不认为这是一个好主意。我,我坐在那里试图说,如果你认为这是一个好主意,呃,你错了。嗯,

不,因为我认为这是错误的。但与此同时,就像我一样,我感觉,我会有人反驳。他们会说,哦,不,这绝对是一个家伙。事情变得尴尬的地方就在这里,因为我必须越过栅栏的另一边,站在你这边,因为那是,那是我的经历。对。我仍在经历的是,是的。你知道吗?嘿,猜猜怎么了?公司不会给你时间从头开始,你知道,所以我经历过,是的,它,

但这非常痛苦,因为你还必须尝试挑选合适的部件来开始。就像你说的,我同意这个想法,好吧,你知道,这有点像建房子,对吧?让我们首先确保核心基础是好的。否则,一切希望都破灭了,你知道吗?所以我明白了,但我不知道。我认为对我来说,

一些吸引力,我承认这一点,我认为从头开始的部分吸引力是选择不同技术的自由,但肯定是一种不同的方法。但我同时也理解并承认,有时,好吧,首先重构这部分,你

是可行的方法。因为有一个非常好的理由来保持产品存活。但我也在想,嘿,无论你走哪条路,你都在保持产品存活,对吧?因为如果我正在启动一个全新的应用程序,旧的应用程序仍然可以进行修补、更新和发布。而如果我……

和工作,是的,我可以创建一个新分支并致力于迁移该代码并改进该代码以及你想使用的任何术语。但我仍然必须确保它以某种方式是可交付的,对吧?与知道它随时都可以交付相反,因为我没有接触现有版本。我明白你可能不同意这一点,但你明白我的意思吗?我明白你的意思。但我……

不相信你。没关系。只要你明白了,我会编辑一下,这样听起来你好像说,是的,是的,不。当你谈到保持项目存活时,保持项目存活,保持应用程序存活。嗯,

你谈论的是,哦,好吧,我们可以构建这个新东西,我们也可以同时修补另一个。问题是,你用于进行此重写的每项资源都是未用于修补、进行新功能、进行所有这些工作的资源。如果你有无限的资源,是的,你可以同时进行两个完全正在进行的项目。对。

你会遇到这样的问题,哦,好吧,这个应用程序将需要这个新功能。好吧,你现在是在同时为旧应用程序和新应用程序构建该功能吗?因为你正在构建两次,因为你必须在这两个地方都构建它。所以我认为在那些时候,你实际上是在花费大量时间仅仅只是进行此重写。

无论你是否同时拥有两个流,你每天都有相同数量的工程小时数。你需要说,我用于仅仅重写已经存在的代码的任何工程小时数都是我无法用于仅仅进行改进、仅仅进行错误修复或新功能或任何其他类似的事情的工程小时数。是的。而且你确实……

至少从我坐的地方来看。在某个过程中,某人,通常是我,你必须向其他人解释为什么以及你在哪里浪费这些时间。例如,让我们从稍微不同的角度来看待这个问题。

你知道这个应用程序的保质期有限,也许它只打算存在一段时间或出于特定原因,然后就会被淘汰。当然,这绝对不是你想重写的东西。我会预先声明,这完全是浪费时间。你知道,这绝对是,你知道,

维护它,让它保持活力,直到它需要保持活力为止,然后让它消亡。不要不必要地浪费时间。而且我实际上会更进一步地说,不要在这两条路径上不必要地浪费这些时间。你知道,我会说,重构某些东西也绝对没有必要。

除非你必须这么做,对吧?一些严重的bug,一些安全漏洞,无论是什么。但如果你的应用程序有一个有限的寿命,这可能根本不应该考虑。你应该让它继续运行,然后让它消亡。但如果你的应用程序或应用程序有无限的寿命,你知道,嘿,据你所知,它将永远存在。嗯,

这就是这场对话的意义所在。但我认为……我不知道。我不得不说,我觉得你可能有点让我动摇了。但我认为我仍然会根据每个应用程序来评估,好吧,这里哪条路最好走,对吧?因为我仍然觉得,对我来说,我觉得有一些场景,代码库可能太旧了,以至于……

它并不是说它无法挽救,而是它不值得。我仍然可以挽救它,但我仍然会留下技术债务,关于它的工作方式和它在做什么。明白了吗?是的。我绝对百分之百理解它的吸引力。就像我说的,我自己也做过。我绝对理解为什么有人可能会认为,嘿,你知道,把这一切都扔掉然后重新开始是个好主意。

问题是,再说一次,这一切都取决于你拥有什么资源?你的时间最好花在哪里?我认为,如果曾经有过的话,这种情况非常非常罕见,那就是我们需要再次做某事。

比我们需要利用我们现有的东西并使其变得更好要好。好的。好的。是的。

好了,这就是全部,朋友们。我们开始时就知道我们都有不同的观点,这很好。我认为这些观点可以进行良好的对话。我觉得我们双方都对双方都提出了相当好的立场。我们从未承诺会为你找到答案。自己做出决定。

但拥有两种不同的观点并从中学习是很好的。如果你想告诉我们你的观点,嘿,你知道吗,杰夫,他们在哪里可以找到你?你可以在Cocotype.com找到我,它很快就会进行重大改版。它实际上包含更多链接。更多链接,朋友们。是的。当然,你也可以在PeterWhitam.com找到我。现在,这是个惊喜,朋友们。你们没想到吧。

在下一集里,我们终于到达了旅程的终点。我们经历了高潮和低谷。我们去过喜马拉雅山脉,去过最深的海底。我们找到了新的名字和品牌,我想,这将与播客一起使用。所有的一切都将在下一集揭晓。所以,嘿,你知道吗?如果你还没有关注和订阅,你应该去做。