Wednesday, November 12, 2008

Public Methods Should be Like Stories

I believe that most of the developers try to write code to be readable as much as possible. I will try to explain how I try to achieve this. From my point of view one of the most important things is to write public methods as stories. This means when somebody is reading your public method its implementation should tell with the sentence like methods what it tries to achieve. This way one can concentrate on the business logic that the method tries to achieve and not how that is achieved.

So I try to follow few short rules:

  • Instead of code within public method call number of private methods
  • Avoid loops
  • Try to minimize if statements
  • If private method is hard to read apply this rules to private method

Following this rules your public methods are easy to understand. It is easier to test if you are doing black-box testing. What may happen to your code is that you will have number of private methods if you implement mentioned rules also on private methods. But I don't consider this to be bad because in that case even private methods are easy to understand so if one should change your code it will be easier.

As opinion is easier to understand through example, I will show one method from my http://www.flexiblefeeds.com site.

Although example is in groovy I believe it will be easily understandable for all developers. Currently method looks like this:

def currentUserVote(Long articleId, boolean upVoting) {
boolean canVote = canCurrentUserVote(articleId)

if (!canVote) {
return
}

vote(articleId, upVoting)

registerVoting(articleId)
}

I believe that is is easy to understand what the method does from the code itself. But to be sure, first it is checked if current user can vote. If user cannot vote method returns. If user can vote voting is done and then voting is registered.

Now let us see how this method can look like if the code would be embedded into this public method.

def currentUserVote(Long articleId, boolean upVoting) {
// decide if user can vote
if (!loggedInUserIsAdministrator()) {
return
}

// logged in user can vote if he didn't voted
if (userIsLoggedIn()) {
return !voted(loggedInUser().id, articleId)
}

// not logged in user can vote if he didn't voted and data is stored in session
if(votedInSession(articleId)) {
return
}

// perform voting
try {
String sql
if (upVoting) {
sql = "SQL_FOR_UP_VOTING"
} else {
sql = "SQL_FOR_DOWN_VOTING"
}
Article.executeUpdate(sql, [id:articleId])
} catch (Exception ex) {
log.error("Failed to vote up for article ${articleId}", ex)
throw ex;
}

// register voting
if (loggedInUser()) {
def a = Article.get(articleId)

try {
ArticleVoting voting = new ArticleVoting(user:loggedInUser(), article:a)
voting.save(flush:true)
} catch (Exception ex) {
log.error(ex)
throw ex;
}
} else {
if (!session().votedIds) {
def votedIds = [] as Set
session().votedIds = votedIds
}
session().votedIds.add(articleId)
}
}
Having look at this method you can notice it is possible to understand what is method doing. But beside understanding what is method doing you are reading code. It means you are doing two things at the same time. Trying to understand business logic and trying to understand how this business logic is achieved.

Therefore in all cases I would recommend to refactor such code and to extract parts of the public methods into private methods.

Tuesday, November 11, 2008

It is very expensive to work with Grails

Just to make disclaimer immediately at the beginning. I don't really thing that working with Grails is really expensive, I would display it as expensive from the funny point of view.

This post is more advertisement then real post. So if you don't want just don't read it.

Small ad. One of my latest expenses, please have a look at http://www.flexiblefeeds.com.

So lets go to the point. Some time ago I discovered Grails. I tried to write few simple applications. Then I tried to write more complex applications. Then I was investigating advance features.
And very soon, less than a month after discovery, I realized that one is able to write real web applications with Grails more or less within minutes.

But if writing web applications is so easy, why not create real web application and put it on line. And there came the first idea. I wrote http://www.grailstutorials.com, payed subscription 20$/month and put it online. Visitors are coming, site is I believe well known within Grails/Groovy community so it stays online and I am still paying 20$/month. But these money can not be compared with satisfaction having real, visited web site online.

But writing web applications with Grails is still easy. So why not try another application. I implemented (actually still implementing) http://www.flexiblefeeds.com, payed subscription 20$/month and put it online.

Now I have two Grails based applications online, still trying to improve both of them. More or less I have idea about two or three more projects that I want to implement with Grails. What I am missing is time.

So why is it expensive to work with Grails:
  • You develop web applications very fast so you will need lot of money to pay web hosting
  • You develop web applications very fast so you will need most of your free time just to try all ideas you get
  • Grails is growing so fast that you will need lot of free time just to read all the blogs and nice things you can do with groovy/grails
So if you don't want to write web applications fast and easy just ignore Grails. If you want to write web applications fast and easy than it would be wise to try Grails.

Sunday, November 9, 2008

Flexible Feeds Launched

New grails powered web site is launched. You can have a look at www.flexiblefeeds.com.

On this site you can register RSS feed of your blog or feeds of your favorite blogs or web sites. Each feed is registered in different category so you can navigate articles by categories. To help others to decide if it is worth to read article you can vote for articles.

You should give a chance to this site and you will see it can be excellent source of news in the blogging sphere.

Why this site? If you are at least a little bit like me your RSS reader is full of feeds. Feeds are probably added to different folders but you need lot of time only to navigate through all new articles. What I am missing in readers is possibility to have kind of unique view and social aspects like voting on articles and tags on articles.

All that I miss in classic readers is supported in the first release of flexible feeds.

But I don't plan to stop here. I would like to have flexibility with feeds. Maybe I want to have different views for the same category. Or I want to combine different feeds. All this and much more is planned for the next version.

And for the end, I would be glad if you register RSS feed of your blog or feeds of your favorite sites.

Sunday, November 2, 2008

Grails Conditional Tags as Method Calls Trap - Part 2

In my previous post I was discussing how grails conditional tags should be used from the code. More or less post was about how to use conditional tags within if blog. Although I thought that my approach is good comment from Graeme Rocher opened my eyes. And therefore I decided to write short post because maybe this comment wasn't noticed by others.

I planned to write this post immediately next day but as I was busy with releasing first version of Flexible Feeds I didn't have enough time. By the way you can also visit www.flexiblefeeds.com :)

But let's go to the point. My approach with conditional tags was that if I want to execute something that depends on condition that is already implemented as tag you should use structure like this one:

if (g.conditionalTag() {true}) {
// execute some business logic
}

{true} part is actually closure that will get executed in the case that conditional tag satisfy condition. I must admit that this structure looks little bit strange but if I need not to copy/paste already existing code I am happy with that.

But as Graeme correctly noticed better approach in such situations would be:

g.conditionalTag() {
// execute some business logic
}

I agree that this is more readable and easier to understand.

In the case you need if...else approach then you still need version with the {true}.

Wednesday, October 22, 2008

Grails Conditional Tags as Method Calls Trap

As you probably know grails tags can also be used within controllers as method calls. In this post I will describe the trap that caught me when I tried to use conditional tag within if statement.

Default usage of grails tag as method call can be described with the following example. g.render tag within gsp page will look like this:

<g:render template="someTemplate" model:[name:"peter"]/>

While within controller you can use this tag like this:

g.render(template:"someTemplate", name:"peter")
I must admit that this is excellent feature of the grails and I use it often. But you can get confused if you try to use conditional tags within if statements. Lets try one example.

Imagine that we have following conditional tag userHasGoldMembership that displays its content only when logged in user has gold membership. Usage of this tag within gsp page may look like this:

...
<g:userHasGoldMembership>
<g:link controller="abc" action="xyz">Perform this action</g:link>
</g:userHasGoldMembership>
...

What example does is that link 'Perform this action' will be displayed only if logged in user has gold membership.

Now let us try to use this tag as method call within controller as condition within if.

def price = 100
if (g.userHasGoldMembership()) {
price = price - discount
}
chargeCreditCard()

Well to my surprise what happens here is that g.userHasGoldMembership() always resolves to false. And after some thinking it becomes clear why this happens. Let us analyze how in the most cases conditional tags work. For example, for mentioned conditional tag implementation may look like this (and I believe this is the case for the majority of conditional tags):

class MembershipTagLib {
def userHasGoldMembership = {attrs, body ->
if (session.user.isGold()) {
out << body()
}
}
}

What we see in this code is that in the case that user has gold membership returned value from the tag will be body of the tag. In all other cases nothing is returned. But what is body within construct if(g.userHasGoldMembership())?

Well there is no body. This means that in both cases, user has and user has not gold membership, result of the tag used as method call will be null.

Does it mean that we cannot use conditional tags? Of course not. It is enough to provide body. Version of the if statement that works is:

def price = 100
if (g.userHasGoldMembership() {true}) {
price = price - discount
}
chargeCreditCard()

Did you notice the {true} part? This is actually body of the tag. It means that when user has gold membership, tag will return result of body execution and that is value true.

And of course example from the real conditional tag that is probably widely used is from acegi. Acegi plugin provides tag <g:ifAllGranted role="LIST_OF_ROLES">content to display</g:ifAllGranted>. And if you want to reuse this plugin within your controller then you have to use it in the form of

if (g.ifAllGranter(role="ROLE_ADMIN"){true}) {
do something
}
otherwise you will never get into the if part of the condition.

Thursday, October 9, 2008

javax.faces.el.PropertyNotFoundException

This is another interesting bug we had in just two days. Again one of those "this is not happening to me" bugs :)

We have JSF project and on JSF projects you are creating managed beans and setting values to those beans within faces-config.xml file.

Well for one of the new managed beans we got javax.faces.el.PropertyNotFoundException. In the first moment it seemed like one of standard typo errors but after verifing the code everything seemed ok but JSF was just refusing to set value of the managed been. Again, after some googling we found solution in this post.

Well shortly, this problem occurs if you have variable in the managed bean that starts with lower-case character after which immediately follows upper-case character. So variables with the names like: xCor, xStreamConverter or similar cannot be found by JSF and finish with the
javax.faces.el.PropertyNotFoundException exception.

java.util.MissingResourceException

These days we had two very strange errors during build of project. Our build configuration is CruiseControl with Maven.
When building project locally everything worked fine while on CruiseControl we got this error:
java.util.MissingResourceException: Can't find resource for bundle com.sun.tools.doclets
.formats.html.resources.standard, key doclet.malformed_html_link_tag
First surprise was why everything works fine locally but fails on the build server. But answer we found quickly. On build server project was build with mvn clean site but locally we are mainly using mvn clean package. After using mvn site locally we got the same error. And then we started with investigation. After hours of investigation we found solution and the problem is described with this Jira issue.

Shortly, with some build versions of Java 5, generation of javadoc will fail if there is <a somewhere in java doc.

So when writing java doc avoid <a characters sequence.