views:

313

answers:

8

I'm not sure if this has been asked or not yet, but how much logic should you put in your UI classes?

When I started programming I used to put all my code behind events on the form which as everyone would know makes it an absolute pain in the butt to test and maintain. Overtime I have come to release how bad this practice is and have started breaking everything into classes.

Sometimes when refactoring I still have that feeling of "where should I put this stuff", but because most of the time the code I'm working on is in the UI layer, has no unit tests and will break in unimaginable places, I usually end up leaving it in the UI layer.

Are there any good rules about how much logic you put in your UI classes? What patterns should I be looking for so that I don't do this kind of thing in the future?

A: 

Input validations attached to control. Like emails,age,date validators with text boxes

yesraaj
But these should also always be duplicated in the business logic layer, because it is business logic too. And maybe another UI might get used on that same logic. (See comment to answer by Ramesh Soni)
peSHIr
+2  A: 

I suggest UI shouldn't include any sort of business logic. Not even the validations. They all should be at business logic level. In this way you make your BLL independent of UI. You can easily convert you windows app to web app or web services and vice versa. You may use object frameworks like Csla to achieve this.

Ramesh Soni
Any validation logic in UI layers should only be there for reasons like lowering usage of backoffice CPU cycles to real backoffice stuff and/or improving user experience. Any validations done should indeed never be only in UI, but be duplicated as actual business logic.
peSHIr
+1  A: 

The pattern you are looking for may be Model-view-controller, which basically separates the DB(model) from the GUI(view) and the logic(controller). Here's Jeff Atwood's take on this. I believe one should not be fanatical about any framework, language or pattern - While heavy numerical calculations probably should not sit in the GUI, it is fine to do some basic input validation and output formatting there.

Yuval F
MVC is one pattern, there are others...
Richard Ev
+5  A: 

Just logic dealing with the UI.

Sometimes people try to put even that into the Business layer. For example, one might have in their BL:

if (totalAmount < 0)
     color = "RED";
else
     color = "BLACK";

And in the UI display totalAmount using color -- which is completely wrong. It should be:

if (totalAmount < 0)
     isNegative = true;
else
     isNegative = false;

And it should be completely up to the UI layer how totalAmount should be displayed when isNegative is true.

James Curran
A: 

James is correct. As a rule of thumb, your business logic should not make any assumption regarding presentation.

What if you plan on displaying your results on various media? One of them could be a black and white printer. "RED" would not cut it.

When I create a model or even a controller, I try to convince myself that the user interface will be a bubble bath. Believe me, that dramatically reduces the amount of HTML in my code ;)

Fusion
A: 

Always put the minimum amount of logic possible in whatever layer you are working.

By that I mean, if you are adding code to the UI layer, add the least amount of logic necessary for that layer to perform it's UI (only) operations.

Not only does doing that result in a good separation of layers...it also saves you from code bloat.

mezoid
A: 

I have already written a 'compatible' answer to this question here. The rule is (according to me) that there should not be any logic in the UI except the UI logic and calls for standard procedures that will manage generic/specific cases.

In our situation, we came to a point where form's code is automatically generated out of the list of controls available on a form. Depending on the kind of control (bound text, bound boolean, bound number, bound combobox, unbound label, ...), we automatically generate a set of event procedures (such as beforeUpdate and afterUpdate for text controls, onClick for labels, etc) that launch generic code located out of the form.

This code can then either do generic things (test if the field value can be updated in the beforeUpdate event, order the recordset ascending/descending in the onClick event, etc) or specific treatments based on the form's and/or the control's name (making for example some work in a afterUpdate event, such as calculating the value of a totalAmount control out of the unitPrice and quantity values).

Our system is now fully automated, and form's production relies on two tables: Tbl_Form for a list of forms available in the app, and Tbl_Control for a list of controls available in our forms

Following the referenced answer and other posts in SO, some users have asked me to develop on my ideas. As the subject is quite complex, I finally decided to open a blog to talk about this UI logic. I have already started talking about UI interface, but it might take a few days (.. weeks!) until I can specifically reach the subject you're interested in.

Philippe Grondier
+5  A: 

As little as possible... The UI should only have logic related to presentation. My personal preference now is to have the UI/View

  • just raise events (with supporting data) to a PresenterClass stating that something has happened. Let the Presenter respond to the event.
  • have methods to render/display data to be presented
  • a minimal amount of client side validations to help the user get it right the first time... (preferably done in a declarative manner) screening off invalid inputs before it even reaches the presenter e.g. ensure that the text field value is within a-b range by setting the min and max properties.

http://martinfowler.com/eaaDev/uiArchs.html describes the evolution of UI design. An excerpt

When people talk about self-testing code user-interfaces quickly raise their head as a problem. Many people find that testing GUIs to be somewhere between tough and impossible. This is largely because UIs are tightly coupled into the overall UI environment and difficult to tease apart and test in pieces. But there are occasions where this is impossible, you miss important interactions, there are threading issues, and the tests are too slow to run.

As a result there's been a steady movement to design UIs in such a way that minimizes the behavior in objects that are awkward to test. Michael Feathers crisply summed up this approach in The Humble Dialog Box. Gerard Meszaros generalized this notion to idea of a Humble Object - any object that is difficult to test should have minimal behavior. That way if we are unable to include it in our test suites we minimize the chances of an undetected failure.

Gishu
glad to help :) However keeping that article in memory is another thing altogether... everytime I read it it's like reading it for the first time.. MVP MVC passive view supervising controller humble aaarrrggghhh!!!
Gishu