µObject : Battleship

At Agile Open Northwest, I had the opportunity to explore µObjects through a battleship kata. I felt the environment and process doing it during the mobbing session were a bit more contrived than I normally work with. Fortunately the limited amount we got through did show some of the power along architecture that microObjects drive.

I'm curious how a full Battleship example in µObject will play out; as well as wanting to share it with others.

That's what we'll go through now. :)

I'm adding an extra twist for myself; I'm going to try to use ApprovalTests and that we used a bit at Agile Open mobbing sessions. I'm going to use it; probably not what I think is the proper way to use it; but to play with it. I also think that it'll be a good validation for battleship which is validation at a broad scale - the board scale.

First test I'm going to go for is a ship placed horizontally. Which I'm not going to do in a board. I'm just going to do the ship. This is where I'll probably deviate a bit from how Llewellyn describes the process and how he was demonstrating it. Maybe I'll hate it and which I hadn't done it like this. Gotta try stuff to figure out where it works and where it hurts.


The first tests is just a Aircraft Carrier horizontal. It passes by just returning AAAAA.
Let's make a vertical version. At least force the use of the Orientation value.
Currently the Aircraft is a hackjob

public class AircraftCarrier : IShip
{
    private readonly IOrientation _orientation;

    public AircraftCarrier(int horzCoord, int vertCoord, IOrientation orientation)
    {
        _orientation = orientation;
    }

    public override string ToString()
    {
        return _orientation.IsHorizontal() ? "AAAAA" : "A\nA\nA\nA\nA";
    }
}

but it is passing.
I can see that starting from the board forces some of the broader constructs that just don't show until we're forced to interact with it differently.

In this case; we're not really looking to verify the WHOLE of the ship location; but from the board, it'll call a specific method to get the ships "value".
Let's update our tests to be this style instead. Working from the lower level does require a bit more churn to get all the API's into place. I think that working from the inside out delivers better structured code; so that's how I'm preferring to do it.

[TestMethod]
public void AircraftCarrierReturnsSpecifiedIndicatorForBeingAtPoint()
{
    //Create an aircraft carrier at zero, zero horizontally
    IShip subject = new AircraftCarrier(0, 0, Orientation.Horizontal);
    IResult result = subject.At(0, 0);
    Approvals.Verify(result);
}

The result is just a 'wrapper' around the "A". I could go with just a string... but that's boring; and not an interface. :)

This works; though I suspect I'm wholely abusing how Approvals should be used. I'm treating it like a Unit Test, not scenario test. Which... yep. I figured I'd be doing it like this; I've got my bias against outside-in testing.

Yep - Definitely using Approvals like I would FluentAssertions. I'm gonna roll off Approvals.
I think I'll use it for bigger scale; but I like inside out; and it's not the correct tool for this. Commit 0a684e49 is before Approvals removal.

Looking at the Aircraft class; I'm seeing a some relationships around the coords (surprise!), but also the size. These all are used together.

I want to introduce the vertical checking before doing the encapsulation; as it might tell me a better way.


I've shoved the "Hit Checking" into the Orientation. Not sure it fully belongs there; but I had it as

if(orientation.IsHorizontal()){
// do stuff
else{
// do other stuff
}

and that felt wrong. It still feels wrong in the orientation; but less so.

I renamed it to "ShipDetector". It makes more sense now.

I'm just kinda plugging along. This is the first time every doing Battleship; so I'm a little in the "solve the problem" phase.

Commit 4f7de85e has the final form of the Aircraft Carrier and ship so far.

At this point I feel I've got the ship pretty well set. There's a smell around the coordinates and the size - they have some kinda relationship; just not sure what yet.

I'm going to move onto the board and get that going. Maybe come back to the points later on; see if they make any more sense then.


There's a board at Commit 916ec15a now. It's using Approvals. That's a pretty clean way using what I have; though I'm a bit uncertain about how it's forcing some string-ification into the project.

I'm not super pleased with this result. It feels a bit cluttered. I'll need to do it again, maybe a couple times to get a better feel for it.

The coordinates stand out as an issue...

This will be sufficient for now. It's not HORRIBLE... but it's not as well done as I think it can/should be.

I'll do another soon; as I think it's a kata that has a little more intelligence capability which will put different pressure on the µObject concept.

I don't want to churn on this code and clutter it. It is a go at it. Not the best result; but a result. I'm seeing a lot of opportunity with Battleship to stress some of the "rules" for µObjects. Which I'm happy to have such a simple example that will allow that kinda investigation.

Code is available in my microBattleshipFirst repo.

Show Comments