interface names

Recently I've been experimenting with interface names and pondering over the best way of naming them based on my progress into the realms of behaviour driven design.

I have been looking at making the names more about behaviour, so instead of the usual "IWhatIAm" (such as IDataRetriever) I've played with three patterns that I could choose from:

IWhatIAm
IWhatIDo
IWhatIAmAbleToDo

Let me give a hypothetical example:
I have a codebase that has a class to save order data, a class to catch the results of an asynchronous order process and one that can retrieve some order data.

Using the above interface naming patterns I could have:

IWhatIAm pattern (commonly used)

IOrderDataWriter orderDataWriter;
IOrderService orderService;
IOrderDataRetriever orderDataRetriever;

IWhatIDo

IWriteOrderData orderDataWriter;
ICatchOrdersService orderCatchingService;
IRetrieveOrderData orderDataRetriever;

IWhatIAmAbleToDo

ICanWriteOrderData orderDataWriter;
ICanCatchOrdersService orderCatchingService;
ICanRetrieveOrderData orderDataRetriever;

The behaviour style names definitely feel catchy and I've experimented with the last examples although I must admit that it has been unusual to see that interface name in a WCF url (for example). But it does convey more context and that's got to be a good thing right?

Posted at at 11:27 AM on Friday, June 19, 2009 by Posted by Justin Davies | 0 comments Links to this post   | Filed under:

driving the design of interfaces

How do you drive the design of your interfaces?

That is a question posed by Brett Schuchert from a twitter discussion and he illustrates a way of driving the design in a test-driven fashion.

As I'm into my context specifications in a big way at the moment I thought it would be interesting to explore how I might drive the same small piece of code from a blank slate.
I'm using the developwithpassion library and am in the middle of a series on my use of context specification that has more detail on my use of the library and how it works.
So here goes:

First, I'd create a new file to contain my specification and call this GameSpecification. I'd then write the context as:

using developwithpassion.bdd.mbunit.standard.observations;

namespace Driving.Interfaces.Example
{
    public class when_initialising_the_hardware_layer_during_game_construction : 
                                observations_for_a_sut_without_a_contract<Game>
    {
    }
}

So I have my context and my system under test is a Game class which doesn't exist so the code doesn't compile. Using Resharper I create the Game class in the same file:

using developwithpassion.bdd.mbunit.standard.observations;

namespace Driving.Interfaces.Example
{
    public class when_initialising_the_hardware_layer_during_game_construction : 
                                observations_for_a_sut_without_a_contract<Game>
    {
    }

    public class Game
    {
    }
}

According to the original post we know up front that Game uses the Hardware Layer. So next step is to put that dependency on using my context - the framework I am using can auto-wire up mocks for any constructor dependencies and I can access them using some prepared syntax:

public class when_initialising_the_hardware_layer_during_game_construction : 
                                observations_for_a_sut_without_a_contract<Game>
{
    private static IHardwareLayer hardwareLayer;

    private context c = () => hardwareLayer = the_dependency<IHardwareLayer>();
}

Again, this does not compile and so I use Resharper once again to construct an interface within the same file.
I now add the constructor on the Game class:

public class Game
{
    public Game(IHardwareLayer hardwareLayer)
    {
    }
}

Now I'm ready to make my observations:

public class when_initialising_the_hardware_layer_during_game_construction : 
                            observations_for_a_sut_without_a_contract<Game>
{
    private static IHardwareLayer hardwareLayer;

    private context c = () => hardwareLayer = the_dependency<IHardwareLayer>();

    it should_set_the_resolution = () => 
        hardwareLayer.was_told_to(layer => layer.SetResolution(expectedWidth, expectedHeight));
}

I have delcared what I expect to be called on the IHardwareLayer interface - a SetResolution method with specific values (that are not yet defined).
First, I define those expected values:

public class when_initialising_the_hardware_layer_during_game_construction : 
                            observations_for_a_sut_without_a_contract<Game>
{
    private static IHardwareLayer hardwareLayer;
    private static int expectedWidth;
    private static int expectedHeight;

    private context c = () =>
                            {
                                hardwareLayer = the_dependency<IHardwareLayer>();
                                expectedWidth = 1024;
                                expectedHeight = 768;
                            };

    it should_set_the_resolution = () => 
        hardwareLayer.was_told_to(layer => layer.SetResolution(expectedWidth, expectedHeight));
}

Notice that my private variable declarations are just that - declarations. I keep the "Arrange" part of my AAA syntax all within the context delegate so the expected values are assigned there.

Now for the interface modification; again I use Resharper and quickly create that method:

public interface IHardwareLayer
{
    void SetResolution(int widthInBits, int heightInBits);
}

I now have an observation via my "it" delegate and I can run this test and see that it fails the expectation on the mock object with a Rhino.Mocks.Exceptions.ExpectationViolationException.
Implementing this code I am first careful about the implementation - I want to set the resolution, but I want to set it to a pair of values that should fail the test. In this way I don't get a false positive test that doesn't actually verify the values as I'd expect.

public class Game
{
    public Game(IHardwareLayer hardwareLayer)
    {
        hardwareLayer.SetResolution(1000, 1000);
    }
}

When I run the test again it still fails as the values are explicitly checked - great. Then I implement the real values in the Game constructor and the test passes.

The above process shows how I drive the interface and the implementation step-by-step. It is geared towards my use of the library and tools that I am using, but I don't think that is a bad thing... leveraging the tools at my disposal allows me to work in this context driven way that is fast and more importantly very expressive.

On reflection I would say there is something missing in the AAA syntax above - I have an "arrange" context delegate and an "it" assertion, but there is no "act" that would normally be in a "because" delegate (see my previous posts for more detail). This would suggest that due to the "act" part being within the constructor, the design might need to be looked at, but this exercise has been to use the code from Brett's post and just see what it looks like in context specification.

Posted at at 10:40 PM on Monday, June 8, 2009 by Posted by Justin Davies | 0 comments Links to this post   | Filed under: ,

iterative context specification code

In my last few posts I've described the process of a basic implementation of a user story that has resulted in a working system that conforms to the specification laid down by test code. You can catch up on the series here.

In this post I'm now going to look at addressing a second user story and showing a process of iterative development of the context specification code itself - if you find something that has a code smell or doesn't look right, bear with the post as it may very well be addressed later on; I'm purposefully showing the code all its forms from inception to finished version. If there's still something that isn't right then please let me know as I'd love some feedback on this process.
The user story detail is as follows:

"As a user I want to input a new balance with an amount and for a particular date, defaulting to today's date if a date is not supplied."

This is going to sit on the same Balance view as the previous story so I start with the BalancePresenter and create a context for this where the input is validated and the appropriate action taken on the view:

[Observations] 
public class when_saving_a_new_balance : BalancePresenterSpecification 
{ 
    [Observation] 
    public void should_call_the_view_for_new_balance_validity() 
    { 
        sut.SaveCurrentBalance(); 
        balanceView.was_told_to(v => v.NewBalanceIsValid()); 
    } 

    [Observation] 
    public void should_call_the_view_to_obtain_new_balance_amount_when_new_balance_is_valid() 
    { 
        balanceView.Stub(v => v.NewBalanceIsValid()).Return(true); 
        sut.SaveCurrentBalance(); 
        balanceView.was_told_to(v => v.GetNewBalanceAmount()); 
    } 
}

This context inherits from the base class I've used in previous specifications and in the first observation I'm asking the view if the balance is valid - at this stage I know this isn't the right location for business logic, but in order for me to slowly introduce my context I find this a suitable place to control the logic for the time being. I'm also combining both tests in one illustration here for brevity when I would normally implement one at a time.
I'm also observing that when the balance is valid that the new balance amount is retrieved from the view - with placeholder code put in for the new sut.SaveCurrentBalance() method, this test fails so I now implement the code in the BalancePresenter class:

public void SaveCurrentBalance() 
{ 
    balanceView.GetNewBalanceAmount(); 
}

The test now passed and I can move onto an observation that evaluates that when the input is invalid the view new balance is not obtained:

[Observations] 
public class when_saving_a_new_balance : BalancePresenterSpecification 
{ 
    [Observation] 
    public void should_call_the_view_for_new_balance_validity() 
    { 
        sut.SaveCurrentBalance(); 
        balanceView.was_told_to(v => v.NewBalanceIsValid()); 
    } 

    [Observation] 
    public void should_call_the_view_to_obtain_new_balance_amount_when_new_balance_is_valid() 
    { 
        balanceView.Stub(v => v.NewBalanceIsValid()).Return(true); 
        sut.SaveCurrentBalance(); 
        balanceView.was_told_to(v => v.GetNewBalanceAmount()); 
    } 

    [Observation] 
    public void should_not_call_the_view_to_obtain_new_balance_amount_when_balance_is_invalid() 
    { 
        balanceView.Stub(v => v.NewBalanceIsValid()).Return(false); 
        sut.SaveCurrentBalance(); 
        balanceView.was_never_told_to(v => v.GetNewBalanceAmount()); 
    }  
}

Note that in both cases the stubbing is now more noticeable as being part of the observation method itself prior to the assertion - this looks like a code smell as I'm trying to write all observations as only having the Assert part of the Arrange-Act-Assert process (and not contain a mixture of arrange and assert) so this is something that I want to address but for now I want to implement the code to get these tests to pass.
In the balance presenter I implement as follows to get my tests to pass.

public void SaveCurrentBalance() 
{ 
    bool newBalanceIsValid = balanceView.NewBalanceIsValid(); 
    if (newBalanceIsValid) 
        balanceView.GetNewBalanceAmount(); 
}

I now want to put in some new observations checking that the balance date is also obtained. When I come to put the code into the context specification I can immediately see that I will need to put a positive version and a negative version as I have done in the previous example and also include the stubs in these new observations. This is starting to really smell now so stopping to think I recognise that I actually have two different contexts... one when the balance input is valid and one when invalid. So I go about refactoring these tests:

[Observations] 
public class when_saving_a_new_balance_but_balance_input_is_invalid : 
                                BalancePresenterSpecification 
{ 
    private context c = () => balanceView.Stub(v => v.NewBalanceIsValid()).Return(false); 

    because b = () => sut.SaveCurrentBalance(); 

    [Observation] 
    public void should_call_the_view_for_new_balance_validity() 
    {    
        balanceView.was_told_to(v => v.NewBalanceIsValid()); 
    } 

     [Observation] 
    public void should_not_call_the_view_to_obtain_new_balance_amount() 
    { 
        balanceView.was_never_told_to(v => v.GetNewBalanceAmount()); 
    } 
} 
[Observations] 
public class when_saving_a_new_balance_and_balance_input_is_valid : 
                                BalancePresenterSpecification 
{ 
    private context c = () => balanceView.Stub(v => v.NewBalanceIsValid()).Return(true); 

    because b = () => sut.SaveCurrentBalance(); 

    [Observation] 
    public void should_call_the_view_for_new_balance_validity() 
    {    
        balanceView.was_told_to(v => v.NewBalanceIsValid()); 
    } 

    [Observation] 
    public void should_call_the_view_to_obtain_new_balance_amount() 
    { 
        balanceView.was_told_to(v => v.GetNewBalanceAmount()); 
    } 
}

With the two new contexts things are certainly a lot clearer and we can put the rest of the specifications and observations in the right location. However the code above still has some repetition... the observation that the validity is obtained from the view is in both. With some more rework I end up with the following:

[Observations] 
public class when_saving_a_new_balance_specification : BalancePresenterSpecification 
{ 
    because b = () => sut.SaveCurrentBalance(); 

    [Observation] 
    public void should_check_for_new_balance_validity_on_the_view() 
    { 
        balanceView.was_told_to(v => v.NewBalanceIsValid()); 
    } 
}

[Observations] 
public class when_saving_a_new_balance_but_balance_input_is_invalid : 
                                BalancePresenterSpecification 
{ 
    private context c = () => balanceView.Stub(v => v.NewBalanceIsValid()).Return(false); 

    because b = () => sut.SaveCurrentBalance(); 

     [Observation] 
    public void should_not_call_the_view_to_obtain_new_balance_amount() 
    { 
        balanceView.was_never_told_to(v => v.GetNewBalanceAmount()); 
    } 
} 

[Observations] 
public class when_saving_a_new_balance_and_balance_input_is_valid : 
                                BalancePresenterSpecification 
{ 
    private context c = () => balanceView.Stub(v => v.NewBalanceIsValid()).Return(true); 

    because b = () => sut.SaveCurrentBalance(); 

    [Observation] 
    public void should_call_the_view_to_obtain_new_balance_amount() 
    { 
        balanceView.was_told_to(v => v.GetNewBalanceAmount()); 
    } 
}

With an additional context that is just about generally saving the current balance I now have a clear separation of code and can continue on with adding my specifications.
My next post in this series will dig into this deeper - please bear in mind that there are still things with the code illustrated in this post that I want to address and it is not necessarily the finished product.

Posted at at 6:46 PM on Wednesday, June 3, 2009 by Posted by Justin Davies | 0 comments Links to this post   | Filed under: ,