Geeks With Blogs
Jonathan Starr's Blog Thoughts on C#, Ajax, WCF, LINQ, Agile et al.

improve my => 'code' Add to Google

I got some responses from a post I made on Saturday, that troubled me.  I really think it is important to code to an interface whenever possible - not only to give your application to flexibilty, but to give it testability as well.  So I thought I might give you an example.

Say I have a class that depends on two other classes I have.  In this example, Partitioner depends on SystemIOAdapter and MerchantRecordCounter.                                                                                                                                                                

                                                                                                                                                                                                                    

using Interfaces;

namespace Program

{

    public class Partitioner : IPartitioner

    {

        public void PartitionMerchants(ISystemIOAdapter io, IMerchantRecordCounter counter, string mappedPath, string partitionPath, int maximumCount)

        {

           // implementation details.

        }

    }

}

If the method PartitionMerchants had been written using class declarations instead of interfaces, than any test I would write for this method would be an integration test, not a unit test...  Because the failure could be in one of the dependent classes, not in the class that is under test in my unit test! 

Integration tests are useful as smoke tests to identify that a problem exists.  But they don't help me quickly identify the root cause of problems when they arise.

The following shows a unit test for a Partitioner class that depends on a SystemIOAdapter (so dependencies on a specific IO is removed),  and a MerchantrecordCounter class.  You may notice that the only way to mock these out are by creating classes that implement the same interfaces used in the PartitionMerchants method.  (In this case I am using Rhono Mocks to do this quickly).

using Project.Interfaces;

using NUnit.Framework;

using Rhino.Mocks;

namespace Tests

{

    [TestFixture]

    public class Partitioner_UT

    {

        private MockRepository mocks;

        private string mappedpath = "mappedpath";

        private string partitionedpath = "partitionedPath";

        private ISystemIOAdapter io;

        [SetUp]

        public void SetUp()

        {

            mocks = new MockRepository();

            io = mocks.CreateMock<ISystemIOAdapter>();

        }

         [Test]

        public void PartitionDirectory_OnlyOneMerchantFound()

        {

            IMerchantRecordCounter counter = mocks.CreateMock<IMerchantRecordCounter>();

            using (mocks.Record())

            {

                // set up call expectations here

            }

            using (mocks.Playback())

            {

                IPartitioner partitioner = new Partitioner();

                partitioner.PartitionMerchants(io, counter, mappedpath, partitionedpath, 0);

                // Add assertions here

            }

        }

    }

}

I hope this clears up why it is so important to write code using interfaces whenever possible!

Jonathan Starr

Posted on Monday, June 23, 2008 6:26 PM C# , Software Design , Software Development , ASP.NET , Agile Development | Back to top


Comments on this post: Code Redundancy is NOT Bad - Part 2

# re: Code Redundancy is NOT Bad - Part 2
Requesting Gravatar...
Hi Jon.

Thanks for clearing up what you meant. The thing is, you can mock a class. I'm with you, prefer an interface, but I have used a class rather than an interface, knowing it was already there, and if I needed to I could've refactored the class.

I responded to this in a post. I also commented on the var thing, which was accidental, I wasn't planning on it, but oh well :P

http://geekswithblogs.net/mhildreth/archive/2008/06/23/that-whole-crazy-var-thing.aspx
Left by Mark Hildreth on Jun 23, 2008 10:49 PM

# re: Code Redundancy is NOT Bad - Part 2
Requesting Gravatar...
You are making a lot of assumptions here. Interfaces are merely a workaround for static languages to use disparate types in a similar fashion. All an interface does is define a contract that an inherited type meets specific way to access methods and data consistently. That way a typed system can be a little more "flexible" in the different types an operation can perform on.

In a dynamic or aspect based system could easily do this without having to define an explicit contract, or have to cast to a common type. The latter, Aspect Oriented Programming handles what interfaces attempt to be, but much more complete, and increases code reuse.

Take the following pseudocode.

class A

function hello()
print "Hello"
endfunction

function foo(num)
return (num + 2)
endfunction
endclass


class B

function hello()
print "Goodbye"
endfunction

function bar(num)
return (num + 5)
endfunction
endclass

class C inherits from B

function baz()
print "I like Potatoes!"
endfunction

endclass

obj1 = new A
obj2 = new B
obj3 = new C

a = new Array(obj1, obj2, obj3)

for each widget in a
widget.hello
endfor

The results would be:

"Hello"
"Goodbye"
"Goodbye"

In this example 3 different types are all used the same way in the for loop.

But you say what if we had an object that didn't support that method? Well, very similar to casting but much more easily.

Take this for example.
x = 5
for each widget in a
if widget.responds_to('bar')
widget.bar(x)
endif
x++
endfor

The result:

11
12

it seems like a bit more code, but in this case, we can reuse certain classes, in ways that don't have to be completely the same or agree to a set contract.

Further testing, in your case, would make this approach much simpler. And the tests themselves would verify that your code is correct.

Left by Jimmy Slicker on Jun 25, 2008 5:40 PM

Your comment:
 (will show your gravatar)


Copyright © Jonathan Starr | Powered by: GeeksWithBlogs.net