Software Engineering of GUI Programming?
cucucu asks: "After ten years of programming for the network, I started programming a GUI Desktop application. My problem is most GUI tutorials out there are nothing more than a taxonomy of buttons, dialogs, and check-boxes. So as I checked GUI toolkits, I found that I can easily learn all the widgets, layouts, callbacks, and the like, and start coding a GUI application. However, very soon I found myself repeating code all over the place. Is there a good guide (online or off) for the Software Engineering aspects of GUI programming, so that I can learn how to reuse code, and build my class hierarchies over the one provided by the toolkit?"
Is there a good guide (online or off) for the Software Engineering aspects of GUI programming, so that I can learn how to reuse code, and build my class hierarchies over the one provided by the toolkit?
Not sure if it is exactly what you are looking for, but I think a good starting place would be Designing Interfaces by Jenifer Tidwell from the O'Reilly collection. It helps if you are already familiar with design patterns, as the book casts its concepts in terms of patterns.
I would think that if you are an experienced Software Engineer and programmer, you would be much better served by something targetting the fundamentals of interface design. You can apply what you learn to any language or toolkit you know now or learn in the future. If you target a particular language or toolkit from the beginning you will limit yourself and make it harder to apply language-specific or toolkit-specific things to a different language or toolkit.
Most people don't seem to think about refactoring their GUIs; already there's one post here telling you not to code your GUIs but use the pathetic drawing tools to create them, even though GUI builders are evil, and one of the very reasons they are evil is they preclude even the simplest refactorings. The bulk of programmers seem to be happy about that.
My experience is that there really isn't anything special about GUI refactoring vs. any other kind of refactoring, at least in the languages I use. That may be a factor; dynamic languages like Python or Ruby seem to be a lot easier to implement "Don't Repeat Yourself" in. You may find you'd be better off switching to one of them, especially if you're trying to work in Java, with seems to elevate repeating yourself to a moral imperative.
But beyond that, I don't really see what's special about GUIs.
The other thing is that when you are first learning an environment, you need to cut yourself some slack. No matter what you do, your first few cuts will suck as you are getting your bearings. I'm all about refactoring and testing, but when I recently picked up Django, I didn't worry about either at all in the first week. Now I have to go back and re-examine everything I did and get the testing going for it, but I don't see any practical way to avoid it; testing my initial garbage would just increase the investment into code that I'm basically throwing away anyhow. (As I have a lot of web experience, that's probably faster than usual; any other framework type would probably take me longer.) You may find that you have built "one to throw away"; consider actually doing so.
Alright, I'm a little busy right now so I won't go into as much detail as I'd like, but here are the basics as far as I understand them.
:) Hopefully other people will have more details to give you.
1) Design patterns still apply. More than ever, actually. If you've not read the GoF, it features a pretty advanced example centered on the design of a rich text editor. You will probably want to dive deeply into the workings of the Model-View-Controller pattern and the related design constructs. The MVC pattern is not the be all and end all of GUI design, and there are many cases where the articulation between View and Controller
2) You may not now it yet, but you want loose coupling. Loose coupling means that, essentially, when a widget's state change, it will report on that change, and some interested party will be notified about it, and neither will have to know anything about the other. Many toolkit nowadays come with good signal and slot mechanisms to implement loose coupling. Understand them, and use them. If you find the sender of a signal and the receiving slot need to know about each other, you may want to go back to the drawing board as suggested in point #1 above; it is usually not necessary.
Conceiving GUIs is not all about the underlying software architecture, though; a good chunk of the work of making great interfaces is in the designing of the GUIs themselves (which is why you want loose coupling -- you WILL have to be flexible against changes as you experiment). I will let others fill you in about that. Quickly: read usability guidelines and get a feel for why they suggest what they suggest. Align your widgets! NetBeans is good for this, IIRC. Use GUI designer tools, experiment more.
That's all I can think of off the top of my head, but there's already a lot for you to chew in there.
All in all, it boils down to the usual rules of engineering: the second rule is to know what works, and the first rule is to know why it works.
-- B.
This sig does in fact not have the property it claims not to have.
And please, PLEASE, when possible, use the colours that are specified in the gtk/qt/windows theme settings.
/rant
I am so sick of applications, like Photoshop for Windows that has ahrd coded black text for most of it's dialogs. I use a bright grey on dark grey/black colourscheme to preserve my eyes at night and no matter how depressed I or Marvin might be, black on black is not readable.
I think there should be some sort of standard or UI Useability Compliance Organization or something to promote this concept.
Am I alone in thinking this way?
GUI's used to be simple in the VB/Delphi days: drag and drop widgets, and then set attributes and fill in methods (on-click, etc.). One used to spend a only few days building GUI's, now they take weeks and months to get how the customer expects them.
Some argue that such tools do not scale for different screen sizes. However, it is possible to build a "stretch zone" so that key widgets can stretch. But even if nested-based GUI's (like HTML) are used, it should not significantly change the nature of the method/attributes setting approach.
People seem to attack the VB/Delphi approach with elistist-sounding rhetoric, but none of it stands up to scrutiny. I think they are just defending their high-cost feifdom. The VB/Delphi style was near the pinnicle of GUI development (minus the stretch zones) and we went backward instead. Java, Smalltalk, and Web approaches ruined a good thing. MVC is a mess only a mother could love.
I think VB/Delphi-style will return one of these days because it was K.I.S.S. done right. GUI's are inharently visual, and thus visual design tools result in the most effeciency and closest match to the domain at hand (Visual GUIs).
Table-ized A.I.
Some resources:
Apple's User Interface Guidelines; adapted from the NeXT/OpenStep Interface Guidelines (PDF).
There's also the Classic "Macintosh Human Interface Guidelines" for System 1 through OS 9 (have to hunt it down yourself), GNOME's HIG,KDE's, and Tog's.
Without reading through them all, I can't point out where they address BPs for reuse, management, etc., but I know it is touched on somewhat (although from a NeXT slant) in Apple and NeXT's guidelines.
That's probably overstating it by a fair margin. ;)
Many parts of C# are awesome, and work very nicely:
- GDI+ is extremely easy to use and predictable.
- I like the way they've organized System.IO and System.Collections.
- The Win.Forms control set is very, very well-done.
- XML web services and Regex are also quite passable.
- Reflection is nice, even though I don't often have a chance to use it.
- ADO.NET's simple classes (Connection, Command, DataReader) are very straightforward, and I use them all the time in my database stuff.
- The Setup and Deployment projects are absurdly easy to use. I love it!
Other parts are so-so. They work, but they're not really intuitive, and I frequently find myself referring back to previous projects in order to remember how it works. Examples:- System.Security.Cryptography, for instance, has a whole lot of junk. When all I want is to generate a set of RSA keys and encrypt something, I still have to refer back to prior code samples.
- Their weird proliferation of Stream types, with all of those weird Formatters, is very confusing. I don't like it.
- Globalization has a lot of byzantine stuff in it that I find very confusing.
- DataSet and DataAdapter are overly complex.
- Events and Delegates are a little too crufty. I don't like the syntax (event += event handler? are you kidding?), and I don't like the fact that if the event doesn't have at least one subscriber, it's Null, and will thrown an exception if you raise it. That's stupid.
Then there are the parts that completely suck:- Resource files? Totally botched! I still have no idea how to create a stupid resource file containing some bitmaps, and have it bundled into the application.
- DataBinding. It is practically impossible to glue a textbox to a string, and have bidirectional updating. I don't understand how MS could have so badly wrecked this stuff.
- The credentialing (Code Access Security, User Security, etc.) is so hopelessly complicated that I won't touch it with a ten-foot pole.
- ASP.NET is very, very, very clunky. None of the controls work right, or in a predictable fashion. They don't even work anything like their Win.Forms counterparts! I can design very beautiful Win.Forms GUIs, but my ASP.NET projects always come out looking like third-grade HTML projects. Terrible!!
I had big hopes for C# 2.0 - but it seems to be a little less stable and predictable. Generics, for instance, are a much-needed feature - but Microsoft didn't bother to implement it for ArrayList, the data structure that I use most often. And the new ADO.NET stuff is hopelessly complicated and useless.So despite its flaws, C# is still the drop-dead easiest API I've ever used. I've written several dozen projects in it, and I will continue to use it until something cleaner comes along. (I'm not holding my breath on that one!)
- David Stein
Computer over. Virus = very yes.
There were number of books that covered the same issues as "Reliable Software through Composite Design" and my appreciation of this issue originated from reading them. To certain degree we have a common frame of reference.
I don't agree, however, that Fowler's works are a logical extention of those principles. The fact that Fowler "allows" reversing refactorings doesn't seem like much of a concession. The goal should be to avoid doing additional work that you have to end up undoing later. Since refactoring by definition doesn't change functionality, "constant refactoring" can descend into constant self-indulgence.
I also don't agree that loops, functions, objects, etc were created to avoid "cut-and-paste". For example, loops go back at least as far as 1954 when FORTRAN was created. There was no such thing as "cut-and-paste" in those days, so that can't be the reason for creating looping capability. Also saving program space was at least as important a factor in adding language support of functions as were organizational considerations.