Book Chat: Refactoring

Refactoring sets out describe what refactoring is, why you should refactor code, and to catalog the different refactorings that can be done to an object oriented codebase. This isn’t the first instance of the idea of refactoring, but it was the big coming out party of the idea in 1999. It is an audacious goal in that the effort to catalog all of anything can be daunting. While I’m not an authority on refactoring by any means, it certainly captured all of the basic refactorings I’ve used over the years. It even includes refactoring to the template method design pattern, though it doesn’t reference something like refactor to the decorator pattern. It seems odd to have included refactor to one design pattern but not to several others.

The description of the “what” and “why” of refactoring are excellent and concise. The catalog is ~250 pages of examples and UML diagrams of each refactoring technique; that each refactoring needed to be shown, feels like overkill. In general, the author shows both directions of a refactor, e.g., extract method and inline method, which can be rather overwhelming. A newer volume on refactoring like Working Effectively With Legacy Code seems more useful in its presentation of actual refactoring techniques, in that it prioritizes where we wish to go, rather than exhaustively describing each individual modifications. Honestly, I think that since Refactoring predates automated tools for performing refactoring, given that  the internet in 1999 wasn’t as full of help on these sorts of topics, the book needed to be more specific since it was the only source of help.

It’s an interesting historical piece, but not an actively useful thing to try to improve your craft.

Advertisements

Akka From A Beginner’s Perspective

I wandered into a new part of the codebase at work recently that contains a number of Akka actors. I was aware of both the actor concept and the library, but had never worked with either.

Actors are a way to encapsulate state from threads so that if you want to make a change to the state you need to send a message to that thread. If you’ve ever done any work with an event loop, it’s similar to that but genericized to whatever sort of data not just events. The idea is that each actor provides a mailbox where you can leave a message, then that actor processes the message and whatever happens to the actor’s state happens on that thread. This means the messages go the actor’s thread rather than the data being fetched from the actor and brought back to the caller’s thread. The big advantage of this is that there isn’t any need for locking since no mutable state is shared. The downside to this message-passing style is that the default message flow is one way. Some typical code using an actor would look like

actor ! message

This would send the message to the actor. The actor itself can be pretty simple such as

class ActorExample extends Actor {
  def receive = {
    case SampleMessage=> println(“got message”)
  }
}

That receives the message and runs the listed code if it is of some expected type (in this case, SampleMesage). This is good for data sinks, but actors can be composed too.

class ForwardingActor(destination: OtherActor) extends Actor {
  def receive = {
    case SampleMessage(content)=>
      println(s“got message {content}”)
      destination ! SomeOtherMessage(content)
  }
}

This actor logs the contained data and passes the data along inside a different message wrapper. This is interesting but requires you to define the destination when creating the actor. Akka provides a syntax for finding out the actor that sent you a message too.

class ReplyingActor extends Actor {
  def receive = {
    case SampleMessage(content)=>
      sender() ! Reply(content) // The () is optional but using it for clarity here
  }
}

This simply sends back the same content inside a new message envelope. There is one small gotcha in this code – if you close over sender() itself it will have unintended consequences, so a different pattern is recommended for your receive message.

class ReplyingActor extends Actor {
  def receive = {
    case SampleMessage(content)=>
      processSampleMessage(sender(), content)
  }
  private def processSampleMessage(sender: ActorRef, content: String) = {
      sender ! Reply
  }
}

This figures out the sending actor before doing any processing to be sure you don’t end up closing over the wrong actor as you chain more complex pieces together. The other interesting thing about this example is that the type of sender is ActorRef not Actor. The ActorRef is a handle to wrap around the actor which keeps track of where it runs and how to get the message to its mailbox for you. This allows you to do things like have two actors interact even though they are being scheduled independently. This all seems pretty straightforward if you send a message from an actor to another actor, but if you send a message from something that isn’t an actor, what does sender() do and how does that work?

The answer is that the message is generally discarded, unless the call was made with an ‘ask’ such as

val result = actor ? message

This captures the result of the actor as a Future[Any], which at least returns the result so you can inspect it even if the type isn’t that useful. Akka currently provides typed actors to try and work around that pain, which is intended to be replaced by Akka Typed which isn’t quite ready for production as of this writing.

That’s all the Akka I picked up delving into this new portion of the codebase. I didn’t need to get into supervision or schedulers, but if building a new application from scratch I’m sure those concepts would come up.

Book Chat: Beyond Legacy Code

Beyond Legacy Code is a description of nine practices to help improve the value of software. The author directed it not just at developers or engineers, but also at development or IT managers, product managers, project managers, and software customers. That’s a broad array of people who are coming to a problem with a wide set of goals and preconceptions. Eight of the nine practices are pretty normal and obvious items for most software engineers. One however was novel to me: implement the design last.

The basic idea is pretty straight forward – do a sort of bottom up build of components and then compose them into larger and larger units. Then allow the design of the larger pieces to emerge from that. Since you already have all these well written and tested units you can compose them together safely in ways that you understand. It keeps you from reaching for a more complex design pattern that you may not need because you are still working through all of the smaller pieces. I see it as the red-green-refactor mantra in the macro sense.

I had often tried to accomplish this similarly by starting at the top and stubbing out other smaller pieces as I went. This didn’t always work out since the interface for the piece you stubbed out may not have the information it needed to do its work. I have also seen this end up with odd pieces that don’t really make sense outside of the context of what I was working on so I had less reusable components afterwards. Overall it worked fairly well to try to map decompose the problem in the initial pass.

Since reading this book, I’ve tried their bottom up buildout a couple of times. It seems to have taken me significantly longer to do the work, but I think the overall reusability of the subsequent design is better. I feel that with more practice that I should be able to be at least as productive as before. I haven’t had to come back to any of the code I wrote like this in maintenance so I don’t have any data yet on if it delivers on the maintainability ideas that it promises.

I don’t think that book delivers to the full audience of people who are intended as readers, but it feels well directed at Software Engineers, considering the principles and guidelines we use. I don’t know what a large portion of the audience would get from reading this other than a familiarization with the terms used so they could communicate better. I don’t see how it would cause a project manager to reconsider the schedule, or an IT manager to deal with a project differently. Maybe I can’t take their point of view well enough, so I saw large portions of the suggested practices as ‘normal’ but to those roles they would help articulate the value of unit testing. I don’t know of a better modern book for those involved in the management side of software without a software background that is still technical. Classics like Peopleware or The Mythical Man-Month still show most of what you need to do to run a software team from a strictly management perspective and this doesn’t supplant those. Looking at the reviews on Amazon though it seems as though my concerns that this isn’t what non-developers want seems to be unfounded. The consistent praise it is garnering there makes me curious to see what other non-developers I know would think if they read it.

2017 Year in Review

I had a couple of goals from last year for the blog.

  • Keep up the weekly post cadence
  • Continued increases in readership
  • Write a longform piece and see what that looks like in this format

I kept the weekly post cadence, but a couple of times I did feel like I was running out of material. Readership was up from 440 views last year to 587 this year. The page getting the most views was the homepage, which almost tripled from last year with 133 views vs 48 last year. I’m not sure what that means, it could mean people just coming back to see what’s new, or visitors just looking at the homepage after whichever article they searched for. Otherwise the most visited page was last year’s Anonymous type XML serialization with 94 views. I appreciate that it seems to have garnered a pretty regular stream of visitors since I first posted it. To me, that means it has lasting value. As for longform I don’t think I accomplished that, I feel like the posts I wrote this year actually hit the 500-750 word mark pretty consistently as compared to previous years.

For 2018 I’ve still got last year’s goals for the blog to continue on. I also want to better understand what articles people are reading. In order to do this I want to try overhauling the landing page, so that it gets me that information. I could achieve this same end by putting a ‘read more’ tag into each post, but I don’t like those when I read content so I would feel hypocritical using them on my own. I am considering a static landing page to see what that does, but I don’t know what I would want to put on it.

In terms of personal technical goals going into next year, I want to carve out time to learn some Haskell or Cats and those efforts seem like they would create interesting posts. I know we’ve got a project coming up at work that will mean switching from Reactive Mongo to the official Mongo Scala driver and upgrading to Play 2.5, which will probably be occupying a good bit of my time early in the year. I’m not sure what other projects I would be doing at work. Other technologies I use at work that I want to get further into are RxScala and the Docker and Mesos infrastructure we build on top of. That’s a lot of ground to cover, and I know I would need to find a project to do with any of those to really dig in.

2017 had plenty of surprises in my programming experiences, and I don’t expect to be able to predict what 2018 will hold. I’ve got a direction, not a destination.