Archive for the ‘java’ Category.

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 :

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();

}

and the implementation

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();
  }

}

This Repository is used by a class called BookingServiceImpl :

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());
  }

}

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 !

The Java Development Environment

Well, you can call me nostalgic, but I really miss it :)

What I miss in Java development environment is a tool or a set of tools that makes easy to develop and provide a good workbench for developers, just like the old Delphi or nowadays Visual Studio .NET.

Just to clarify I am not an IDE addicted and I like to perform some manual tunnings in the application as well, but as JEE development gets more complex, like using Spring, Hibernate, EJB 3, WebServices, JSF, and a huge stack of frameworks sometimes it’s difficult to get everything configured, setup, tested and validated quickly.

There are plugins for eclipse, IntelliJ that helps a lot, and NetBeans is doing a great job on this direction trying to build a unified environment ( NetBeans IDE + GlassFish + Frameworks support and so on ) to help developers to have a more consistent environment.

One hard to goal to achieve to bring a good level of productivity to the development team with the tools they are using, I mean, we always have to use lots of things, such as eclipse, maven, and so on, and sometimes the time spent struggling to some problem because they don’t have the right tool. But, I am confident we are getting better with out tools.

A good bookshelf

Well, I’ve been postponing this for so long, but not anymore :)

If you didn’t already read my post about learning, please read it first.

These are the books I consider nice books to learn how to program, what is agile methodologies, OO/OOAD, Java/J2EE/JEE and Software Architecture.

1) To learn learn Java and JEE you should read this books :

Head First Java, 2nd Edition -> This book is a very nice and didactic introduction about Java (Fundamentals).

Test Driven Development: By Example -> The title talks for itself.

SCJP Sun Certified Programmer for Java 6 Exam 310-065 -> If you want to take the certification and have an in depth explanation about some core java subjects, this book is for you. (Fundamentals)

Head First Servlets and JSP -> This book is about Web Development with Java, and also a help to pass in the certification, this book is part of Head First Series, that is a very didactic reading.  When I was studying Java Web Development, I used the next one, but feel free to choose the most convenient 4u. ( Web Dev )

SCWCD Exam Study Kit -> The same subject as the previous one. Actually there is a second edition of this book, but as I don’t read it yet, I’m suggesting the first edition. ( Web Dev )

Head First EJB -> The best book to learn the fundamentals of EJB 2.x spec. Of course this specification became deprecated with the introduction of EJB 3 spec, but there still a lot of things running on the previous spec in the world. So, it’s nice to know how things work if you have to provide some maintenance on this ( Distributed Programming )

Mastering Enterprise JavaBeans, 3rd Edition -> The same as before, but this book will give you another view ( not so didactic ) about EJB 2.x ( Distributed Programming )

EJB Design Patterns: Advanced Patterns, Processes, and Idioms -> Almost the same thing as I wrote for Head First EJB… if you want or need to develop something on that way, take a look at this book. ( Distributed Programming )

Enterprise JavaBeans 3.0 (5th Edition) -> Now we got the an interesting point. In this book you’ll learn the new way of develop distributed components using the EJB 3.0 spec. This book shows how to work with business components as pojos, the life cycle, mapping the database ( JPA ) and more. ( Distributed Programming )

Java Messaging -> Here you will learn distributed programming model in java using asynchronous messages and JMS.

Core J2EE Patterns: Best Practices and Design Strategies (2nd Edition) -> Design Patterns focused on the J2EE world.

2) To learn Software Integration, SOA and EAI :

Service-Oriented Architecture (SOA): Concepts, Technology, and Design -> This is a award winner book about SOA. Here you’ll learn the guts of SOA, the concepts, what is a service, how to build a service, how to compose a service, what is the true and the false SOA. This book is a must read for every one that wants to work with software integration. ( Distributed Programming / SOA )

SOA Principles of Service Design -> A sweet continuation of the above subject. ( Distributed Programming / SOA )

Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions -> A book about Enterprise Application Integration. This book shows lots of design patterns about how to handle software integration using messaging. ( Distributed Programming / EAI / Messaging )

3) If you wanna learn about what UML is and how to use it, then this books will help you :

UML Distilled -> Although this book is about the old UML specification (1.3) I still consider it a good introduction, but feel free to choose any other you want !!!!

4) Learning OOAD :

Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development (3rd Edition) -> As the book’s title said.

5) To Learn Design Patterns and Software Architecture :

Head First Design Patterns -> An introduction about what design patterns are and how to use it properly. I recommend you to read this book first because it was written on a simple, visual and didactic language, and you won’t have to fight with the complex code that the Gamma’s book will show you ;)

Design Patterns: Elements of Reusable Object-Oriented Software -> This is the design patterns book ! At this point things will become very interesting. Here you’ll learn in depth how to apply design patterns to avoid code duplication, bad designs and make you software flexible enough to accommodate changes easily and keep woking. The down side of this book is the C++ syntax, but indeed this is one of the best books you ever read !

Patterns of Enterprise Application Architecture -> This is an awesome book about Enterprise Software Architecture. This one is a must read for all enterprise software developers. It covers a wide range of topics, such as layering your application, concurrency, domain models, remoting, presentation patterns and more.

Pattern-Oriented Software Architecture Volume 1: A System of Patterns -> Another great book about software architecture, here you’ll learn a more general SA.

Software Architecture in Practice (2nd Edition) -> Another sweet SA book. This one has lots of good contents about what is an architecture, how to create it, how to document, evaluate and analyze the costs. Throughout the book you’ll see very beautiful examples about many different systems challenges and their solution.

Domain-Driven Design: Tackling Complexity in the Heart of Software -> Here Eric Evans brings valuable thoughts and teachings in how to design a good and functional software taking care, modeling and preserving the domain model.

Applying Domain-Driven Design and Patterns: With Examples in C# and .NET -> Maybe the concepts of Evans book will be dense to digest, so this book will help us with some other practical examples.

6) Learning about Agile Software Development :

Extreme Programming Explained: Embrace Change (2nd Edition) -> The roots of XP development.

Agile Project Management with Scrum (Microsoft Professional) -> Scrum from manager’s perspective (Scrum Master).

Agile Software Development with SCRUM -> Scrum for software developers.

Lean Software Development: An Agile Toolkit -> Lean principles in software development management and process.

Well, I’m gonna stop by here, what else I will propose you to buy the whole amazon website + the company :D

I will revisit this subject sooner, trying to bring something else to share with you. Another tip I want to share it that you should not feel unmotivated because there are so many books up there !!!

You don’t need, you can’t and you won’t read everything at once ! what else you’ll need a psychiatrist, in order to help you to recover you mind. As I don’t want you to damage your brain, I will ask you to follow my tips :

I tried to put the books on some kind of “natural” way, kind from beginning to expert, but feel free to choose whatever fit in your needs, you can mix basic ones with distributed computing or even architectural with methodologies. I tried to make it easy for novices to have an “easier” path to go, but you can build your own path and feed your knowledge hungry !

I hope I could help you to learn more and better, feel free to post a comment back !

See Ya !

Will a persistence framework always be enough ?

Indeed, persistence is always a nice topic to discuss, and I’d like to bring here more one round about this so nice subject.

In the early Java days, we used to create our persistence layer programatically, we simply used an Active Record design pattern ( or something closer to it) to make our classes “persistable”. Some time later, we introduced the DAO design pattern inside our applications, creating an abstraction to separate our “dirty work” to access any data resource, in this case, most common a database connection, and CRUD operations.

Nowadays, we’ve seen the advent of Object-Relational mapping tools, such as Hibernate, TopLink, Kodo, among many others. Nobody can deny that these tools are becoming better and richier every day, adding new features, development plugins, database support and so on. The best advantage of using them is the bridge they make between our application to the database, solving or trying to solve the well known object-relational impedance mismatch problem. Besides that they have some mechanisms that facilitate our lives as developers. I can point out Hibernate features :

  • Transparent Persistence
  • Flexible Mapping
  • Query Facilities
  • Metadata Facilities, among others.

You can know more looking into Hibernate’s website.

In opposition what people tend to believe, an object-relational mapping tool will be enough when we won’t need some in depth database specific capability. But, sometimes we need more. Depending on what kind of system we are dealing with, we’ll need care more about performance, we may have some legacy database to deal with, there might have some company policy that forces us to access data through stored procedures, or issue some special SQL statement, a PL/SQL block, a Transact-SQL block, or something related.

In these cases, I’d like to stand against the myth about portability between databases !

As I told before, there are people who believe that a persistence framework will shield their applications about every single database system, or evey every single different problem found in an Enterprise Software. That’s indeed a really wrong ideia about enterprise software.

Instead, I do prefer to give an appropriate solution for each case. The the role of any software developer, is to choose the most suitable solution for a given problem. We should not limit everything to a single solution, doing so, we might be making things more difficult to solve than it should be.

It’s not a sin to use a separate DAO and make JDBC calls, and it WON’T prevent you to migrate your application to another database. Of course a dose of common sense, analysis and good design are always welcomed. There are design patterns and guidelines to help us in how to develop a better data access layer using both a persistence framework and plain sql/jdbc access, and the effort to migrate your application won’t be a big deal, as long as you didn’t build your entire software inside your database.

I consider two nice actions dealing with this situation :

  1. Keep any specific sql inside your database ( as a stored procedure ). Doing so,you’ll have a centralized repository, you can have your sql tested and validated for free, instead of keeping strings inside your application, that can change and break your functionality.
  2. Issue any batch operation to your database, because in most cases it’s is easier and cheaper to call a procedure/function to query and calculate something ( that is already there in the database), rather than try to load this data on a distributed environment, passing through a network, and summarize your information in memory.

So, my answer is NO, there are situations where a persistence framework won’t be enough to solve your problems. You should bear in mind that there is more than one way to solve a problem, and keep your view as pragmatic as possible, in order to don’t limit your solution to a single vendor / product / architecture / etc.

In this first post, I provided some ground about this discussion, there are a lot more to discuss about this subject, and I will be posting more about this sooner. ;)