µ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.

Quinn Gil

Quinn Gil

Seattle Code Crafter. Quinn beats the drum of FAST Agile, Extreme Programming and Object Oriented Design through MicroObjects. He blogs for fun and frustration of exploring new concepts.

Read More
µObject : Battleship
Share this