我的团队正在开展一个转换项目,将一种产品(但有很多方面)从 VB6 转换为 .Net(我们有超过 300k LOC)。在我加入之前,我决定不管程序集的位置或文件夹结构如何,所有类/结构都将位于一个命名空间中:
.
他们甚至会更改自动生成的应用程序设置设计器代码、资源设计器代码等以强制统一。我如何说服他们使用命名空间是好的?命名空间的正确使用是什么,优缺点是什么?我想我很难理解为什么我的同事会经历如此多的麻烦来节省一些使用线。任何支持您的论点的外部、有信誉的参考将不胜感激。请帮忙!
我的团队正在开展一个转换项目,将一种产品(但有很多方面)从 VB6 转换为 .Net(我们有超过 300k LOC)。在我加入之前,我决定不管程序集的位置或文件夹结构如何,所有类/结构都将位于一个命名空间中:
.
他们甚至会更改自动生成的应用程序设置设计器代码、资源设计器代码等以强制统一。我如何说服他们使用命名空间是好的?命名空间的正确使用是什么,优缺点是什么?我想我很难理解为什么我的同事会经历如此多的麻烦来节省一些使用线。任何支持您的论点的外部、有信誉的参考将不胜感激。请帮忙!
我读了很多很好的答案(例如,驱动器文件夹的图像很好,对象/概念分离/组织也是如此)。
尽管如此,其他一些不那么“技术性”的论点可能会有所帮助,不是解释为什么命名空间比替代方案更好,而是找出不使用命名空间的坏原因。
每个 C#、VB.NET、Java、C++,无论在这个星球上什么值得一试的开发人员都承认命名空间/包是一件好事。嘿,他们甚至在 Mozilla 的 JavaScript 中考虑它。
我猜你关于 Stack Overflow 的问题有“权威论据”的感觉...... ^_^
我相信你正在陷入“旧习惯”的情况。
虽然我没有关于 VB.NET 与 VB6 旧习惯的直接经验,但我对 C++ 反对精简的 C 类 C++ 有经验。
在处理遗留习惯时,一半的工作是发现他们已经使用命名空间,而没有承认这一点。
例如(这对于 C++ 开发人员与“旧时尚”、类似 C 代码的冲突最为正确,但我猜它在任何地方都是可行的),他们是否使用前缀作为符号。
他们有没有:
类/符号,并解释帐户的“用户”与登录的“用户”不同,因此,区分它们的前缀?
当“模式”按模块为其符号添加前缀时,“模式”会直接穿过天花板(如果代码足够大,这肯定是您的代码的情况):
您有 MyUtil DLL、MyKernel DLL 和 MyGui DLL 吗?因此,您是否有:
类/符号?
如果是,那么他们应该承认他们已经在使用命名空间。
如果不是,那么您的代码库太小(但您的“9 个项目”告诉我不是),或者它们经常是名称冲突的问题......这可以通过上面解释的前缀解决,或者更好的是,通过命名空间。
另一半的工作是让他们解释为什么他们的“命名空间”比语言中内置的更好(这是你应该避免因为致命的暴露脑死亡推理而沮丧地撞到墙上的那一刻) .
同样,您可以使用按权威论证的事情(什么?您确实相信比微软的壮志凌云工程师更了解?),但在这种情况下,您应该举例说明为什么 .NET(或其他)命名空间比他们使用(或不使用)的那个。
对于 VB.NET/.NET,已经有足够多的好论据了,我不会继续讨论 C++ 命名空间背后的论据,因为它会超出主题。
但至少,使用内置命名空间使上述前缀成为可选的。引用互联网上的一个例子(我对 VB.NET 不是很了解):
Imports MyWholeProject
Class HelloWorld
Public Sub Main()
Dim o As MyModuleAAA_MyObject = New MyModuleAAA_MyObject
Dim t As MyModuleBBB_MyThing = New MyModuleBBB_MyThing
Dim g As MyModuleCCC_MyGizmo = New MyModuleCCC_MyGizmo
REM etc.
End Sub
End Class
比启用的命名空间更详细:
Imports MyWholeProject.MyModuleAAA
Imports MyWholeProject.MyModuleBBB
Imports MyWholeProject.MyModuleCCC
Class HelloWorld
Public Sub Main()
Dim o As MyObject = New MyObject
Dim t As MyThing = New MyThing
Dim g As MyGizmo = New MyGizmo
REM etc.
End Sub
End Class
冗长会导致更晦涩的代码,从而导致错误。当然,您可以将 MyModuleAAA 替换为较短的内容,例如 MMAAA ......但是,它会导致代码更加晦涩,等等。
谷歌搜索可以找到 .NET 上命名空间的更多用途,例如:http ://www.vbdotnetheaven.com/UploadFile/ggaganesh/NamespacesInVbDotNet04202005005133AM/NamespacesInVbDotNet.aspx
这些原因与项目/职业管理更相关......
如果您的应用程序是一头垂死的老牛,更改标签或组合的内容值得 2 天的工作(确实会发生),那么重构的额外工作可能没有意义。另一方面,如果重构是自动化的,那么无论如何你都应该这样做。
但是,如果您的应用程序应该在将来使用,那么破坏它以将其保留在过去是一个坏主意。总有一天你会为此付出代价的。避免维护应该赢得的每一小时将在不可避免的那一天获得两倍或十倍的报酬(你知道,因为紧急而没有时间正确完成它的那一天......)
这个论点适用于有职业并且必须保住工作的工程师:像应用程序一样,软件工程师可能会过时。
这意味着过时的开发人员在申请另一份工作时也会失败。因为,嘿,谁愿意为没有像命名空间这样简单的东西买单?
经验与当前最新技术的知识相结合是一件好事。如果不是,那么这只是恐龙时代的愤世嫉俗和无用的漫谈“在我的时代,当我们不需要所有那些像物体这样的小玩意儿时,它是如何变得更好(阅读:更简单)”。
通过拒绝适应语言的新特性(通常是因为“我们知道得更好,你知道吗? ”),工程师只是在穿上混凝土鞋,而竞争对手可能在穿上跑鞋。这意味着一个过时的团队制作的应用程序最终会失败。时期。
以类似的方式,该团队将聘请新工程师,他们可能知道这些功能,并且会感到惊讶,然后对他们只是像他们的祖母几十年前所做的那样编程这一事实感到沮丧。过时的团队不会留住新工程师很长时间(至少,那些值得他们付出的人)。
请注意,开发一个过时的产品使高层管理人员更容易决定从头开始重写它会变得更容易......而且可能在其他地方,与薪水较低的工程师和管理人员......
命名空间的正确使用是为逻辑分组的类、接口、枚举等提供有序的结构。这就像将所有文件放在一个文件夹中......或者更糟糕的是,将它们全部放在 C: 驱动器的根目录中......
我绝对不能指出你的团队非常短视,我并不是真正开始质疑其他团队的政策和程序的地方——但如果我处于你的位置,我会坚持下去。
希望您的团队了解面向对象的设计原则。您将相关信息分组到具有对该信息进行操作的类中。命名空间是(或应该)相似的。您使用命名空间将相关的类组合在一起,它们一起提供操作以处理命名空间的集体信息。
这有助于代码的可理解性。将数据层类分组到单个命名空间中将它们标识为相关的,并且以某种方式相关以提供命名空间指示的功能 [顺便说一句,这就是为什么您需要为命名空间和类提供有意义的名称]。如果您将所有类分组在同一个命名空间中,那么这一切都会变成一团泥。您已经丢失了代码组织的语义线索,必须深入研究以找出哪些类协同工作以提供所需的功能。
关键是:这不仅仅是个人喜好的问题。就像您不能期望将所有句子都放在一个段落中一样,而是必须将它们组织成几个段落,其中句子是相关的;你需要把你的类组织到命名空间中。将您的写作分解成相关句子的段落可以提供清晰性和意义,将您的类分解为命名空间可以提高代码的清晰度。随着班级数量的增加,这只会变得越来越重要。
虽然您完全正确地认为命名空间是好的、有益的和完全必要的,但听起来已经付出了相当大的努力来建立您团队的现状。我认为你有机会推销这个想法的唯一方法是:
确定没有命名空间的成本(可维护性、调试等),并让执行管理人员参与进来。
自愿创建命名空间约定并完成所有工作以转换项目。
不幸的是,根据我的经验,一旦建立了像命名空间约定这样普遍的东西,就需要国会的行动来改变它。
就像许多人指出的那样,代码的易读性和组织性。
将类似名称的类分隔到不同的“空间”中,例如 Network.Session、Meeting.Session、WebServer.Session 等。在现实世界中,有许多对象具有相同或相似的名称。这就是为什么名称需要自己的空格来限定它们的原因。如果使用得当,命名空间还有助于程序集的命名,例如System.Web.DLL和System.Messaging.DLL。这有助于代码重用,因为您将代码分成更小的功能块 (DLL),可以根据需要包含这些块,而不包括整个巨大的块(或混乱)。
命名空间是分隔不同项目、用途和类别的代码的边界。在共享和重用许多 DLL 文件的大型项目中,程序员需要一种易于记忆的方式来引用正确的类,并避免引用错误的类。如果微软决定将所有的 .NET 类放到一个单一的“系统”命名空间中,人们能想象这种难以控制的疯狂吗?程序员怎么会开始编写代码来调用这些类?此外,您将需要处理名为WindowsFormsTextBox和WebUIWebControlsTextBox 之类的类或比这更长的名称。拥有适当的命名空间有助于程序员快速安全地编写代码。
命名空间的好处在大型项目中变得更加明显,或者当小型项目逐渐变得大到成为问题时。您可以查看当前项目的规模,并确定您需要多努力地扭转同事的手臂。
对于某些人来说,再多的逻辑论述都不会像物理类比那样令人信服。
所以,当每个人有一天都在吃午饭时,把他们所有的书从办公室和书柜里拿出来,然后堆放在会议室的桌子上。一定要把电脑书和漫画漫画和一个月前的 MSDN 杂志等彻底混为一谈。
告诉他们这是拥有一个命名空间的物理表示——会议桌是命名空间,书籍是模块/类/项目。
然后让他们在书堆里找到关于遗传算法的书。(确保你把它藏在堆的底部)。
如果他们仍然不明白,放弃并开始寻找另一份工作。你不想和这么厚的人一起工作!;-)
如果您的代码是洗衣房,那么您将有两种选择,或者您可以将所有东西都放在一大堆中并在每次需要时通过它进行检查,或者您可以将衣服放在办公室里。
如果我有一个设计良好的命名空间方案,代码文件顶部的 using/Imports 语句会记录我在此文件中使用的内容。
如果您必须说服他们拥有分区命名空间而不是简单的“唯一真正的命名空间”是一件好事,那么这似乎表明您可能无法说服他们相信它。说实话。
如果开发人员对 VB6 和现有 VB6 项目的结构感到满意,那么将移植的项目结构与原始项目非常相似可能是有意义的,即使它损害了 .net 中的一些最佳实践。(我假设 VB6 不支持命名空间?)当新的代码库稳定并且开发人员更熟悉 .net 时,可以稍后引入命名空间。
他们认为命名空间有什么用?他们为什么认为 BCL 使用它们?