I’m doing a little refactoring this week of some code (not authored by me) that involves a WinForms app that drives tests. I didn’t set up to do any refactoring, but in trying to fix some bugs and add a few simple features, what I’m finding everywhere is
private void btnTheButton_Click(object sender, System.EventArgs e)
//all the program logic is here…
Time and again we see this “pattern” in code. In order to use that same functionality in the context of a different UI action, I now have to take the time to factor out the program logic into a separate method which can be called from two different locations (as should have been done in the first place).
Now, in defense of the guilty, WinForms encourages this behavior, which I must admit is my single biggest gripe about WinForms. Say what you will about MFC, I loved the way MFC’s designers defaulted to the MFC Command/CommandHandler pattern. Every UI action represented a command, and it was up to the command handler map to decide what method actually handled the command. Thus, the default pattern made it easy to do things like having a button and a menu item that both fired the same action. I wish some of that had rubbed off on WinForms instead of the current VB-esque, every-bit-of-code-gets-attached-to-an-UI-element pattern.
However, it’s not just in WinForms that this is a problem. I found that when I was teaching Web Services using ASP.NET, I ran into the same pattern. A Web Service should be thought of no differently than a UI. It’s an external way to make things happen. So, having all of one’s program logic right in the ASP.NET Web Service code (.asmx) introduces the same problem. Do yourself (and whoever is going to have to maintain your code in the future) a favor and create separate “code behind” classes for your web service that hold the real logic. All that should be in your ASP.NET web service code is argument processing and calls into your “code behind”. A full-blown MVC architecture might be overkill for a web service, but removing your logic from what is essentially your “user-interface” will save many headaches later on down the road.