Search This Blog


Monday, April 28, 2008

Why Windows Form Designer is Bad

Windows Form Designer in Visual Studio seems great for a newbie programmer. With drag and drop capability and a powerful visual designer, you can easily mock up a beautiful looking screen in no time. Programming couldn't be simpler.

Need to customize the positioning of a control? Just move it to the location you want it to be! No coding.

Want to enable the status of a button only when a menu item is clicked? No problem, just create an event handler to handle the clicking event and set the buttons status right there in the method.

What about the need to handle complicated UI logic? Easy, for every form designer there is an associating .cs file for you to code your logic. With a little bit of programming knowledge you can create even the most sophisticated looking interface in the world. No kidding. If you like, you can even put some application into the class.

The problem with it is that it is hard to maintain the code afterward because there is no easy way to create automated tests for it.

Unit testing has been widely successful in testing the application logic and programs that can accept batch input, but it is not being successfully applied to the testing of GUI logic. Oh yes, there are attempts to create GUI unit testing framework, such as Nunit Forms and NUnitASP, but they never gain a substantial followers.

Why this is so? Partly because GUI is harder to test for it requires interactions between the user and the program, another reason is because Form Designer in Visual Studio does not allow a proper separation between the logic and UI objects.

To illustrate the situation, supposed that you have a tax filing application. For this simplified application, it contains only two textboxes:
  1. Age
  2. The yearly income
The business rule is that you are eligible for tax only if you are 18 years old and above. So the yearly income textbox is turned on only if the age is more than 18. The logic should be straightforward to implement:

private void CheckTaxEligible()

Simple, isn't it? You just have to call the CheckTaxEligible() every time the Age changes. But in real life things can be more complicated; it could be that the status of a single button is dependent on not just one field, but many fields or many variables; or that if a particular menu bar item is activated then an array of bar item must be enabled or disabled. In either of these situations, you have to write elaborate logic involving the status of the controls coupled with their interactions with other controls and at th same time handling all the popup menus, dialog boxes that get called should the need arises.

The logic starts to get complicated. And somehow down the road, you are getting lazy to separate the UI logic and the application logic, so you put all of your code in the designer class just to save time and thoughts. You thought that you would find time to refactor all those mess, but there are just too many bugs to keep you occupied, so you keep piling spaghetti code on top of spaghetti code until one day you wake up realizing that the application is too messy that it requires a complete rewrite.

Congratulations, my friend. The power of Windows Form Designer has just ruined you.

The UI logic is supposed to be easy because it is not so amendable to unit testing, but in real life application it is rarely easy, because there are many possibilities to user interaction and all possibilities must be considered.

Imagine the trouble you have to go through when you are doing regression tests. Not only you need to make sure that new features are working well, but all the old features must be working, too. But in the hurry of rushing out an application it is easy for one to forget or to overlook minor details and to introduce breaking changes. But the UI is the software as far as the users are concerned. If your UI is broken, your software is no good.

Although the situation can be remedied somewhat by using automated GUI test tools, but still it would be great if one can apply unit testing to GUI components. And Windows Form Designer -- the way Microsoft implements it--is bad because it discourage unit testing and TDD.

Windows Form Designer is bad because it encourages one to put the UI logic directly into the designer class. As a consequence of this, all of the logic is simply not testable. In the hands of unskilled programmers, the Windows Form Designer actually empower them to write highly coupled, speghetti code that is hard to read, debug and test. Although the Form Designer gives one the speed in mocking an application, it takes away the ease of maintenance. It is great for prototyping purpose, but not so good for creating readable applications.

I guess that's the reason why we have ASP.NET MVC and WPF, but I would like to have an equivalent WinForms MVC, too.


Bill said...

The designer has NOTHING to do with this. After all, WPF has a designer, and yet MVC is very important to most WPF developers.

MOST UI languages don't lend themselves to easy MVC compositing. However, it can be done. And the existence of a designer doesn't change that fact.

Isaac Rodriguez said...

I agree with all the problems you describe; however, I disagree with the title of the post, and specifically, with your statement, "Windows Form Designer is bad because it encourages one to put the UI logic directly into the designer class."

I do not think the Windows Form Designer encourages programmers to couple UI and logic. Laziness encourage people to do it (and many other bad design decisions, I might add).

The other problem lies in how programming is teached in languages like C# and Visual Basic, where the designer is used to create simple programs, students never learn how to create a real-world UI.

When learning any kind of UI toolkit, one must code everything by hand to understand how it works, and how UI and logic can be decoupled. Once the toolkit is learned, a designer is just a tool to speed-up things.

Andrew said...

The Windows Form Designer really does encourage programmers to couple UI and logic.

Unit testing is something that has been tacked on as an afterthought instead of being built in.

Perhaps the code behind the page should not be allowed to make direct calls to the database.