为什么开源
Source: Dev.to
介绍
本文档说明了我为何会编写一个开源软件项目。原因众多且有趣。这是一篇关于我的历史的非技术性文档。
简而言之,创建开源项目的主要原因是我受益于使用其他开源项目。我理解了它们的价值,并决定也将我的项目开源。
我决定自行启动框架的动机源于公司可能会停止其产品——或者它们的产品生命周期在某个时间点结束。我常常发现很难跟上这种生命周期的步伐,所以我更倾向于长期使用较旧的产品。
我会不时扩展本文档,并在 GitHub Pages 版本中填入更多我的历史。
Lothar Behrens – Saturday, 20 Oct 2024
阅读至文末后——您想要一个 MFC 代码模板吗?
在本文的结尾,我得出结论,我将再次创建一个 MFC 应用程序。主要原因已在文中说明。
最可能的起点是一个基于 MFC 框架生成代码的模板。我的主要问题是:您想要它吗?
早期的计算机时代
我的第一台电脑是在我开始接受教育时买的。它是一台 IBM‑PC‑兼容机,只有 512 KB 的 RAM——在当时已经够用了。它运行 MS‑DOS 和 GEM。
在学习期间,我把能找到的每一本书都抓起来阅读,深入了解计算机的方方面面。
我用 BASIC(在我姑妈的 C64 上)学习编程。很早在我的学习阶段,我就意识到还有比 BASIC 更好的语言,所以我从未在我的 Schneider PC 的 BASIC 2(Locomotive Software)上做任何事。
编程起步
正如所述,我在接受教育前不久(或刚开始时)购买了第一台电脑,并很快偶然接触到一种面向对象的语言。它比 BASIC 更吸引我,于是我相应地做了下一次购买。
在学校,BASIC 是我们学习的语言,我常常比其他同学更快准备好——可能是因为我已经在 C64 上使用过 BASIC,它类似于 GW‑BASIC。
我的第一个软件创意
当我获得 Turbo Pascal 时,我也产生了第一个软件项目的想法。在学习期间,我收集了许多软盘,而仅靠纸张或贴纸来记录每个软盘的内容变得非常繁琐。
我编写了 dateiver —— 一个带有命令行界面的磁盘目录系统。即使在今天,Linux 上也有许多可以协同工作的命令行工具,非常实用,但我的应用是一个独立程序,并未设计为与其他工具互操作。
注意: 当时文件夹的名称不同。我没有很好地组织源码,后来导致了一些困难。
dateiver后来被复制到一个新应用Tvvt中。
那时我还学到了很多关于编程数据结构的知识,这对磁盘目录系统是必需的。当时我对数据库一无所知,所以我专注于数据结构、文件 I/O,以及遍历文件系统以读取磁盘数据。
对客户的首次尝试
在完成学业后,一位潜在客户联系我,询问我是否能够实现一个特定功能。我与客户协商了需求并交付了第一版解决方案。
然而,客户并不满意。界面仍然是基于控制台的,这让他们觉得不够美观。我当时还是个新人,未能达到他们的期望。
专业人士使用 SAA
Later, when I tried to market dateiver as a shareware version, I was told the application would not sell because it lacked a modern UI. The software dealer I approached was not interested in offering it in his store.
I learned that many customers (not just this one) prefer a graphical UI over a console UI. The shareware seller suggested I look at the fancy SAA UI toolkit, so I did.
To use SAA, I had to buy a newer compiler and migrate my code from Turbo Pascal 5.5 to Turbo Pascal 6.0.
我的首个模型驱动想法
在学习了 SAA 和现代 UI 概念后,我在一本书中发现了一个对话框设计器。它承诺能够帮助软件创建。我很快意识到我可以用它做更多的事情,于是创建了我的第一个模型驱动应用开发环境 TVBuild。
Pascal 之后的 Windows 与 C++
时间流逝,我需要一台更现代的电脑。继 Schneider PC 之后,我的下一次购买是一台子笔记本(当时首批 A5 纸幅笔记本之一)——仍然是只能运行 MS‑DOS 的机器。
随后我买了一台 386 DX 40 塔式电脑,装有 Windows 3.1,配备了惊人的 4 MB RAM。在这台机器上,我还购买了当时最快的编译器之一 Watcom 10.6,它因用于编译 Doom 而闻名。
使用 Watcom,我学习了 C++ 和 Windows 编程。我先从简单的 C API 入手,迅速转向面向对象编程,并开始使用 MFC。
那时我仍未接触数据库编程,于是重复了之前对数据结构的经验——这次在 MFC 中实现。我以 DrawCLI 为基础,为一个拥有真实蒸汽机车和历史列车的模型铁路俱乐部编写了一个应用程序。
Trainres 与 MFC 之旅
在新的编译器和俱乐部队友的帮助下,我写了一个火车预订系统——或者说我尝试过这样做。某位利益相关者想要类似车站里展示的地图的精美图示,但要做成缩小版的。那是 16‑bit Windows 3.1 时代,我的机器是 386 DX 40 MHz。
当时我已经把自己的知识发挥到了极限,渴望为俱乐部进一步开发这个应用。
截图(已描述)显示了一张网络列表,红色线条代表两条火车行程计划。应用在输入计划后会绘制相应的表格,允许用户在标题下方添加乘车时间表。
计划还包括使用这种图形化展示来存储数据。客户信息被输入到左下角窗口,并注册了火车行程 001。所有这些都是使用数据结构和 DrawCLI 基础实现的。
Trainres – MFC 版存活至 Windows 10
后来该应用存活到了 Windows 10 时代,现在可以使用 Visual Studio 进行开发。
Source:
开始学习数据库
使用 Watcom 10.6 和 MFC 一段时间后,我注意到一个更高级的开发工具:Power++,它来自 Powersoft。Powersoft 已经收购了 Watcom 的编译器工具和数据库组件,但我当时并不知道这件事。
Power++ 的营销宣传吸引了我,因为它承诺快速应用程序开发(RAD),并且内置了数据库,让我能够快速学习数据库。
我开始移植 Trainres
当我购买了 Power++ Developer(当时可用的最小版本)后,我开始将我的俱乐部应用程序移植到 Power++ 类库上。在此过程中,我花了更多时间构建复杂的图表功能,而不是数据库本身。事后回想,我忽视了作为专业软件开发人员职业生涯中最大的问题之一——我仍然不够专业。
图表功能之所以有趣,是因为我编写了自己的解释器,让用户能够设计自己的符号。数据存储在数据库中,我甚至在表中有了简单的客户条目。
Sybase 停止了 Power++
后来 Sybase 决定停止 Power++。我很沮丧——不仅钱白花了,我的移植工作似乎也成了死路。我立即停止了开发,因为再继续已经没有意义。俱乐部从未得到一个可运行的应用程序。
我吃了苦头才明白,公司并不总是关心他们的小客户。我从未弄清楚 Power++ 被停用的原因;还有一个我错过的最终版本。多年后我发现,Sybase 把 Enterprise 版提供给所有已注册的客户,即使他们只拥有 Developer 版。我后来回到了 Enterprise 版。
那时我必须重新思考我的开发方式。与此同时,我开始学习 Linux——当时的新潮事物。我也想在 Linux 上编程,于是研究了各种 API 和框架,最终选择了 wxWidgets,因为它免费且能节省我的时间。
在同时尝试 Linux 和 Windows 的过程中,我意识到想把应用程序运行在一台机器上,而另一台机器作为服务器,两者相互通信。客户端‑服务器编程于是成为下一个大挑战,建立在我之前的数据库工作之上。
那是 1999 年。长话短说——我启动了一个新项目,并一直在上面工作至今……
我的开源项目的诞生
我的新项目当时还不是开源的。我尝试创建一个 UI 包装层,使其不依赖任何特定的 UI 框架。我想要类似 CORBA 的东西,但由我自己构建,因为我已经不再信任那些在供应商更改时就迫使我重写代码的商业产品。
那时我有一份软件开发员的工作,积累了客户端‑服务器和数据库编程的经验。我还学习了 CVS,一种版本控制系统。跳入深水区让我获得了宝贵的经验,后来得到了回报。我从业余爱好者转变为专业软件开发者——仍然是个新人,但那是另一个故事。
开始我的开源项目
在我的 Windows 和 Linux 实验取得进展并完成了对大型项目的首次尝试后,我退后一步重新审视目标。范围太大,无法一次性全部攻克,我意识到最初的尝试不可能在我设想的规模上成功。
尽管如此,我仍然进行了完整的重写。大部分代码都是可复用的,我只需要让它们兼容新的设计。代码片段仍然可以在 CVS 项目历史中查看。
现在我已将仓库迁移到 Git,并保留了历史记录。这次 Git 迁移是我在长时间停顿后重新启动开发的当前工作的一部分。我又遇到了另一个致命问题——CVS——但那是另一个时候的故事。
Why I Started an Open Source Project
产品通常会提供自己的框架。这些框架可能在其他产品中也可用,但不能保证不需要移植工作。
如果某个产品没有通用框架——比如 MFC(在 Watcom 和 Microsoft Visual C++ 之后使用)——你就只能使用它的专有框架,并有被锁定在该产品线的风险。这不仅仅是锁定(Power++);当 Sybase 决定放弃该产品时,它甚至成为了致命障碍。
有了自己的框架,我可以像这些公司一样做同样的事,但由我掌控。我可以继续使用它,以自己的节奏做决定,并且仍然公开发布。该项目已经启动、重写、公开,并且在稳定状态下保持活跃开发。我把它设计得类似于 COM 或 CORBA,使用纯抽象类(即接口)。正是这种设计选择使得项目至今仍然存活。
当前状态及其仍然存活的原因
今天该项目仍然活跃的主要原因有两个:
-
模块化设计 – 在早期,我将最初的设计重写为一个完全模块化的软件系统。我理解了 COM 所展示的内容:它的接口设计技术。COM 的接口只定义一次,且永不更改;如果需要更改,就会创建一个新接口(通常带有版本后缀)。我采用了类似的方法,使用 C++ 纯抽象类,而不是低层的 C 风格绑定技术。
-
个人利益相关者 – 我是该框架的主要使用者。它提供跨平台能力(macOS、Linux、Windows)以及一种模型驱动的软件原型开发方法,使我能够快速开发数据库软件原型。这一能力在之前的 Power++ 迁移中缺失,导致产品未完成。
现在,我可以从 UML 模型(即主应用本身)生成一个现代外观的应用程序,使用完全不同的语言和框架。
为什么 MFC 能够存活至今?
MFC 曾是过去的主要 UI 工具包,微软在其旗舰产品——“摇钱树”中使用它。对这些项目投入了巨额资金,因此微软坚持使用该技术。
- 大量的遗留代码库使得微软在短期内不太可能放弃 MFC。
- 开发者常常停留在较旧的 Visual Studio 版本,以避免破坏现有的 MFC 项目。
- 微软继续依赖提供 MFC UI 改进的供应商。如果该供应商遇到困难,微软可以收购它,这将进一步巩固 MFC 的未来。
- Ribbon UI 等功能仍在使用 MFC 开发,Office 本身也可能使用该框架。
为什么我要提到这个?
我的开源框架(或者说基于它构建的主应用)在 Windows 机器上看起来有点过时。我计划通过创建一个商业衍生版,仅在 Windows 上进行全新改版。
为什么我再次使用 MFC?
MFC 现在提供的现代 GUI 功能是当代应用程序的关键。我也希望支持基于 MFC 的原型开发。
是否有商业 GUI 库的后盾?
是的。不过,我的框架旨在避免锁定。通过保持架构的模块化,我可以:
- 在需要时集成诸如 DevExpress 等商业库。
- 尽可能重用我已有的 C++ 代码。
模块化设计赋予我灵活性,让我能够选择最佳的 UI 工具包,而不受单一供应商的限制。
结论
这就是我为何开始开源开发的故事,对项目未来的简要展望,以及我目前的活动。欢迎随意探索代码:
- lbdmf 仓库 – 尽可能贴近我的开发工作流(目前正在迁移到 Git)。
- 其他仓库 – 过去工作的快照,结构不够完善,纯粹为趣味而共享。
感谢阅读!