在C#中编写新项目时,我创建了一个包含所有动态创建实例的公共静态列表。让我给你一些代码来澄清我的意思。
class myClass
{
public static List<myClass> ListForGlobalUse = new List<myClass>();
public myClass()
{
ListForGlobalUse.Add(this);
}
}
我这样做是因为我需要其他类中的实例,并且我认为它比在每个类中创建List更方便,更容易阅读。
现在我很好奇这是否合法,或者这可能是(出于任何原因)一个坏习惯。 也许有人也可以解释它是如何影响汇编代码的,因为静态对象和方法分配在内存中与动态对象不同的位置。
也许我选择了错误的标签,但我真的不知道哪种标签最合适。
答案 0 :(得分:1)
这是合法的,没有律师可以起诉你。
但是,它实际上只是一个全局对象,而且它们在任何地方都很容易使用,将代码中的所有内容拼凑在一起。
你在开始时节省了一些写作工作,但从长远来看,你会越来越高,你会后悔你的超紧密耦合。
您始终可以将对象作为构造函数或函数的参数传递给调用树。如果某个类是对象的唯一用户,那么只有该类应该知道或拥有它。
个人陈述: 至少在过去的10年里,我不记得我需要一个全球物体的情况;好的效果是我从未遇到任何与这种最糟糕的耦合有关的问题。
示例:的
假设您有数据库连接;称之为mongoConnection
:
global:
MongoDB mongoConnection
您的商业模式中还有getCustomers
功能:
business-module:
getCustomers (arguments)
... mongoConnection.fetch("customers") ...
但是,有人还没有读过mongoConnection
应该如何使用,但因为她/他/它熟悉MongoDB
,她/他/它认为这不是问题,现在到处使用它:
// core.cs
mongoConnection.fetch("customers")
// misc.cs
mongoConnection.fetch("customers")
// foobar.cs
mongoConnection.fetch("cutsomers")
// api/web/authentication/local/core/foo/bar/core.cs
mongoConnection.fetch("customers")
因此,您现在不再使用干净的Customers-API,而是全面传播实施细节,因为有人比客户API更了解MongoDB
。
暂时没问题。
但在三个月中,您意识到您对customers
的定义很糟糕。您将其重命名为users
并更改所有字段的名称。
您进行全局搜索和替换:
// core.cs
mongoConnection.fetch("users")
// misc.cs
mongoConnection.fetch("users")
// foobar.cs
mongoConnection.fetch("cutsomers")
// api/web/authentication/local/core/foo/bar/core.cs
mongoConnection.fetch("users")
然后您手动完成代码,调整所有查询字段。这是一个在中型项目中工作的蠢货。更改后,您将发布代码。
三个月后,一位客户抱怨说广告宣传的Foobar模块不起作用;怎么可能,这一切都编译好了。
您调试并修复...
// foobar.cs
mongoConnection.fetch("users") // fix: not cutsomers, but users
...并释放。客户再次打电话,称你为欺诈和白痴。他现在想要退钱了。
嗯。哦,废话,你忘了也调整foobar模块中的所有重命名字段。你解决了这个问题你好几个小时跟客户说话。
然后你决定添加单元测试,这样就不会再发生这样的事了。一切正常,你有夜间测试和一切。
三个月后,您的应用程序已经发展到100 KLoC,现在测试运行了几个小时,这使得它们对于手动编程人员的使用毫无用处。您的测试数据库也已满。您意识到在模拟数据库连接上运行测试会更好,这些测试只需要测试所需的内容。
现在请记住,您可以在大约121个源文件中随处传播直接数据库连接。其中许多源文件正在将数据库连接传递给一些用特殊的&#34;编写的插件。一个离开公司的人的风格。
您的一些客户现在需要重要的功能,而且您还没有完成测试程序所需的劳动力。
三个月后。
您的成长和成长,并再次意识到您的Users
数据结构应该被修改,否则您的应用程序可以扩展到足以为您的一些关键客户提供服务......
您的应用程序已发展到269个文件。连接遍布各处。有些插件现在自己使用插件......你的连接是病毒,感觉它开始生活。有些模块会修改缓存参数并忘记重置它们,其他模块会询问应该从未被问过的非常有效的查询......
客户需要更多功能......您聘请了更多的MongoDB专家,并且他们都找到了您熟悉的连接。
圣诞节前一天晚上,打电话给客户。
&#34;你疯狂的窃贼,你的蹩脚模块是错误的,因为我的最重要的活动产生94%的年销售额只是错过了它的最高点我希望你死,因为我的员工现在会饿死... &#34;
你质疑你决定使用全局变量。
答案 1 :(得分:0)
您可以使用对象池模式:http://sourcemaking.com/design_patterns/object_pool
这是c#中的一个很好的实现:https://stackoverflow.com/a/2572919/3437025