Writing a flexible code

For sure it’s a very desired subject, for both development teams and management as well. Flexible code allows us to keep the code base beautiful, clean, testable, gives us the ability to accommodate new features without struggling to existing components, and new features won’t probably impact in previous ones.

In despite of the fact flexible code is so wanted for almost everybody, I’ve seen so many times entire teams fighting to add a single new feature, fighting to management to get few extra hours to be able to re-factor some code and so on.

I thought it would be very nice to bring this topic to an open discussion, about how to achieve a flexible code in our applications, sharing my ideas to help some other people to understand a bit more about this mechanics and learn more from others as well, so let get into this.

The first thing to talk about flexible code is Test Driven Development ( TDD ), because it’s a shift and how to build programs using this technique. It is possible to write every single code using the cowboy mode, I mean, we usually have a flow inside our heads, we know how to link things together and we go straight that way without thinking about how things should behave or not. That approach “works”, of course, if it didn’t nobody would have never ever delivered a single software solution, but in the majority of those “success” cases people delivery a poor quality software. The first big problem is that without tests we can’t be sure neither if the code is working as it’s supposed to be, nor if it will keep working after the first change on it. TDD is a true mind shift about how to write software, aiming first the simplicity, because at a coarse level we have to create a test first to our classes, subsystems and complete deliverable (story, use-case, etc). So, if we are building something weird our tests will tell us about that, and we’ll also be able to run our tests suite against the old and new code, which will show us how it is going, and if any error pops up we’ll be noticed and able to fix it shortly.

The second aspect of a flexible code is to apply constant refactorings to the code base. Why ? because things usually never gets well done at first, maybe because our knowledge is limited at that time, and also, because a good decision today can be an impacting factor tomorrow, people change, business change and so on. So, it’s always good to leave the place better than we found when we arrived. Of course, we don’t need to refactor an entire code base at once, refactorings should be used as we go, specially in small steps. A good example is picking up a big method which is preventing us to add a new behavior and create a test case against it ( if there isn’t one ), apply some refactorings to extract methods, variables and so one.

After all, code must be written targeting human beings and secondly machines, because the computer can understand everything we write, unless we commit some typo and then the compiler will catch us. On the other hand, humans need something clean and not misleading to understand to keep working on.

The third aspect I will talk in this post is the usage of design patterns to guide our design towards a flexible code. As you may know, design patterns are proven solutions to remove code duplication and provide us a more clear tool to communicate our intentions inside the code we write. What is most clear, trying to explain a 1.000 lines class or say you have a flexible algorithm because you are using a strategy pattern for example ?

There are many other things to discuss about flexible code, but I preferred to limit our universe into these few points, and I’ll be bringing more information on the next posts where I’ll explain these topics in more depth, I hope you enjoy reading it as much as I’m enjoying writing it.

 

Australia, new country, new life

Hi Guys,

It’s been a very long time since my last post, so I thought I had better show up again :-)

Last year was an year full of work, big challenges, tight deadlines, emotions and very nice surprises. The earth shaking thing was that I finally received my permanent residence visa last December, which allowed me to migrate to Australia.

People usually ask me : Man, are you crazy ? why do you want to do this ? why a so far far away place ? I always answer laughing!

Well, the reasons were always very simple and obvious to me, because I always had the desire to live abroad, being inserted inside a different culture, so I had been pursing this objective until I got it. Australia was the best option to me, as a Brazilian it’s been very comfortable to adapt to a similar weather, culture and values.

I will complete one month living here and I can say that it’s a very nice and beautiful country, with very nice, kind and educated people. The experience of living here has been great, my family’s adaptation is going very well and I have no complaints !

Of course, there is the overhead of a fresh start, learning everything again, know new people, show how competent and dedicate I am, I still think people will talk to me in Portuguese, and I still have the feeling I’m still in Brazil (that is completely crazy), but it’s all part of the package ;)

So, I couldn’t be happier !

My presentation about JBoss Clustering at RIOJUG 02/25/2010

Last Thursday I did a presentation about JBoss Clustering at RioJug, and it was a very nice, energized and pleasant night. The room was full and people there were eager to participate and asked me a lot of interesting questions about the topic and beyond.

I’d like to thank again RioJug’s leaders for the time spent and all attendance that did not care about the heavy rain that felt just before the session.

If you weren’t there, you can see the presentation at SlideShare : http://www.slideshare.net/marciomarinho/jboss-clustering

Sorry, but as I presented it here in Brazil, it is written in my mother tongue portuguese.

Injecting new skills into the team

Last week I passed through a very nice experience, so, I couldn’t hold my self about the desire to share it.

Out team needed to build something really new and a bit though, also we have a very mixed skill sets in the team, furthermore we had to bring awareness to everybody about what should be done and how, but we had no easy way of doing this. The solution couldn’t be better, we defined two sessions of what I called “team design/programming”, where we locked ourselves into a room, using a notebook and a 50″ TV, this way everyone could see what was happening. We started presenting the goal of that session, what we would look for, what to build, the platform we’re aiming and so on.

After that we started coding and all of us could code a bit, fix, re-factor, bring new ideas, ask questions, discuss and help. That was really an amazing experience, in despite of the fact that sometimes someone wanted to dominate the notebook ( that includes myself :D ). The bottom line of these sessions was a well defined platform, everybody having the knowledge about what we did, why, how, the ability to provide support to other teams, and now we have these new skills into the team. That was really astonishing.

Bringing new people into the team

Change is always something stressing at some level, because there is uncertainty, energy must be spent to adapt, react, change minds, learn new skills and so on. I’ve passed through the experience of move from companies and also moving from different teams inside the same company, and I learned something very useful about it.

It’s a very simple rule of making the newcomer comfortable with the new environment, making things clear and easy to him/her, give them time to breath and perceive the environment. Also, the team should be supportive to this new person, because the adaptation will be at the speed of light in comparison of any other kind of environment.

Happy new year !

I wish all of you my friends a very happy new year. May all your plans become true !!!!!

In 2010 I will be very activelly posting nice things to share and discuss with all of you ;)

Sincerely,

Marcio Alves Marinho

Domain Driven Design, The Repository pattern

I’ve seen so many times a heated discussion about Repositories in Domain Driven Design, there is a kind of misunderstanding and/or confusion about what really a Repository is.

People usually disagree about the role of the Repository, if it should be a kind of  “Data Access Layer”, such as a DAO or if it must be something that is injected in the domain class, then it will talk to the DAO in the beneath layer.

I’ve always wondered why people had these fights, but now I can see why ! The thing is, as far as I read in the book (Chapter 10 : Supple Design),  the examples of Reposotory has been shown almost exactly as a DAO implementation. I even downloaded the source code examples from the Domain Driven Design Community, and the example IS a DAO implementation, as I’m showing below :

<code>package se.citerus.dddsample.domain.model.cargo;

import java.util.List;

public interface CargoRepository {

  /**
   * Finds a cargo using given id.
   *
   * @param trackingId Id
   * @return Cargo if found, else {@code null}
   */
  Cargo find(TrackingId trackingId);

  /**
   * Finds all cargo.
   *
   * @return All cargo.
   */
  List findAll();

  /**
   * Saves given cargo.
   *
   * @param cargo cargo to save
   */
  void store(Cargo cargo);

  /**
   * @return A unique, generated tracking Id.
   */
  TrackingId nextTrackingId();

}
</code>

and the implementation

<code>
package se.citerus.dddsample.infrastructure.persistence.hibernate;

import org.springframework.stereotype.Repository;
import se.citerus.dddsample.domain.model.cargo.Cargo;
import se.citerus.dddsample.domain.model.cargo.CargoRepository;
import se.citerus.dddsample.domain.model.cargo.TrackingId;

import java.util.List;
import java.util.UUID;

/**
 * Hibernate implementation of CargoRepository.
 */
@Repository
public class CargoRepositoryHibernate extends HibernateRepository implements CargoRepository {

  public Cargo find(TrackingId tid) {
    return (Cargo) getSession().
      createQuery("from Cargo where trackingId = :tid").
      setParameter("tid", tid).
      uniqueResult();
  }

  public void store(Cargo cargo) {
    getSession().saveOrUpdate(cargo);
    // Delete-orphan does not seem to work correctly when the parent is a component
    getSession().createSQLQuery("delete from Leg where cargo_id = null").executeUpdate();
  }

  public TrackingId nextTrackingId() {
    // TODO use an actual DB sequence here, UUID is for in-mem
    final String random = UUID.randomUUID().toString().toUpperCase();
    return new TrackingId(
      random.substring(0, random.indexOf("-"))
    );
  }

  public List findAll() {
    return getSession().createQuery("from Cargo").list();
  }

}
</code>

This Repository is used by a class called BookingServiceImpl :

<code>
package se.citerus.dddsample.application.impl;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.transaction.annotation.Transactional;
import se.citerus.dddsample.application.BookingService;
import se.citerus.dddsample.domain.model.cargo.*;
import se.citerus.dddsample.domain.model.location.Location;
import se.citerus.dddsample.domain.model.location.LocationRepository;
import se.citerus.dddsample.domain.model.location.UnLocode;
import se.citerus.dddsample.domain.service.RoutingService;

import java.util.Collections;
import java.util.Date;
import java.util.List;

public final class BookingServiceImpl implements BookingService {

  private final CargoRepository cargoRepository;
  private final LocationRepository locationRepository;
  private final RoutingService routingService;
  private final Log logger = LogFactory.getLog(getClass());

  public BookingServiceImpl(final CargoRepository cargoRepository,
                            final LocationRepository locationRepository,
                            final RoutingService routingService) {
    this.cargoRepository = cargoRepository;
    this.locationRepository = locationRepository;
    this.routingService = routingService;
  }

  @Override
  @Transactional
  public TrackingId bookNewCargo(final UnLocode originUnLocode,
                                 final UnLocode destinationUnLocode,
                                 final Date arrivalDeadline) {
    // TODO modeling this as a cargo factory might be suitable
    final TrackingId trackingId = cargoRepository.nextTrackingId();
    final Location origin = locationRepository.find(originUnLocode);
    final Location destination = locationRepository.find(destinationUnLocode);
    final RouteSpecification routeSpecification = new RouteSpecification(origin, destination, arrivalDeadline);

    final Cargo cargo = new Cargo(trackingId, routeSpecification);

    cargoRepository.store(cargo);
    logger.info("Booked new cargo with tracking id " + cargo.trackingId().idString());

    return cargo.trackingId();
  }

  @Override
  @Transactional
  public List requestPossibleRoutesForCargo(final TrackingId trackingId) {
    final Cargo cargo = cargoRepository.find(trackingId);

    if (cargo == null) {
      return Collections.emptyList();
    }

    return routingService.fetchRoutesForSpecification(cargo.routeSpecification());
  }

  @Override
  @Transactional
  public void assignCargoToRoute(final Itinerary itinerary, final TrackingId trackingId) {
    final Cargo cargo = cargoRepository.find(trackingId);
    if (cargo == null) {
      throw new IllegalArgumentException("Can't assign itinerary to non-existing cargo " + trackingId);
    }

    cargo.assignToRoute(itinerary);
    cargoRepository.store(cargo);

    logger.info("Assigned cargo " + trackingId + " to new route");
  }

  @Override
  @Transactional
  public void changeDestination(final TrackingId trackingId, final UnLocode unLocode) {
    final Cargo cargo = cargoRepository.find(trackingId);
    final Location newDestination = locationRepository.find(unLocode);

    final RouteSpecification routeSpecification = new RouteSpecification(
      cargo.origin(), newDestination, cargo.routeSpecification().arrivalDeadline()
    );
    cargo.specifyNewRoute(routeSpecification);

    cargoRepository.store(cargo);
    logger.info("Changed destination for cargo " + trackingId + " to " + routeSpecification.destination());
  }

}
</code>

Well, I cannot deny that I did not dig so deep into the code ( and I did not finish the book ) yet,
but what I can state for sure is that this architecture really looks like this sequence :

Repository Sequence Diagram
Also, the layering :

Layering Repository Diagram
Ok, I know I am over simplifying things here, but my intention is only to communicate my point of view about
the topic. I’m not saying that what is inside this code is wrong at all, I am just skeptical about how “new” or
effective this thing is, because I’ve been developing large scale software systems using the same approach, but with a
different name “DAO”, and so far I could not see anything different from this. I might let you guys twist my arms in the end of the book,
but so far I’m pretty sure the Repository and a DAO pattern are the same thing.

Any idea, suggestions, thoughts and counter-argument are very welcome ! :)

Building a ubiquitous language – 1

The ubiquitous language is one of the crucial parts of Domain Driven Design, because it’s the basis of all communication among all the team. It’s hard to point out how it’s important to a project, because maybe everyone inside a project have a particular “view” about the same project, I mean a business analyst would be closer to the user who is giving the requirements, and afterwords these same requirements will be translated to a bunch of documents and diagrams that will ultimately reach the developers, who will deliver the most waited product, the production code!

As I stated before, the communication is the heart of everything in software development, so, how can we achieve of deliver the software that the customer wants if we can’t completely understand the user language, jargons and way of work ? we simply CAN’T.

I remember a project where I worked, first providing bug fixes, and later working to re-write it, where we had a glossary about all the terms the software had, of course, they were all related to the users terms. This application was a governamental app, that handled some kind of documents and users workflow. So, the users usually talk to us using their language, about how the documents should be “routed” between two departments, how it should be handled, who was responsible for “stamp”, “endorse”, “forward” or “deny” something related to the documents they were receiving. The glossary was a nice tool to capture those things we did not know, because we’re all IT guys, not business owners.

The bad thing was that this was the only place where we had some insight about what the user think or need, and what are their jargons and way to work. Our domain model did not express those things at all, so it was hard to get some clue about what that software was in the first place, because the code did not express the domain model, and worse, the domain model did not express the business case. We only started to have some clue after few meeting with the users, then we started to say “Eureka” this thing is that piece of code !

Domain Driven Design

After a long time, I’m rushing to finish the Eric Evans best seller book Domain Driven Design, and I found very interesting the ideas inside it. I’ve been fan of object-oriented, software architecture and OOAD since the first time I learned OO, a long time ago.

The idea behind Domain Driven Design is very simple :  Put the model to work through a set of techniques that will make the development easier, things more clear, and shield the domain model against things that doesn’t belong to there. As a known issue, the domain model is the most critical issue behind enterprise software development, because it’s the heart of every software written by a human. Every single funcionality comes from it, and the domain is the basis of all external interfaces and services, because is the Domain Model responsibility’s to deal with the business issues.

Seems to be clear and easy to understand ? the answer is yes and no !

Software is about humans writing software ( good or bad ones ), and a software is just a tool to achieve a business goal, such as “place an order” to buy a book. The company’s goal is to sell the book, but it will need a good software that supports their business needs. Coming back to the part of putting the model to work, where a model is an abstraction of the reality, I mean, a way to visualize and communicate the ideas behind that particular software that we’re writing.

I’ve seen so many times a model that has little to say about the software that is running or it completely does not say anything anymore about working program, because someone draw it in the past, but they did not evolve it, in order to keep track of their communication. It’s very frustrating to start work on a software like this, because it looks like there is a documentation or concepts that will guide us to understand the problems the software is supposed to deal with, but in the end what exists is a poor picture about some fact in the past. So, domain driven design tackles this issue, putting the model to work, bringing life to these pictures, in order to communicate what exacly the software is, keeping track of changes, creating a unique vocabulary between technical and non-technical people ( the Ubiquitous Language ), that is a technique to put everybody on the same page, speaking the same language.

Talking about Ubiquitous Language, I answered a post at linkedin few days ago, because there was a person who asked which “Jargons” he should use to present a software architecture, and I just answered him, use a language that the his audience can understand better, preferrably use or build a Ubiquitous Languag, because you can’t have a concept that the user doesn’t understand, because it will lead you to an infinite talk about what is what, there will be lots of misconceptions and you’ll fail to deliver a good software… and I hope he listened to me.

Making your code more testable

Testability is one of the most beautiful, desireable and must have feature that a code must be compliant. Nowadays there is no space for untested and low quality code, that means many problems at production environments, long hours debugging code, and late delivery.

As usual, this is again a farly big subject that I will try to resume in few tips to improve code’s testability as follow :

First of all, start designing and writing a test for your code before you write your business code, just follow test driven development approach.

Never write long methods, because it will probably lead to low quality code and cluttered design, as a result it will make your test very difficult. If there is a need for such a big calculation, temporary variables or things like this, then just split the big method into smaller methods and delegate your calls.

Add the right responsibility to the right object, another smell that will make your tests hard is when one object knows too much about the other object’s internals.

Try to write cleaner and less code, because less you write, less errors you’ll produce/find, and faster will be your program.

Singletons are usually evil for tests, because they usually cache some data that may hurt you.