Fresh from Typesafe’s “Fast Track to Akka in Java”, I decided to apply Akka to a problem I know well, the bowling game kata. Although I’ll be using some code snippets to illustrate my journey, the full solution is on GitHub.
Bowling Game kata
For those of you know aren’t familiar with it, the kata was created by Uncle Bob Martin and involves the creation of a class that can score a game of bowling. While bowling does have a couple of “business rules”, if you will, it’s pretty straightforward. A game of bowling requires a ball, some pins and a long, narrow floor called a lane. The game consists of ten rounds called “frames”, and each frame involves rolling the ball up to two times with the goal of keeping the ball in the lane and knocking down the ten pins at the end of the lane.
Akka is a toolkit for abstracting away asynchronous code so you can think about your code in a single-threaded, synchronous way. Akka is an actor-based system, so designs are comprised of a handful of actor types (the “nouns”) and a group of message types (the “verbs”). Interactions between classes are conducted through messages, which is reinforced by the fact that you can’t get to an instance of an actor. Actors are created in a hierarchy, with a system actor called a guardian at the root. If you are intrigued as I was, visit akka.io.
Let’s dig in….
Application of Akka
I started by asking myself how to incorporate Akka into the bowling game kata. The problem doesn’t lend itself to concurrency, which is where Akka shines as a toolkit. Part of the fun here is the constraint.
I decided to get going and to figure it out as I went alone. Being an
actor-based system, Akka has a mantra that “everything is an actor”. Embracing
this, I made my
Game class inherit the
AbstractLoggingActor class from the
Akka actor package. I immediately ran into issues.
The Java implementation of Akka is not as well used nor documented as its Scala sibling. I had trouble finding examples of what I was trying to achieve. In particular, I was stuck for a while getting a test to run with the framework. I even resorted to asking Stack Overflow.
It turned out in my Maven POM, the Akka testkit package required a different version of Scala than the Akka actor package. After that hiccup, my test suite started working as expected. I suddenly understood what the version numbers in the package names were trying to tell me!
Problems solved, I started the kata by implementing the gutter game use case and the open frame use cases. These are simple because the final score is simply the sum of the pins knocked down.
However, when I started the spare frame case, I realized how I could pull Akka into the kata. Scoring gets complicated – by complicated, I mean some pins count double – when all the pins are knocked down in a frame. To do that, the scoring class needs to understand what pins were knocked down in which frame.
The canonical implementation of this kata in Java, the one that Uncle Bob
teaches, illustrates that premature decomposition of problems into objects can
result in extraneous code. However, I realized that if I did create a
class, I’d have a second type of actor and a reason for actors to collaborate.
When an actor wants the
Game to score a game, it sends the
message. This message contains an array with the number of pins knocked down
during each attempt.
In the original algorithm, the scoring method parses such an array into frames
and iterates through the frames. In this Akka implementation, the
it like this:
In order to describe the work of this method, I need to talk about Akka actors.
Inside an Akka actor
In contrast to the plain
Game class in the canonical version, there’s some
extra plumbing involved in getting an Akka actor to work. In fact, this extra
code is why many people prefer the Scala implementation.
For an Akka actor, it’s recommended that you create a Factory method called
create(). For the
Game class, it looks like this:
In it, we’re creating a
Creator<> class inline that calls the default
constructor. If you need arguments, it looks like:
The second thing an Akka actor needs to do is to accept messages from other
actors. To do that, we override the
receive() method. Here is the example from
In Akka, it’s typical to create a class for each message type. These classes are simply plain old Java objects (POJO). However, because they need to be serialized and there will be multiple instances of them, there’s a lot of plumbing code:
If you have been thinking, “who needs Scala anyway?”, here’s an equivalent class in Scala:
Back to the design
To recap, here’s how the
Game class starts to score a game:
I say ‘start’ because this is an asynchronous operation. Actors are powerful
because they allow you to subdivide work and conquer tasks in parallel. In this
Game actor is spawning ten child
Frame actors and telling each
one of them to score their particular frame, which is passed in the frame’s
When a Frame is done with its work, it sends a
ScoreFrame message back to the
Game class. When the
Game has received all ten
ScoredFrame responses, it
ScoredGame message that it sends back to… wait, the last message
it received should be from a
Frame child. That’s why the
has to save off the original sender into the
querent field. In our case, the
sender is always a test actor.
Testing the Actors
There are a couple styles of Akka testing in Java. I kept examples of both in
FrameTest class. These are the two helper methods I use to perform the
frame is a field that contains a
In this case, we’re sending a
GetFrame message to the
Frame class using
ask(). In contrast to the
tell() method introduced earlier,
ask() deals in
possible futures. This paradigm uses a
Future<> object that will hold the
result when the operation is complete. By wrapping the result in a
allows the caller to interact with the
Future the same way whether it’s done
or not. This prevents a lot of boilerplate exception-throwing, null-object
handling logic duplicated in each receiver. (If you have done any programming in
In this test, we set up the
Future and wait zero time for it to complete. We
can do this because
TestActorRef<> handles messages in a synchronous way
suitable for testing. While this works, I prefer the asynchronous testing model,
because it more closely resembles the way that actors are used in production
code and it doesn’t require understanding
Like in the
Frame classes, we’re using
tell() here rather than
getRef() gets a reference to the anonymous
JavaTestKit actor, which
is how the tests interact with its subjects. The Akka toolkit offers a lot of
useful assertions to handle message verification, so there is no need to extract
the values in the messages and compare them directly as we did in the
synchronous case. In this case, the assertion will pass only if the message is
the equivalent of the expected one and is received within 500 milliseconds.