So you have a great class written and you want to integrate it into your project. Whether it be C#, Java, VB even C++ you may have asked yourself “How do I go about getting my class to update my form controls?” or “How do I get the class to change something on my interface or another class?” It is a common question asked on the board and the answer is rather simple, but this object oriented principle is wordy and requires a bit of conceptualizing to explain. The trick is not to have your class do the updating, it has its own problems to deal with. You should have the interface/class use the other class to update itself. We will explain what we mean on this entry of the Programming Underground!
Whether it be a calculator engine in Java or a ClientEngine in C#, the concept of tight and loose coupling can make even the most experience programmers baffled. The old adage “A class/function should do one thing and do it well” is at the heart of the matter. There are many reasons why you should keep a class in the dark about a GUI interface. These reasons may include…
1) If the class attempts to access or modify GUI controls, it ties the class to the interface. This means that your class becomes “tightly coupled” to the interface (aka dependent on the interface).
So your class accesses some textboxes on the form called “txtInput” and “txtOutput”. Harmless right? Wrong! What if you or another programmer was put in charge of changing the names of the controls or simply removing them from the project to update the look of the GUI? They would have to A.) know your class is updating those controls or B.) make modifications to the class to either get rid of the code or change it to the new control names which doesn’t solve the problem.
2) The class no longer becomes reusable.
Since the class depends on txtInput and txtOutput to exist, you can’t just move the class file to another project and expect it to work. You would be forced to drag along the two textboxes along and put them on the form with the same name. Your class should be independent of what the interface is doing. It should just be asked for information or handle processing without knowing who or what is asking it to do so. Perhaps your class is no longer tied to an individual project and is instead in a DLL shared by multiple applications. What will it do then if you need to update specific controls that no longer exist?
3) As eluded in the other points, it can become a maintenance nightmare.
Every time you change your GUI around you are forced to change all the classes dumping content in its controls. Why give yourself or your fellow programmers a maintenance problem like this? If you keep the class modularized and only offer public methods by which the interface itself could use, then the interface could be changed around and the only code needing to be touched would be in the interface classes.
The fix for all of this is rather simple if you think about the problem in a slightly different way. Objects are meant to be used. They don’t know anything about who or what is using them. They don’t care. They just ask for proper info and will return proper info back. This is great because that means we can use an infinite number of these classes, we can have multiple forms use them, we could have other classes use other classes and all would be right with the world.
So instead of seeing something like this in a class…
public void updateTextbox() { txtOutput.Text = "Hello there Martyr2!"; }
Which wouldn’t work anyway because txtOutput is not local to the class (and where most programmers become confused on how to communicate with the objects of their form and come to the board asking about it) they should be looking at a solution like so…
public string getHelloText() { return "Hello there Martyr2!"; }
This simply returns the text to the caller of the method. This caller could be your form where the txtOutput control exists or it could be another class. Here is how it would look back in the form class that has the txtOutput control…
Ourclass hello = new Ourclass(); // Notice now that txtOutput is a local control on the form and it is "requesting" the information from the class // The class has no idea about this control. It is worrying about its own calculations and data. txtOutput.Text = hello.getHelloText();
Now with this style we could use our class in other ways related or unrelated to the GUI interface. Maybe we later decide that the hello message shouldn’t go to txtOutput which is a textbox, but instead be added to a listbox. We can leave the class alone and instead have the form dictate where the data is going to go.
// Old way was to dump it to the textbox txtOutput.Text = hello.getHelloText(); // We changed the control receiving output, different name, even different control altogether // This works flawlessly because our class has no idea where the data is going or isn't trying to push the content to the control // Instead the control is pulling the info from the class to itself. OurListBox.Items.Add(hello.getHelloText());
One last example using our new little class here would be if another class wanted to say hello. If the class had been tied to an interface, the hello class would be trying to push the answer to controls that may not exist or are corrupt the controls that have valid data in them just because one class is asking your hello class to say hello. So if we had a class called “hi” then we could write something like…
public class hi { // Create an instance of our other class private OurClass hello; // Initiate the class public hi() { hello = new OurClass(); } // Create a function that if called creates a messagebox that uses our class to say "Hello there Martyr2!" public void SayHello() { MessageBox.Show(hello.getHelloText()); } }
Notice how we now used our class to update a form’s textbox called txtOutput, a listbox called “OurListBox” and used it in a completely other class called “hi” without ever needing to change the OurClass functionality. This is an example of true reusability, modularization, and low maintenance.
So the next time you find yourself asking how to update one class using another class, ask yourself instead of how you can have one class use another class to update itself. You will find the solution will turn out much nicer for you. You will also have a class that you can reuse, put in your own personal library, and leverage the true power of modularization in your code.
I hope this has helped you all and again I thank you for reading. 🙂