A: 

I'm not really sure, but for me, when in doubt, I always like to provide shortcut convenient methods that wrap this kind of abstraction.

Something like

void runCommand(string cmd) // objects instantiated and used inside

so even if I have too much abstraction, there's still a straight-forward way to just "do it dammit".

hasen j
+6  A: 

The question you need to ask is, does this additional abstraction solve some problem you had before adding it, and is the complexity of the abstraction acceptable to you? When to abstract is a pretty subjective decision...as is often said, abstracting can solve almost any problem, but at the cost of greater complexity.

If you are asking this question, it seems your questioning the value of the additional complexity this abstraction brings to the table. It doesn't look terribly complicated given your diagram, and if it does indeed solve a problem you were having before...I would say go with it.

Ultimately, go with your instincts...abstract when necessary, but avoid it if you can.

jrista
I'd add: start with the least amount of abstraction possible, and only add more if you really need it. (YAGNI)
hasen j
Well it does make developing the higher class objects like Table, Map, Window, Object etc a lot easier because they don't have to worry about the commands getting run only the result thus meaning easier to mock the tablecommandrunner rather then the strings needed for IComObject.
Nathan W
+2  A: 

I don't think it's too many levels of abstraction. Your solution looks quite elegant to me because you are simply testing that the Table class calls the right ComandRunner functions. You are testing how the Table class deals with the CommandRunner, and you have removed all the complications of the CommandRunner implementations including the IComObject. This is what Mocking is all about.

Uncle Bob