Interfaces are a great way to develop applications that are loosely coupled, making it easy to maintain and update your code. An interface behaves like a contract, meaning that the class implementing the interface and the class using the interface both know exactly what to expect. A good example of an interface that makes it easier to understand is the power outlet. The lamp could care less how it gets its power, if only knows that if you plug it in, it gets power. Likewise, it doesn’t matter if you’re plugging in a TV, lamp, alarm clock, or anything into the outlet, if you have the right connection you are going to get your power. In this case, the power outlet is an interface.
Let’s get started with an example. For the sake of argument, let’s say that we have a bunch of music that we want to store information for in a database. For the purposes of keeping this simple, I’m just going to store albums, which will contain the artist and a list of songs that make up the album. In reality, it’s not the best way to store this information, but you get the idea.
Now that I have the basic objects defined, I need to figure out what exactly I want to do with them. I’ll keep it relatively simple for this example, and I’ll just store the information and retrieve it based on a search string. My interface looks like this.
The next thing I want to do is create a database storage class that implements this interface. If you telling yourself that we could have skipped the interface creation and just wrote a library that stored the information directly to the database…….hold that thought. I’ll answer that question a little later. The next thing I need to do is create my database storage class which will implement my interface.
I chose to use SQL Server 2005 as my backend, and I used stored procedures for all of my data access. I have provided all of the create scripts for any stored procedures I created, as well as create scripts for the database itself and the tables. These are available with all of the code if you would like to take a look at it. My storage class looks like this:
Now I have all the pieces in place, and I can now work on the user interface to test all of this. The interface I put together to test this is by no means a thing of beauty, but it will work for this example. Using this interface, I enter an album to store in the database, as shown in the screenshot below.
This works the way we expect it to, and the data in our database looks like this:
OK, after all of this, you may be wondering why I went through all the trouble of even creating the interface. Suppose this application is running on your PC, you show it to one of your friends, and now he would like to run it at his house. He doesn’t have SQL Server running though, so the current storage option just won’t work. Your friend would love to have his stuff stored in XML though. Rather than rewriting the entire application, you can just write an XML storage class, and change a single line of code in the client application to use the new engine.
This is the implementation in our user interface to store our album in the database.
The key here is that you implement the same interface you did for the database storage engine when you write the XML storage engine. It might look something like this:
Changing a single line of code in the client changes our storage from SQL Server to XML. The line that you have to change is this one:
The output using the same album as before looks like this:
I hope this example has been helpful in showing how interfaces can be used to promote code maintainability. Feel free to download the example code.