So, reading the last post, it might seem like I’m advocating a lot of extra work to do anything. Having each class create its own interfaces for everything probably seems a bit insane. Wouldn’t it be better to define a single, universal interface for, say, a database?
Short answer: no. By doing so, you’ll inevitably end up intermingling aspects of the dependency with your core code. In the User example in the previous post, even if you abstract the DBConnection to an IDatabase, you still have to deal with the fact that you’re now tied to a database, and have intermingled knowledge of the database layout and SQL variant you’re using into your User class.
The problem is that each class has its “natural” language. The “natural” language of the User class is “save the user with this id and this name” (and whatever other information is appropriate). The natural language of the database is “run this sql command.”
Just as it would be inappropriate to put code specific to the User object in the database, it’s also inappropriate to put database specific code in the user.
So, instead, what we can do is create small classes that take the output of one class (the User, in this case), and turn it into the input expected by the other class (the database, file system, etc.). There’s no real extra code required to do this, as all of the code would have to be written ayway. By doing this, you remove the knowledge of this glue code out of either of the two classes, and allow it to live in its own classes, possibly even its own assemblies.
There are times, though, that you do want to maintain a common interface between classes. But only do this if the classes in question naturally end up with the same interface, or it’s a “natural” dependency - if you’re writing something that retrieves data and writes to a disk, then a mocked file system is appropriate. An FTP client would be a good example of this, as there wouldn’t really be a point to writing an FTP client that saved to a database.
Additionally, if the “glue” classes are more than simple pass-through classes, it may be worthwhile to test them more thoroughly, and so mocking their underlying data store may be appropriate.
Post a Comment
You must be logged in to post a comment.