有什么好的设计模式可以避免在主窗体的顶部使用全局变量? [英] What is a good design pattern to avoid having to use a global variable at the top your main form?

查看:119
本文介绍了有什么好的设计模式可以避免在主窗体的顶部使用全局变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

每次我与经验丰富的程序员交谈时,他们都会谈论由于调试或安全漏洞而使全局变量成为不良做法。我有一个简单的字符串列表,我想从文本文件中加载并在表单中通过不同的方法进行访问。之前,我只是在表单类内部的顶部初始化该变量,然后在各个方法中使用它。我总是尽量减少这种做法,只有在确实需要它们时才初始化它们。这样做是不好的做法,还是有经验的程序员也这样做?有没有执行此操作的标准设计模式方法,因此您不必在表单顶部使用全局变量?

解决方案

在谈论C#时,它是一种完全面向对象的编程语言,无法声明全局变量



在像C#这样的OOP语言中,做法可以使用静态类来模拟全局变量

  public static class全局
{
public static string Value1 {get;组; }
public static int Value2 {get;组; }
}

...以便以后从其他类中获取或设置这些值。绝对,这是一个不好的做法,因为状态应该由特定且有意义的对象持有。使用构造函数的类:

 公共类X 
{
public int Value1 {get;组; }

public void DoStuff()
{
Y y = new Y(this);
y.DoChildStuff();
}
}

公共类Y
{
公共类Y(X父)
{
父=父;
}

public X父母{get; }

public void DoChildStuff()
{
//与父母
做些事情}
}

或者,也可以传递提供某些方法自变量的状态:

 公共类Y 
{
public void DoChildStuff(X parent)
{
//与父母做些事
}
}

由于您要传递具有引用类型的州,如果链中的任何方法都决定将 Parent.Value1 更改为另一个值,所有对象都引用相同的 X 对象将获得新的 X.Value1



有些人可能会认为我们通常构建配置对象拥有其他任意对象访问的许多属性,对吗?顺便说一句,配置本身就是一个概念,不是吗?我们通常使用组合对配置值进行分类:

 公共类ApplicationConfiguration 
{
public DatabaseConfiguration数据库{ ; } = new DatabaseConfiguration();
public StorageConfiguration存储{ } = new StorageConfiguration();
}

公共类DatabaseConfiguration
{
公共字符串ConnectionString {get;组; }
}

公共类StorageConfiguration
{
公共字符串TemporalFileDirectoryPath {get;组; }
公共字符串BinaryDirectoryPath {get;组; }
}

所以以后我们注入任何地方的应用程序配置我们需要它:

  //请注意,这是一个非常假设的示例,不要使用
//作为有关如何实现数据映射器的实际建议!
公共类DataMapper
{
public DataMapper(ApplicationConfiguration appConfig)
{
AppConfig = appConfig;
}

public ApplicationConfiguration AppConfig {get; }
私人IDbConnection连接{ }

public void Connect()
{
//我们从应用程序配置对象
//中访问已配置的连接字符串
Connection = new SqlConnection (AppConfig.Database.ConnectionString);
Connection.Open();
}
}

总而言之,由于我喜欢比较现实世界和编程用例,假设您从不打扫房间,而只用一个盒子来存放一天可能需要的所有工具。有一天,您需要从整个盒子里取出一把螺丝刀,而且您知道里面的东西了……但是您需要将盒子中的所有东西都扔到地上,弄清一团糟,然后才能找到无价的螺丝刀来完成一些家庭任务。 / p>

或者想象您已经购买了一个工具箱来按顺序存储工具,并且一旦需要一把螺丝刀,您就会知道它在工具箱中以及存储区域中您的螺丝起子。



您知道第二种方法最省心。也就是说,在开发软件时,您需要设计易于理解的体系结构,而不是将大量无关数据和行为协同工作。


Every time I talk to experienced programmers, they talk about having global variables being a bad practice because of debugging or security exploits. I have a simple List of strings I want to load from a a textfile and access across different methods in my form. Before, I would simply initialize said variable at the top, inside of my form class and use it across methods. I always try to reduce that practice when I can and only initialize those variables when I really need them. Is it a bad practice to do this or do more experienced programmers do this too? Is there a standard design pattern method of doing this so you don't have to use "global variables" at the top of your form?

解决方案

As you're talking about C# and it's a fully-object-oriented programming language, there's no way to declare global variables.

In an OOP language like C#, a bad practice can be simulating global variables using static classes:

public static class Global
{
     public static string Value1 { get; set; }
     public static int Value2 { get; set; }
}

...to later get or set these values from other classes. Definitely, this a bad practice because state should be held by specific and meaningful objects.

Usually, in a perfect/ideal OOP solution, you should pass such values from class to class using constructors:

public class X
{
    public int Value1 { get; set; }

    public void DoStuff()
    {
        Y y = new Y(this);
        y.DoChildStuff();
    }
}

public class Y
{
    public class Y(X parent)
    {
         Parent = parent;
    }

    public X Parent { get; }

    public void DoChildStuff()
    {
         // Do some stuff with Parent
    }
}

Or also, you might pass states providing arguments to some method:

public class Y
{    
    public void DoChildStuff(X parent)
    {
         // Do some stuff with "parent"
    }
}

Since you're passing states with reference types, if any of the methods in the chain decide to change Parent.Value1 with another value, all objects holding a reference to the same X object will get the new X.Value1.

Some fellows might argue that we usually build configuration objects which own a lot of properties accessed by other arbitrary objects, right? BTW, configuration is a concept per se, isn't it? And we usually categorize configuration values using composition:

public class ApplicationConfiguration
{
     public DatabaseConfiguration Database { get; } = new DatabaseConfiguration();
     public StorageConfiguration Storage { get; } = new StorageConfiguration();
}

public class DatabaseConfiguration
{
     public string ConnectionString { get; set; }
}

public class StorageConfiguration
{
     public string TemporalFileDirectoryPath { get; set; }
     public string BinaryDirectoryPath { get; set; }
}

So later we inject the application configuration wherever we need it:

// Please note that it's a VERY hypothetical example, don't take
// it as an actual advise on how to implement a data mapper!!
public class DataMapper
{
     public DataMapper(ApplicationConfiguration appConfig)
     {
           AppConfig = appConfig;
     }

     public ApplicationConfiguration AppConfig { get; }
     private IDbConnection Connection { get; }

     public void Connect()
     {
           // We access the configured connection string
           // from the application configuration object
           Connection = new SqlConnection(AppConfig.Database.ConnectionString);
           Connection.Open();
     }
}

In summary, and since I love comparing real-world and programming use cases, imagine that you never clean your room and you would use a single box to store every tool you might need some day. One day you need a screwdriver from the whole box, and you know that's inside it... But you need to throw everything in the box to the ground and work out the mess prior to find the priceless screwdriver to complete some home task.

Or imagine that you've bought a toolbox to store your tools in order, and once you need a screwdriver, you know that's in the toolbox and in the section where you store your screwdrivers.

You know that the second approach is the most mind-friendly. That is, when you develop software, you need to design mind-friendly architectures rather than a big mess of unrelated data and behaviors working together.

这篇关于有什么好的设计模式可以避免在主窗体的顶部使用全局变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆