Follow @RoyOsherove on Twitter

API Usability vs Backwards Compatibility

Here's an interesting issue. At what point in the life of an API do you decide that it's better to keep a less than perfect API convention but keep backwards compatibility to a maximum, than to change or add new overloads of methods that are more self expressive and understandable?

Rhino.Mocks is a good example of just such a scenario.

Rhino.Mocks contains several ways to create a Mock Object:

  • MockRepository.CreateMock(type)
  • mockRepository.DynamicMock(type)
  • MockReposity.PartialMock(type)

 

Looking at the method names you might wonder what is the difference between the first two. Without telling you that, what if we changes the method names to these:

  • MockRepository.CreateStrictMock(type)
  • mockRepository.CreateNonStrictMock(type)
  • MockReposity.PartialNonStrictMock(type)

A strict mock means that you can't call any of the methods that were not explicitly expected. If you do, you get an exception from the mock object. A non strict mock will let you call anything you want, as long as what you expected to happen to it also happens. A partial mock will mock only part of a concrete class.

 

Better yet:

  • MockRepository.CreateMock(type,StrictOptions.Strict\NonStrict)
  • MockReposity.PartialMock(type) (non strict is implied)

When I contacted Oren (Ayende) with this he said that it may be a nice idea but he would rather keep things as they are and conserve backwards compatability (that it would even be too ugly to use [Obsolete] on the older methods.

Personally I don't think that I agree with this. You could easily search and replace your existing tests from CreateMock to CreateMock(nonStrict,type), just as an example. But hte readability benefit and ease of use I think grows on many levels because of this change.

What do you think?

Chapter 5 - Mock Object Frameworks - Done

Scrum - What it looks like in the real world