Agile software development using Kanban & Scrum. We code Flex & Ruby on Rails in Auckland, New Zealand.

  • Viewing all posts tagged "architecture"

  • Extract Responsibility Refactoring.

    In Martin Fowler’s “Refactoring” he introduces the “Extract Class” refactoring. I love this refactoring pattern and I use it all the time.

    This refactoring is (unless im sorely mistaken) the most important one for the SRP.

    Because of this intimacy with the SRP, I think there is an umbrella refactoring, called “Extract Responsibility” with two concrete methods for achieving it:

    Extract Responsibility

    You have one class responsible for the work that should be done by two.

    Decide if the extra responsibility is encapsulated as a Component (Has-A) or a Process (IoC)

    Extract Component

    You have one class with an additional responsibility that exhibits compositional behaviour

    Create a new class and move the relevant fields and methods from the old class into the new class (lifted directly from Extract Class)

    The new class is a component if all it takes to make the refactoring, is to move methods. In my experience you are ‘Extracting A Component’ if the original classes’ data easily fits into a “Has-A” relationship.

    Extract Process

    You have two methods in subclasses that perform similar steps in the same order, yet the steps are different. (lifted directly from “Form Template Method”)

    Create a new class, add process hooks in the new class and use those to call on the original classes actions.

    OK so here is the crux of the matter. There are classes that still have too much responsibility, but it’s not in a ‘Has-A’ relationship. These classes have a ‘process’. These classes often present themselves in sets. Usually you will find two classes doing the exact same thing with moderately different behaviour.

    The most suitable term for this extraction is “Inversion of Control”. Please don’t think I mean DI. DI, especially automated DI, is “Orthogonal Control” in my mind (topic of another post I must write).

    The most common way I’ve seen of inverting control for a class or set of classes is the Form Template Method Refactoring. There are probably quite a few other methods for achieving IoC, including utilizing annotations.

    The one I prefer is the Fluent Interface, and a beautiful example of IoC in fluent interfaces is Shaun Smith’s Promise Class.

    In general I prefer Fluent Interfaces over Template Methods because they turn an ‘Is-a’ into a ‘Has-a’, providing far less coupling, and allowing for more than one ‘Process’ to be utilized by any given class.

    This actually makes the new Fluent class a “has-a” relationship, so how does this differ from ‘Extract Component’? - You are not extracting data, you are extracting common behavior.

    There is one downside to Fluent Interfaces: Language support.

    In languages like Actionscript 3, you cannot delegate methods with static typing. This means that the callbacks you give your fluent interface are not compile time checked. In my next ‘Actionscript 4’ article I’ll talk more about static typed delegates and how much I think we need them in the language.

    Finally

    My apologies that my writing is not succinct. Writing is a craft I need to take more time to master. So please, feedback, opinions and constructive criticism!

  • Why Boiler is better than Robotlegs. Pt. 1

    Haha! That’s gunna turn some heads.. I hope.

    Herein I set out to explain why I’m building Boiler. Other than the obvious fun of writing a framework, I have some very specific reasons.

    I could be wrong of course, Robotlegs is so good (and it’s well past the alpha stage, unlike Boiler) that it’s a tough call. However, why would I bother if I wasn’t trying to improve on something awesome?

    Doubling intent

    Imagine this is a mediator I just wrote:

    package views {
        public class WidgetMediator {
    
        [Inject]
        public var notifier:IEventDispatcher;
    
            private var view:Widget;
    
            public function register(view:Widget):void {
                this.view = view;
    
                view.addEventListener(MouseEvent.Click, handleClick);
            }
    
            public function deregister():void {
                view.removeEventListener(MouseEvent.Click, handleClick);
            }
    
            protected function handleClick(event:MouseEvent):void {
                notifier.dispatchEvent(event);
            }
        }
    }
    

    I consider this class to have all the markings of a mediator. It’s name ends in mediator, that should be enough… But there’s more. It’s in the views folder where a lot of folk stash their mediators. It expects to be registered against a view:

    register(view:Widget)
    

    Despite not inheriting from a Mediator Interface, it’s a mediator. In the land of Ruby, they call it ‘duck-typing’. It looks like a duck, quacks like a duck, it’s a duck.

    So in Boiler, we use conventions to invert control. When you start using Steam, you follow convention to describe the intent for a class. Steam, by the way, is the reference desktop framework for Boiler, like MVCS is for Robotlegs.

    The above mediator needs only be ‘Mapped’ using SwiftSuspenders and Steam will configure injections and view mappings ‘because it looks like a mediator’.

    In Boiler:

    lifetime.mapClass(WidgetMediator,WidgetMediator); // A little note on the first param later.
    

    In Robotlegs:

    mediatorMap.mapMediator(WidgetMediator);
    

    It’s a tiny difference, really, except now we don’t have to inherit from anything to look like something. Later I’ll show that we also don’t let ourselves get caught by inheriting from sugar classes.

    The first thing that Boiler gives you, is no more polymorphic dependencies that only serve to duplicate intent.

    When you want to extend the framework behavior, remove behavior, or use certain behavior in only some modules, the benefits of avoiding framework polymorphism become clear. Later on, I’ll demonstrate this with examples that extend or modify the framework.

    About that first parameter

    Why does SwiftSuspenders require an interface separate from the class to instance? This example is a mediator, all of it’s dependencies are injected. It’s never injected into another class. Where it’s built is where it’s stored, in a generic, testable class… So I can’t see a problem with lifetime.mapClass(widgetMediator);

  • Why Boiler is better than Robotlegs. Pt. 2

    I’m starting out with the “not terribly awesome” and perhaps even “that’s crap!” stuff. That is, you might think I’m losing my mind at this point. Remember these are things that I love about Boiler. You might not.

    I promise you, though, that the final two articles in this series will be epic. I’ll show you how to extend Steam using ‘commands’ as an example. I’ll also show you how to integrate some syntactic sugar without making the framework brittle.

    Sugar be damned.

    It’s sugar that I want to discus in this post.

    Sugar is usually not the same concern as the base class.

    Mediator#addViewListener makes me think that Mediator is-a view listener.

    Mediator#addContextListener makes me think that Mediator has-a context bus AND is-a contextListener.

    In Steam, neither is true. Mediator is-a class that expects to be told when a view of a specific type has been added to the stage. That’s all it is, period.

    Without sugar, there is no Mediator Interface, only duck typing as I explained in the previous article.

    It’s all about SRP

    Sugar can hide the obvious from tools.

    This ones pretty fluffy, purely a matter of taste.

    Again with the Mediator sugar from Robotlegs, I would usually start typing:

    addContextListener(MyEvent.EVENT_NAME,eventNameHandler);
    

    IntelliJ would highlight the ‘eventNameHandler’ so I could select ‘create method’. Which is great. I can automatically stub out:

    public function eventNameHandler():void {
    }
    

    That’s not bad… Except if I had used:

    myContextBus.addEventListener(MyEvent.EVENT_NAME,eventNameHandler);
    

    IntelliJ would offer to stub out:

    public function eventNameHandler(event:MyEvent):void {
    } 
    

    Boiler want’s us to avoid hiding language conventions. Kthx?

  • On the benefits of refactoring

    You can’t build an office block and then decide you had better put in some concrete foundations afterwards.

    You can, however build a large scale app and decide you want a different foundation along the way.

    When you start an agile project, you “pitch a tent in dirt”.

    E.g. write a simple app that lets users drag a ‘job’ - which only has a name and id - onto a timeline.

    You then itterate, turning the the tent ever so slowly into the office block ( e.g. vWorkApp ). You get to revisit every aspect, and you must revisit it.

    If you don’t, you’ll have an office block sinking into the mud.