YAGNI: Some thoughts
Although it can sometimes be used to ignore things we don’t want to focus on as Ian points out, in general the aim is to stop people from working on code that isn’t currently required.
So assuming our team isn’t being lazy and trying to avoid decisions that they don’t want to think about, why do we hear the YAGNI call and more importantly, perhaps, what happens when we don’t heed that call.
Jack of all trades, master of none
One of the problems of writing APIs that are designed based on potential future use (by multiple clients) is that the API ends up not being what any of the clients want - it does its job but not in a way that makes life easy for any of the clients.
From my experience the easiest way to design usable APIs is to drive the design by using examples. We only write code if we have an example/test to drive that out.
At a higher level this means that we should drive the design of our code by working out how the client is going to use it rather than trying to anticipate how it might be used. This is sometimes known as client driven development as opposed to assumption driven development.
Joe Walnes' XStream library is often referenced as an easy to use library because he only added features that he needed (as a client of the library) rather than trying to imagine what features people might want.
Change becomes difficult
If we have driven our code based on assumptions of how we think it might be used in the future then it becomes more difficult to change it because we need to ensure that the changes we make won’t cause problems for these potential future clients.
Code driven this way rather than by examples tends to be much more complicated because we don’t know which cases we need to handle and which we don’t - we end up trying to handle them all.
Making changes to code after it has been written is quite common but we have now made this more difficult for ourselves. Changes end up taking longer and we can’t be sure that the change will work for anyone beyond our current clients anyway.
When we only develop an API for clients that currently exist we are writing much less code than when we try to code for the generic case and therefore we can accomplish our task much more quickly. The inverse being that when we don’t we spend a lot of time trying to write a solution that veers more and more towards being a framework.
This doesn’t mean that we should completely tie our API to that client - instead we should ensure that our solution is flexible and easy to change in the future.