When do you need an abstraction

I had a good question from an architect the other day.  He was looking at one of my models, where I had created an abstraction and then modeled some of the concrete entities under it.  He didn't believe that the abstraction was necessary.

He mentioned that it is possible to create abstractions from nearly any pair of objects in the world.  An infinite variety of abstractions are possible.  Therefore, we need to create abstractions only when they are useful.  Otherwise, the abstraction, and subsequent inheritance, simple add complexity to the solution.

Of course, I defended my design like a champ, but it did make me think: what is the rule of thumb?  What is the lithmus test for whether an abstraction is needed or not?

The answer that I've settled up, after thinking about it, is that an abstraction is primarily useful in two cases: 1) to create a list of items that may change, or 2) to seperate two different lists of items, especially if the membership in one or both lists may change during the lifetime of the system.

In other words, if you have a system that cares only about apples, and provides a list of the attributes of an apple, and the list of attributes changes over time, then you don't need an abstraction between the apple and the list.  The list is simply attached to the apple.  On the other hand, if you want to change the apple to a list of different kinds of fruit, then you now have two lists (fruit and attributes) and it makes sense to place an abstraction between them (good choice may be the Bridge pattern).

 Another abstraction is the list of business capabilities provided by the MSBA capability hierarchy.  The strategies of a company change, and the business processes change.  You need a stable abstraction between them (the business capability hierarchy) to allow you to convert strategy to changes in business process in a rational and simple manner.