代码之家  ›  专栏  ›  技术社区  ›  ChristianLinnell

如何在没有全局变量的情况下持久化数据?

  •  8
  • ChristianLinnell  · 技术社区  · 16 年前

    我习惯于编写语言脚本。PHP、JavaScript等,我编写了一些比较简单的Java和C语言应用程序。这是一个我反复需要回答的问题,我想我不是唯一一个。

    假设我使用的是JavaScript。

    我有一个函数a(),由GUI调用,它检索一些值。

    函数b()也由GUI调用,需要该值,但函数b()将被调用任意次数,即a()之后的任意时间长度。

    我不希望()每次都重新计算该值。

    登录凭据就是一个例子。a()请求用户名,b()每次调用日志时都使用该值追加到日志中。

    为此,我可能只使用一个全局变量。

    现在,C。没有全局变量!我该怎么做?

    编辑: 喜欢这些答案,但是有很多“尽量不要使用全局”的评论。我确实理解,但是我想听听这个需求的替代模式。

    5 回复  |  直到 16 年前
        1
  •  4
  •   Tim Jarvis    16 年前

    首先,总是问自己是否真的需要一个全球性的,通常你不会。但是如果你真的需要一个全球性的…

    实现这一点的最佳方法是在一些敏感命名的类上拥有一个静态属性,它有效地成为全局变量。

    public class Credentials
    {
      public static string Username {get;set;}
    }
    
    //...somewhere in your code
    
    Credentials.Username = "MyUserName";
    

    编辑:

    这里的一些人说了一个笼统的说法,即全局变量是不好的,我同意这种观点,而且似乎C的设计者也同意,因为他们根本不可用。

    不过,我们应该看看全局变量不好的原因,它们大多被认为是坏的,因为您违反了封装规则。不过,静态数据并不一定是坏的,静态数据的好处在于可以封装它,上面的例子是一个非常简单的例子,在现实场景中,您可能会将静态数据包含在同一类中,该类与凭证进行其他工作,可能是登录类或用户类,或者其他任何类型的你的应用程序。

        2
  •  5
  •   Fabio Vinicius Binder    16 年前

    这不是一个好的实践,但是如果你真的需要它,有很多方法:

    1. Web应用程序:您可以将变量放在某种上下文中,比如会话或应用程序范围。
    2. 桌面应用程序:您可以创建一个对象,并将其存储为始终有活动对象的类的属性。
    3. 任何类型的应用程序:使用公共静态属性。每个人都能看到。
        3
  •  1
  •   Jorge Córdoba    16 年前

    我想你应该使用 Singleton Pattern .

    如果您要使用多线程应用程序,那么还需要确保对singleton实例的属性的访问是线程安全的。

    和往常一样,请仔细考虑在应用程序中引入任何类型的全局性,但不要害怕使用它。很多东西确实是全球性的,比如应用程序。比如设置,没有任何“坏”的地方。

    这个 article on MSDN 解释如何在C_中正确创建单例。

        4
  •  0
  •   Paul Sonier    16 年前

    在C中,获得类似于全局变量的行为的方法之一是使用静态类方法和类变量。静态类方法和变量在C语言中只有一个实例,并且在某种程度上类似于其他语言中的全局变量。

    也就是说,对于您的问题,它听起来更像是一个设计问题。C非常关注面向对象的设计;我怀疑您给出的问题是,更好的OOD可以解决您的问题。

        5
  •  0
  •   workmad3    16 年前

    函数A是类的一部分(称为C)。然后,函数A可以存储登录凭据并提供一个函数(或在C_中,一个属性)来获取凭据。当需要它们时,您可以简单地使用属性来获取存储的凭证并将它们传递到函数B(在不同的类上)。

    class C
    {
        public void functionA()
        {
             credentials = obtainCredentials;
        }
    
        private LogonCredentials _logonCredentials = null;
    
        public LogonCredentials logonCredentials
        {
            get { return _logonCredentials; }
        }
    }
    
    class D
    {
        public void functionB(LogonCredentials credentials)
        {
           //do stuff
        }
    }
    
    ///other stuff
    ///other function ...
        ...
        instanceC = C();
        instanceC.functionA();
        ///more stuff here
        instangeD = D();
        instanceD.functionB(instanceC.logonCredentials);