@TODO

test

leave a comment »

this is a test

Written by cramsdale

October 5, 2012 at 9:27 pm

Posted in Uncategorized

Complex systems in need of simple solutions

leave a comment »

Wouldn’t it be nice if your business could throw an assertion when you’re completely hosed?

In the technology industry it seems that we’re constantly faced with the challenge of integrating and maintaining large systems across a rather diverse, and often global, ecosystem. And while we may fumble along the way, the end solution is generally a good, and sometimes extraordinary, one. All involved parties are happy and, as if that weren’t enough, a system of automated checks are put into place to ensure that they stay that way. At my current job we maintain a set of developer tools used by a slew of internal and external teams. To ensure that changes we introduce don’t break existing projects, we run a series of automated tests as part of our continuous build process (pulling in pieces of other applications as often as possible). If there are errors, sensors go red, emails start flying…you get the picture. Not too different from other software teams.

While flying back from SFO to ATL I started questioning why it was so hard for the airline industry to do the same — integrate seemingly disparate systems and apply a set of tests to ensure that your solution is still on par. I know, they seem like such an easy target. You’re right, they are. But the airline industry is also a good example of a business that is so fundamentally inefficient, the opportunity to change is by and large low hanging fruit. And while the fact that the Federal and State Governments have their hands in the pot makes matters it a bit more complicated, it makes the opportunities even riper for the picking. To make the conversation a bit more digestible (and realistic), I’ll all but forego the topic of upgrading their internal computing systems (ticketing, air controller consoles, navigation systems, etc…), and instead focus on coordination, execution, and reallocation of workers and cost.

The way I see it there are two fundamental initiatives in play:

  1. Airlines need to increase revenues
  2. The Government needs to increase security

Two simplistic points that lead to a handful of juxtaposed situations. To start with, let’s look at what the airline industry has done to increase revenue. In a knee jerk reaction it has started charging passengers more to check their luggage and, what I would argue most impacting, removed the notion of your first bag for free. As a result we all start stuffing as much as we can into carry-on bags that we normally would have checked. In a parallel, and completely uncoordinated effort, the Dept of Homeland Security (DHS) continue to step up security, especially after the Christmas crotch explosion incident. I’m in no way against increased security, but increasing scrutiny of luggage while you simultaneously increase the amount of luggage is an exponential recipe for disaster. Security lines grow, stress goes up, and customers are unhappy. Basics of business #1: unhappy customers are less likely buy your product or service at an increased price, and if anything, will drive the price down. We see this unfolding right now; airlines are in a perpetual race to the bottom when it comes to ticket prices. The resulting gap in revenue has to be made up somewhere. I know…let’s just raise the price of checked luggage. Wait…no…isn’t what got us here in the first place?

The DHS actually does care that you’re waiting 45 mins to get through security. The only problem is that their solution to decrease wait time is more of the same. X-ray machines that are a step above an easy bake oven, and attendants that overlook a jock strap lined with explosives because their too busy interrogating my kid’s sippy cup. To say they’re throwing money into a failing system is an understatement.

On top of that, the overhead of handling luggage doesn’t simply disappear when high prices motivate travelers to carry-on rather than check it. It simply shifts the work from the counter to the flight attendants. Flight attendants already have to spend hours in a confined area, with a 100 or so needy passengers and crying babies. Do we really want to piss them off anymore than they already are. Basics of business #2: unhappy employees will breed unhappy customers (please see point #1).

It’s a nasty set of circular dependencies in which no one benefits. Something and someone has to give…and I’m afraid that it has to be a joint venture between the Airlines and the Government.

Starting with the issue of security, the Government needs to invest in and install hi-tech, full body x-ray machines. Ones that are completely automated, requiring human intervention (in the form of law enforcement, not TSA employees) only when it detects a possible security issue. When our build breaks external projects, we don’t call support, we call an Engineer because they’re the ones that can fix the problem. This has the added bonus of creating longer term jobs rooted in the technology sector rather than short term jobs in the construction sector. Admit it, you’re not terribly happy with billions of dollars going to road construction either.

Next remove the ticket counters all together. The check-in kiosks have been a success from day one. They already allow me to specify how many bags I’m checking, having them dispense those wrap around stickers isn’t asking too much. Keep the carousel running, and guess what? I’ll put the bag on there myself. Remove the fees for checked luggage, and offset your lose in revenue with your cost savings here.

Finally take some of the stimulus money and lend it to airlines that want to upgrade their existing computer systems. And while you’re at it, upgrade the control towers. The 1960’s green radar screens scare me to death. I know, I said I would stay away from this topic. But seriously, if this isn’t prime for Government investment, I don’t know what is. Creates technical jobs: check. Long term: without a doubt. Return on invest: almost guaranteed as the result is a leaner, more efficient company. Basics of business #3: maximized efficiency = lower costs = increased margins = higher profits.

If there was a big flashing light that went off every time these two entities botched an opportunity, it would have burnt out a long time ago. The sad truth is that there is no light, and they have no way of knowing that they’re fundamental screwing up. Everyone is operating in their own silos, with no coordination, and poor lines of communication. The Government needs to take the first step and fix the inefficiencies within our security system, and use this first step as a way to motivate the airline industry to follow suit. With the really low hanging fruit picked, they can move into a more strategic relationship, where Government funds are being used to bring this archaic industry into the 21st century.

Written by cramsdale

April 4, 2010 at 5:00 pm

Posted in Uncategorized

MVP – The UiBinder Way

leave a comment »

Check out the GWT doc, “Large scale application development and MVP” for context.

If you’re like others, the MVP I/O presentation got you thinking about writing GWT apps in a different (presumably more structured) way. Then we come along and ship 2.0 with this fancy new UiBinder feature, and you’re left wondering, “great, can someone help me understand how to make this work with my shiny new MVP-based app?” One thing to note is that it’s not the layout of your UI that’s your real hurdle. It’s hooking up the UI events with the @UiHandler annotation that has you scratching your head. The reason, and solution, below.

So you’ve followed along with Ray’s presentation you most likely have Presenters sinking click events on Widgets inside of the View, and at a meta level abstracting Widget events out of the Views. Something akin to the following in your Presenters:

display.getDeleteButton().addClickHandler(new ClickHandler() {
  public void onClick(ClickEvent event) {
    ...
  }
});

Now let’s say you’re taking in the UiBinder goodness, and you’ve moved all of your layout code over accordingly, and now you’re wondering how to sink events. You checkout the GWT 2.0 docs and quickly find that what you want to do is use the @UiHandler annotation like this:

@UiHandler("deleteButton")
void onDeleteButtonClicked(ClickEvent event) {
  ...
}

But where does this code live? It can’t live in your Presenters unless they’re going to a) declare the interface that extends UiBinder, and b) call initWidget, in which case you’ve completely mangled Presenter and View code, and you’re now going to have to rely on GWTTestCase to test all of your complex application logic. This is bad.
So, this leaves us with the Views. But wait, now my Views have knowledge of Widget-based events, and doesn’t that defy MVP best practices? At its purest level it may, but we need not be so stringent. The goal, at least from a GWT perspective, is to maximize code coverage using vanilla JRE tests.

So starting with the fact that the delete button click will originate from the view, we start to work our way back into the Presenter where all of the real work happens. So flip what you currently know on its head, and move the Display interface, defined within the Presenter, to a Presenter interface defined within the View. Clear as mud right? Bear with me…

public interface ContactsView {
  public interface Presenter {
    void onAddButtonClicked();
    void onDeleteButtonClicked();
  }
  public void setPresenter(Presenter presenter);
  public List<Integer> getSelectedRows();
  public void setData(List<String> data) {
}

Your ContactsPresenter then ends up looking like the following:

public class ContactsPresenter implements ContactsView.Presenter {
  public ContactsPresenter(ContactsServiceAsync rpcService,
      HandlerManager eventBus, ContactsView view) {
    ...
    this.view.setPresenter(this);
  }
  ...
}

Pretty straight forward, and we can still mock out our ContactsView so that we can test our ContactsPresenter using a vanilla JRE test. Finally we end up in the more complex, deleteContacts() within our ContactsPresenter.

public void onDeleteButtonClicked() {
  List<Integer> selectedRows = view.getSelectedRows();
  ArrayList<String> ids = new ArrayList<String>();
  for (int i = 0; i < selectedRows.size(); ++i) {
    ids.add(contactDetails.get(selectedRows.get(i)).getId());
  }
  rpcService.deleteContacts(ids, 
      new AsyncCallback<ArrayList<ContactDetails>>() {
    public void onSuccess(ArrayList<ContactDetails> result) {
      ...
    }
  });
}

That’s it, move an interface around, have your Views and Presenters know a little more about each other, but not so much that we hinder our ability to test and swap out views. And really this is just half of it. I’ll follow-up with a method of driving more complex views that will remove the need for the getSelectedRows() and a setData() method that takes in a list of primitives. After all, don’t we really just want to pass DTOs around?

Written by cramsdale

March 16, 2010 at 2:37 pm

Posted in Uncategorized

DevNexus – GWT Best Practices

leave a comment »

I gave a “GWT Best Practices” presentation at the DevNexus conference here in Atlanta yesterday. The presentation covered:

  • Creating MVP-based apps
  • Integrating UiBinder
  • Driving complex Views
  • Bundling resources
  • Code splitting
  • Prefetching RPCs

Oddly enough, it was followed up with a presentation by David Chandler entitled “GWT MVP Case Study”. Luckily for both of us, the two presentations complimented each other. In fact, without evening knowing it, David even managed to stumble upon some of the same design concepts that we’ve been baking up in the bikeshed (subversion repository).

My presentation slides can be found here.

Written by cramsdale

March 10, 2010 at 5:14 pm

Posted in Uncategorized