14

While I've never delivered anything using Smalltalk, my brief time playing with it has definitely left its mark. The only way to describe the experience is MVC the way it was meant to be. Essentially, all the heavy lifting for your application is done in the business objects (or domain model if you are so inclined). The standard controls are bound to the business objects in some way. For example, a text box is mapped to an object's field (the field itself is an object so it's easy to do). A button would mapped to a method. This is all done with a very simple and natural API. We don't have to think about binding objects, etc. It just works.

Yet, in many newer languages and APIs you are forced to think from the outside in. First with C++ and MFC, and now with C# and WPF, Microsoft has gotten it's developer world hooked on GUI builders where you build your application by implementing event handlers. Java Swing development isn't so different, only you are writing the code to instantiate the controls on the form yourself. For some projects, there may never even be a domain model--just event handlers. I've been in and around this model for most of my carreer.

Each way forces you to think differently. With the Smalltalk approach, your domain is smart while your GUI is dumb. With the default VisualStudio approach, your GUI is smart while your domain model (if it exists) is rather anemic.

Many developers that I work with see value in the Smalltalk approach, and try to shoehorn that approach into the VisualStudio environment. WPF has some dynamic binding features that makes it possible; but there are limitations. Inevitably some code that belongs in the domain model ends up in the GUI classes.

So, which way do you design/develop your code? Why?

  • GUI first. User interaction is paramount.
  • Domain first. I need to make sure the system is correct before we put a UI on it.

There's pros and cons for either approach. Domain model fits in there with crystal cathedrals and pie in the sky. GUI fits in there with quick and dirty (sometimes really dirty).

And for an added bonus: How do you make sure the code is maintainable?

Berin Loritsch
  • 45,784
  • 7
  • 87
  • 160
  • You could do that in Java - create a framework and use XML to bind UI elements to methods/fields. I don't even think it would be that difficult - reflections is prety powerful. Great question, btw - makes you think pretty hard. – Michael K Jan 12 '11 at 20:02
  • With Java, there's a library called JGoodies that has a really cool binding feature for JavaBeans. It's the only reason I ever saw any value with JavaBeans, and probably gets you closest to the SmallTalk way of building a GUI. http://www.jgoodies.com/ – Berin Loritsch Jan 12 '11 at 20:26

7 Answers7

5

Neither

Over the years I've been developing software I found myself to practice a both first methodology because there is always a "middle ground" to take into consideration. Put an interface between the UI code and business code, and make an agreement upon what the UI needs at the moment from the domain.

Let me make a figure to make this concept crystal clear:

  +------+
  |  UI  | <- Think about how to make an effective user interface
  +------+
      |
      |
 +----------+
 | Contract | <--- This part over here is really REALLY important, man!
 +----------+
      |
      |
+--------------+
| Domain model | <- Think about what the user needs
+--------------+ 

That way you can iteratively work on UI and the domain model seperately if the middle ground makes it crystal clear on what data the UI can receive.

The reason I see why some projects become unmaintainable is because the interface between data and presentation has been rushed or is inexistent (with direct data handling code is in the ui). I've seen so many projects where database code resided inside form code that I've lost faith in humanity. Only the few projects I've seen that do have this rigid middle ground restores that lost faith.

It doesn't really matter from which end where you start first... what matters is that you've got that clear seperation of concerns in place. That contract in the middle pretty much defines the application or system at hand. Think of that one first before going bottom-up or top-down.

Spoike
  • 14,765
  • 4
  • 43
  • 58
4

Domain first. I need to make sure the system is correct before we put a UI on it.

Nothing else can be made to work -- except in simple cases.

Starting from the UI often leads to fragile, buggy software that may look like fun, but often has serious problems in the model.

It's not a given that UI first is doomed to failure -- if the model is simple enough then the UI can be built first with confidence that the model will work out fine in the end.

In any case where the model cannot easily be imagined, it has to be built first.

The worst case is where some programmer thinks they can imagine the model. They may have omitted important details, special cases, exceptions, or performance considerations. Since the GUI has already been built, and many considerations where omitted, the model is terrible.

S.Lott
  • 45,264
  • 6
  • 90
  • 154
  • When developing a UI I could care less what the data looks like as long as it is there. I can add a layer of abstraction to place the data in a desired structure...tying myself to the back end implementation details is asking for problems down the road. – Aaron McIver Jan 12 '11 at 22:50
  • @Aaron: You're brilliant. In the past 30 years, I haven't had the privilege of working with someone as brilliant. I'm not being snarky. It's simply my experience that when the GUI was done first, the application could not be made to work, maintained or adapted. I've had to be on more than one "technical review" where the job was to figure out who to sack because the GUI couldn't be made to work. Your experience is singular. – S.Lott Jan 13 '11 at 00:30
2

This really depends on the application at hand.

If you are building a closed client/server application then either approach would suffice; as you are going to manipulate the back end to suit the front ends needs inevitably.

If you are building an open client/server application where a potential web service will be exposed for use by your customers then being aware on how that service may be used by a customer to develop a front end is critical.

Often times as of late with regard to a push of small iterative cycles in development (Scrum, Kanban, etc...) the front end and back end is done in parallel. It's about providing what you need for that given iteration; disregarding the build it in case we need it approach. In a parallel approach both ends stay much closer throughout development which can alleviate the need for continual change when the front end and the back end merge. This is my preferred approach when feasible.

You mentioned...

...WPF has some dynamic binding features that makes it possible; but there are limitations. Inevitably some code that belongs in the domain model ends up in the GUI classes...

Not sure what you mean by some? WPF and SL are both noted for their binding functionality. It is endless. If you are being forced to place code within your View in an MVVM based WPF application then something needs addressed. Attached Behaviors are one way to implement behavior without tying into events within the View, as well as many other approaches in assuring your View stays clean.

The front end from a user interaction stance should have nothing to do with the back end implementation. The back ends sole job to a front end is to supply data via processing data or other means. This ties back into the type of application being developed.

Making sure source code is maintainable is really an entirely different question in and of itself. At a high level it pertains to best coding practices along with following proven patterns, architectures, and technologies.

Aaron McIver
  • 3,262
  • 16
  • 19
  • I say _some_ because compared to the Smalltalk approach it is very cumbersome. I admit there is a lot for me to learn about WPF, considering I just started using it mid last year. – Berin Loritsch Jan 13 '11 at 12:53
2

I prefer to design the basic UI first (even if it is just on paper), with input from the customer. The customer might not really know what they want until they see it. You can't always trust what the customer tells you. You could invest weeks writing a robust domain model only to find out it doesn't fit into what the customer figures out they want after they start seeing UI prototypes.

TaylorOtwell
  • 2,657
  • 1
  • 21
  • 26
1

We try to drive our software with automated tests. Automated UI testing is pretty darn time consuming. Scripts to check some values on a console are easier.

With that in mind, we are quite careful to keep the business logic separate from the UI.

I remember once even having a lead developer yell at me that the Document/View architecture was considered obsolete when I suggested that we needed to stop binding all our business code with UI (and we were using win32 in C++ at the time so this drag&drop programming thing wasn't even our problem). I was simply dumbfounded.

IMNSHO, there's simply no excuse for not having at least a business vs. UI layer. If your product does anything mildly interesting it's absolutely necessary for this separation to enable code reuse.

Edward Strange
  • 9,172
  • 2
  • 36
  • 48
0

As a C# developer, I definitely don't think you're pigeonholed into working outside-in. I prefer to do domain-model first, actually.

For WPF, the only downside to the model I described, then, is that you sometimes need to mediate between your UI and your domain model. Still, while that sometimes means more work, it also means cleaner code.

Rob
  • 101
  • 1
0

Certainly, domain first!

The beauty of Smalltalk was you could very easily "drive" a domain model in numerous ways, including doing "print it" from a workspace or inspector. Only when you were sure your domain was performing as desired did you dare focus on building the perfect GUI.

That's not to say that Smalltalkers didn't work on the two concurrently, but when your GUI failed to implement the business logic, you generally fixed the domain model first, rather than put special cases in your GUI.

Jan Steinman
  • 121
  • 3