views:

250

answers:

8

I have developed certain financial and accounting packages on the basis of global variable which is I want to share. Here I present the small example of global variable which is communicated between multiple forms.

Form1 :-  
Component require :-
1.  ComboBox
2.  Button


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;


namespace Globalvaribale
{
public partial class Form1 : Form
{
    public static string name;

    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        name = comboBox1.Text;
        Form2 f2 = new Form2();
        f2.Show();
    }
    private void Form1_Load(object sender, EventArgs e)
    {

        string connstr = "server=.;initial catalog=maa;uid=mah;pwd=mah";
        SqlConnection con = new SqlConnection(connstr);
        con.Open();
        string sql = "select name from dummy";
        SqlDataAdapter dap = new SqlDataAdapter(sql, con);
        DataSet ds = new DataSet();
        dap.Fill(ds);
        comboBox1.DataSource = ds.Tables[0];
        comboBox1.DisplayMember = "name";
        comboBox1.ValueMember = "name";

    }
  }
}

Form2

Component is Label1

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Globalvaribale
{
public partial class Form2 : Form
{
    public Form2()
    {
        InitializeComponent();
    }

    private void Form2_Load(object sender, EventArgs e)
    {
        label1.Text = Form1.name;

    }
  }
}

And thus I have prepared all my project which is works very well and no compliant on it. Note that there is more than 50 winforms on each projects. But recently I have noticed: Global Variables Are Bad.

Some people call me “mad” to utilize this type of global variable. The above article suggests many disadvantages, and I am confused that if it is true, than how are my projects and applications successful without any errors or mistakes?

A: 

Global variables itself are not bad. Using them without thinking is bad.

You might consider using singletons, but if it's not really big & complex application, it might be safer to leave it as global var.

BarsMonster
a singleton is not really much different from a global variable...
Daren Thomas
@Daren: From the OP's link: "If a global variable exists, I would assume that it is used. If it is used, there are methods associated with it. Colocate those methods in a single class and one has created a singleton. It really is better to specify all of the rules for use of a global variable in one place where they can be reviewed for consistency. The veil may be thin, but it is valuable."
Brian
@Deren Thomas : But it sounds cool and make you look smart ;-)
BarsMonster
@BarsMonster, Suppose above example code works for you as it is works for me. So what are you going to do with it. You are decline it to use or accept with it?.
mahesh
@mahesh: I would approve. If your code would have 100 globals - then I would decline :-)
BarsMonster
@BarsMonster, Your answer also approved. don't worry i am not a mad in real manner to apply 100 globals. Your welcome.
mahesh
+1  A: 

It is certainly possible to write code that works with global variables. Even code that works well. It is just that in most cases (which does not include all cases, but very, very likely, your one), not using global variables, once you get used to that, makes reading and maintaining the code much, much easier, and writing it not much harder. Most of the time. There are times for global variables, certainly, but trying to reduce their number as far as reasonably possible helps in the future – not only, but most obviously, when you are trying to make your code multithreaded.

The problem with this global variable issue is that the drawbacks of global variables are hard to show in short examples, so they have to be experienced in real-world code. They strike especially hard with code you “inherited” from some other programmer no longer reachable – but after a while, your own past projects will probably be numerous enough that the difference between your own old code and old code written by someone else will be much less than you previously thought or experienced.


Edit: Since you asked, I'll try to describe what I mean by an example.

Assume you use some logging mechanism, with a global variable pointing to where the output should go.

std::ostream *out = &std::cout;

void log(Object &o const) {
    *out << "Log: " << o.getSomeData() << std::endl; // or whatever
}

If you want log messages somewhere else, you'd simply assign out to some other value, call log and set it back. Easy enough, right?

std::fstream logfile("operation.log");
std::ostream *oldLog = out;
out = &logfile;

someOperation();

out = oldLog;

Now, the first problem with this is that the code above fails to reset out in case of errors. The C++ way around that would be to use some RAII object, other languages need explicit try/catch blocks or whatever. Nothing complicated, it just makes the code a little more verbose.

But what happens if some code inside someOperation() wants to write log messages itself, which are not meant to go into some specific log file? It needs to temporarily set out back to &std::cout again. Doable, of course, but it needs to be done in all those places – and the interface of log does not necessarily make this clear.

You may not have a problem keeping all these cases in mind. For me (and a lot of others), keeping all this global state in mental memory is something that takes up space where other things cannot go any more. Sure, to change the code, I need to have additional parameters, which has costs of its own:

someOperation(std::fstream("operation.log"));

or

std::fstream logfile("operation.log");
logfile << someOperation();

or some other option. But I gain that I can look at code locally and see much more easily (i.e., without going through my knowledge of 800 global variables in 372 files of 5k lines of code each) what happens.

Now, factor in other developers who may have other ideas of “clean code” than you do – and for me, the size and complexity of projects I can do on my own is limited. Most code these days is written in teams, I believe.

Christopher Creutzig
@Christopher, But it is my experience with this code i suggested it in my question that i have prepared all my application with the help of above without any mistake. and it's handle very well by me.
mahesh
@mahesh: As I said, that is not uncommon. Avoiding globals is an investment in the future. Assume you don't see the code for three or five years and then need to go back and fix a problem or add some functionality. Most people (and I'm not saying that necessarily includes you, but my guess would be it will) would find well-written code without globals easier to read, understand, and maintain than well-written code excessively using them. This is very similar to using `goto`, creating flow control with exceptions and lots of other options. Not wrong, but often not the best choice.
Christopher Creutzig
@Christopher, Do you mean after four or five year later modification in code?. So what you think there is backup is not solution for it. and it is develop by one person than it is easy to understand it.
mahesh
@makesh: I'm not sure what you mean by backup. Code usually needs changes over time, and a program of 100k lines that is easy to understand is a rare beast, no matter how many or few people developed it.
Christopher Creutzig
@Christopher, To be honest that I have no idea about web form application. I have develop winform application which code is front of you as above. So please resolve it in my language i mean in winform.
mahesh
.... to be honest it is gone over my head.
mahesh
@makesh, I have no idea about winforms and no intentions to learn a language only available on one platform (and a platform I deliberately don't use unless I have to at that). From reading your code, it seems to me that it works only as long as you are not trying to use the same thing in multiple places on the same page or whatever winforms create, since to do that, you'd probably need multiple instances of `Form1` and `Form2` (again, I'm necessarily guessing here). …
Christopher Creutzig
… If and as long as your environment ensures that you'll only ever need at most one `Form1.name`, this works, but you have no options other than duplicating the code if it doesn't.
Christopher Creutzig
@Christopher, Oh! don't bother about guessing it is also part of it. we are here for discussion so it will happen.
mahesh
... I think you are guessing is right that i don't need to put my code in multiple places in the same page. and that is the trick which is works.
mahesh
.... and you are again right that i have need to utilize multiple instances of forms but it is only for once in a particulars page of class on each forms.
mahesh
+6  A: 

Global variables are not bad per se.

In fact, sometimes it is a blazingly simple solution to a really complicated problem. Instead of passing the same value between dozens of classes in different layers, one could just use a single global variable. I've done this and it has greatly simplified the code.

The reasons why it is considered bad have to do with potential dangers. Note the word potential.

  1. Global variables represent a global pool of data where everybody is eligible to read/write. As the code grows, you risk losing control over who writes what, when and how.

  2. You make many classes and modules dependent on one little thing. One little change and you have to rework lots of your code. A small bug and it will have repercussions everywhere.

This is very old knowledge and experience gathered in the days of functional programming before OOP came in. Like with many other questionable practicies, you have to know the risks. Whether you will get into trouble, depends on you. To coin a phrase, it's not about global variables, it's how you use them.

In your specific case I do not believe a global variable is a good solution to what you're doing. If you explained the idea behind your code, we might give you better alternatives.

Developer Art
@Developer Art, Strange even though it is so dangerous I had finished my all application with success. No error or not any mistake.
mahesh
It's not strange. Whether you get into trouble or not and if yes, when at what stage, depends solely on you, on how you applied this potentially dangerous technique.
Developer Art
@Developer, No I didn't get into trouble as i know that how to handle it and it is being so easily works. that's why i avoid event and delegates as it is very much complex itself.
mahesh
@mahesh: It depends on a lot of factors, including how many people you work with, how many other projects you need to keep in mind at the same time, how good your memory of what you did back then is, how disciplined you wrote your code and comments, the particular problem your code originally set out to solve, the problems it later on had to accommodate additionally etc. If globals work for you, great, but I suggest you also try the other thing and see if that works, too, and if you see any benefits for yourself.
Christopher Creutzig
@Christopher, You are wright as per your point of view and i am also wright as per my point of view as it is my personal experience. you are looking for future investment. and I am looking to do present better.
mahesh
@Christopher, Please show me your way. I mean your different code which is better than mine. Please.
mahesh
@mahesh, as I said, it's difficult to do on small examples. I hope you understand that I don't feel like creating two versions of a large example – browse through a couple of articles and books on programming, especially about the problems inherent in mutlithreaded programming, and look for sections focussing on global state and global variables. It's not that I don't use globals or generally recommend not to. Global variables are a tool, and like any tool, every one of us finds places where it works well and places where other tools work better. …
Christopher Creutzig
… The line between these places for different tools of course differ between applications, between languages, and of course also between developers. And they move over time. That is perfectly ok; what I regard as important is to make sure I learn to use tools many others have found useful.
Christopher Creutzig
@Christopher, See First thing is i am not blaming anybody over here as well as other books' author or else. but thing is I put my opinion here. hope you will understand.
mahesh
... my opinion means if it is works with my case than why should i change it?. if any better example you have than present it. it will helpful to me as well as others.
mahesh
... and describe it as comparison with my code. So what happen it will make better sense to understand me and as well as other so please present your way here with example code.
mahesh
.... I understand that it will difficult on small ground of code but at least possible to put your way by small coding. as i did above.
mahesh
@Christopher, Please don't be feel bad as we all are here for sharing knowledge and our discussion will pour out something which will useful to others. my efforts is here only pour out the knowledge nothing else.
mahesh
.... and it will make me sense to accept the answer otherwise i will be confuse what to do? accept or not?
mahesh
@mahesh: I'm not saying you should change. You asked why people feel global state is not necessarily a good idea and I tried pointing out some of the problems I have seen in practice with it. If I find time later on, I'll try to add some code to my answer – why do you ask for that in comments to another answer?
Christopher Creutzig
@Christopher, i am sorry for that as i don't know about it.
mahesh
+1 : Good answer.
Ian
@lan : +1: "Good answer" what is this?
mahesh
+1  A: 

Global variables really can come in handy. But they come at a cost.

Relying on global variables tends to create tightly coupled designs. It is hard to run parts of your program in other contexts, because it expects this global context to be in a certain state.

This kind of coupling can get in the way of (unit) testing. As you want to run stuff out of context or in a controlled context.

Global variables also tend to lead to designs with side effects. A function / method will produce a side effect by altering global state that is not obvious from the code surrounding the code to this function. This can lead to bugs that are hard to track down.

Daren Thomas
@Daren, What you think about my above code?.
mahesh
@mahesh, it reminds me a lot of VB6 code. `Form1` and `Form2` are closely coupled and can only ever be shown once. In my code I prefer to overload `Form.Show(string name)` to pass this kind of information.
Daren Thomas
@Daren Agree but it is c# question. is it possible in c# what you suggested?. and i remind you this is question of global variable?. if you have better solution than present it i will welcome your suggestion.
mahesh
.... and keep in mind that first You have to reply my first question which is asked before? "What you think about my above code?"
mahesh
@mahesh, maybe I was being a bit, sorry. I think your above will only work for simple cases, is a bad habit as it leads to tight coupling between forms and I am fully aware of your question being a c# question about global variables. My better solution remains to create a method `Form2.Show(string name)` and call that instead of `Form2.Show()`. Thus the global variable is not needed and the galaxy will not implode.
Daren Thomas
@Daren, I think your method is wrong i tried but fail to create it. can you explain it in details.
mahesh
+1  A: 

Having just started working on a legacy project with tens of global variables, I have to say that I'm opposed to using them.

They're not bad per se, but they can infinitely complicate maintaining the code:

  • They introduce a lot of unexpected behaviors, simply because it's extremely hard to track their values.
  • They can be modified by anyone, anywhere, at any time.
  • Removing them is much harder once your code base has grown.
  • Decoupling different modules becomes a real issue, if most of them are intertwined by these global variables.

If you're the only one working on the project, and you know what you're doing, you can use them, nothing's going to explode. Just don't expect to understand why your project's working in a particular way years down the road.

alex
@alex, You are talking about my code as above or talking about generally please clarify.
mahesh
@mahesh I'm talking about code in general. But, to be honest, it also goes for your code. The thing is, it's better to do a little more work now and do less afterwards.
alex
@alex, Please read Christopher and Developer answer's comment first.
mahesh
I fully agree with what alex said. I've inherited too much code that needed major untangling before I could even start to address the customer-visible problems.
Christopher Creutzig
A: 

Well, let's consider why globals are considered bad. It's their unconstrained visibility. Global variables are accessible to all code, for reads and modifications. A design based on proliferation of globals, defeats structure. The reads and writes can come from anywhere. And while this may be OK when you first implement something (because you know the land), it can be catastrophic because of the kind of code it encourages. Soon you end up with a spaghetti of relationships and interactions.

Having said this, a blind hatred of globals is also not warranted. I mean, globalness can be relative. A class name is global within a namespace. A class member is global within the namespace established by the class. So, if the codebase for a class becomes large enough, the same argument made against globals, can likely be made against class members. In fact, namespaces and classes are, in part, mechanisms to contain this disease of globalness. They are (in part) mechanisms to draw boundaries of visibility and access.

So, in my view, the question is not of globalness. It's really about structure.

Ziffusion
A: 

When i have too many global variable i will create new static class (or more than one class) and I'll put this variables in that class so later its more easy to find this variables and their behavior.

public static class CommonGlobal
{
    public static string XName {get;set;}
    public static int x {get;set;}
    ....
}

This class will be initialized just one time, and if i change the Form1 class (in your sample) there is no need to change all of classes which uses Form1.name because i have CommonGlobal.XName, so the UI changes make a little change in my code and keeps my business Free from extra changes, without adding any layer i have a layering accessibility. so sometimes developer calls it Common layer, but in fact its not a layer its just a Common and shared items. and there is no difficulty to use it or change it. For better practice see the structural patterns like this.

SaeedAlg
mahesh
In what way is that better than using a plain global variable? At least, use some getter/setter methods, so you can centrally add validation, logging, or locking if and when you need it.
Christopher Creutzig
@Christopher Creutzig I agree to use properties and @manesh i think the way I'm using global variables is a manageable way than a way you use it. but yes i'm using static items.
SaeedAlg
@manesh i read the article it was about c++ in c# u have some ability that eases the way of doing something so u can't refer it as a good article for C# :)
SaeedAlg
@SaeedAlg, very good suggestion as it is very much close to mine, but Do you note think that it is very much lengthy than my suggestion for communication between multiple forms?
mahesh
... my code is single line code and it will detect very easily between multiple forms as i did before in my many application.
mahesh
... actually i really appreciate your way also.
mahesh
A: 

There are already excellent answers, but I'll give you my experience.

The most obvious reason not to use globals the way you did above, is that the day you will have to open two or more Form1, nothing will work anymore. And one day you will need it.

In a large project I'm working on, we made the design mistake of storing some application-wide objects in a static class -they were unique in the application-. This backfired in a spectacular way when a part of our application needed to be used in a different context as part of a multi-threaded engine (yes I know ThreadStatic, but there were other reasons as well). All of a sudden those objects were not "unique" anymore (as every thread needed their own) and we had to redesign a lot of things.

In general I'm not a fan of over-design and don't like to make things super complicated just to support possible but very unlikely future scenarios. However this is a case were the effort to do things in a more proper way is usually not huge (if you do it from the beginning) and the probability you'll gain benefits is high.

Francesco De Vittori
@Francesco, I am really wanna talk about your second and third line for your information it is really working in my case i am trying here to explain how?
mahesh
....I have main entry form1 of accounting packages where you can create company and alter the same. and second form2 to select the various company and after select it.
mahesh
....It will put user to MDI form where user can does each and every activity related to financial and accounting.
mahesh
.... again back to form2 where company selection is there as well as their ID, period from field and period to field.
mahesh
...So I have take the "ID,periodfrom" and "periodto from form2" as per above and applied it to associates forms which is 100% working.
mahesh
... there is need planing and well proof work on. and i have done and got success.
mahesh