Object oriented programming vs. class oriented programming

In the last post, the code was pretty clean. Our resident Rhino.Mocks guru at work, Sean, left a comment saying that the new code was much better than the Do-Func stuff I had before. Sean was the one that pointed me to the Repeat.Times methods in Rhino.Mocks. I thought I’d post the old code that I had cobbled together from a StackOverflow answer.

           IDataReader reader = MockRepository.GenerateStub<IDataReader>();

            reader.Stub(x => x.Read()).Do((Func<bool>) delegate()

                                                           {

                                                               m_NumberOfTimesIDataReaderHasBeenCalled++;

                                                               return

                                                                   (m_NumberOfTimesIDataReaderHasBeenCalled%2 != 0);

                                                           });

            reader.Stub(x => x["ID"]).Return(Guid.Empty);

            reader.Stub(x => x["FullName"]).Return("Test User");

 

            List<UserDTO> list = SearchProvider.ParseUserData(reader);

            Assert.IsNotNull(list);

The re-factored code using the Repeat.Times methods.

            IDataReader reader = MockRepository.GenerateStub<IDataReader>();

            reader.Stub(x => x.Read()).Return(true).Repeat.Times(1);

            reader.Stub(x => x.Read()).Return(false);

            reader.Stub(x => x["ID"]).Return(Guid.Empty);

            reader.Stub(x => x["FullName"]).Return("Test User");

 

            List<UserDTO> list = SearchProvider.ParseUserData(reader);

            Assert.IsNotNull(list);

You can see how the second code sample is much cleaner than the first. A lot of the messiness of the first code sample comes from talking to the compiler instead of talking to objects. What do I mean by that? Well, in the first example we have to tell the compiler what the delegate should return

Func<bool>

You’ll also notice some ugliness inside of the delegate body.

m_NumberOfTimesIDataReaderHasBeenCalled++;
return (m_NumberOfTimesIDataReaderHasBeenCalled%2 != 0);

Here, I was incrementing a class member and checking to see if it was odd or even. If it was even, I’d return true, otherwise I’d return false. This allowed me to control the number of times the IDataReader.Read() method would return true. In this case, it would return true once, then the variable would be incremented to an odd number and the Read method would return false.

That’s all part of me telling the compiler what to expect, when what I really want to do is just tell my objects what to do. This episode of the Alt.net podcast also talks a little bit about class-based programming versus object-oriented programming.