Model – View – Controller (MVC). Where do you put your business logic?

When I first started doing Rails development over a year ago, I often found other developers suggesting that I refactor my code to move the business logic out of the controller, and into the model.  After this happened several times, I wondered why this seemed so obvious to them, and why that wasn’t the way I was naturally doing things.  It wasn’t just me and another developer approaching problems in different ways.  It was multiple people approaching problems in a similar way — and then me.  I wondered why there was this general difference in thought processes and solutions?

I began to passively wonder if my background in Java was contributing in some way to my way of thinking here.  Since then, I have also heard other Rails developers who are working with former Java developers say things like

"these are good developers but they keep putting business logic in their controllers!"

That made me think more seriously about what a person’s Java background might have to do with this.

VIEW 

In earlier days of PHP, classic ASP, and early JSP, it was OK to put business logic in the view.  Back in the day, it was common to find <% %> tags in JSPs with all kinds of logic in the Java code.  I think we all now agree that business logic does not belong here. 

let the view deal only with DISPLAYING what it has.

MODEL 

It seems like I’ve spent a lot of time seeing a model as simply a data-holder class.  Something like a Struct in C.  Something like a Bean in Java, with private attributes, and with get/set methods for each attribute.  It’s just a data transfer object, nothing more.  But why?  Perhaps it comes from my EJB days.  That might explain why so many other former Java developers do the same thing.  To us,

the model carries data but is dumb. 

CONTROLLER 

I always thought of the controller as being the one smacking around the model objects to get them to do what the controller wants – and

what the controller wants the model to do, is the business logic. 

A RAILS WAY OF THINKING 

Give the model more credit.

The model isn’t so dumb after all.  It doesn’t just hold state.  It contains the business logic behind the behavior of that model.  A model knows better than any other code how itself behaves, what it does or does not do, and how it interacts with the outside world.  I can try to predict how my brother will behave in a given situation; I can take a guess based on what I know about him.  But only he knows for sure, and the only way I can know for sure is to interact directly with him and find out.

Let the controller control the flow of information.

This leaves the controller with only the responsibility of collecting information and routing it to the right place.  It’s the electronic curator that finds and obtains art, and hands it off to the decorators to display.  He decides what pieces go in which rooms.  However, the decorators (analogous to the view) are the ones that decide how to arrange the art within that room for all to see.

I still need to be reminded sometimes to not put so much logic in my controller.  It is starting to come more naturally to me, but old habits die hard I suppose.  This way of thinking makes more sense to me now that I understand where my past way of thinking comes from.  I like this new way because it really makes sense now, and also because

I find that code re-use comes much easier when needed business logic is already available in the model.

.

Posted in code. Tags: , . 7 Comments »

My big move: from Java to Ruby

I’m pleased to announce that effective 6/9/2008 I have accepted a Ruby/Rails job with MedWiz Technologies. I’m taking the leap from Java, which I’ve done for over 9 years now, into Ruby, which I’ve been interested in for over a year. I’m very excited, somewhat nervous, but very much looking forward to this new opportunity and step in my career!

Posted in Uncategorized. Tags: , . 7 Comments »

JSTL and boolean values

I just realized something I did not know about the JSTL <c:if … > tag recently.

I had assumed that the item in the conditional test had to be either a Boolean object, or some other expression that would evaluate to a boolean primitive type. But JSTL is also smart enough to handle the String value “true” as a boolean as well (I didn’t know that before!)

As a Boolean object, this results in putting fish in the water:

In the Java:
request.setAttribute(“aquariumHasWater”, Boolean.valueOf(someMethodThatReturnsBooleanPrimitive()));

In the JSP:
<c:if test=”${aquariumHasWater}”> <aquarium:putFishInWater /> </c:if>

As a String, JSTL is smart enough to know the String value “true” and deal with it as a boolean

In the Java:
request.setAttribute(“aquariumHasWater”, Boolean.toString(someMethodThatReturnsBooleanPrimitive()));

In the JSP:
<c:if test=”${aquariumHasWater}”> <aquarium:putFishInWater /> </c:if>

Many times we have methods that return primitive boolean values.

Since primitives are not objects, we can’t put them in the Session/Request/etc. We have to convert it to some Object. A Boolean. Or A String. So I got to wondering, which way is better? Does it matter?

So I dug into the way it works (thanks to the JAD decompiler) and figured out that ultimately, the String value is “coerced” (org.apache.taglibs.standard.lang.jstl.Coercions) into being a Boolean object, by calling Boolean.valueOf() on the String. So, it would be slightly more efficient to just call Boolean.valueOf() on the primitive to begin with, rather than calling Boolean.toString() on the primitive, only for the taglib to turn around and just call valueOf() itself.

For anyone curious enough to see this coercion code, here’s a portion of the coerceToBoolean() method taken from the org.apache.taglibs.standard.lang.jstl.Coercions class:

public static Boolean coerceToBoolean(Object obj, Logger logger) throws ELException {
  String s;
  if(obj == null || "".equals(obj))
    return Boolean.FALSE;
  if(obj instanceof Boolean)
    return (Boolean)obj;
  if(!(obj instanceof String))
    break MISSING_BLOCK_LABEL_70;
  s = (String)obj;
  return Boolean.valueOf(s);

  ... // more

}
Posted in code. Tags: . Leave a Comment »

The life & times of JSP custom tag libraries

First off, I must say that I have used this diagram of the JSP Tag Lifecycle  so many times: http://www.examulator.com/images/iteration_tag.png It has been an invaluable resource.  If some of the events I’m talking about in this post don’t make sense in the big picture, take a look at that diagram.

I recently came across something interesting that I didn’t know before. Sometimes the doAfterBody() event handler does not get invoked within the lifecycle of custom JSP tags that extend TagSupport. Once I figured out when and why, it seems obvious. I just never thought much about it before.

I was creating a custom tag that could optionally take parameters (similar to the way jsp:include tag does). I created a parent tag (aquarium:hasfish) and a child tag (aquarium:param) to be used like this:

<aquarium:hasfish>
   <aquarium:param species=angelfish />
</aquarium:hasfish>

Event handlers for aquarium:hasfish are invoked in this order:

1. doStartTag()
2. doAfterBody()
3. doEndTag()

It is important that the aquarium:param child tag is evaluated before the aquarium:hasfish parent tag does what it needs to do. In other words, since the child tag lives in the body of the parent tag, the body of the tag must be evaluated before the parent tag does anything.

This is how this works:
1. The child tag executes, takes the param value, sets the value on it’s parent tag, and it’s done.
2. the parent tag then does its processing and can use the param value set by the child in step 1.

For the child tag to execute first, the parent tag must wait to use the param until the child tag in the body has executed. Event handlers for BOTH tags together are invoked in this order:
1. doStartTag() for aquarium:hasfish
2. doStartTag() for aquarium:param
3. doEndTag() for aquarium:param
4. doAfterBody() aquarium:hasfish
5. doEndTag() aquarium:hasfish

The param value is not available yet in step 1 when doStartTag() is invoked. The parent must wait until Step 4 doAfterBody() or Step 5 doEndTag() before it can use the param. So it doesn’t matter if you put the parent tag’s code in doAfterBody() or doEndTag(), just pick one, right? Maybe. Read on…

——————————————————————-

If we aren’t interested in passing a parameter, these two examples are basically equivalent….

<%-- no parameter example 1 %-->
<aquarium:hasfish>
</aquarium:hasfish>
<%-- no parameter example 2 %-->
<aquarium:hasfish />

….or are they?

For the most part they are equivalent. Both examples are empty tags without any tag body to evaluate. But when you look at the life cycle of a custom JSP tag that extends TagSupport, there’s one subtle difference.

The second example evaluates the following event handlers in this order:
1. doStartTag() for aquarium:hasfish
2. doEndTag() aquarium:hasfish

What happened to doAfterBody? doAfterBody() doesn’t get invoked in the example 2. Even though there’s an empty body in example 1, there is no body in the example 2. So, doAfterBody() isn’t invoked because there’s no body after which to be invoked.

Makes sense, no body == no after body. Keep in mind if you have custom tags in your application that may or may not have something in the body.

What’s the lesson here?
———————–

1.

<aquarium:hasfish />
/* doAfterBody() not called */
<aquarium:hasfish>
</aquarium:hasfish>
/* doAfterBody() is called */

2. make sure to put the parent tag’s functionality in doEndTag() NOT doAfterBody() if there’s a chance that your tag could be used like

<aquarium:hasfish />

instead of

<aquarium:hasfish>
</aquarium:hasfish>
Posted in code. Tags: . 1 Comment »

JSTL empty operator

A teammate and I were foiled by an interesting JSTL quirk this week. The code looked something like this

<c:if test="${not empty aquarium.fish}">
    <!---- feed the fish or something ---->
</c:if>

THE PROBLEM

The problem was, the fish were being fed whether the aquarium was empty or not.

The code

<c:if test="${!empty aquarium.fish}">

behaved the same, weird way. But we were sure, either way, that our syntax was correct. So that leaves only one question: WTF?

We know that we’re receiving an instance of aquarium from a method call developed by another team. We know that getFish() returns a java.util.Collection. Other than that we don’t care about the implementation, we just want our fish. In theory.

So we dug into the code for the other team’s getFish() method, and found out that our Collection is actually implemented as a HashSet. And JSTL behaves a little weird with respect to the empty operator: it does not work with java.util.Set. Incidentally this isn’t a problem in JSTL 1.1 or 1.2, and unfortunately we’re stuck using JSTL 1.0 for now. So unfortunately this forces us to know how this Collection is implemented in order to know how to handle it.

WHY?

As of JSTL 1.1, “… the Expression Language now belongs to the JSP specification (JSP 2.0).” [from the JSTL 1.1 spec]

Since versions numbers don’t always line up such that it’s clear what is compatible with what, here’s a view of which JSTL versions go with which JSP versions:

JSTL 1.0>JSP 1.3;  JSTL 1.1>JSP 2.0;  JSTL 1.2>JSP 2.1;

Now let’s compare the specs for the empty operator

From the JSTL 1.0 Spec:

To evaluate empty A:

  • If A is null, return true,
  • Otherwise, if A is the empty string, then return true.
  • Otherwise, if A is an empty array, then return true.
  • Otherwise, if A is an empty Map, return true
  • Otherwise, if A is an empty List, return true,
  • Otherwise return false.

From the JSP 2.0 and 2.1 Spec, which are identical in this regard:

To evaluate empty A:

  • If A is null, return true,
  • Otherwise, if A is the empty string, then return true.
  • Otherwise, if A is an empty array, then return true.
  • Otherwise, if A is an empty Map, return true
  • Otherwise, if A is an empty Collection, return true,
  • Otherwise return false.

The difference is the last comparison. The older version uses the List interface, the newer uses Collection interface. List is a sub-interface of Collection, so anything that’s a Collection but not also a List will not work in JSTL 1.0. For example:

  • The “empty” keyword in JSTL will work for things like List, ArrayList, LinkedList, Vector, etc.
  • The “empty” keyword in JSTL will not work for Set, HashSet, TreeSet, etc.

REFACTOR

There’s 2 options around this.

1: upgrade.

2: If that’s not an option, there is another workaround.

The nice thing about “empty” is that it will check for both null and empty lists for you. Our workaround had to be a little more verbose:

<c:if test="${aquarium.fish != null && !aquarium.fish['empty']}">
    <!---- feed the fish or something ---->
</c:if>
Posted in code. Tags: . 15 Comments »