Category Archives: Architectures

Need-Driven Development

I recently came across a 10 year old article titled “Mock Roles, not Objects“. I recall reading this article at some time in the past, but I guess that I really didn’t get it the first time. This article is awesome, and I recommend reading it. But maybe like me, you need to become fairly familiar with TDD and using mock objects before it will have much impact on your thinking.

When I reread the article, I was immediately struck by the opening 2 sentences:

“Mock Objects is an extension to Test-Driven Development that supports good Object-Oriented design by guiding the discovery of a coherent system of types within a code base. It turns out to be less interesting as a technique for isolating tests from third-party libraries than is widely thought.”

Wow. The article then goes on to explain how the proper use of Need-Driven Development can help in the creation of good, clean architecture. I think that maybe the first time I read this article, I was still stuck in creating relatively few, large objects with lots of methods. After repeated viewings of Uncle Bob’s videos though, I changed my mindset to using lots of small, SRP compliant objects. Without that mindset, it might be possible to misinterpret this article as recommending the use of partial mocks to intercept calls from one method to another within the same object. Been there, done that, got help and am hopefully on the road to recovery now.

I think that there are still parts of this article that I’m not evolved enough yet to fully grok, for example section 4.1. I think I’ll come back and reread the article in another year or so and see if I get it then.

Using Storyboards

We generally do not use Storyboards in our projects where I work. That’s mainly because, at least as of iOS 6, they cannot be merged. This means that only a single developer can make changes to a storyboard at any given time. However, it appears that Apple is working on correcting this situation. So I’ve been taking another look at Storyboards, and investigating how these can be integrated into our best practices (TDD, clean code and architecture).

The first question that I had was “how to unit testing view controllers loaded from a storyboard?”. This appears to be fairly easy, and I found the answer on Rafael Adson’s blog. Simply load the view controller from the storyboard in the test setUp method:

- (void)setUp
{
    [super setUp];
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    self.vc = [storyboard instantiateViewControllerWithIdentifier:@"main"];
    [self.vc performSelectorOnMainThread:@selector(loadView) withObject:nil waitUntilDone:YES];
}

You’ll need to set the identifier for the view controller in the storyboard, and then modify the code above to match the name of your storyboard and the id you chose for the view controller.

The second question is how to integrate storyboards into the VIPER architecture. First off, it seems that the storyboard should replace the wireframe component. But there’s a problem. Normally the wireframe would be responsible for creating the view controller, interactor, and presenter. But the storyboard only creates a view controller.

Now, we can easily have the view controller’s viewDidLoad method create the interactor and presenter, but that results in making the view controller aware of those components. From a clean architecture perspective, we’d prefer that these components remain as detached from each other as possible.

That said, I don’t know how the storyboard can be used to create all three components, so I guess we’re stuck with the viewDidLoad hack at this point. I’m continuing to investigate, and I’d love to hear your suggestions.

First Observations on TDD with VIPER

In a previous post, I mentioned that I was rewriting WhatsMySpeed (now called HowsMyFuel and posted publicly on Github) using TDD and the VIP architecture. I’m committing changes at each step of the TDD cycle. I’m exploring to see if commit comments on Git can be used blog style. Let me know if this works for you.

One of the reasons in VIP of separating the ViewController into 3 components (ViewController+Presenter+Interactor) is to eliminate the Massive View Controller, so common in iOS apps. I’m discovering that one of the up sides to doing this is that I can move many of the unit tests from application to logic tests.

View controller tests typically require running in OCUnit application tests. OCUnit application tests are slower, since the app bundle is loaded. I don’t know how much slower yet, but I hope to test this later, as the number of unit tests gets larger.

So what goes into the View Controller vs the Presenter or Interactor? Normally the View Controller does nearly all the work. That’s why iOS view controllers tend to be huge. And huge typically means hard to read, even harder to unit test. However, I’m attempting to reduce the size and complexity of the view controller by removing all business logic. By that, I mean the logic that decides what an event does.

ViewController should contain basic iOS glue stuff; outlets, actions, etc.

Presenter should contain display-specific business logic, without interacting with the models.

Interactor should implement the business logic, aka use cases. It maps model data to the form needed by the Presenter and/or ViewController.

For example, the HowsMyFuel code as of April 25, 2013 contains code to register a tap gesture recognizer, and handle the tap event to recenter the map display when it is tapped. As is often the case, the event handling code is about 5 times the size of the business logic, which obscures the business logic, or intended behavior. To fix that, I’m going to elevate the business logic into the Presenter, where the expected behavior will be made crystal clear (when map is tapped, recenter the display on the user). Since this behavior is related directly to the UI display, I’ll put it in the Presenter. If it was dealing with Model data and/or not UI display specific, then I’d elevate it even higher to the Interactor.

VIP Architecture

One of the architects at work has started exploring using an architecture he is calling VIP (View-Interactor-Presenter?). He started thinking about this idea from reading an Uncle Bob blog entry on 8thlight.com. Yesterday he presented his ideas to the group during a brown bag session, and it got me thinking about the implications of such an architecture to unit testing.

The main idea is to abstract and extract use cases up out of the other components, primarily the view-controller, into a separate, simple NSObject called the Interactor. This object then deals with implementing use cases (aka business logic).

In a sense, the traditional MVC model becomes the Presenter component, used similarly as in an MVP architecture.

What about the Model? This is still a bit fuzzy in my thinking, but there can actually be two different types of model, and places where they exist. The Interactor interfaces with the traditional model, which could be CoreData, a RESTful API extraction layer, local persistence, etc. A key concept though, is that this Model uses fully abstracted, reusable objects, not customized for a particular presentation method or style.

Within the Presenter component, there may exist another presentation-specific model object that converts the reusable Model object into a form needed for presentation. Like I said, still too fuzzy of a definition, but it feels like a good starting point.

What does this mean, really? I think it means that business logic gets put into a single place, instead of being scattered around in various other places. The really big implication here is that the high level behavior of the system is defined in abstract terms in the Interactor! I think this makes it possible to do TDD starting with tests built from Use Cases, which I believe is the definition of Acceptance Test Driven Development (ATDD).

I’m going to start redoing my What’s My Speed sample app this weekend to see how well this concept works, hopefully firming up some of the fuzzy areas. In order to really test the ATDD aspects, I’ll need to start from scratch, creating and working from User Stories. I’ll be posting my progress as I go.

Update: I’m renaming the new code HowsMyFuel to avoid confusion with the older code. HowsMyFuel will use OCUnit, OCHamcreset, and OCMockito for unit testing. The code is posted publicly on Github.