Your three questions are wrong!

I’m constantly skeptical on how hard is to make a good Stand Up (daily scrum if you prefer). Often the main point of it is missed along the path: make small checkpoints and baselines to set everyone on the same page.

Sometimes a simple status update like “yesterday I was with a problem, I’ve sent an email, I’ve got the reply and I implemented it. Today I’m going to work on the same feature” is really annoying. It doesn’t convey any information and will add nothing to the team.

A really good article about the Stand Up is the one written by Jason Yip and published at Martin Fowler blog. Although it’s a excellent source of information it bring the same three questions to be answered during the Stand Up:

  1. What did I accomplish yesterday?
  2. What will I do today?
  3. What obstacles are impeding my progress?

So, what is exactly wrong about it? Instead of answering this I’m going to propose another set of questions:

  1. What did I/we discover yesterday?
  2. What is my/our plan for today?
  3. What might impact my/our plan?

Let’s discuss a little bit about each one of these questions.

What did I/we discover yesterday?

Can I say what I did yesterday? Definitely! But, I want to know what things you discover yesterday that everyone should know. The simply things accomplished/made might not be sufficient to satisfy my curiosity of what my peers did/discovered. Remember, we want to remember what was done and also keep everyone informed.

What is my/our plan for today?

Now, it’s not a simple “I’m will continue on it”. I wanna know what are your plans, what you have discussed with your pair. The tricky is to already have some thought on it!

What might impact my/our plan?

That’s differ completely from what the original question is. It unwittingly tend us to wait until next day to raise the blocked flag. A team will need to know at the very same moment a blocked/impediment happens. Waiting for the next to communicate a very important detail that’ll avert you/team of making progress is leastwise naive. So, here, the question that I propose is make you thing of what might avoid your progress  towards your plan. And it’s ok if you don’t know of any.

And you? Any other trick question to help your team to make a good checkpoint?

 

About writing software code

In the past couple of years I’m reading and learning how to write a better software and all. It’s ok since everyone is doing it. Right?

Wrong. Learn how to do it it not the same thing as do it. Have you ever read this sentence “Any damn fool can write code that a computer can understand, the trick is to write code that humans can understand”* ?

Yes? What are you waiting to do it?

Even if my rants about it can be expressed just with words it’s always better to show an example just in case. Come along with me and let’s get through a little scenario.

Imagine you were kindly asked to create a dialog by your (client|PO|BA|mommy) to save a document. And there you go writing the code to handle it all (events, data, behavior, tests). And there is a crucial point where the user of the software will instead of pressing the save button chooses to cancel it. For your pleasure, your code:

...
file = dialog.choose_the_file_to_be_saved();
if (file == null) {
  do_not_save_the_file()
} else {
  save_the(file)
}
...

One may ask: “what’s wrong with this code?” Your dialog, which might be a system dependent one, returns null in case the user cancel the save. In order to deal with it we simply check for a null. I have to ask you: will your client knows what does “== null” means? No, she won’t.

Here comes what that sentence is all about: write code that your mom will understand. Let’s change it:

...
file = dialog.choose_the_file_to_be_saved();
if (user_cancelled_to_save_the(file)) {
  do_not_save_the_file()
} else {
  save_the(file)
}
...

You may be wondering what is inside this new method? And I show you:

method user_cancelled_to_save_the(file)) {
  RETURN file == null
} 

At this point you may still thinking: what? Creating one method just to check for a null? And I will necessarily answer to you:

-YES!

Do you know why? Your mom? Exactly! Not saving a file is a business requirement. The user will not save the file if she does press the cancel button. And you need to convey this on your code.

The method to check for a null will be hiding on your code and no one will never ever wants to know what is inside of it. I will be well tested, I trust you. Nevertheless, that is what the code is doing, right? At least the contract of these method says it. By the end you have to trust on methods or do you actually go inside your language API and confirm that your “new” method really creates a new Object?

If you wanna learn more about it, here is the link: Domain Driven Design, page 18-19.

* Fowler, Martin

ehcache and hibernate: cache of collections

Last post I wrote about activating the hibernate second-level cache. Now, let’s see how to activate the second-level cache for collections.

In this example I’ll use a Customer with Orders. Please, take a look in the representation of the relationship between them, below:

Implementing the classes with Java will look like this:

package com.rodrigow;
class Order {
    int number;
}
package com.rodrigow;
import java.util.Set;
class Customer {
    String name;
    Set<Order> orders;
}

Now, the hibernate mapping:

<hibernate-mapping>
  <class name="com.rodrigow.Order" table="ORDER">
    <cache usage="read-only"/>
    <id name="number" type="int" />
  </class>
</hibernate-mapping>
<hibernate-mapping>
  <class name="com.rodrigow.Customer" table="CUSTOMER">
    <cache usage="read-only"/>
    <id name="name" type="java.lang.String" />
    <set name="orders" lazy="false">
      <cache usage="read-only" />
      <key column="number" />
      <one-to-many class="com.rodrigow.Order" />
    </set>
  </class>
</hibernate-mapping>

There is a configuration, in bold, that tells hibernate to look in the cache for objects of this type.

EHCache configuration (ehcache.xml) will became something like below:

<ehcache>
  <cache
    name="com.rodrigow.Customer"
    maxElementsInMemory="200"
    eternal="true"
    overflowToDisk="true"
  />
  <cache
    name="com.rodrigow.Customer.orders"
    maxElementsInMemory="200"
    eternal="true"
    overflowToDisk="true"
  />
</ehcache>

In bold we tell how it will find the objects. In order to find the client’s orders, it is needed to add an entry with the same name we gave in the class Client, i.e. orders.

Now everything is ready to go. No hits in the database!!! But wait… looking the hibernate logs I’m finding hits on the database for every single Order from a Client. But, should it be in the cache? What? Cache not found for the Order? AHHH!?!?!, Well, the documentation from EHCache it’s not that good, so, let’s dive into source code.

EHCache holds a cache version of the collection but it isn’t enough for hibernate to hydrate the objects. By the time it try to materialize the objects, hibernate look for each cache version of each Order and it does not find it, therefore hibernate ends up querying database for each Order from a Client.

Thus, we’ll need to add one more entry on ehcache.xml:

<ehcache>
  ...
  <cache
    name="com.rodrigow.Order"
    maxElementsInMemory="200"
    eternal="true"
    overflowToDisk="true"
  />
</ehcache>

Now you can check hibernate logs and actually see the cache hits for each order on the customer!

hibernate: activating the second-level cache

Hibernate has two different cache levels: the first-level and the second-level cache. The first one is always activated. The second-level cache is up to you.

So, first-level cache, it’s related to session objects, i.e, objects on the managed state. These objects are results from a query, an object after inserted or updated. Again, first-level is activated by default.

In the other hand, second-level cache, when activated, it’s a in memory copy from the database. Hibernate still using the first-level cache, but, instead of querying directly the database it uses this second-level cache. Faster and do not overload the database.

The second-level it’s just a interface on Hibernate. You’ll need to use an implementation of second-level in order to get it working. In java, the most commonly used is the EHCache.

Technical speaking, to activated the EHCache you’ll need to add two properties in the Hibernate configuration:

<property name="hibernate.cache.use_second_level_cache">
   true
</property>
<property name="hibernate.cache.region.factory_class">
   net.sf.ehcache.hibernate.EhCacheRegionFactory
</property>

Note: Depending on the Hibernate version, you’ll need different configuration. Please, checkout the EHCache help page.

Next step will configure Hibernate to make the cache of an object. Directly in the Hibernate configuration, add the cache tag or use the annotation:

<cache usage="read-write|nonstrict-read-write|read-only" />
--
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)

The last step is the EHCache configuration: ehcache.xml. We need to create and define an region for our cache. The default would be the class signature:

<ehcache>
  <cache
    name="com.rodrigow.Blog"
    maxElementsInMemory="200"
    eternal="true"
    overflowToDisk="true"
  />
</ehcache

Now is just a matter to turn on the Hibernate and EHCache logs and make sure you see some cache hit. There won’t have any SQL on database.

configuring git

Some useful git configurations to candy eye it:

  • Email and username:
git config --global user.name "My Name"
git config --global user.email my@email.com
  • Aliases:
git config --global alias.st status
  • Colors:
git config --global color.branch auto
git config --global color.diff auto
git config --global color.interactive auto
git config --global color.status auto
  • Editor:
git config --global core.editor emacs

Setting up the shell to show which branch you are using. Just add this line into your .bashrc:

export PS1="\w \`ruby -e "print (%x{git branch 2&gt; /dev/null}.lines
.grep(/^\*/).first ||'').gsub(/^\* (.+)$/, '(\1) ')"\`\[\033[37m\]$ "

Don’t forget to install ruby in order to get it working.

ruby, rvm, rails, zlib and ubuntu

When installing the ruby version 1.9.2 through rvm on an Ubuntu box, you might get and error related to the zlib lib. The simple solution is to uninstall the ruby 1.9.2 version. After that, you should install zlib using rvm, as follow:

$ rvm package install zlib
$ rvm remove 1.9.2
$ rvm install 1.9.2 --with-zlib-dir=$rvm_path/usr

This should fix your zlib error.

More information: rvm website.