Interfaces

Interfaces

Old forum URL: forums.lhotka.net/forums/t/1377.aspx


pfeds posted on Tuesday, October 03, 2006

Do you ever get the feeling that you're doing things the wrong way, or maybe the right way, and then you get all confused...?

I've developed a number of apps using CSLA and have never felt the need to use interfaces.  I'm currently working on a new, fairly large, development so we're at that critical time of starting things off correctly. 

My plan was to create an object library, then simply use these objects in the Windows GUI, Web Services and such.  This seems like the simplest method to me, and I like to opt for the simplest method.

Other people in the team (including the team leader and other lead developers) are insisting on the use of interfaces which also requires the use of factories.  I'm outnumbered, so I'm trying to reason with myself that this is a good method.  My instincts are stubborn, so I could really do with someone giving me a good argument why I might be being stupid.

This method will mean our code will need to be something like this (using Customer as an example):

 

ICustomer customer = ICustomerFactory.GetCustomer(customerId);

or

ICustomerList customerList = ICustomerFactory.GetCustomerList();

instead of simply:

Customer customer = Customer.GetCustomer(customerId);

 

My opinion is that the interface/factory method means more coding aka more complexity, and for what?

Their argument for this is "How else are we going to use mock objects?".  I agree that this does add a level of abstraction, but I can't help believing this is unnecessary.  Isn't it a simpler solution to just create a mock object library if need be, and use that instead of the production library?

Additionally, I've run into a slight issue with databinding to interfaces...

We now have a definitive interface heirarchy such as this:

IItem (Id, Name, Description)

ICustomer : IItem (adds Address, PhoneNumber etc)

If I add a Data Source to a Customer object then all's well.  If I add a Data Source to ICustomer then all I get are the properties definied by ICustomer.  IItem properties are ignored. Any ideas???

Thanks in advance for any advice, even if it involves calling me a muppet.

ajj3085 replied on Tuesday, October 03, 2006

Interfaces are good if you'll have two or more objects which need to be interfaced with in the same way, but otherwise are unrelated.  For example, IDbConnection.  SqlConnection and OleDbConnection will never need to work together, but it would be nice if we didn't care which kind of connection we used.

Converse this to inheritence, where you can modify behavior through its use.

Adding interfaces for the sake of adding interfaces doesn't seem like a good idea to me.  You are constraining yourself for no reason up front.  If you need that later, fine, add it then.  Remember, YAGNI (you aren't going to need it).  Any arguement that says 'we may need this later' should be countered by 'then we'll add it later.'

Why would you mock away your library anyway?  That's not going to help you test it at all.  I should also point out I believe that in most cases mocking is a waste of time, unless some objects have a complex interaction and you want to make sure that object A is properly using object B.

Just my two cents.
Andy

pfeds replied on Tuesday, October 03, 2006

Andy - thanks for your useful opinion.  I have just finished reading your earlier thread on interfaces and data binding which cleared up that issue Big Smile [:D] 

I'm not sure I can see the reasoning to prevent data binding to an interface heirarchy (when adding Data Sources).  I figured that as an object could have a number of interfaces, why would you try and bind to any number of them when it's far easier just to bind to the concrete object... does that make sense, or am I rambling!?!

For me your comments about YAGNI and 'we may need this later' so 'then we'll add it later' really hit the nail on the head. I'm all for agile development and XP.  Unfortunately for us we have legacy software and our developers are constantly saying "We know we'll need this in the future, so lets do it all now".  I normally retaliate with "Do we really need it, and if so we'll do it when it's needed".  Then I get "Don't be daft, that will mean refactoring a lot of the code in the future".  I reply "So what?".  Hmm.  As far as I can see, these interfaces and factories aren't necessary at the moment.

I also agree with you about mock objects. Why create them until we have a need?  They're certainly worth while, especially in unit testing.  I quite often think they're a waste of effort, but I can't dismiss that proper unit testing is also very useful to have.  Besides, I can't see why mock objects are dependant on interfaces... but it seems that other people believe you can't have a mock object without an interface.

Sorry about the rant. And thanks, I really appreciated your 2 cents.

It's very interesting to see other peoples opinions.

guyroch replied on Tuesday, October 03, 2006

pfeds:

Unfortunately for us we have legacy software and our developers are constantly saying "We know we'll need this in the future, so lets do it all now".

Shame on any developers that creates software parts for the future - guess what - the future might never come.  And if they do so, then they are creating more issues for the future, and for what, for something they think they will need!  I say if you don't have a use case today, you don't code it today.  If you get a new use case tomorrow, you code it tomorrow.

More code = more testing = more bug prone = more refactoring = less efficient code reviews = higher cost of change in the future...

Sorry for the rant here but I fully agree with 'pfeds'- and not necessarily with the developers he is working with :)

pelinville replied on Tuesday, October 03, 2006

guyroch:
pfeds:

Unfortunately for us we have legacy software and our developers are constantly saying "We know we'll need this in the future, so lets do it all now".

Shame on any developers that creates software parts for the future - guess what - the future might never come.  And if they do so, then they are creating more issues for the future, and for what, for something they think they will need!  I say if you don't have a use case today, you don't code it today.  If you get a new use case tomorrow, you code it tomorrow.

More code = more testing = more bug prone = more refactoring = less efficient code reviews = higher cost of change in the future...

Sorry for the rant here but I fully agree with 'pfeds'- and not necessarily with the developers he is working with :)

 
There are times when you do, actually, know that you will need that functionality.
 
Say you are upgrading a system from Borland Delphi using a Pervasive database to .Net and Micorsoft SQL server.  You decide to do it in steps converting modules on a specified schedule.
 
You do, in this case, know that you will need all the functionality of the previous system.  You also know what additional functionality you are going to add (because you promised it).
 
In those cases you can safely "design for the future".  And using interfaces does give flexiblity to the intermediate steps.
 
But outside of that, I agree with you.
 

malloc1024 replied on Tuesday, October 03, 2006

A mock object must have the same interface as the real object because the client should be unaware whether it is using a mock or real object.  You can achieve this by using abstract classes or interfaces.  Interfaces are used to make sure that the mock objects have same interface as their real counterpart.  If you create a mock library without using interfaces you could mess up. This would increase the time spent on debugging the mock library.   IMO, using mock object improves your code because it forces you to program to an interface.

malloc1024 replied on Tuesday, October 03, 2006

The other people on your team are correct.  One of the basic principles of OOP is to program to and interface not an implementation.  By interface, I mean an abstract class or interface.  This will make your code more flexible and easier to maintain.  Of course you will need to program to concrete classes some times; however, you should limit this as much as possible.

JHurrell replied on Tuesday, October 03, 2006

What is their reasoning for wanting to use mock objects? Is it solely for testing?

I just want to make sure that before we give you any more advice, we clearly understand why they're pushing the interface route.

If they were saying, "We should use structs instead of objects because, how else are we going to do X" there might really be a legitimate reason if we knew what X was.

- John

ajj3085 replied on Tuesday, October 03, 2006

JHurrell:
What is their reasoning for wanting to use mock objects? Is it solely for testing?

I just want to make sure that before we give you any more advice, we clearly understand why they're pushing the interface route.


Usually mocks are done when testing.  Personally, I rarely mock anything when building unit tests.  My reasoning is that I define 'unit' as the class (or classes) which I'm testing.  That includes the objects responsiblity to persist itself. 

There is a nice discussion on mocking vs. not mocking in this forum if you search for it.  Personally I don't usually see mocking in unit testing as necessary, and so its not a valid reason to create a bunch of interfaces.  Abstraction is nice, but too much of it makes things overly complex and hard to maintain.    Usually you abstract things that change often.  Is Customer going to change a lot? Probably not..  you need to find a balance.

Of course though we don't know all the details of the discussion from the OP, so he'll have to sort out our opinions and apply them himself.  The YAGNI prinpical is a pretty good one to stick by; unless you have a case, or will shortly have a case for something, you shouldn't do it.  If the coworkers are saying 'maybe' and 'might' in their argument, its a pretty good time to apply YAGNI.

Again, this is all my opinion, so salt to your liking.
Andy

JHurrell replied on Tuesday, October 03, 2006

That's also the only reason I can think of for wanting to mock objects.

If it's the case that they want to mock up objects to simplify unit testing, then I'm of the opinion that it's not appropriate to stress "everthing is an interface" to make testing easier.

I'm also a big fan of YAGNI and have been supported by futures that never seem to require the changes that somebody wanted to put in "just in case."

Just throw out the current industry buzzword "refactor" and watch your co-workers' eyes glaze over as they drone, "Yes... we can refactor later."

- John

alexh replied on Tuesday, October 03, 2006

The question is, are there multiple implementations of "Customer"?

If so, then an interface may certainly be in order along with a factory to deliver an implementation.  If not, then it sounds a little bit like your team may be following the "silver bullet" methodology.  That is, find a technology or practice and insist on applying it in all circumstances.  Its attractive in concept - you only have to learn "the way".  But you then spend most of your time trying to force everything to fit that picture.

For example, program to an interface not an implementation is not an edict to apply in all circumstances.  Should you create an interface to represent ALL concrete classes?  The answer is obviously no.

The databinding question rings some alarm bells.  Is your team attempting to build application related plumbing and infrastructure on top of a construct (interfaces) that is intended to be used to allow programmers to separate interface from implementation?  You'll end up struggling against both ends, you'll be constrained in your use of interfaces programmatically, and your plumbing will be constrained by the interface paradigm.  Should an interface generally contain properties that represent the state of an object, or should it represent the behaviours that fulfill the responsibilities of the object?

Mocks can be great, but maybe the "tail is wagging the dog".  Are you developers who do testing, or are you really a team of testers who do development?  Test methodologies shouldn't drive your development, established development patterns and practices should.

Just some thoughts,
Alex

Copyright (c) Marimer LLC