It's a simple problem and one that has been annoying me for quite some time now.
A typical project has too much special-purpose code in the GraphicalUserInterface
. Much too much. In the projects I design the percentage floats between 20% and 30%. A friend, who does Mac development, was amazed that I manage to keep it under 50%. (Maybe your friend should use PowerPlant.)
Why so much GUI code? Job requirements (we're writing <program name>, not a general class library), inflexible existing libraries, and "requirements creep" seem to be the big culprits.
Does anybody else think that with good design, we could get it under 10%?
If you do your modelling right and have a good display framework already in place, shouldn't the GUI just "pop out"?
Is there any code as brittle as GUI code inserted at the last minute in response to a new customer requirement?
One major cause of the ballooning of GUI code is that it does things that should be done by the model. It's quite typical for GUIs to violate the LawOfDemeter
, ripping the guts out of the model objects and slamming information back in. They also tend to embed code to maintain various kinds of integrity among objects. This, too, is code that the model should be supporting. I would guess that if you see ballooning code in your GUIs, analysis of it will show you
- that it needs refactoring to reduce redundancy, and
- that responsibility is being placed in the GUIs that should properly be in the model. -- RonJeffries
What is the concern with "Too Much GUI Code?"
I'm having a hard time relating to this, maybe because our programs are large and the graphical user interfaces are dwarfed by the other human interfaces (like phones...). Even in the graphical programs I've built (like some social network visualization stuff) the amount of actual GUI stuff is small.
It also depends on how you count GUI stuff. A good part of my network visualization stuff is ProgrammingByConstraints?
, used to place graphical artifacts on the canvas relative to neighboring artifacts. I don't count that as GUI code, since the placement reflects analytical properties of the data being analyzed.
The amount of code that is peculiar to the platform (X, Sunview, S4, etc.) is microscopic relative to the rest of the code (about 1500 lines per terminal type, relative to the total program size of 22,000 lines of Romana code and 12,000 lines of GIL code).
Is there something you can say about your context, or about what constitutes "GUI code," to support further insightful discussion here?
I am not sure what the problem is. How is GUI versus non-GUI code defined and measured? How would the "correct" ratio be determined? If the code is clear and manageable, I really don't care how much of it is GUI code. If the code is unclear or not manageable, I don't care how little of it is GUI code. So what is the problem with too much GUI code?
I sympathize with what WilliamGrosso
is saying above. In my experience I've seen many systems written in which all of the logic that we would think of as "domain classes" be coded into the GUI code, that is they fail to SeparateDomainFromPresentation
. This is one of the forces behind a pattern that I'm submitting to PLoP'96 called FourLayerArchitecture
. This seems to be endemic to the MIS world, and is especially bad among those programmers whose backgrounds are in PowerBuilder
What is the problem with "all of the logic ... coded into the GUI code?" I don't believe that the ratio of GUI code to total code is the issue.
The issue is the tight integration of platform/interface dependent (GUI) code with code that might be reusable if it were separated from the GUI code.
O.K., I'll take your word for it. Furthermore, I'm eager to see the pattern - particularly since I just returned from a visit to a company where they believed everything would be solved by a ThreeLayerArchitecture?
: GUI on top, MiddleWare
in the middle (with little semantics beyond just that) and OS kind of stuff on the bottom. I'm, like, really skeptical that it's that simple. But it's O.K., Kyle - four
, I can believe :-)
Looking forward to your pattern.
Actually, Cope, what you've described is a different beast closer to a ThreeTierArchitecture
I've been thinking about this a little bit since I first wrote the editorial and I was postponing my clarification until I got it all sorted out, but then I realized: I'm never going to get it sorted out.
So, a first cut at some bad things:
Note that I'm not, in particular, complaining about where I work. As KyleBrown
said (above), the problem is endemic in the MIS world.
GUI code should be the most flexible code in your application or system. It will, and should, change as your customer requirements and expectations evolve. It is often disastrous to cast GUI development into an engineering point of view. GUI components can be engineered - I want a good set of reusable tools. I also need guidelines (GuiGuidelines
? -- TimOttinger
), but ultimately the front end must meet the user's needs. This is more an art than a science.
Sure, we want to promote consistent, solid reusable GUI front ends (frameworks?), but a user must live
in the environment that you provide. One way to do this is to allow the user to try the interface on and see how it fits. This shouldn't stop development. However, you need to plan your development around the fact that the user may be fickle. While some users (office workers and the general public come to mind) expect to see standard look-and-feel interfaces (most Mac programs, by standard, has a similar look-and-feel), quite a few will want specialized interfaces that they can live with.
Sure, we want to reuse and adopt standards (COSE, Motif, Mac, Win95, etc), but the user may require interfaces quite different from what we have produced before.
In my current programming world (Defense/Intel) customers use our software in mission-critical situations. While we adopt standards (often supplied by the customer themselves), usability is the highest priority. Often, that requires us to make GUI changes months after the application is done
Our architecture supports a changing GUI, but doesn't define
that GUI or treat it as another component to be cast in a formal design document. Capabilities are another matter...
GUI component level reuse concerns me. We need more. GUI (high level) reuse doesn't concern me as much. We need initial GUI requirements and a model, but expect it to change (sometimes quite radically). GUI development is not engineering: InterfacesCannotBeEngineered
I am not sure I agree that GUI Code should be any more flexible or volatile than any other code in the system. The GUI code and other interfaces expose the operation of the system to the outside world. Any significant change to the internals of the system will require an equivalent change in the interfaces to expose it. Likewise, any significant change in an interface will require underlying changes in the system to support it. Uncoupled, refactoring changes where one section is modified independently of another are probably more correlated with code quantity than with code function. In practice, I think we often tend to spend too much time cleaning up the GUI and not enough time cleaning up the underlying code.
. -- StevenBlack
I realized about a week ago that on my current project [in VisualBasic
- I agree with KyleBrown
that it's very prone to this] that the reason I was writing TooMuchGuiCode
was that I was creating what I've been thinking of as KnowItAllControls
I had my domain model separated out okay. Instead, the big mistake I fell into was having the GUI elements pull the data to display directly in from the domain model and then having the GUI elements update the domain objects on any changes being made.
I've since switched to a system where I'm using NaiveControls
that rely on separate [or as separate as you can make them in VisualBasic
] Renderer objects to fill them with data from the domain model objects, and to update the domain objects with the changes made by the user.
[This sounds to me a bit like the JimCoplien
a lot cleaner and more elegant than the tangle I was generating before, and I'm finding it a lot simpler and easier to design and code.
Looks like I've gone and re-invented my own version of FourLayerArchitecture
-- Stefan Kapusniak
pattern sounds very similar to the structure of my latest project. I can't say that the boundaries between the Application
and the Domain
layers are always particularly clear and well defined, but the structure is there. The splitting of the "Middle-Ware"
layer is in my opinion the only way to handle the different requirements of the visualization objects and the domain objects cleanly.
It's good to know I'm not alone in my "nice-idea-but-I-don't-think-so" opinion of the 3-tier/layer version.
The very word 'GUI Code' triggered me to add some comments. Our project is using a model-based approach to GUIs. It's based on task modeling and interactor networks (from CNUCE, Italy). The goal is to specify the dialogs in a task model and generate the user-interface out of it. A customization tool, both for developers and end-users, allows for adjustments according to personal tastes.
Especially from a viewpoint of standard software that is configured and parameterized, this approach is more promising than coding it by hand.
Maybe I'm just talking about FourLayerArchitecture
There is a distinction between the semantic content of user artifact and its representation. The information that a particular attribute is a single value chosen from a set of possible values is, IMHO, a *data model* decision, and can be captured in the user model with an appropriate "mutator". The choice of whether to interact with that mutator by using a ComboBox
, validated entry field, or collection of radio buttons is a user interface decision.
My experience has been that when I reflect this distinction in my design, the resulting solution is both cleaner and more flexible.
On the other hand...to paraphrase Don Norman, if you design the control of a refrigerator to resemble two thermostats (one for the freezer and one for the other part), it doesn't matter HOW beautiful you make the knobs... the user will still freeze the grapes or melt the ice cream.
If the user interface reflects the affordances of the user model, and the user model accurately reflects the "reality" of the system, the GUI code will tend towards simplicity.
. Reused or not, GUIs will bury you and your team. Besides, it's easier to negotiate about them when the customer is hot to get things released. -- RonJeffries
Ron, why does this comment strike me as something a command-line apostle who despises GUIs in general might say? What you're proposing sounds like sweeping the user's metaphor (naive though it may be) under the rug - along with the user.
A really good GUI that obeys the law of least astonishment is not a trivial achievement, or one to be despised, whatever else is under the covers. That some cadre of purists finds such things inconvenient - well, isn't that just a little beside the point? "Chrome don't make it go," but a good GUI is a hell of a lot more than chrome.
Getting the visual metaphor that the user interacts with is important. It may be more important than the developer's internal metaphor, which neither the goal donor nor the gold owner is likely to see, or care about. Yes, it's our professional responsibility to see to maintainability and other such Good Things; but, sub specie aeternitatis, we need to listen to the user - and the user deals with the interface. It's an afterthought to some of us, but to them, it's the system - and it's generally their nickel.
You're reading things into Ron's comments (e.g., value judgements about the importance of GUI's) that aren't there to support your personal rant. Why not state these things independently instead of constructing a strawman?
This all sounds very reminiscent to me of the old ModelViewController
programming paradigm (from Smalltalk in the late 70's, also in NEXTSTEP since the late 80's, and in the new Swing UI tools in JDK 1.2). The basic idea is that you have 'model' objects that implement your domain specific behavior (e.g. an object that models the temperature in a room, with an input & output of a thermostat setting and an output of the current temperature). The 'view' objects know how to display values in response to receiving messages, and the 'control' objects know how to generate messages. You wire the pieces together using a GUI/application builder. Using this model, all of the components are generic and reusable. The model is application specific (usually) but is completely independent of the GUI, and the view and controller are platform specific, but are completely independent of the application. If the development environment provides the same (logical) GUI widgets across all platforms, all you have to do is reposition things a bit. If you build platform-specific UI widgets, you have to implement them across all platforms, of course, but then you can use them across all applications. Without the separation between UI and application logic (e.g. if you use VB the way most people do) your code can't be reused, and large applications become unmaintainable.
It's a shame Smalltalk has pretty much died, but IBM's VisualAge
for Java is mighty nice.
w.r.t. GUIs just "popping out" of good design, take a look at the Dialogs in the BlackBox
Component framework (http://www.oberon.ch
). Records, for example, turn directly into dialog boxes for data entry, without having to write any code.
But then, one could argue that records a not good design at all. They do not exhibit behavior except getting and setting values. (At least in my definition of records, i.e. what's called struct in C.) They don't "carry their weight" and thus are candidates for refactoring. IMHO, most objects in a reasonable system shouldn't be record-like. This makes automatic GUI generation harder, to say the least. -- HaskoHeinecke
I'm working on Java GUI which is fairly big and contains a lot of code. I'm looking to transition into doing the GUI code using KawaScheme
. So far it's going terribly well, though I'm only using it for the simple task of "prototyping" layouts quickly into the way I want them. I have a screen shot handy for my current primitive setup, built in ~100LOC (www.javagroup.org/luke/scheme-gui.jpg).
It's my hope to grow my KawaScheme
code into a simple declarative language which can describe most of my layouts, well-formedness checks, enabled-when-<something> constraints, etc, while still allowing arbitrary tweaking in Java or Scheme. Wish me luck! :-) -- LukeGorrie
was actually a fundamental problem that inspired me to launch a startup software company to provide a web based portal framework.
It didn't take more than a few web projects to convince me that the complexity of rendering rich, personalized web pages needed abstracting. It doesn't help when developers are given a language (HTML) that mires presentation with content.
Fortunately, a lot of AlanCooper
's work on UI design and development (i.e. VisualBasic
) is being applied to web development in the MicrosoftDotNet VisualStudio
I believe < 10% GUI code is an achievable goal with our framework. I'll gladly send a copy to anyone interested in testing this.
In my opinion, GUI layouts should be mostly "meta data" for the most part. Some will vote for XML, others for database tables (DataDictionary
-like). The GUI engine should run off the meta data instead of code, only using code when an event is dispatched. This also allows the GUI engine and layout manager to be language-neutral. -- AnonymousDonor
This is how a lot of frameworks work, PowerPlant and the CocoaFramework among them. You don't write code to display a window, add a button to it, etc. You create a resource file that describes what the interface looks like and how it's bound to the application, and load this & link it up at run-time. (Though the CocoaFramework isn't language-neutral; it relies on ObjectiveCee's dynamism and is extremely powerful as a result.) -- ChrisHanson
We can minimize this gui code. I am dreaming of describing my gui (in XML). The creation of the gui components will be done automatically. Now I only have to code the behaviour of my gui components. The generation will be hidden in framework classes and will not count to the gui code anymore, because I do not need to code this (in my developer role). The other huge advantage is, that the creation of the gui components are strictly divided from the use or the behaviour from these components.
There is also a discussion on the java wiki JinxWiki
on the SwikiFarm
at the page "Swing XMLs" http://jinx.swiki.net/384
. A list of "Gui XML Projects" are found there on the page http://jinx.swiki.net/165
You don't need to dream anymore about using XML to describe GUIs if you're using WxWidgets
) as your GUI development framework. It supports the standard C++ way of creating a button in code, but also allows describing GUIs in resource files, one in a native WxWidgets
format and another in XML format.
I also note that some of this discussion seems to point that TooMuchGuiCode
reduces reusability of GUIs. Honestly, I don't see how much of a given GUI developed specifically for one project is reusable in another project. Most GUIs are customized and arranged in an order that makes sense for that project and that project only. Stereotypical reusable items such as toolbars and common dialogs are already provided by the development framework.
Does anyone out there actually have a good example of GUI code reuse? How hard should I be trying to develop "reusable GUIs".
was part of our motivation for devising NakedObjects
. A typical NakedObjects
application contains precisely 0% of GUI code. -- RichardPawson
Since GUIs are the only part of modern software that actually achieves significant reuse, investing heavily in a good set of base components is good practice. In how many apps do you see pages of code devoted to basic datagrid/flexgrid operations? I'm all for using too much GUI code in your components, and very little GUI code in your apps. The MicroSoft
standard components are horribly insufficient.
What is the problem exactly? Back on the DOS days, every GUI coder had to know how to draw a line on the raw ScreenBuffer?
. Today, even on the very rare occasions we need to actually draw our own widgets, the library or the OS manages to accelerate that line drawing using the hardware. The amount of code reuse we managed to obtain here is tremendous. Now, what this page seems to call GuiCode?
is "whatever deals with user interaction". We consider HTML as being a physical representation of the screen, while fifteen years from now it would have been considered as a high-level abstract presentation language.
The problem is the very nature of software: we take input from the user, we do some processing, and we report results to the user. Two of these three fundamental steps are all about interacting with the user. How much "GuiCode?
" do other industries have? When I look at a car, for instance, I would tend to think that most of the effort has been put on the "GuiCode?
". When I buy a car, what matters is how comfortable it is, how silent it is, how nice the AutoRadio?
is, the overall car design, etc... Of course the raw engine power and the consumption matters as well, but that's 50-50.
We can take another analogy with architecture: there is a lot of "CodeReuse
" there: these guys don't need to reinvent how to build a wall or to lay a roof for each new house they design. Still, no two houses are the same, and a lot of time is spent on the GUI: two bathrooms are never exactly the same and the room layout has to be reinventer for each house. Of course, we can find some patterns, but still: you can't have a one size fits all bathroom, you can't even split that room into some reusable components, unless you go very low level and you speak about the water tap itself. And still, there is an horrible amount of different available water taps.
So my point is: there must be a lot of GuiCode?
: that's where the user is living into. You can reuse a button, you can reuse a tabbed panel, but whatever more sophisticated than this doesn't deal with the presentation itself, but with the flow. And the flow can't be reused from one application to another because, well, the flow is more of less what defines an application from an user's point of view.
Well, I've used tools that put much of the GUI design into a "database of attributes", or something similar, and it made the code cleaner. The app code is then mostly just event handlers instead of GUI layout descriptions. Code that is mostly just attribute-setting and widget linking is a smell in my opinion (sometimes called set/get-syndrome). You don't need a lot of custom actions to describe typical GUI's (custom actions go in event handlers). When the web and Java came along, GUI's got all verbose and cluttered again, setting us back 12 years and slowing productivity. I suppose it is a personal preference. Some like tons of declarative configuration info in app code for reasons that escape me, but if it floats your boat... --top
Well not all applications are CrudScreen
s. For instance, I had to implement a tree-based provider/category/product display with on-the-fly search capability (such as stock thresehold and so on) and asynchronous loading. I'll find difficult to believe you've managed to describe that exact behaviour using a couple of DB tables.
Now again it all depends on what you call GuiCode?
: the screen itself takes less than 300 lines of code. All the complexity is hidden through generic ItemGroup?
s and update events. The generic tree widget takes an ItemGroup?
as roots, a column description group (with a name to bind the column settings into the DB), and a model provider to give the sub ItemGroup?
of each node in the tree. The ItemGroup?
is built from a Criteria. The tree widget is completely generic (and is reused elsewhere), the ItemGroup?
is also a generic construct (that serves both for lists and trees), the actions that the user can perform are extracted from an ActionProvider?
, taking into account the item ACL and the User's roles, etc. Of course it is a RichClient
, it might be different with WebApplications?
First let me state that I believe that just about ANY widget can be described with declarative tables plus generous event handlers (assuming certain vendor limitations are removed or worked-around). Second, I didn't really limit the "attribute DB" to the relational model, that's just my preference. The combo is TuringComplete. But I also agree that some GUI's need fancy widgets and at this stage not sure how conveniently this mixes with a DB-like model.
I liked the VBX/COM model that Microsoft used to support (minus the bugginess) where you could purchase fancy widgets for special needs from myriads of vendors. Having a single widget implementation for say trees and try to have it be everything to everybody is not realistic (and I think Java choked on this). Thus, vendors filled in the gaps and niches. Whether all vendor-plugin widgets could effectively use a DB-like model, I don't know.
But also keep in mind that if we want widgets to be fairly language-independent, one almost *must* go with a DB-like model (navigational or relational), because an OO-behavioral-wrapper-centric approach is very tough to port to different app languages because of the different ways polymorphism, inheritance, and typing work in each app language. And, I think its dumb to reinvent a GUI kit for every different app language (unless proven the only real choice). Thus, heavy-OO and having cross-language kits tend to conflict, and the "fix" is a DB-like treatment of GUI engines. And, a DB-like approach is best handled "off-code" for the most part. Related: CrossAppLanguageOopIsRough.
See also RemoteGuiProtocols