How not to go about "Building user interfaces for object-oriented systems"
Update: This article is fron 1999, which I somehow missed, not news by far. Still wrong, even for its time, though.
This really annoys me, the author of the article tries to preach an OO methodology for writing UI. In general, I don't have an issue with that, but his arguments contains this:
Name
class, objects of which know how to both display and initialize themselves.I am not sure where to begin. To start with, an entity should not have ties to the UI. Then we have this dream vision about editing a single class, and suddenly all the relveant screen sprout the new field, and we can start working on it. UI doesn't work like this. It doesn't work like this because adding a new field to screen can horribly break the screen. It might push the Ok/Cancel button outside of the visible realm of the screen, it might break the tab order, it will definately break the flow of the screen.
I am all for OO and encapsulation, but this is not a problem that you can generalize.
This just gets better when you keep on reading:
The other bugaboo that I want to put to death is the notion of different views into the same object, usually characterized by the question: "Suppose you need to display this data as a pie chart over here and a grid over there? How can you do this if the object displays itself?"
Now let's get real. How often in your work has this problem actually come up?
Um, all the time? The simplest version is showing items in a list and then in a details view, but I just finished talking about the different views that I present to the various aspects in my systems. Beyond that, I have different views for different screens. In one screen, I am showing an Employee's personal data, in another the Employee's salary data, etc.
Comments
I read the article and wondered what kind of drugs he was on. I think his question about how many times anyone has had to present the same data in different ways is an indication as to what kind of projects he has been involved in. Gives me some serious Microsoft vibes; "Get real, why would anyone want to :hover anything other than the A element?".
"It doesn't work like this because adding a new field to screen can horribly break the screen. It might push the Ok/Cancel button outside of the visible realm of the screen, it might break the tab order, it will definately break the flow of the screen."
These are very important problems that should be fixed by the UI layer (adding a scroll bar is just one way) and which the displayed object should not care about.
The alternative of manually adding a new field to the UI is not very DRY (see my next comment to your DRY post).
"In one screen, I am showing an Employee's personal data, in another the Employee's salary data, etc."
Allen Holub has more object-oriented solutions for these scenarios, keep reading his stuff and you will find them.
"These are very important problems that should be fixed by the UI layer (adding a scroll bar is just one way) "
A scroll bar is not an option in many scenarios, not because it is not technically possible, but because the UI guidelines wouldn't allow it.
"The alternative of manually adding a new field to the UI is not very DRY"
You are correct, but not doing it this way would break the UI.
Did you see his comment about different views for the same data "Who does that?"
A scroll bar is one solution, there are others. Are you saying that every field you've ever added really required manual manipulation of the UI which couldn't have been done automatically? I'm not saying 100% of cases are standart, but even a 20% duplication is worth avoiding...
Regarding multiple views for the same data I think Allen Holub refers to 'data' in atomic terms ('Salary' not 'Employee') but in any case I assure you there are very good ways to accomplish this without exposing an object's state, such as having the object display itself to an abstract UI and implement that UI in multiple ways.
"I assure you there are very good ways to accomplish this without exposing an object's state"
Just don't get too excited about encapsulation. It's a good concept, but not as an end in itself.
"having the object display itself to an abstract UI and implement that UI in multiple ways"
Just one more layer of indirection and a good possibility for leaking abstraction.
Sorry, hit submit button too early.
Have to say that modifications to UI are implemented by programmers, but sanctioned by designers. At least in our company, we try to reach a good level of usability even for data entry forms. So, UI changes certainly require a human intervention and no 'auto' layout. This makes sense, since you are building software not for machines, but human Users.
"Just don't get too excited about encapsulation."
Every time I've broken encapsulation I've regretted doing it. Every time I've refactored towards encapsulation I ended up with less code and improved maintainability. The whole "pragmatic programmer" approach of "Keep it DRY, Shy and Tell the Other Guy" - is about encapsulation (mainly the "Shy" and "Tell the Other Guy" part).
I guess I don't see why encapsulation should be broken, I never thought of it as a burden.
"Just one more layer of indirection and a good possibility for leaking abstraction" - that sounds like an argument you can throw at just about anything...
"This makes sense, since you are building software not for machines, but human Users"
Humans like order and templates too. Usability has rules (every designer I've met told me that) - and they can be implemented in code. Have you seen an application of more than 20 data entry forms that didn't contain duplications in the UI layer (explicit or implicit)?
I agree with you on encapsulation part :)
My point was that Object.Save() is not appropriate in all situations (but truly encapsulated, isn't it?) while Save(Object) is something to consider too (i personally prefer this approach).
Abstract UI sounds too vague to say anything concrete. Could you elaborate more on this? My main concern is over-architecting, just in case you may sometime have a need to reuse the same presentation logic for say ASP.NET and WinForms or WPF application.
I don't know a rule that allows me to safely display/position UI widget on screen based solely on the fact that there is a string field on some Domain class. Hey, it's only recent advent you can declaratively validate and show feedback in the UI. On the contrary, i can persist that field to DB and even change a schema 'automatically'. Just need to add a couple of Attributes/lines in config. This is possible mainly due to the reason this meta data is consumed by machine, not human.
If Save(Object) requires my object to expose internal state and have it inspected by the saving code I don't see why it is something to consider. Using a "Tell don't Ask" approach of Object.Save() or Object.Save(DataStore) will always end up with less code and a more loosly-coupled design. Don't you find a lot of duplication in all those Save(object) methods which simply inspect object properties and construct saving commands?
Anyway, there are of course other options.
What I mean by a UI abstraction is that if you find the need to display a certain piece of data once as an editable TextBox and once as a non-editable ListBox item you simply have to extract a common interface and have the object present itself to that interface without actual knowledge of the underlying presentation form. That way you achieve both encapsulation of the object's data and multiple presentations. The bonus here is that when another form of presentation is needed, it becomes as simple as implementing an interface.
Do you have any rules for a default string editing widget? Do you have any rules for how editables are layed out on the screen (spacing, alignments, anchoring)? Is it safe to say that if you have to add a field to a form with a grid on it you would try to fit it in the grid without causing any of the other columns to get below their minimal width, and if you can't you simply place that field on the form outside the grid?
The main point is, though, that even if you have no such rules you can still encapsulate an object's presentation by having it add the field to the UI (manually) from within the same class, without exposing another public property.
If you generally agree with my point about encapsulation you should give Allen Holub another chance. Andres Taylor of ThoughWorks put as number one of his " Top ten things ten years of professional software development has taught me" the item "Object orientation is much harder than you think". I really think Allen Holub is the one to learn OO from, and I strongly recommend his book "Holub on Patterns".
Comment preview