【问题标题】:How to refactor global variables out of your code如何从代码中重构全局变量
【发布时间】:2009-09-04 11:32:07
【问题描述】:

围绕全局变量及其滥用的讨论似乎带有某种教条主义的语气。我不是在这里对“全局变量不好”的概念提出异议,因为对我来说它们为什么不好是有道理的。但是我想知道人们是否有一些有趣的代码 sn-ps 可以准确地演示如何从代码中有效地重构更高范围的变量和对象。在这个问题中,我正在寻找通用但有用的解决方案的示例或模式,以解决“我需要在这里使用全局变量,因为它很容易”问题。

这是一个假设的,也许是人为的例子。我正在使用全局变量来跟踪发送给函数的参数。然后,如果在链的下游发生故障,我可以返回并使用全局变量中的参数再次调用该函数。

public var myGlobalState:Object = new Object();

public function addPerson (name:String, person:Object, personCount:int, retryCount:int):void
{
     myGlobalState = null; // Clear out old values

     myGlobalState = new Object();
     myGlobalState.name = name;
     myGlobalState.person = person;
     myGlobalState.personCount = personCount;
     myGlobalState.retryCount = retryCount;

     person.userId = personCount + 1;
     person.name = name;

     savePerson(person);
}

public function savePerson (person:Object):void
{
    // Some code that attempts to save the person object properties to a database...
    // The process returns a status code for SUCCESS of FAILURE.

    // CODE TO SAVE TO DATABASE ....

    // Return status code...

    if (status == "fail")
    {
        // Retry at least once by calling the addPerson function again

        if (myGlobalState.retryCount < 3)
        {
            addPerson (myGlobalState.name, person, myGlobalState.personCount, myGlobalState.retryCount);
        }
    }
}

【问题讨论】:

    标签: java refactoring global


    【解决方案1】:

    我没有 sn-p,但我有一个真实世界的例子。 线性校准常数(质谱场) 应用程序是全球性的,并且有复杂的代码 存储和恢复全局校准常数 不同的光谱。这两个值的使用被广泛传播 在程序上,很难更改或检查 未校准和校准质量之间的转换 使用这两个常量的值在所有情况下都是正确的。

    我通过封装两个校准常数进行了重构 在一个负责在 未校准和校准的质量值。执行的功能 还引入了转换,因此它集中在一个 放置在程序中,而不是散布在整个程序中 程序。这个封装后来很容易介绍 一种新的校准方式(非线性)。

    类不是访问两个全局变量 代表一个频谱将改为拥有并使用一个 新校准类的实例,每个实例都有 它自己的一组校准常数。

    【讨论】:

      【解决方案2】:

      一种快速的解决方案是将所有全局变量添加到一个巨大的对象中,可能还有几个子对象来分隔数据组。将所有这些变量都放在一个对象中,您只需要一个全局变量来存储该对象。然后,您的所有代码都将引用此对象中的变量而不是全局变量。

      下一步将摆脱这个单一的全局对象。这应该比摆脱数百个全局变量更容易。这可以通过将其更改为您传递给任何其他方法的附加参数来完成。

      一旦所有的全局数据都消失了,你可以考虑重构你的代码,尝试通过例如优化这个共享对象。将其分成多个较小的对象。但是,通过将所有内容移动到单个对象中,您可以更轻松地进行管理。

      【讨论】:

        【解决方案3】:

        答案通常在于程序的架构。您可以以绝对必要的方式设计全局变量,并且您可以以永远不需要它们的方式进行设计。在后面的场景中,您通常会得到一个更好、更简洁的架构,并且可以避免为依赖全局变量等的方法创建单元测试时出现的所有常见问题。

        This question 也会有所帮助。

        附:在您的特定场景中,根本不需要全局变量 - 您可以轻松地将其作为参数传递给 addPerson 方法。

        【讨论】:

        • 在您的特定场景中,根本不需要全局变量 - 您可以轻松地将它作为参数传递给 addPerson 方法。
          这就是我的一部分糊涂了。它会是一个可选参数吗?那么它会不会像 public function addPerson (name:String, person:Object, personCount:int, retryCount:int, callBackParams:Object = null):void 其中 callBackParams 在我的示例中的行为方式与 myGlobalState 相同?
        猜你喜欢
        • 1970-01-01
        • 2019-11-28
        • 1970-01-01
        • 2016-04-24
        • 1970-01-01
        • 1970-01-01
        • 2016-12-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多