Wednesday, February 3, 2010

Partial commits with git

I've been using git for a few months now. Like all the best dev tools it has slowly permeated my workflow to the point where I'd feel pretty crippled without it. In fact, I don't think I would ever go back to a centralized system like svn at this point. In a pinch I'd fall back to using git locally and then using the appropriate git-to-foo integration to push my local changes from my git repo to whatever the centralized repository was.

So, git is great. However, there's one practice which is common amongst git users which I am still uncomfortable with (even though I do it myself on occasion). I'm referring to the practice of staging some, but not all, of the changes in your working tree to the index, and then committing that partial change set. For example, let's say I've been hacking away on my stamp collector application. I added the ability to 'tag' stamps (folksonomy now being mainstream enough to appeal to your average philatelist). While I was working, I also fixed a couple of badly named methods that I happened to come across during my other changes. With git I can decide to commit these changes separately, through judicious use of the index. I can say 'add changes to files x and y to the index, but leave out z for now', then commit, then add the changes to file z to the index, and then commit that change. If I want to get really fancy I can even add some of the changes to a file to the index, but not all changes. This way I can seperate my changes into two logical commits, one for the feature addition of tagging stamps, and one for the miscellaneous method name cleanup.

This is definitely one of those features that is very cool once you realize the power it offers. It means someone else reviewing my commits will have an easier time, and it even means that I could roll back my feature addition change but still keep the method name cleanup work. Still, I would submit that this can be a Bad Idea.

Why does this concern me? Because any such partial commits haven't been tested before being commited. At this point you might be thinking "Well, don't know about you, but I run my tests before each commit". The point here is that the tests run before you commit are run against your working tree, which in the world of git isn't necessarily the same as your commit. In the Good Old Days of svn, the changeset in your working tree was always the same as the changeset in your commit. With git and the index (aka the stage, aka the cache, don't get me started on that) that's not the case. Your working tree may contain changes to files x, y and z, but you've decided to only commit the changes to files x and y. Or even more extreme, you've decided to commit the changes to file x but only some of the changes to file y (maybe the other changes where related to your method renaming binge). So you're running your tests against one set of code (your working tree, with changes to x, y, and z), but your commit is another set of code. I think that ninety nine times out of a hundred this distinction won't matter. Your "technically untested" commit would still have passed the tests anyway. Plus, what you're almost certainly following it up straight away with another commit which will be the same as your working tree. What are the chances that someone will manage to stumble upon an invalid state like that. Probably really low. But still, kinda scary I think. It seems a bit like saying "well, this race condition is really unlikely to happen, right...". I'd rather not have to even think about that. Another thing to consider is the 'cool' use case that someone could decide to revert one commit but not the other.At that point you have code sitting on head that hasn't been tested.

One solution to this would be to ban the use of commits that don't include all changes in the working tree. Yeah, right. Not likely, and not helpful. Staging is definitely a useful way to add more structure to your change history, and not something I'd like to leave behind.

I wonder if a better solution could be achieved with the judicious use of commit hooks. What if we had a pre-commit script that would take the change set that was about to be committed (NOT whatever is in the working tree) and run tests against that tree. If the tests fail the commit fails. Now we would be left in a place of greater confidence than before. We wouldn't even need the discipline to run the tests by hand, because even if we forgot then git would be running them for us anyway. To be honest I'm not sure of the feasibility of creating this kind of setup. I'd love to find out more about how feasible it would be.

Option number 3 would be to have a CI pipeline such that you don't ever commit changes to a branch that others can touch until the CI system has had a chance to run tests against your commit. Instead, you would always be commiting changes to a private branch. The CI system would detect your commit, run a build, and then merge your changes into a shared branch if and only if your commit passed muster. I don't think this would prevent commits in the middle of a batch of commits being pushed to your private branch from bein un-tested, but it would prevent the system ever getting into a state where the shared head is untested. This is an idea I'm planning to blog about more at some point in the future.

In conclusion, while I find myself sometimes taking advantage of this powerful feature of git, I always feel a little nervous doing so, and try and take extra care.

Sunday, January 31, 2010

an inverted include? for ruby

I've always found it a slightly hard to read ruby which uses Enumerable#include?(), especially when the Enumerable your testing against is a literal or a constant. For example, let's say you're checking an input parameter to guard against invalid input. You might write something like:

unless VALID_COMMANDS.include?( command_param )
  whine_to_user()
  return
end

This makes sense, but it seems backwards to me. I don't care whether some array has a value in it so much as I care whether a value is in some array. Obviously that's just two ways of saying the same thing, but the latter seems to capture the intent much more to me. I think it would be easier to understand this:

unless command_param.in?( VALID_COMMANDS )
  whine_to_user()
  return
end

This evening it (finally) dawned on me that this would be ridiculously trivial to implement:

class Object
  def in?( enumerable )
    enumerable.include?(self)
  end
end

In fact, this was such a trivial fix that I'm now left wondering (a) whether this is already in ActiveSupport or Facets or whatever and I just haven't found it yet and (b) whether there's some huge flaw in this that I'm not spotting...

Sunday, January 17, 2010

Flex Patterns: Presentation Adapter

Flex Patterns: Presentation Adapter

Encapsulate the logic for presenting a domain object, and provide an object for skinny views to perform data-binding against.

Problem

When using Presentation Model our goal is to bind UI elements in your Skinny View directly to individual components of the Presentation Model. This requires translating information in Domain Model instances into a presentation-specific form. At the same time we need to be able to map back from that presentation-specific form to the underlying domain model instance in order to present user interactions in terms of our domain model.

Context

We are developing a UI component in a Flex application using some form of MVC/MVP. This UI component will be displaying information about a domain object, e.g. a list of Users. We are using the Presentation Model pattern or similar, so we want Skinny Views.

Forces

  • We need to transform information from a Domain Model class into something suitable for display
  • We want to keep formatting logic out of the view, using Flex databinding from view controls to a Presentation Model
  • We want to keep formatting logic out of the Domain Model, because it's presentation-specific, and not the responsibility of the domain model.
  • Clients of our UI component expect to interact with it using instances of the Domain Model class. For example, clients should be able to pass in a list of Domain Model instances to display, and the UI component should publish events which refer to Domain Model instances.

Solution

We can use a Presentation Adapter (PA) to wrap a domain object (an instance of a Domain Model class). The PA provides a presentation-specific formatting of some or all of the information represented by that domain object. The PA also exposes a reference to the domain object itself. This allows UI component code to map from the PA back to the domain object is represents when reporting user interactions back out to clients of the UI component.

Example

Let's say we are creating a Post Listing component which lists a collection of blog posts, and allows the user to select specific posts from that list. Our Presentation Model needs to include a collection of posts to list, and our View will contain some kind of list control which will be bound directly to that collection of posts. We want each post to be listed in the UI using a specific format, which will include the post title and the number of comments associated with the post. The application's Domain Model contains a BlogPost class, and our component is expected to expose an interface which talks in terms with BlogPost instances. The client of the Post Listing component will supply a collection of BlogPost instances which it wishes to be displayed in the list. When a user selects a post the component's client expects to receive a 'post selected' event which includes the BlogPost instance that was selected by the user. In other words, the client does not need to know anything about the Presentation Adapter we will be using.

We'll create a PostPA class which will act as a Presentation Adapter for the listing. It will expose a label field. The Presentation Model can hold a list of these PostPAs (one for each BlogPost supplied to the Post Listing component), and the View's list control can be bound directly to that list of PostPA instances.

We also need some simple formatting logic which transforms a BlogPost instance into the appropriately formatted string which will eventually be shown in the list control. That formatting logic should live within the Post Listing component, as it's presentation-specific. In fact it's likely that the formatting is specific to this particular UI component. The Presentation Adapter is a good place to put this formatting logic (although there are alternatives which I'll see below in the Variants section).

public class PostPA
{
 private var _post:BlogPost;
 
 public function PostPA( post:BlogPost )
 {
  _post = post;
 }
 
 public function get label():String
 {
  return _post.title + " ["+ post.comments.length+" comments]";
 }
 
 public function get post():Post
 {
  return _post;
 }

}

We also need to map from BlogPost instances to PostPA instances, and vice versa. We'll put that logic in our Presentation Model. core UI logic can supply the Presentation Model with a collection of BlogPost instances, and the view will be updated with a list of corresponding PostPA instances.

public class Model extends EventDispatcher
{
 function Model(){
  _postPAs = [];
  _selectedPostIndex = -1;
 }
 
 private var _selectedPostIndex:int;
 private var _postPAs:Array;
 
 public function get selectedPost():Post
 {
  if( _selectedPostIndex < 0 )
   return null;
  else
   return _postPAs[_selectedPostIndex].post;
 }
 
 public function set selectedPostIndex(index:int):void
 {
  _selectedPostIndex = index;
 }
   
 public function set posts(posts:Array):void
 {
  _selectedPostIndex = -1;
  _postPAs = posts.map( function( post:Post, i:int, a:Array ):PostPA {
   return new PostPA(post);
  });
  dispatchEvent(new Event("postPAsChange"));
 } 
 
 public function get posts():Array
 {
  return _postPAs.map( function( postPA:PostPA, i:int, a:Array ):Post {
   return postPA.post;
  });
 }
 
 [Bindable (event="postPAsChange")]
 public function get postPAs():Array{ return _postPAs; }
 
}

Our Post Listing component needs to send an event whenever a user selects a post, and that event needs to reference the BlogPost instance that was selected. To that end, the Presentation Model also exposes methods which allow the view to update the selected post based just on a list index, while the core UI logic can ask for the underlying BlogPost instance which was selected. Now, when the list control sends an event saying an item has been selected the View can update the Presentation Model appropriately and then signal the core UI logic. That logic can then ask the Presentation Model for the selected BlogPost, and dispatch a 'post selected' event, including that BlogPost instance in the event.

Variants

The decision on where and when the presentation formatting logic is done defines several variants on this pattern.

Dynamic Presentation Adapter

Presentation formatting logic lives in the PA class, and the formatting is performed on-the-fly as the view requires it.

Static Presentation Adapter

Presentation formatting logic still lives in the PA class, but the formatting is done at construction time. Depending on usage patterns this could be more or less performant than the Dynamic Presentation Adapter variant.

Dumb Presentation Adapter

Presentation formatting logic lives within the Presentation Model which is creating the Presentation Adapter. In this case the Presentation Adapter itself becomes a simple value object with no logic, or even just a dynamically created object.

Related Patterns

Generally a Presentation Adapter will be used in the context of a Presentation Model, where the Presentation Model contains instances of one or more Presentation Adapters (collections or otherwise). A Presentation Adapter is a specific form of the GoF's Adapter Pattern.

Alternative Patterns

Instead of a Presentation Adapter one could use a Transformer/Mapper, where a single Mapper instance performs the presentation-specific formatting for a whole class of domain objects. This Mapper is attached to the UI control as part of the binding mechanism, and does the formatting on the fly. The Mapper could be a simple Function, or an instance of a specialized Mapper class.

Tuesday, November 17, 2009

How much code did I just delete?

Today I had the great pleasure of deleting a huge chunk of old code from my application. Using git it's surprisingly easy to figure out exactly how much code:
 
git checkout -b deletion_task

# ... delete lots of code...
# ... time passes...

git add -i
git commit
git co master
FILES_DELETED=`git diff --summary master deletion_task | grep "^ delete" | wc -l`
LINES_DELETED=`git diff --summary master deletion_task | grep "^ delete" | awk '{ print $4 }' | xargs cat | wc -l`
echo -e "$FILES_DELETED files deleted.\n$LINES_DELETED lines deleted."

Monday, November 16, 2009

Introducing Gimme: a lightweight ruby Registry

I recently created Gimme, a small ruby gem which allows you to configure and access a simple Registry using a nice little DSL.

Gimme in a paragraph

The general idea of Gimme is to allow a single point for configuring the well known services which your application uses (think DB connection, twitter API gateway, email server, etc). Once configured Gimme then exposes a single point to access those services, without needing to resort to singletons or global variables.

Show me teh codez

Here's a simple example showing how you would configure your registry:
Gimme.configure |g|
  g.for_the(ExternalService) do |env,name|
    ExternalService.new(env[:setting1],env[:setting2])
  end
end
and here's how you'd use it from within your app:
Gimme.the(ExternalService).some_method
Here's a more complete example, showing both configuration and usage:
# your Emailer class

class Emailer
  def initialize( smtp_hostname, port )
    @smtp_hostname, @port = smtp_hostname, port
    puts "creating an emailer: #{inspect}"
  end

  def send_email( subject )
    puts "Sending email '#{subject}' via #{inspect}"
    # ...
  end

  def inspect
    "#{@smtp_hostname}:#{@port}"
  end
end


# your Gimme configuration

Gimme.configure do |g|
  g.for_the( Emailer ) do |env|
    email_settings = env[:email_settings]
    Emailer.new(email_settings[:hostname],email_settings[:port])
  end
end

Gimme.environment = {:email_settings => {:hostname => 'smtp.mymailserver.com', :port => '2525'} }



# in your app


Gimme.the(Emailer).send_email( "Gimme is the awesomez" )
Gimme.the(Emailer).send_email( "Emailing is fun" )
Gimme.the(Emailer).send_email( "notice that only one Emailer was created above" )
Gimme.the(Emailer).send_email( "even though we sent 4 emails" )

Pseudo-singletons

If you use the Gimme#for_the(Service) form when configuring Gimme then gimme will only create one instance of that object. If you use the Gimme#for_a(Service) form then the creation block will be called each time you ask for an instance of that object. That way things which hold on to expensive resources (database connections, TCP sockets) can be shared within your app, which services which need to maintain unique state for each client can be private to each client.

Environments

In any non-trivial application you need to configure your services. You can supply Gimme with an environment hash which it will then pass to your creation blocks whenever you ask for an object. This allows you to store settings like smtp hostnames, database passwords, twitter API keys, etc in a single environment hash, and use that hash in one place to configure all your external services at the point they are created.

Dependency Injection/IoC

There is nothing to stop you from calling Gimme.a() or Gimme.the() from within a creation block. This allows you to use Gimme as a lightweight IoC container.

Check it out!

Check out the github page for more info, including lots of example usages, and a more detailed README.

Sunday, June 28, 2009

Adding hamcrest-as matchers to mock4as

Just a quick post to mention that I recently did an experiment with extending mock4as to use Drew Bourne's awesome hamcrest-as3.

The idea for this work is to specify mocked method arguments in a more flexible way. It was actually surprisingly trivial to implement. I'll be writing a more detailed post in the future explaining what these changes mean to a user of mock4as.

I also took the opportunity to experiment with using git and github, so the changes are available to all and sundry as a github repository. I will be talking to the mock4as guys about getting my changes merged into the official mock4as codebase

Sunday, June 14, 2009

Presentation Model Pattern

Presentation Model

We want to achieve a Skinny View without the View needing to expose UI details to the Controller.

Also known as

View State, Logical View

Problem

We want to have as much presentation logic under test as we can by having a Skinny View. At the same time we don't want our Controller to be burdened with the minutiae of maintaining UI elements.

Context

We are creating a presentation layer in Flex using some variant of MVC/MVP and want to implement controller logic which modifies the view.

Forces

  • Exposing individual UI elements to our controller makes tests fragile and tedious to write.
  • Burdening our controller with both abstract presentation logic (what to do when a user clicks a button) and concrete UI display logic (directly modifying the state of UI elements) violates SRP.
  • We want to take advantage of the powerful data binding functionality that Flex offers.
  • We do not want our Domain/Business logic to be polluted with UI layer details.

Solution

We create a Presentation Model that is a logical representation of the view. The controller maintains the view by manipulating the Presentation Model. We bind our view directly to the Presentation Model, so any changes to the Presentation Model are immediately reflected in the view.

To keep as much logic as possible out of the View and under test we advise not allowing the View to update the model directly. All updating must be done by the Controller. Often that will be initiated via a handler on the Controller called by the view in response to some user action.

Example

In this very simple example we will assume we're working on a Contact Manager application. Specifically we're working on a UI which contains a list of contacts and allows a user to add contacts to the list.

Presentation Model

We'll create a Presentation Model for that screen like this:

package com.example.contacts.ui
{
 import mx.collections.ArrayCollection;
 
 
 [Bindable]
 public class Model
 {
  public function Model()
  {
   names = new ArrayCollection();
  }
  
  public var names:ArrayCollection;
 }
}

View

Next we'll create a view which binds to that Presentation Model:

<?xml version="1.0" encoding="utf-8"?>

<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" 
 width="600" height="600" 
 implements="com.example.contacts.ui.IView" 
 creationComplete="onCreationComplete()">
 <mx:HBox>

  <mx:VBox>
   <mx:Form height="100%" width="100%">
   <mx:FormItem label="First Name:">
    <mx:TextInput id="tiFirstName"/>

   </mx:FormItem>
   <mx:FormItem label="Last Name:">
    <mx:TextInput id="tiLastName"/>
   </mx:FormItem>
   <mx:Button label="Add Contact" click="onAddContactClick()"/>

  </mx:Form>
  </mx:VBox>
  <mx:VBox>
   <mx:List id="cbNames" dataProvider="{_model.names}" />

  </mx:VBox>
 </mx:HBox>

<mx:Script>
 <![CDATA[
  import com.example.contacts.*;
  
  private var _controller:Controller = null;
  
  [Bindable]
  private var _model:Model = null;
  public function set model( value :Model ):void {
   _model = value;
  } 

  private function onAddContactClick():void {
   _controller.onAddName( tiFirstName.text, tiLastName.text );
  }
 
  public function clearNameInputFields():void {
   tiFirstName.text = '';
   tiLastName.text = '';
  }
 ]]>
</mx:Script>
</mx:Canvas>

Controller

Finally we'll implement our Controller:

package com.example.contacts.ui
{ 
 public class Controller
 {
  private var _model: Model;
  private var _view : IView;

  public function Controller() {
   _model = new Model();
   _view = null;
  }
  
  internal function bindView(view: IView): void {
   _view = view;
   _view.model = _model;
  }
  
  internal function onAddName( firstName:String, lastName:String ):void {
   _model.names.addItem( lastName + ", " + firstName );   
  }
 }
}

Communication Diagram

The communication diagram above shows how the three classes collaborate to handle a user interaction event. The user takes an action, which results in an event handler in the View being called. The View's event handler delegates immediately to a handler method in the Controller. The Controller's handler method performs whatever logic is necessary, including updating the Presentation Model. That update indirectly triggers Flex data binding to update the View's UI elements. Note that communication tends to travel in one direction here - From View out to Controller, from Controller to Presentation Model, and from Presentation Model back to View. It is rare for a Controller to communicate directly with its View, and it is expressly forbidden for a View to directly manipulate the Presentation Model.

Note that the View is very skinny - it mostly just binds to the model and delegates handlers straight through to the Controller. Also note that the controller doesn't interact directly with the View when manipulating the UI. It just manipulates the Presentation Model, which results in the UI updating thanks to the View's data binding.

You can also see that we didn't follow the Pattern dogmatically in this example. We could have pulled the View's clearNameInputFields() method into the Controller by representing the contents of those 2 input fields in the Presentation Model and then binding those to the view. That would then allow us to clear the input fields by clearing the corresponding Presentation Model properties. However, in this case I decided that it was a nicer separation of concerns to hide the details of those elements from the Controller and the Presentation Model. Instead the View exposes a simple method with an Intention Revealing Name. This removes the need for the Presentation Model to be cluttered with these elements just to serve the one operation of clearing the fields.

This is a very basic example, but hopefully it conveys the concept. For a more sophisticated UI the View would have additional UI elements which would be bound to additional properties added into the Presentation Model.

Resulting Context

  • It is extremely easy to test how our Controller is modifying our View.
  • Our View no longer has to expose its UI elements.
  • Our Controller no longer has to deal with the View's UI elements.
  • Data binding allows our View to contain very little logic related to updating UI elements.

Rationale

It is really powerful to take advantage of data binding in Flex in order to simplify your view logic. At the same time it doesn't make sense to bind directly to our domain model classes. These classes are focused on representing the relationships and rules of our business domain, and should not be concerned with the UI layer at all. We need to map domain concepts like 'Collection Of Users' to UI concepts like 'list of strings for a dropdown'. Presentation Model allows us to do that. Presentation Model also allows us to very easily test the way our Controller updates the UI. Our tests simply have to exercise the Controller logic that is under test and then check the state of the Presentation Model.

Related Patterns

Presentation Model is really just a twist on Fowler's Two Step View, focusing on MVC/MVP and with a consideration of Flex data binding.

Authors

Pete Hodgson, Hosung Hwang