2010-05-05 86 views
6

我写的大多数程序都是相对可流程化的过程,有一个明确的开始和希望的结束。问题本身可能很复杂,但不容易倾向于集中使用对象和事件驱动的编程。通常,我只是通过大量不同批次的文本数据来产生不同的文本数据。我偶尔需要创建一个类:作为一个例子,为了跟踪警告,错误和调试消息,我创建了一个具有一个实例(myErr)的类(Problems),我相信这是一个Singleton设计模式的示例。另一个因素是,我的同事比我更老(程序性),而且不熟悉面向对象编程,所以我不愿意创造他们无法解决的问题。请尽量减少使用全局变量来描述你的工作

但我一次又一次地听到,即使Singleton设计模式真的是反模式,应该避免,因为全局变量不好。

小功能需要很少的参数传递给他们,并不需要知道配置(不变)或程序状态(改变) - 我同意。然而,主要控制程序流程的链中间的函数需要大量的配置变量和一些程序状态变量。我相信将一个或多个论点传递给一个函数是一个“解决方案”,但几乎没有吸引力。当然,我可以将变量压缩到单个哈希/字典/关联数组中,但这看起来像是作弊。

例如,连接到Active Directory以创建新帐户,我需要配置变量作为管理用户名,密码,目标OU,某些默认组,域等。我必须通过这些参数通过甚至不使用它们的各种功能,只是通过一个链最终导致实际上需要它们的功能将它们洗掉。

我至少会声明配置变量是恒定的,以保护它们,但我最近选择的语言(Python)没有提供简单的方法来做到这一点,尽管食谱确实存在作为解决方法。

许多堆栈溢出问题已经打到了为什么?坏的和必要的回避,但不要经常提到与这种准宗教限制一起生活的提示​​。你是如何解决全球变量和计划状态问题的,或者至少是和平的?你在哪里做出妥协?除了围绕函数的参数成群之外,你有什么技巧呢?

+0

好问题 - 您是否将类级变量(成员)分类为全局变量? – 2010-05-05 15:27:05

回答

5

我认为有一个单身模式或类似情况的时间和地点。要记住的关键是,一次又一次,许多人在使用全局/共享/静态变量以及单例模式的“错误”选择方面遇到了特定的恐惧。

就你而言,你正在专门讨论配置。我认为使用单例风格模式访问这些配置项目并没有什么坏处。每个应用程序都有配置,它应该位于一个你可以调用的位置,不需要传递它,这比它帮助复杂。

这里的关键是确保您确实需要信息只存在一次,配置是迄今为止我发现使用这种类型的模式的最佳理由之一。

3

全局数据是不变的,或定义良好的全过程对象(例如日志记录),通常可以用作全局数据。配置数据,特别是如果它驻留在本地文件中,将属于同一类别(整个过程/应用程序只有一个文件,与日志类似)。

一般来说,如果你发现你必须传递额外的参数才能将它们传递给另一个函数,那么你应该把这个函数调高,然后再调用另一个函数。说明这一点的另一个更实际的方法是测试驱动的开发,因为它强制你传递依赖关系。

另一种考虑它的方式是:如果该函数不能轻易知道调用子函数的所有细节,则将该子函数拉起来,并强制一个更高的,更知道的图层来获取所需的信息。我发现这种技术对代码质量具有高度的传导性,因为它构建了分隔的部分,而不是单片的动物。

在您对于活动目录例如,代替绕参数传递到ad_connect,绕过处理该必要的逻辑的对象,则具有介导该对象和功能之间的相互作用的功能使用它

def create_user(name, ad_user, ad_pass, ad_ou, ...): 
    conn = ad_connect(ad_user, ad_pass, ...) 
    conn.CreateRecord(ad_user) 

def create_user_mediator(name, ad_controller): 
    ad_controller.CreateRecord("cn=%s" % name) 

这只是一种做法,当然也有其优点和缺点。它仅仅是一个例子,说明如何避免使用全局变量。