Encapsulation is not Information Hiding
published: Thu, 17-Mar-2005 | updated: Mon, 16-May-2005
I came across this article by Nat Pryce in the PlanetTW blog. It came at the right moment.
I've been grappling with reviewing the code in a new part of Enterprise Configuration Manager (ECM) here at Configuresoft, mainly for a sanity check (could this code be written better? could this thread-safety design be improved? could this process be optimized?) but also for a testability check. There are tons of unit tests at the moment, but they don't provide full coverage. (Indeed that's a topic for another time: should unit tests fully cover your code?) Part of the problem is the number of classes that require a fairly full set of infrastructure objects and services to be set up for testing, the least of which, believe it or not, is database access.
There are a whole bunch of hard-coded constant strings in the code: registry keys, file names, database names, SQL Server connection strings, remoting URIs, and so on. It's hard to test the classes that rely on these strings because in using them you require the services to which they pertain. For example, if the SQL Server connection string is hard-coded then, boom, I'm going to be accessing the production server in my testing. Urk.
This is exactly the problem that Nat Pryce is discussing. Too often, the inclusion of hard-coded values is excused by the word encapsulation. "The value is encapsulated in class X so you can't change it. Class X needs that particular value in order to work."
Well, no, not true. Class X generally needs a value, yes, but it could be anything. Give us the opportunity to change this kind of value, and the first time we make use of this functionality will be in order to test the class.