New Rails Project

I’ve been working for a while on a new Rails project and now it’s up and running. You can have a look at mintmarket.co.uk.

Building a website from ground up these days seems to be more about supporting services rather that the actual website coding. Monitoring, infrastructure, backup, building and deploying take up far more time that writing code. I think using efficient technologies like Rails leaves us with enough time to address these issues rather than ignore them.

The business model behind mintmarket.co.uk is lean and I’m glad I finally have the chance to try out the ideas from Eric Ries’s book The Lean Startup. If you’re not familiar, have a look here: theleanstartup.com.

Software Minimalism

Complexity

Complexity baffles

Well, perhaps minimalism is not the right word for what I mean, but it reflects a very important characteristic: simplicity. As a software consultant I often find myself moving from project to project and tackling different kinds of problems. But among the most common of the problems it’s over-complexity.

Complexity is the worst enemy of a software project. And it’s even worse when complexity is not even required to build the respective solution. The latter I call viral complexity because it spreads like a deadly virus killing team motivation, product quality and adding unexpected costs for future development and support. This is the sad death of many software products.

How it all starts

In most cases it all starts with a blind rush. It’s a simple requirement, a small project and needs to be ready yesterday. So we’re looking for the simplest solution that will work given our situation. We do a quick hack and voilà! The whole thing is up and running, ready to be delivered. We have little time to congratulate each other because the business comes in with more requirements. We’re supposed to be agile and embrace change so we adapt our hack to include the new changes. But again, there are more and more and more. Soon enough our hacky solution becomes a major point of complexity as we’re not merely adding features to a project, but we’re adapting a hideous hack to support more and more features for which it’s not adequate anymore.

Hurry, hurry, hurry!

By now the business is happy with the results and learns that giving just a small set of requirements for implementation upfront works great. Agile really works! They also congratulate themselves for putting pressure on the development team for releasing something quickly. What they don’t know is they’ve built a long queue of technical debt which, like all debts, is expensive. And they don’t even know they need to repay it.

The requirements keep on coming in and the developers struggle to implement them. Some never get done, others take very long. People outside the project will soon start wondering what’s going wrong. But do they really want to know the truth?

The Truth

The truth is the project started with technical debt, that the quick hack was intended to be a short-term solution to a more complex and time-consuming one. This means that as soon as the initially simple product was deployed in production, the project should have started from scratch. That didn’t happen and created a huge pile of issues that no one is willing to take the blame for.
Now it may be too late or too expensive to start again. It may also be the case that the business doesn’t really understand all this and plainly blames the developers. And so they should!

The best cure is prevention

When the business comes in saying they need a product and they need it fast and when they say it’s something simple and should take a very short while and it’s a key thing for the entire company’s business and needs to get done — it’s not the right time to panic, it’s just the right time to say no. It’s just not possible to do it without many side effects and if the business is ready to pay for the technical debt, they’d better be ready and they really need to understand this is not just developer fuss about something that not beautiful code or unprofessional. It’s just expensive.

When you want to buy a car and don’t have all the cash, you take a loan. But you know the loan comes with interest and in the end you’ll be paying more. That’s acceptable if you really need the car now and can’t wait to save the money and then buy it. The same way the business needs to now that soon they’ll need to start paying for the technical debt before adding some more features to the product.
Lack of repaying the due technical debt leads to greater complexity as adding more features to an inappropriate structure is complicated. The more features are added the more complex it becomes and harder to understand.

Start simple, keep it simple and self-explanatory

A good solution explains itself. It doesn’t require documentation, experts, expensive consultants or even code comments. Some will say these are just words and it’s easier said than done. I disagree, it’s all in the attitude.
First everyone needs to understand that we’re better off adding fewer features, but making them part of a simple and self-explanatory system. It’s always better to have a simple and stable product than a clunky one.
As more features are added, keep refactoring the system so it adequately grows to house the new functionality. If you need to build a skyscraper, it needs a solid foundation. If you start with a tent, you can’t evolve it into a skyscraper without refactoring the foundation several times. This is part of the development cost so we all need to live with it. It’s just common sense.

Think before you write code

Ask yourself before committing to a solution: is this simple enough for a newly joined developer to understand? Is this the standard way of doing it so that other developers would easily understand what we need to do? Are we using the right tools and technologies for the job?
Don’t just accept something because it works. If it’s not simple and straightforward, it’ll just bite you back soon enough. And although this is not a functional feature and no one will actually pay for it, you must make sure the system is covered by tests that not only certify its stability, but, most importantly, documents its behaviour.

Will we ever learn?

This words have been said over and over again for the past decade and still I find projects making these mistakes. I can’t stop wondering why are we never learning?

Spring Roo and Active Record

Roo Screen Shot

Roo Screen Shot

I love Spring Roo! It makes everything so simple, especially when starting a new project, that I tend to forget how rainy and unproductive were the old days of Java programming. Now it’s like the spring has actually arrived after the winter of loads of XML files, procedural service-oriented coding and redundant classes and interfaces.

DAO, Repository and the Like

It’s so cool having tiers and layers. That if you’re an onion! But if you’re a software project what you mostly need is objects, not layers, because this is actually procedural programming in disguise.

There’s a famous book by Eric Evans that teaches how to get back to the roots and use the power of object oriented programming, I really love it. Problem is the book is pretty old and really hard to adapt to the kind of coding we’re doing nowadays. Using JPA/Hibernate is of a real help, but I needed Roo to teach me the courage to adopt the Domain Driven Development completely rather that just partially.

I always wondered how I would inject the Repository into the Entity in order to achieve that independence of the domain object, that standaloneness. It just did’t sound right to me. And a couple of years ago when I started looking at Ruby on Rails I realized how much simpler things can really be. Enter Active Record, farewell DAO/Repository/EAO/etc.

Roo Generates Active Record Style Entities

Spring Roo, among other cool things, can reverse engineer a database schema and turn it into a bunch of very useful and selfmaintaining entities. There’s only a simple command:

database reverse engineer --schema MYSCHEMA

And the magic starts happening. Roo scans MYSCHEMA and generates the entities. The interesting thing is how they are generated – using the Active Record pattern.

In case you didn’t just know, Roo generates most of the code in .aj files (AspectJ) and maintains that part. As you update the .java files, Roo maintains the generated code. But for the sake of simplicity, I’ve assembled the example below into one listing.

Let’s imagine an entity called Account. Roo would generate something of the sort:


public class Account {
    @Id
    @GeneratedValue(generator = "system-uuid")
    @GenericGenerator(name = "system-uuid", strategy = "uuid")
    @Column(name = "uuid", columnDefinition = "VARCHAR", length = 128)
    private String uuid;
    @ManyToOne
    @JoinColumn(name = "registration_request", referencedColumnName = "uuid")

    private RegistrationRequest registrationRequest;
    @Column(name = "email", columnDefinition = "VARCHAR", length = 128)
    @NotNull
    private String email;
    @Column(name = "public_name", columnDefinition = "VARCHAR", length = 128)
    @NotNull
    private String publicName;
    ...
    @PersistenceContext
    transient EntityManager Account.entityManager;
    @Transactional
    public void persist() {
        if (this.entityManager == null) this.entityManager = entityManager();
        this.entityManager.persist(this);
    }
    @Transactional
    public void remove() {
        if (this.entityManager == null) this.entityManager = entityManager();
        if (this.entityManager.contains(this)) {
            this.entityManager.remove(this);
        } else {
            Account attached = Account.findAccount(this.uuid);
            this.entityManager.remove(attached);
        }
    }
    @Transactional
    public void flush() {
        if (this.entityManager == null) this.entityManager = entityManager();
        this.entityManager.flush();
    }
    @Transactional
    public void clear() {
        if (this.entityManager == null) this.entityManager = entityManager();
        this.entityManager.clear();
    }
    @Transactional
    public Account merge() {
        if (this.entityManager == null) this.entityManager = entityManager();
        Account merged = this.entityManager.merge(this);
        this.entityManager.flush();
        return merged;
    }
    public static final EntityManager entityManager() {
        EntityManager em = new Account().entityManager;
        if (em == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
        return em;
    }
    public static long countAccounts() {
        return entityManager().createQuery("SELECT COUNT(o) FROM Account o", Long.class).getSingleResult();
    }
    public static List findAllAccounts() {
        return entityManager().createQuery("SELECT o FROM Account o", Account.class).getResultList();
    }
    public static Account findAccount(String uuid) {
        if (uuid == null || uuid.length() == 0) return null;
        return entityManager().find(Account.class, uuid);
    }
    public static List findAccountEntries(int firstResult, int maxResults) {
        return entityManager().createQuery("SELECT o FROM Account o", Account.class).setFirstResult(firstResult).setMaxResults(maxResults).getResultList();
    }
}

Isn’t that beautiful?!

No More Incomplete DDD

For too long I have written incomplete DDD code where almost all the business code went into the model objects themselves while some of it crept into the so-called service classes. So, if an entity needed another entity to make some calculations, things had to go into the service because this guy could have Repositories injected to retrieve the entities required for the respective  calculation. This made the DDD incomplete, impractical as well as boring to code.

The Active Record pattern is fixing this by making it simple to write (if not to generate) and beautiful to use:

// disable an account
Account account = Account.findByWhatever(whatever);
account.disable();

or

// use the new keyword
// TODO even better, use a static factory or builder
Account account = new Account();
account.setEmail("my@email.com");
account.setPassword("secret");
account.persist();

Efficiency

I’ve always hated writing boilerplate code. The service classes were usually Spring Beans or EJB stateless sessions. They also called for an interface, not necessarily, but it is considered a good practice. OOP? To me the service class looked a lot like C code. No state at all, just some methods grouped in by functionality. It even had the header file – the allegedly good-practice interface.

Using Active Record and implementing a rich domain can replace a lot of boilerplate code and make everything more natural, object oriented and efficient.

Testing is Impossible Using Active Record

God, I hear that a lot. Is it just me or people like to repeat what the hear instead of thinking about it for a minute? There is this thing that was invented like in the Stone Age of Agile development – it’s called mocking. Nowadays with the advancing of technology, the invention of iPad 2 and the sending of a new rover to Mars, we can mock even the static methods.

To prove to you testing is possible, Roo even generates the (integration) tests. But I won’t paste the example here, I’ll let you try it instead. I works, you know!

Stay productive, efficient and employed!

Software and Fashion (really?)

I haven’t met many software people who followed fashion, in fact many of them despise it. So several times I’ve heard why: fashion is so superficial and dealing with such shallow things that is not the thing for a geek spending hours in front of the computer trying to optimize loading data from the database with the new and cool ORM, or trying to figure out how to fix a security vulnerability in an Internet Banking application.

I’m not so sure this is right, not even sure it’s a good idea to think this way. Because building software is much like fashion design.

What? No way!

Adopting a great clothing style creates a wonderful image of yourself in the eyes of the others. No need to tell anyone how important is to dress up for the occasion, but let’s try to figure out what’s really going on.

Fashion

Fashion

Dressing up, having a nice style as well as being in fashion has a big impact on the people you interact with. Remember the seeing is believing saying? Seeing has an insurmountable psychological power on an individual because perceptions are built upon data sent by the senses (and sight is quite important among the others). That’s why people easily believe what they see. For example, it’s been quite hard to accept that the Sun is not actually moving around our planet as it looks like, but the other way around. And humanity accepted that, again, after seeing it using telescopes. What we see is utterly important and hard to ignore even if judgement dictates otherwise. So this may be shallow, but that’s the way we function and going against our nature is not feasible in every circumstance.

Geeks can dress up their software instead

Now it’s true that not many programmers go out much in a sense they need to create a good impression by using the latest and trendiest fashion outfits. So I agree fashion may not always serve them unless they take to a more un-geek career that requires relating with people a lot, managing, selling stuff or something similar. Spending most of your time in front of a computer makes fashion pointless.

However I want to point out that the geekiest of geeks that may live in a basement and spend 99% of their time in front on the computer screen still interacts with the world through the product of his/her work — something we normally call software.

The software product is my social outfit

We build software for users. Sometimes they are corporate employees, sometimes they are homeworkers, single moms or rebel teenagers. But they will almost always judge us by the software we’ve built for them. The same as folks on the street may judge us by our clothes.

Being out of fashion in software may be dramatic as users would part their ways. So what I’m trying to say here is that building software may have a lot more in common with being a fashion designer than we may have previously thought.

Software too is a matter of image.

Mobile Flash and the Sensory Experience

Having more features for your consumer oriented product doesn’t necessarily sell better. It will make it look nice in a comparison chart, but that advantage is not bound to last. The customers will form their own opinion as soon as they start using it and if they hate it everyone else will know in a press of page reload on Twitter.

How’s a device good?

fritz höger, kirche am hohenzollernplatz, berlin 1930-1933 by seier+seierTo be good means to be liked by the consumers. To be great — it has to be loved. But thinking for a moment, how do people begin to like a device, a smartphone for example? A person would normally first see the device, then touch it and interact with it. So the first steps towards a good impression is the looks and the feel.

I would go about the same way in what concerns software. Liking it means it should be beautiful and it should feel nice. That is to say the User Interface is the major player in assessing software quality.

Mobile Flash delivered a bad sensory experience

Recently Adobe announced they would discontinue development for the mobile Flash Player. This is the end of iOS doesn’t support Flash argument and the victory of the end-user positive experience. The Flash player performed poorly on mobile devices and was not ready for the touch screen interaction. Steve Jobs had foreseen this and pointed these issues in the famous Thoughts on Flash letter.

Bottom line is that a poor feature can hinder the overall user experience with the device. Thinking for a moment we can clearly see that web browsing is a fundamental activity for a smartphone/tablet user and most of the websites have Flash banners. Not even wishing to see the rich media that Flash exposed on the Web, users would be annoyed by a sluggish device.

So Android didn’t feel right because is was slow while the iOS device felt great because it was very responsive. And since humans form perceptions using the sensory information they extract using their senses, like vision, some of the Andriod users would form a negative perception and yearn for the beautiful iPhone.

Software is great if the UI is great

This is not novelty whatsoever, but there are so many companies out there that build sheets of features instead of good software that sometimes I’m ashamed to admit I’m a programmer. This is the same as boasting a certain device supports Flash.

The main thing for consumer oriented software is to be perceived well and then to get the job done. No one really cares about the little extra features most customers don’t even use. No one wants the features that are so hard to use they even cause more frustration than if they hadn’t existed in the first place. And no one could care less about the database or so-called technologies employed to build the software.

Unlike programmers, users have no grasp of the internals of software, just as us, humans, when we interact with each other, we note our external looks, language and body language or we exchange feelings. But we rarely note the internal state of each other’s bowels in a middle of a discussion. We just can’t notice these details using our senses and, because perception is made out of sensory information, we can’t build perceptions of such hidden things.

Users work with what they can see and feel. If the application is ugly or slow, it leads to the creation of a negative perception in the mind of the users. This is very difficult to overcome, even well featured software may find it hard to fight such a negative perception and on the long term, users tend to switch to other solutions as they become available.

Beautiful, simple, fast, obvious and friendly, these are the qualities that software needs to expose before implementing tons of features just to overcome their competitors. This is what less is more means in this industry and this is why Apple is so loved by the consumers.

Dart is the new JavaScript (hopes Google)

Google published a draft specification of a new programming language Dart. The intention is that Dart replaces JavaScript on the long run making it a lot easier to program web clients. It is currently at a very early version — v0.0.3.

Optional Typing

Undoubtedly, JavaScript’s prototypal typing isn’t too popular, especially among programmers coming from the Java platform. Dart is offering a good alternative and a clear and concise class definition style:

class MyClass {
  // put the class definition here
}

But this is not breaking the dynamic typing the seasoned JavaScript programmers have come to love. Instead Dart offers an interesting middle way called optional typing. This means the developer may choose between writing static typed code and dynamic typed or even combine both at the same time.

var birthYear = 1452;
int birthYear = 1452;

Both declarations above are valid.

Closer to Java than JavaScript

The new language goes way beyond JavaScript borrowing many language constructs from Java. It supports interfaces, single-class inheritance, constructors or static factories. Here is what the early preview spec says:

Dart is a class-based, single-inheritance, pure object-oriented programming language. Dart is optionally typed and supports reifi ed generics and interfaces.

So it yields considerable power, but  also brings in the possibility of cleaner code on the client side web development.

How Would it Run?

Google claims Dart will eventually run on all modern browsers using a native interpretor (likely to be build into Chrome) or a JavaScript translator. For the moment only Chrome, Safari and Firefox are supported.

The code can be embedded into web pages just as js code can be:

<script type="application/dart">
      main() {
        Element element = document.getElementById('message');
        element.innerHTML = 'Hello from Dart';
      }
</script>

And yes, it has the main() method!

Example

This is a more extensive code example, depicting the Dart syntax:

main() {
  Shape shape = new Rectangle.withSizes(10, 5);
  num area = shape.computeArea();
  print('We calculated the shape area to be ${area} units.');

  Polygon poly = new Square.createLargeSquare();
  area = poly.computeArea();
  print('We calculated the area of the polygon with ${poly.lines} lines to be ${area} units.');
}

interface Shape {
  num computeArea();
}

class Polygon implements Shape {

  // numeric field (private because it starts with _)
  num _lines;

  // constructor
  Polygon(num lines) {
    this._lines = lines;
  }

  // abstract method
  abstract num computeArea();

  // getter
  num get lines() {
    return _lines;
  }

}

class Rectangle extends Polygon {
  num _width = 1;
  num _height = 1;

  // constructor with defaults
  Rectangle() : super(2), _width = 2, _height = 1;

  // named constructor
  Rectangle.withSizes(width, height) : this() {
    this._width = width;
    this._height = height;
  }

  num computeArea() {
    return this._width * this._height;
  }

}

class Square extends Rectangle {
  // empty constructor (just calling super)
  Square(num size) : super.withSizes(size, size);

  // static factory
  factory Square.createLargeSquare() {
    return new Square(999999999);
  }
}

The output will be:

We calculated the shape area to be 50 units.
We calculated the area of the polygon with 2 lines to be 999999998000000000 units.

You can test the code yourself in an online environment at try.dartlang.org.

Dart’s APIs

Dart has 2 APIs (they call them libraries): Core and DOM.

  • Core Library contains interfaces to support common data structures and operations.
  • DOM Library contains interfaces to the HTML5 DOM, loosely based on the proposed HTML5 standard as specified by the W3C/WHATWG. These interfaces will evolve in parallel with the HTML5 standards.

The Core is documented here http://www.dartlang.org/docs/api/index.html.

Using the new NSPopover (since Mac OS X 7)

NSPopover in action

NSPopover in action

NSPopover is the animated balloon-like component that shows the downloaded files in Safari 5.1. This was added in Mac OS X Lion. If you ever wondered how to add it to your code, it’s extremely simple.

How it works

The principle is that the popover links a NSView with a certain position in the window. The NSView contains the stuff the user will see in the popover while the position is what the popover will point to. This is a NSView itself, usually a NSButton (like in our example). So we’ve got 2 NSiews: the popover view and the trigger view. Looking at the image on the right, the popover view contains the application icon and the You may put anything here text. The trigger view is the round button called Popover.

How it’s made

First let’s create the main window containing the Popover button. It would be nice to have an on/off button. When the button is pressed, the popover should appear whereas the button is depressed, the popover would, not surprisingly, disappear. Then, completely separate from the main window, we’ll add a NSView and put the image and text inside it. Finally we can add the popover. To do that, in the xib editor we search for NSPopover. An object named Popover and View Controller will come up. We need to drag it into the objects list in the xib.

Popover XIB

Popover XIB

The popover is already connected with the controller, so we only need to connect the controller’s view property with our view. That’s the actual trick, this is how the popover knows to display the custom view when it’s shown.

Connection popover controller with view

Connecting popover controller with view

And finally we are left with implementing the button action. This may look like this:


- (IBAction)togglePopover:(id)sender
{
    if (self.buttonIsPressed) {
        [self.popover showRelativeToRect:[popoverTriggerButton bounds]
                                  ofView:popoverTriggerButton
                           preferredEdge:NSMaxYEdge];
    } else {
        [self.popover close];
    }
}

To determine is the button is pressed or not, look for the button’s value.

- (BOOL)buttonIsPressed
{
    return self.popoverTriggerButton.intValue == 1;
}

Detach the popover to a window

This is a pretty cool effect. Users can drag the popover and this would create a nice transition to a window. For this, a method needs to be implemented in the popover’s delegate (NSPopoverDelegate):

- (NSWindow *)detachableWindowForPopover:(NSPopover *)popover
{
    return self.popoverWindow;
}

The window can have different contents than the popover. Actually it must contain other components and if we wanted to show the same things as the popover we’d need to copy those from the popover. In our example, we changed the label text slightly.

Popover-Window Transition

Popover-Window Transition

Sources

To help you getting started with NSPopover, you can download the complete source code for the example application described in this post:

PopoverExample.xlsx (change extension from xlsx to zip after download, wordpress restrictions).

JUnit with new Date()

Writing unit tests for your code is great, but there are situations when it’s not possible without a little tweaking of the code itself. This is actually one good reason to write the test first.

For example, what do we do when confronted with the situation of writing a test for the following code:

public BigDecimal getInterestRate() {
  Date now = new Date();
  if (now.before(SWITCH_DATE)) {
    return oldInterestService.getInterestRate(ProductType.CREDIT);
  } else {
    return newInterestService.getInterestRate();
  }
}

The method is intended to get the interest rate from the old interest rate service unless we have passed a certain switch date. In this case, another service needs to be used to get the interest rate.

So how do we unit test this method? Well we can’t. It’s because of the infamous

Date now = new Date();

Writing a test for this will be unpredictable since every time we run it, the new Date() will return a different result.

Passing in the date as a param? Using a factory? Not so nice…

Normally we need to write 2 tests. One for the case when new Date() is before the SWITCH_DATE and assert the oldInterestService is used. Another for the case when new Date() is equal or after the SWITCH_DATE and assert the newInterestService is used.

To be able to quickly fix this, the Date can be passed in as a parameter to our method:

public BigDecimal getInterestRateForDate(Date date) {
  if (date.before(SWITCH_DATE)) {
    return oldInterestService.getInterestRate(ProductType.CREDIT);
  } else {
    return newInterestService.getInterestRate();
  }
}

Unfortunately this is not so great because we don’t completely encapsulate the implementation any more and actually allow the caller to control the resulted value. The caller may force using one service or another by passing a past or future date.

So we need some way of setting the date, but only from our test. Using the factory pattern may come in handy, but won’t be long until it would show its ugliness and weirdness. Why introduce complexity where things can be a lot more cleaner and easier?

Using a DateTimeService and mocks

If we have Dependency Injection at hand (like with EJB, Spring etc), and this is the case for most Java enterprise applications, things are about to get very neat. Why rely on the new Date() to tell us what day is today? Instead we can define a separate service for that. The big advantage is that we can later mock it.

public interface DateTimeService {
  Date getCurrentDate();
}

Then have it injected into the code and use it to get the current date.

public BigDecimal getInterestRate() {
  Date now = dateTimeService.getCurrentDate();
  ...
}

Of course, the default implementation of the DateTimeService interface would just return new Date(), but in our tests, we can mock it and have it return any date we need. Let’s assume we’re using EasyMock in our tests:

@Test
public void interestRateIsRetrievedFromNewInterestServiceAfterSwitchDate() {

  Date dateAfterSwitchDate = ...
  expect(dateTimeService.getCurrentDate()).andReturn(dateAfterSwitchDate);
  replay(dateTimeService);

  ...

}

Using EasyMock is just an example, but since the DateTimeService is an interface all mocking libraries will manage to work with it without any special tricks.

All this while the production code would use a simple implementation like:

public class DefaultDateTimeService implements DateTimeService {
  public Date getCurrentDate() {
    return new Date();
  }
}

Taking it further

Now a word from our unit test

Now a word from our unit test

This is a simple solution, but in the end it proves to be very powerful. This separation may be taken even further, especially in large enterprise systems. We all know how much applications rely on the system date. Trouble is that in large and heterogeneous deployments, the system date may vary slightly from system to system and sometimes it’s best the application retrieves its current date form a specialized system — like from a time server.

This can be easily accomplished by adding another implementation of our DateTimeService and have it connect to our time server instead of relying on system’s date. All other servers in the cluster, the DB etc. may do the same thing.

The only trick is to never use new Date() in code. Thankfully having your code unit tested will reveal all the dirty new Date()s before entering production an causing mayhem in, let’s say… credits department of a global bank.

Sorting through long and cluttered JavaScript code with MVP

JQuery is a wonderful tool for JavaScripters and it’s been around for years, showing its true power and simplicity. But even jQuery falls short of solutions when the web site/application grows in size and complexity.

After writing a lot of JavaScript code on a web application, it becomes more obvious that the direct way of doing it is not the right way and ends up having code no one understands anymore.

So how to get rid of the JavaScript clutter? Enter MVP!

Model View Presenter

Actually it’s all about separation of concerns. The problem with most code is it mixes 3 aspects:

  1. AJAX calls
  2. DOM manipulation
  3. Event handling

We can call them the Model, the View and the Presenter and instead of putting them together in one place, we can define separate objects for each.

Let’s see how the code may look like on a page that performs an async search.

The Model

var model = {
  searchWebsite: function(searchQuery, handlers) {
    $.ajax({
      url: "/search",
      type: "POST",
      data: "q="+searchQuery,
      success: handlers.success,
      error: handlers.error
    });
  }
};

This guy is only responsible for sending the search query to the server, to the right URL and using the right method (POST). He will not interpret the response to populate the page with the results, for example. That’s not his problem. He only manages server calls.

The View

The View, on the other hand, he knows about how things are arranged on the page. He’s really good at finding stuff in the DOM tree, moving things around, changing styles and so on. In our example, he’ll be responsible for installing a handler on the search button, providing the search query and, later on, putting the results where they belong.

var view = {
  installSearchHandler: function(searchHandler) {
    $("#searchButton").click(function () {
      var searchQuery = $("#searchQuery").val();
      searchHandler.call(this, searchQuery);
    });
  },

  showSearchResults: function(searchResults) {
    for (aResult : searchResults) {
      // create a DOM node and show the aResult in it
      $("#searchResults").append('<p>'+aResult.title+'</p>');
    }
  },

  showSearchError: function(error) {
    $("errorDiv").show();
    $("#errorDiv #errorMessage").html(error);
  }
};

The Presenter

This guy is responsible for putting things together, he’s the middle man, deciding the flow of the page. The Presenter will install the listeners into the View and send requests to the Model to retrieve or send data from and to the server. An important aspect of the Presenter is that he’s aware of the other 2.

var presenter = {
  init: function() { // start from here (page load)
    view.installSearchHandler(this.search);
  },

  search: function(searchQuery) {
    model.searchWebsite(searchQuery, {
      success: function(data) {
        view.showSearchResults(data.searchResults);
      },
      error: function(data) {
        view.showSearchError(data);
      }
    });
  }
};

Starting up this chain of objects

The presenter.init() is supposed to start up this whole deal, from there on, he’ll handle everything and delegate tasks to the view or model as appropriate. We can use jQuery document ready for this:

$(document).ready(function() {
    presenter.init();
});

And we’re done!

What’s the gain?

Now that we’ve implemented our search the MVP way, let’s take a moment and look at our accomplishment. Why did we do this? What is our gain? If that’s not obvious, let’s see how the code would have looked without structuring it the way we did:

$(document).ready(function() {
    $("#searchButton").click(function () {
      var searchQuery = $("#searchQuery").val();
      $.ajax({
        url: "/search",
        type: "POST",
        data: "q="+searchQuery,
        success: function(data) {
          for (aResult : data.searchResults) {
            // create a DOM node and show the aResult in it
            $("#searchResults").append('<p>'+aResult.title+'</p>');
          };
        },
        error: function(error) {
          $("errorDiv").show();
          $("#errorDiv #errorMessage").html(error);
        }
      });
    });
});

Everything is put together in one place, making it harder to read and understand what is all about.

On the other hand, if we look at our presenter, we understand immediately what the page is supposed to do: search by a searchQuery and, in case of success, showSearchResults, in case of error, showSearchError. You notice we used words from the code itself to explain what the page does – that’s because the code sounds more like an English language phrase than cryptic JS code.

In the real world out there, the code grows a lot more, as well as the clutter. Out there, this design will prove even more useful while our counter-example – even worse.