Sunday, June 23, 2013

Introduce Middle Man

I found I enjoyed wasting time here by snapping some photos of the insides of a book and writing up some thoughts on code which only really tied in with the book's contents within my imagination and thus, I feel compelled to do something similar again. I have a good (well, better) excuse this time, and thus I will draw upon three books as I want to show off a refactoring I will dub: "Introduce Middle Man"

Alright, in preparing for this presentation, I looked through Martin Fowler's "Refactoring" for a refactoring that matched one I would speak to. I did not find what I had hoped for. The closest thing I found was the exact opposite of what I hoped to find. It was a refactoring called "Remove Middle Man."

In the example shown here, a Client speaks with a Person within a Department to interface with the Department. One would embrace the refactoring by deciding that not only was it not a violation of the Law of Demeter for Clients to just interface directly with Departments but moreover it was sloppy to have to go through a Person in lieu of having a direct line of interaction as it created unneeded complexity. Alright, what if we wanted to introduce a middleman instead of taking one away. Could there ever be an application for as much? If there was, why didn't Fowler put it in his book?

In second edition Advanced Dungeons and Dragons, the last version of the game that I really embraced, a lot of the spells were marked as reversible meaning that if your character knew the spell your character also knew an alternate opposite. This was at least true with the way we played priests specifically. The fourth level Priest spell "Sticks to Snakes" which one may use to turn fallen tree branches in a woody area into serpents was, for example, reversible and its reverse was "Snakes to Sticks" which, as the name suggests, turned snakes into sticks. Both versions were a corny thing I just saw in the Player's Handbook and not something that I actually ever saw come out in actual gameplay. I don't think I ever was in a Raiders of the Lost Ark* Scenario, facing down a bunch of snakes, in which I wished I had "Snakes to Sticks" in my pocket. I suppose that the praxis for "Snakes to Sticks" was turning back off an opponent's "Sticks to Snakes." I mention this because I feel that the "Remove Middle Man" refactoring should be marked as reversible and that the reverse would be "Introduce Middle Man!" The closest thing to a reverse of "Remove Middle Man" in Fowler's book is "Hide Delegate," but it sort of assumes that an existing class/method/function/thingamabob will take away responsibilities from a dance partner which should not be directly talking to the thing it hides. What if we instead want the class/method/function/thingamabob to be a new creation that empowers better interactions with the two things it separates as a sole responsibility in lieu of a secondary feature? Why would we ever want this complexity, why wouldn't A and C just talk to each other without B being sandwiched between them. The answer comes in scenarios in which C is third-party code which you cannot or should not change on your own that yet needs to do more than it does. In these circumstances B becomes an extension for C. Examples:

  • This is how one extends a controller in ASP.NET MVC: Every controller inherits from Controller which sits in the System.Web.Mvc namespace. I do not recommend that you use JetBrains dotPeak to break open System.Web.Mvc so that you may change its guts about and then save off your alternate System.Web.Mvc .dll as a delicate little snowflake somewhere else. A better way to go is to have controllers inherit from a middleman class which in turn inherits from Controller. At AMD, our implementation came in a class called BaseController which inherited from Controller. All of the individual controllers inherited from BaseController and it held some stuff for helping in serializing types to JSON. Every controller in our app could have access to the new feature we bolted onto Controller by way of a middleman.
  • More recently, I have written on how we extended the default transition within a dojox/app application to allow it to fire an event when it finished which it did not do by default. Within the config.json (the Web.config of dojox/app) one may specify an AMD module to use in lieu of the default for transitions. We specified a middleman which just turned around and called the default module for transition. In setting up this pass-through, we could then shove stuff into the pass-through and we added an event which fires when transitions end. This solution comes from one of my superiors, I originally thought to make a copy of the default (dojox/css3/transit) and doctor it up, but it was pointed out to me that we didn't want to make something we could not upgrade. (We don't alter any of the dojox code itself, just our own extensions of it and controllers and views for it.)

*Speaking of arks (good segue?), as I thought to type this I thought of the bit in the sequel to The Hitchhiker's Guide to the Galaxy called The Restaurant at the End of the Universe which had to do with getting rid of all of the middlemen by sending them off on Ark B. When I read the The Hitchhiker's Guide to the Galaxy as a teen I initially cared enough to start into the sequel, but I gave up on the series partway through this second book. (I love the place of Douglas Adams' books in geek culture, but his books aren't really good books by any means.) I think I only learned of the Ark B stuff via some TV representation of the book. Anyways, a planet-bound society wants to get rid of all its middlemen (personnel officers, security guards, public relations executives, management consultants) and does so by drumming up a lie that the planet is doomed and that all of the citizens will journey out into the stars to find a new home in three giant arks (spaceships). Ark A will hold the "achievers" (brilliant leaders, scientists, great artists), Ark B will hold the middlemen, and Ark C will hold the people who actually do all the work on the "doomed" planet. Ark B leaves first, and of course the A and C groups don't leave at all. This sort of cleaning is pretty consistent with Martin Fowler's "Remove Middle Man" refactoring, but I for one have come to find that middlemen are not always wastes of space and that there are times when they are needed.

No comments:

Post a Comment