I'm having a hard time trying to get my team comfortable with interface based programming ... anyone have some suggestions?
views:
604answers:
9An Interface is a Contract. It just specifies what a particular category (hard to get around the word class here) of Class is supposed to offer as a public API.
What are they familiar with?
When I learned C++, the teacher built on my existing knowledge of C, for example:
- Take the C library routines for file I/O: open, read, and close using a file handle
- Show how these can be rewritten as methods of a File class: create, invoke the read method, invoke the destructor of a File instance
Building on top of that, I might compare an IFile interface to a File class by saying that IFile exposes no implementation details at all: if the application uses IFile instead of File, then you can change the underlying file system / implementation details).
I would suggest you show them the benefits that can come from it. Imagine this C# scenario:
class User
{
public String GetFirstName() { return "foo"; }
}
class App
{
void Run()
{
User user = new User();
String firstName = user.GetFirstName();
}
}
Here we have a User
class that will go and get a first name from somewhere and return it. Now your app is coupled to this class and it will be difficult to later change where you get first name from because you have used the User
class everywhere. What would happen if you implemented a service and wanted to begin calling that service for the FirstName
value? You would have a bit of refactoring to do.
Consider this approach:
interface IUser
{
String GetFirstName();
}
class User : IUser
{
public String GetFirstName() { return "foo"; }
}
static class UserFactory
{
public static IUser GetUser() { return new User(); }
}
class App
{
void Run()
{
IUser user = UserFactory.GetUser();
String firstName = user.GetFirstName();
}
}
Now you can implement the interface in any class you want like:
class UserService : IUser
{
public String GetFirstName() { return "bar"; }
}
and just change the factory method like:
static class UserFactory
{
public static IUser GetUser() { return new UserService(); }
}
and your app code will be none the wiser.
An interface is like a class's dress code. If a class implements an interface, its public members (its appearance to other classes, if you will) will include what the interface declares at minimum.
Another way I've used succesfully when teaching new junior hires in our company is considering an interface as "a way of looking at an object", literally.
Analog: take a 3D object, like a piece of tube. Depending on which direction you look at it, it looks like ("behaves as") either a circle, a rectangle or a 3D object. The concept of casting can then easily be equated to "try to rotate the object so you can make it look the way you want/need" which either succeeds or fails depending on the object and the view you're looking for.
The analog isn't really 100%, but it can help to make something that is very abstract for people not already grasping the concept into something concrete.
In order to help your team get comfortable with the idea, the best route would be to demonstrate what interface-based development can accomplish and contrast that with how the same thing would need to be done without it. For them to "really" accept and begin to understand it, they first need to understand and feel the pain of the problem that it solves. They really need to have the "I'm sick and tired of having to do X every time that Y happens" conversation with themselves or the team. One thing that my father drilled into me in my "formative" years is this little gem:
No matter how many times it's been told to you, you'll NEVER have the answer until YOU ask the question.
Once this conversation occurs (self-initiated by the individual or the team) THAT is where true learning can occur. The trick is to foster an environment that will stimulate these types of questions. If you can show them that they want an answer to the problem that interfaces solves, well, then THEY will ask the question themselves.
One good example demonstrating the usefulness of interfaces follows:
You've been assigned to be a bouncer at an international math convention. You've been told only to let people in that can supply a correct answer to the question "What's two plus two". Since this is an international event there are naturally many people attempting to enter that speak many disparate languages. At first your tactic is to figure out (or guess) what language a person requesting entrance speaks, then finding an interpreter that speaks the same and ask the question through him. It turns out that this works, and soon you learn to recognize some of the languages quickly and now know which interpreters speak this language, BUT it sure is a pain when someone that speaks a language that you can't identify outright shows up and you have to spend all that time to figure out which it is and then find an appropriate interpreter. So, knowing that there has to be a better way, you try to noodle out an improved method to do your job, and that is when it comes to you. You get a ream of paper and some marking pens and each time someone comes up to get into the convention, you write the following on a sheet of paper:
2 + 2 =
Lo and behold, it works! Each person quickly provides the answer. You don't have to figure out what language the person speaks or find an interpreter. Heck, you don't even care what language they speak, they just answer the question because they all know math! Instead of figuring out each case individually you've used the "IKnowMath" interface that each person attending the math convention understands.
Tell them that interfaces are a trick word. Because the meaning is hidden right out in the open :P
Interfaces describe... an INTERFACE. They tell how you can interface with a class that implements it.
Hi
A copy of Head First design patterns or atleast the code examples from Head first Design patterns
Story telling like the way its done in Head First Design Patterns actually works great many time with skeptics
regards Edwards
I like the analogy of Legos, which are the classes and instances, and the pegs/holes on the top/bottom respectively as well as the sizes and shapes, which are the interfaces. For example, I may have a need for for a rectangular block with pegs in a grid of 2x4. These are the interfaces i'd be interested in - the pegged male/female inteface, as well as the rectangle interface. These can be satisfied by either an instance of the Rectangular Block Lego, or another instance of something "composed" of two half-sized Legos, of 2x2 pegs each, thereby still adhering to said interface. Because all the Legos have a common interface (male and female pegs) we can mix and combine however necessary, whether the piece comes from one of those new sets where I can build a giant robot ant, or is just a plain old square or rect. lego that comes in the giant vat you used to get back in the day. Hell, I can even mix official Legos with brand X legos, because the "male/female pegged interface" is so well understood.
Programming to interfaces allows us to mix and match reusable code components like we do Legos.