Monday, January 12, 2009

Just Fake It

No matter what some people might say, faking it is perfectly acceptable. Seriously, faking it allows you to get finished your task sooner. Some people think that faking is cheating, but it's not.

Ok, enough with the double entendres, what am I really talking about? Why using mock objects or stubs of course.

Stubs are more common in the types of projects that we tend to do, but we do use mocks as well. I really like these design patterns and try to use them often to decouple different teams from each other. This being said, the concept of stubbing and mocking is starting to become a bit of a lost art.

Once the interface and supporting data structures are designed, one team can start to work on developing the user interface using stubs and mocks whilst the back end team works on implementing the actual functionality.

This has several benefits:
  • It removes the back end team from the critical path
  • Facilitates the creation and maintenance of unit tests
  • Facilitates the top-down coding methodology
  • Provides an actual user of the APIs and data structures to validate their design
  • Allows the team to focus on the big technical risks
  • Helps facilitate the separation of teams
Shortening of the Critical Path
By the smart application of mocks and stubs, the manager can reduce the overall critical path of the project and the dependencies on the back end team. All the teams need to collaborate together to define the interfaces and use cases, but once that is done the teams can work independently, and most importantly, in parallel. Without the use of stubs and mocks, the user interface team for example, would be unable to accomplish much work until the back end was implemented.

Creation and Maintenance of Unit Tests
Many teams and projects now work in the Test Driven Development methodology, or at the very least rely on unit tests to demonstrate correctness of the code and help guard against regressions. The use of mocks and stubs can help encourage the creation and maintenance of unit tests by allowing the developers to first stub the back end and then write the unit tests to exercise the interfaces. Additionally, mocks provide the ability for the unit test writer to write the unit tests that exercise code that relies on complex objects. Additionally, since mock objects implement the interface and simulate more complex real objects they allow programmers to implement and unit-test features in one part of the application without actually having to call the more complex underlying objects. A broad, well maintained unit test suite will give you the manager a lot of confidence with regards to the overall quality of the application. In addition, a good test suite can give the manager a lot of confidence to approve the re-factoring exercise without fear of introducing regressions.

Facilitates top-down coding
Stubbing and mock objects are an essential part of the top-down coding methodology, or as some people like to call it "breadth-first coding". Read the link for a much more detailed explanation then what I have room here for.

Validation of APIs and Data structures
Often "paper" doesn't match reality, and the best designs on paper fall apart in real life applications. The use of mocks and stubs that meet the interface requirements and behaviors of the design allow the users of the interfaces and complex objects to actually use them in a real life scenario while the real implementations are still progressing. This can safe costly redesign and re-factoring exercises, both in terms of budget and schedule.

Move the big rocks first
Clever use of stubs and mocks allows the team to focus on solving the big technical hurdles without getting bogged down in the small little details of the project, the so called while stubbing "boilerplate" functionality. For example, your web application needs to implement complex domain specific functionality that requires a lot of collaboration between the development teams and the stakeholders, of course you need user management and login, but those problems have been solved a thousand times before, and the amount of work required to implement them is well known, leave the actual implementation to the end. Removing the technical hurdles upfront in the project allows the manager to more accurately estimate the end date of the project as the most riskiest items in terms of budget and schedule have been solved.

Separation of teams
With today's global teams distributed across the globe all efforts have to be made to decouple the teams and reduce time to market while at the same time keeping the project as a whole cohesive and highly productive. When the developers from your user interface team come to you and say they are blocked because they are waiting for the back end guys to finish their service layer, or that no one but the team here in the head office can work on that feature because it depends on another feature from another team, remind them of the concept of stubbing the APIs and mocking the complex pieces in the interim, this may well indeed allow another team in another location work on that feature with little to no impact in quality or time to market. Of course the teams still need to communicate constantly with each other. The ability to easily separate areas of the application will help the manager build out the team in multiple locations, potentially allowing the team to grow faster then could be hired locally.

1 comment:

Gilles Duchesne said...

or as some people like to call it "breadth-first coding"

Some people being... me, I guess. :-)

I know the term isn't an instant sell. Our own Sylvain doesn't like it much.

At first, I was looking for a term that would conjure the right image in developers' minds. However, aside from "top-down", which we already knew didn't always seem to work. So I ended sticking with "breadth-first", for reasons covered in the post.

At least if you bring it up to a developer, and he goes "Muh?", he'll feel compelled to ask around or look it up. If at that point he goes "Oh, that's just top-down. I already do that.", great! ;-)