I often hear/read about interfaced based programming but I am not exactly clear on what that really means. Is interfaced based programming an actual stand alone topic that actually has books written about it? If so, can anyone recommend any good ones?
I came across interface based programming as I was reading about how good APIs are designed and would like to learn more about it. Right now I am not clear how to properly go about designing an API around interfaces.
Any info is greatly appreciated.
It's basically a matter of expressing your dependencies in terms of interfaces instead of concrete classes (or worse, static methods). So if one of your classes needs to perform authentication, it should be provided an IAuthenticator (or whatever).
This means that:
You can write your code before implementing the real dependency
You can test via mocking really easily (without having to mock classes, which gets ugly)
It's clear what you depend on in terms of the API instead of implementation (i.e. you have looser coupling)
See if these very popular discussions help:
What is the best analogy to help non-oop developers grok interface based programming?
Why would I want to use Interfaces?
When are interfaces needed?
When should one use interfaces?
What is the purpose of interfaces?
Good Case For Interfaces
What does it mean to “program to an interface”?
Chapter 6 of "Practical API Design" by Jaroslav Tulach is titled "Code Against Interfaces, Not Implementations". It explains that, by coding against an interface rather than a specific implementation, you can decouple modules (or components) in a system and therefore raise the system quality.
Bertrand Meyer in OOSC2 explains clearly why "closing" a system and making it more modular raises its quality.
What you refer to as "interface based programming" is more commonly referred to as programming to an interface. Here is an example below. The benefit is hiding the actual implementation of the interface and allowing your code to be more flexible and easily maintained in the future.
YourInterface foo = CreateYourInterface();
foo.DoWork();
foo.DoMoreWork();
CreateYourInterface() would return a concrete implementation of YourInterface. This allows you to change the functionality of the application by changing one line:
YourInterface foo = CreateYourInterface();
If you google for interfaces, you will find plenty of information about how useful interfaces may be.
The concept is to define clear interfaces, which will be used by the various components/parts/classes/modules to communicate and interact. Once you have defined what should be the input/output of these interfaces, you can let the various teams to develop whatever is needed to fulfill the interface requirements, including the input/output testing, ... etc
If you follow this pattern, various teams can start developing their part without waiting for the other parts to be ready. In addition to that you can use Unit testing (using fake objects to simulate the other parts which you are not developing, and test your part).
This method is quite the standard for any new programming project and everybody will take this for granted.
This is something that I don't recommend using heavily in C# development.
Interface-based programming is basically programming to interfaces. You develop the interfaces you're going to use an Contracts, and the actual implementation of the interfaces is hidden behind these contracts.
It was very common prior to .NET, as the best way to get reusable components in Windows was via COM, which worked via interfaces everywhere. However, given .NET's ability to support multiple languages with a single runtime (the CLR), as well as it's superior support for versioning when compared with native code, the usefulness of interface based programming is lessened dramatically when you're programming in C# (unless you're trying to make COM components, in which case, you'll still be creating the COM interfaces indirectly from your C# classes).
Interface based programming can be thought of as decoupling the implementation of functionality and how you access the functionality.
You define an interface
interface ICallSomeone {
public bool DialNumber(string number);
}
and you write your implementation
public class callsomeone: ICallSomeone {
public bool DialNumber(string number) {
//dial number, return results
}}
You use the interface without caring about the implementation. If you change the implementation, nothing cares because it just uses the interface.
From a very abstract view, interface based programming is akin to the components used by a plumber (pipe joints and pipes).
As long as the pipes and the joints are manufactured according to the interface specified (the number of threads and the spacing, etc) various manufactures can provide joints to pipes that were potentially manufactured by some other vendor (but adhering to the aforementioned joint/pipe interface).
Thus, there is more interoperability of components and freedom for the plumber to choose from various vendors, price ranges etc in order to create a functional plumbing system.
Replace the pipes and joints with software components and the parallels are astonishingly simple.
Related
Let's assume I am in charge of developing a Scrabble game, being that one of the principal requirements of the client is the ability to later try out different ways and modes of the game. I already made a design that is flexible enough to support those kinds of changes. The only question left is what to expose to the client(objects' access modifiers), and how to organize it (how to expose my objects in namespaces/packages).
How should I define things such that the client can both easily use my standard implementation (a standard Scrabble game, and yet be able to make all the modifications that he wants? I guess what I need is a kind of framework, on which he can work on.
I organized my classes/interfaces in a non-strict layered system:
Data Types
Contains basic data types that might be used in the whole system. This package and its members can be accessed by anyone in the system. All its members are public.
Domain
Contains all the interfaces I've defined and that might be useful to be able to make client's new Scrabble's implementations. Also contains value types, like Piece, that are used in the game. All its members are public.
Implementations
Contains all the needed classes/code to implement my standard Scrabble game in a Implementations.StandardScrabble package. If the client decides to implement other variants of the game, he can create them in Implementations.XYZ, for example.
These classes are all package protected and the only thing that is available to the outside of the package is a Game façade. Uses both Domain and Data Types packages.
UI
Contains the UI class that I have implemented so that both the client and the users of the program can run the game (my implementation). Can access all the other layers.
There are several drawbacks to the way I am organizing things, the most obvious being that if the client wants to create its own version of the game, he will have to basically implement almost everything by himself(I share in the Domain the interfaces, but he can do almost nothing with them). I feel I should maybe pass all the Implementation's classes to the Domain and then only have a Façade that builds up my standard Scrabble in the Implementations namespace?
How would you approach this? Is there any recomended reading on how to build this kind of programs (basically, frameworks)?
Thanks
I think that you're trying to give too much freedom to a client. This must be making things that difficult for you to handle. Based on what you have described it seems that a client will be able to modify almost all parts of your game - model, logic, UI... I think it would be better to restrict modifiable areas in your application but expose some via general Plugin interface set. This would make it easier for a user as well - he will only need to learn how plugins work, not the entire application's logic. Define areas for your plugins if you want - UI plugin, game mode plugin and so on. Many production applications and games work in such way (recall Diablo II and that AMAZING variety of plugins it has!).
For the algorithms and strategies I would define interfaces and default implementations, and provide abstract superclasses which are extended by you own implementations, so that all the boilerplate code is in the abstract superclass. In addition I would allow the client to subclass your impl. Just make more than one impl, and you see what to place where.
But most important: Give your client the code. If he needs to understand where to place his code, he should be able to see what you have coded, too. No need to hide stuff.
Whatever design you come up with, I would err on the side of hiding as much of the implementation as possible. Once you expose an implementation, you cannot take it back (unless you're ready to wage a flame war with your client base). You can always provide default implementations later as you see fit.
Generally, I'd start with only providing thin interfaces. Then, before providing abstract classes, I might offer utility classes (e.g., Factories, Builders, etc.).
I'd recommend reading Effective Java by Josh Bloch for useful general practices when designing object-oriented code.
MVC/Compund Pattern
You may release earlier version of your package.
later on you can upgrade it based on user requirement.
If you are using MVC or other compound pattern wisely, I believe you also can upgrade your package easily.
I have seen code where every class has an interface that it implements.
Sometimes there is no common interface for them all.
They are just there and they are used instead of concrete objects.
They do not offer a generic interface for two classes and are specific to the domain of the problem that the class solves.
Is there any reason to do that?
No.
Interfaces are good for classes with complex behaviour, and are especially handy if you want to be able to create a mock or fake implementation class of that interface for use in unit tests.
But, some classes don't have a lot of behaviour and can be treated more like values and usually consist of a set of data fields. There's little point in creating interfaces for classes like this because doing so would introduce unnecessary overhead when there's little point in mocking or providing alternative implementations of the interface. For example, consider a class:
class Coordinate
{
public Coordinate( int x, int y);
public int X { get; }
public int y { get; }
}
You're unlikely to want an interface ICoordinate to go with this class, because there's little point in implementing it in any other way than simply getting and setting X and Y values.
However, the class
class RoutePlanner
{
// Return a new list of coordinates ordered to be the shortest route that
// can be taken through all of the passed in coordinates.
public List<Coordinate> GetShortestRoute( List<Coordinate> waypoints );
}
you probably would want an IRoutePlanner interface for RoutePlanner because there are many different algorithms that could be used for planning a route.
Also, if you had a third class:
class RobotTank
{
public RobotTank( IRoutePlanner );
public void DriveRoute( List<Coordinate> points );
}
By giving RoutePlanner an interface, you could write a test method for RobotTank that creates one with a mock RoutePlanner that just returns a list of coordinates in no particular order. This would allow the test method to check that the tank navigates correctly between the coordinates without also testing the route planner. This means you can write a test that just tests one unit (the tank), without also testing the route planner.
You'll see though, it's quite easy to feed real Coordinates in to a test like this without needing to hide them behind an ICoordinate interface.
After revisiting this answer, I've decided to amend it slightly.
No, it's not best practice to extract interfaces for every class. This can actually be counterproductive. However, interfaces are useful for a few reasons:
Test support (mocks, stubs).
Implementation abstraction (furthering onto IoC/DI).
Ancillary things like co- and contra-variance support in C#.
For achieving these goals, interfaces are considered good practice (and are actually required for the last point). Depending on the project size, you will find that you may never need talk to an interface or that you are constantly extracting interfaces for one of the above reasons.
We maintain a large application, some parts of it are great and some are suffering from lack of attention. We frequently find ourselves refactoring to pull an interface out of a type to make it testable or so we can change implementations whilst lessening the impact of that change. We also do this to reduce the "coupling" effect that concrete types can accidentally impose if you are not strict on your public API (interfaces can only represent a public API so for us inherently become quite strict).
That said, it is possible to abstract behaviour without interfaces and possible to test types without needing interfaces, so they are not a requirement to the above. It is just that most frameworks / libraries that you may use to support you in those tasks will operate effectively against interfaces.
I'll leave my old answer for context.
Interfaces define a public contract. People implementing interfaces have to implement this contract. Consumers only see the public contract. This means the implementation details have been abstracted away from the consumer.
An immediate use for this these days is Unit Testing. Interfaces are easy to mock, stub, fake, you name it.
Another immediate use is Dependency Injection. A registered concrete type for a given interface is provided to a type consuming an interface. The type doesn't care specifically about the implementation, so it can abstractly ask for the interface. This allows you to change implementations without impacting lots of code (the impact area is very small so long as the contract stays the same).
For very small projects I tend not to bother, for medium projects I tend to bother on important core items, and for large projects there tends to be an interface for almost every class. This is almost always to support testing, but in some cases of injected behaviour, or abstraction of behaviour to reduce code duplication.
Let me quote OO guru, Martin Fowler, to add some solid justification to the most common answer in this thread.
This excerpt comes from the "Patterns of Enterprise Application Architecture" (enlisted in the "classics of programming" and\or the "every dev must read" book category).
[Pattern] Separated Interface
(...)
When to Use It
You use Separated Interface when you need to break a dependency between two parts of the system.
(...)
I come across many developers who have separate interfaces for every class they write. I think this is excessive, especially for
application development. Keeping separate interfaces and
implementations is extra work, especially since you often need factory
classes (with interfaces and implementations) as well. For
applications I recommend using a separate interface only if you want
to break a dependency or you want to have multiple independent
implementations. If you put the interface and implementation
together and need to separate them later, this is a simple refactoring
that can be delayed until you need to do it.
Answering your question: no
I've seen some of the "fancy" code of this type myself, where developer thinks he's SOLID, but instead is unintelligible, difficult to extend and too complex.
There's no practical reason behind extracting Interfaces for each class in your project. That'd be an over-kill. The reason why they must be extracting interfaces would be the fact that they seem to implement an OOAD principle "Program to Interface, not to Implementation". You can find more information about this principle with an example here.
Having the interface and coding to the interface makes it a ton easier to swap out implementations. This also applies with unit testing. If you are testing some code that uses the interface, you can (in theory) use a mock object instead of a concrete object. This allows your test to be more focused and finer grained.
It is more common from what I have seen to switch out implementations for testing (mocks) then in actual production code. And yes it is wroth it for unit testing.
I like interfaces on things that could be implemented two different ways, either in time or space, i.e. either it could be implemented differently in the future, or there are 2 different code clients in different parts of the code which may want a different implementation.
The original writer of your code might have just been robo coding, or they were being clever and preparing for version resilience, or preping for unit testing. More likely the former because version resilience an uncommon need-- (i.e. where the client is deployed and can't be changed and a component will be deployed that must be compatible with the existing client)
I like interfaces on things that are dependencies worth isolation from some other code I plan to test. If these interfaces weren't created to support unit tests either, then I'm not sure they're such a good idea. Interface have a cost to maintain and when it comes time to make an object swappable with another, you might want to have an interface apply to only a few methods (so more classes can implement the interface), it might be better to use an abstract class (so that default behaviors can be implemented in an inheritance tree).
So pre-need interfaces is probably not a good idea.
If is a part of the Dependency Inversion principle. Basically code depends on the interfaces and not on the implementations.
This allows you to easy swap the implementations in and out without affecting the calling classes. It allows for looser coupling which makes maintenance of the system much easier.
As your system grows and gets more complex, this principle keeps making more and more sense!
I don't think it's reasonable for Every class.
It's a matter of how much reuse you expect from what type of a component. Of course, you have to plan for more reuse (without the need to do major refactoring later) than you are really going to use at the moment, but extracting an abstract interface for every single class in a program would mean you have less classes than needed.
Interfaces define a behaviour. If you implement one or more interfaces then your object behaves like the one or other interfaces describes. This allows loose coupling between classes. It is really useful when you have to replace an implementation by another one. Communication between classes shall always be done using interfaces excepting if the classes are really tightly bound to each other.
There might be, if you want to be sure to be able to inject other implementations in the future. For some (maybe most) cases, this is overkill, but it is as with most habits - if you're used to it, you don't loos very much time doing it. And since you can never be sure what you'll want to replace in the future, extracting an interface on every class does have a point.
There is never only one solution to a problem. Thus, there could always be more than one implementation of the same interface.
It might seem silly, but the potential benefit of doing it this way is that if at some point you realize there's a better way to implement a certain functionality, you can just write a new class that implements the same interface, and change one line to make all of your code use that class: the line where the interface variable is assigned.
Doing it this way (writing a new class that implements the same interface) also means you can always switch back and forth between old and new implementations to compare them.
It may end up that you never take advantage of this convenience and your final product really does just use the original class that was written for each interface. If that's the case, great! But it really didn't take much time to write those interfaces, and had you needed them, they would've saved you a lot of time.
The interfaces are good to have since you can mock the classes when (unit-) testing.
I create interfaces for at least all classes that touches external resources (e.g. database, filesystem, webservice) and then write a mock or use a mocking framework to simulate the behavior.
Why do you need interfaces? Think practically and deeply. Interfaces are not really attached to classes, rather they are attached to services. The goal of interface is what you allow others to do with your code without serving them the code. So it relates to the service and its management.
See ya
This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
Interfaces: Why can’t I seem to grasp them?
How will I know when to create an interface?
I am using C# and I know what are the interfaces and how syntatically use them,etc.
but what I have not learned yet is that when I am tasked to write a project, create a component,... How should I learn better about interfaces so when I want to do something I be able to Think about using them in my design...or for example I want to learn about dependency injection or even using mocking objects for testing, these are all related to good understanding of interfaces and know when and how to use them ... Can you plase provide me some good advice, reading,... then can help me with that?
Use interfaces when you have several things that can perform a common set of actions. How they do those actions can be different, but when as far as using the classes they act the same.
A good real world example is like a network drive vs a regular hard drive. Either way you can perform basic file operations. How they're actually done is different, but most of the time when you want to do something on a drive you don't care if it's a network drive or a physical one. That's an interface.
In hardware, different keyboards are designed differently, they (could) have buttons in different locations, but none of that matters to the computer. The computer's view of a keyboard's interface is the same regardless of any aspects other than it sends key strokes.
What is the interface these things must have in common if they are going to be used in the same way?
If you can answer that then you are on your way to design and using the interface properly in real life scenarios.
The goal of interfaces is to reduce coupling between components of your application. By using interface, you are binding to a contract instead of an implementation. This means that you can change the implementation as you see fit, provided you follow the same contract.
For example, it is considered good practice to use IList<T> instead of List<T>, because IList<T> only states that you need something that acts like a list. This way, other implementations of lists can be substituted without affecting your code. (For example, NHibernate, an object mapping and data access library, uses this to allow lazy loading of collections.)
Excellent candidates for interfaces are classes that interact with external systems (File system, database, network, web services, etc...). If you directly use those systems in your code, you will have trouble testing and refactoring.
I personally find interfaces especially useful in dependency injection and testing scenarios. Since you already understand what interfaces are, you should be able to understand dependency injection. Reading on those concepts will help you recognize good candidates for interfaces.
It's really something that you learn to use with experience.
I've found understanding how interfaces are used in plugin architectures really helpful.
Lots of links out there, e.g. : http://www.codeproject.com/KB/cs/c__plugin_architecture.aspx
Try to imagine how you might write that sort of architecture without using interfaces - then you might fully appreciate what they bring to the table.
If using a a TDD-like workflow, interfaces are often used to define the requirements an object has of another object that it will eventually use. Using interfaces in this fashion allows them to be used to create 'seams' in your application where logic can be replaced/inserted/etc.
One way of thinking about interfaces in this fashion is to think of your objects as sending messages to one another, and that the interfaces are the definitions of the messages that can be sent.
I have used OO programming languages and techniques years ago (primarily on C++) but in the intervening time haven't done much with OO.
I'm starting to make a small utility in C#. I could simply program it all without using good OO practice, but it would be a good refresher for me to apply OO techniques.
Like database normalization levels, I'm looking for a checklist that will remind me of the various rules of thumb for a 'good' object oriented program - a concise yes/no list that I can read through occasionally during design and implementation to prevent me from thinking and working procedurally. Would be even more useful if it contained the proper OO terms and concepts so that any check item is easily searchable for further information.
What should be on a checklist that would help someone develop good OO software?
Conversely, what 'tests' could be applied that would show software is not OO?
Objects do things. (Most important point in the whole of OOP!) Don't think about them as "data holders" - send them a message to do something. What verbs should my class have? The "Responsibility-Driven Design" school of thinking is brilliant for this. (See Object Design: Roles, Responsibilities, and Collaborations, Rebecca Wirfs-Brock and Alan McKean, Addison-Wesley 2003, ISBN 0201379430.)
For each thing the system must do, come up with a bunch of concrete scenarios describing how the objects talk to each other to get the job done. This means thinking in terms of interaction diagrams and acting out the method calls. - Don't start with a class diagram - that's SQL-thinking not OO-thinking.
Learn Test-Driven Development. Nobody gets their object model right up front but if you do TDD you're putting in the groundwork to make sure your object model does what it needs to and making it safe to refactor when things change later.
Only build for the requirements you have now - don't obsess about "re-use" or stuff that will be "useful later". If you only build what you need right now, you're keeping the design space of things you could do later much more open.
Forget about inheritance when you're modelling objects. It's just one way of implementing common code. When you're modelling objects just pretend you're looking at each object through an interface that describes what it can be asked to do.
If a method takes loads of parameters or if you need to repeatedly call a bunch of objects to get lots of data, the method might be in the wrong class. The best place for a method is right next to most of the fields it uses in the same class (or superclass ...)
Read a Design Patterns book for your language. If it's C#, try "Design Patterns in C#" by Steve Metsker. This will teach you a series of tricks you can use to divide work up between objects.
Don't test an object to see what type it is and then take action based on that type - that's a code smell that the object should probably be doing the work. It's a hint that you should call the object and ask it to do the work. (If only some kinds of objects do the work, you can simply have "do nothing" implementations in some objects... That's legitimate OOP.)
Putting the methods and data in the right classes makes OO code run faster (and gives virtual machines a chance to optimise better) - it's not just aesthetic or theoretical. The Sharble and Cohen study points this out - see http://portal.acm.org/citation.cfm?doid=159420.155839 (See the graph of metrics on "number of instructions executed per scenario")
Sounds like you want some basic yes/no questions to ask yourself along your way. Everyone has given some great "do this" and "think like that" lists, so here is my crack at some simple yes/no's.
Can I answer yes to all of these?
Do my classes represent the nouns I am concerned with?
Do my classes provide methods for actions/verbs that it can perform?
Can I answer no to all of these?
Do I have global state data that could either be put into a singleton or stored in class implementations that work with it?
Can I remove any public methods on a class and add them to an interface or make them private/protected to better encapsulate the behavior?
Should I use an interface to separate a behavior away from other interfaces or the implementing class?
Do I have code that is repeated between related classes that I can move into a base class for better code reuse and abstraction?
Am I testing for the type of something to decide what action to do? If so can this behavior be included on the base type or interface that the code in question is using to allow more effect use of the abstraction or should the code in question be refactored to use a better base class or interface?
Am I repeatedly checking some context data to decided what type to instantiate? If so can this be abstracted out into a factory design pattern for better abstraction of logic and code reuse?
Is a class very large with multiple focuses of functionality? If so can I divide it up into multiple classes, each with their own single purpose?
Do I have unrelated classes inheriting from the same base class? If so can I divide the base class into better abstractions or can I use composition to gain access to functionality?
Has my inheritance hierarchy become fearfully deep? If so can I flatten it or separate things via interfaces or splitting functionality?
I have worried way too much about my inheritance hierarchy?
When I explain the design to a rubber ducky do I feel stupid about the design or stupid about talking to a duck?
Just some quick ones off the top of my head. I hope it helps, OOP can get pretty crazy. I didn't include any yes/no's for more advanced stuff that's usually a concern with larger apps, like dependency injection or if you should split something out into different service/logic layers/assemblies....of course I hope you at least separate your UI from your logic.
Gathered from various books, famous C# programmers, and general advice (not much if any of this is mine; It is in the sense that these are various questions i ask myself during development, but that's it):
Structs or Classes? Is the item you're creating a value of it's own, make it a struct. If it's an "object" with attributes and sub-values, methods, and possibly state then make it an object.
Sealed Classes: If you're going to be creating a class and you don't explicitly need to be able to inherit from it make it sealed. (I do it for the supposed performance gain)
Don't Repeat Yourself: if you find yourself copy-past(a/e)ing code around then you should probably (but not always) rethink your design to minimize code duplication.
If you don't need to provide a base implementation for a given abstract class turn it into an interface.
The specialization principle: Each object you have should only do one thing. This helps avoid the "God-object".
Use properties for public access: This has been debated over and over again, but it's really the best thing to do. Properties allow you to do things you normally can't with fields, and it also allows you more control over how the object is gotten and set.
Singletons: another controversial topic, and here's the idea: only use them when you Absolutely Need To. Most of the time a bunch of static methods can serve the purpose of a singleton. (Though if you absolutely need a singleton pattern use Jon Skeet's excellent one)
Loose coupling: Make sure that your classes depend on each other as little as possible; make sure that it's easy for your library users to swap out parts of your library with others (or custom built portions). This includes using interfaces where necessary, Encapsulation (others have mentioned it), and most of the rest of the principles in this answer.
Design with simplicity in mind: Unlike cake frosting, it's easier to design something simple now and add later than it is to design complex now and remove later.
I might chuck some or all of this out the door if i'm:
Writing a personal project
really in a hurry to get something done (but i'll come back to it later.... sometime..... ;) )
These principles help guide my everyday coding and have improved my coding quality vastly in some areas! hope that helps!
Steve McConnell's Code Complete 2 contains a lot of ready to use checklists for good software construction.
Robert C. Martin's Agile Principles, Patterns, and Practices in C# contains a lot of principles for good OO desgin.
Both will give you a solid foundation to start with.
Data belongs with the code that operates on it (i.e. into the same class). This improves maintainability because many fields and methods can be private (encapsulation) and are thus to some degree removed from consideration when looking at the interaction between components.
Use polymorphism instead of conditions - whenever you have to do different things based on what class an object is, try to put that behaviour into a method that different classes implement differently so that all you have to do is call that method
Use inheritance sparingly, prefer composition - Inheritance is a distinctive feature of OO programming and often seen as the "essence" of OOP. It is in fact gravely overused and should be classified as the least important feature
Have I clearly defined the
requirements? Formal requirements documentation may not be necessary, but you should have a clear vision before you begin coding. Mind-mapping tools and prototypes or design sketches may be good alternatives if you don't need formal documentation. Work with end-users and stakeholders as early as possible in the software process, to make sure you are implementing what they need.
Am I reinventing the wheel? If you are coding to solve a common problem, look for a robust library that already solves this problem. If you think you might already have solved the problem elsewhere in your code (or a co-worker might have), look first for an existing solution.
Does my object have a clear, single purpose? Following the principle of Encapsulation, an object should have behavior together with the data that it operates on. An object should only have one major responsibility.
Can I code to an interface? Design By Contract is a great way to enable unit testing, document detailed, class-level requirements, and encourage code reuse.
Can I put my code under test? Test-Driven Development (TDD) is not always easy; but unit tests are invaluable for refactoring, and verifying regression behavior after making changes. Goes hand-in-hand with Design By Contract.
Am I overdesigning? Don't try to code a reusable component. Don't try to anticipate future requirements. These things may seem counterintuitive, but they lead to better design. The first time you code something, just implement it as straightforwardly as possible, and make it work. The second time you use the same logic, copy and paste. Once you have two working sections of code with common logic, you can easily refactor without trying to anticipate future requirements.
Am I introducing redudant code? Don't Repeat Yourself (DRY) is the biggest driving principal of refactoring. Use copy-and-paste only as a first step to refactoring. Don't code the same thing in different places, it's a maintenance nightmare.
Is this a common design pattern, anti-pattern, or code smell? Be familiar with common solutions to OO design problems, and look for them as you code - but don't try to force a problem to fit a certain pattern. Watch out for code that falls into a common "bad practice" pattern.
Is my code too tightly coupled? Loose Coupling is a principle that tries to reduce the inter-dependencies between two or more classes. Some dependencies are necessary; but the more you are dependent on another class, the more you have to fix when that class changes. Don't let code in one class depend on the implementation details of another class - use an object only according to its contract.
Am I exposing too much information? Practice information hiding. If a method or field doesn't need to be public, make it private. Expose only the minimum API necessary for an object to fulfill its contract. Don't make implementation details accessible to client objects.
Am I coding defensively? Check for error conditions, and Fail Fast. Don't be afraid to use exceptions, and let them propagate. In the event your program reaches an unexpected state, it's much, much better to abort an operation, log a stack trace for you to work with, and avoid unpredictable behavior in your downstream code. Follow best practices for cleaning up resources, such as the using() {} statement.
Will I be able to read this code in six months? Good code is readable with minimal documentation. Put comments where necessary; but also write code that's intuitive, and use meaningful class, method, and variable names. Practice good coding style; if you're working on a team project, each member of the team should write code that looks the same.
Does it still work? Test early, test often. After introducing new functionality, go back and touch any existing behavior that might have been affected. Get other team members to peer review and test your code. Rerun unit tests after making changes, and keep them up to date.
One of the best sources would be Martin Fowler's "Refactoring" book which contains a list (and supporting detail) of object oriented code smells that you might want to consider refactoring.
I would also recommend the checklists in Robert Martin's "Clean Code".
SOLID
DRY
TDD
Composition over inheritance
Make sure you read up and understand the following
Encapsulation
(Making sure you only expose the minimal state and functionality to get the job done)
Polymorphism
(Ability for derived objects to behave like their parents)
The difference between and interface and an abstract class
(An abstract class allows
functionality and state to be shared
with it's descendants, an interface
is only the promise that the
functionality will be implemented)
I like this list, although it might be a little dense to be used as a checklist.
UML - Unified Modeling Language, for object modeling and defining the structure of and relationships between classes
http://en.wikipedia.org/wiki/Unified_Modeling_Language
Then of course the programming techniques for OO (most already mentioned)
Information Hiding
Abstraction
Interfaces
Encapsulation
Inheritance / Polymorphism
Some of the rules are language agnostic, some of the rules differ from language to language.
Here are a few rules and comments that contradict some other the previously posted rules:
OO has 4 principles:
Abstraction, Encapsulation, Polymorphism and Inheritence.
Read about them and keep them in mind.
Modelling - Your classes are supposed to model entities in the problem domain:
Divide the problem to sub-domains (packages/namespaces/assemblies)
then divide the entities in each sub-domain to classes.
Classes should contain methods that model what objects of that type do.
Use UML, think about the requirements, use-cases, then class diagrams, them sequences.
(applicable mainly for high-level design - main classes and processes.)
Design Patterns - good concept for any language, implementation differs between languages.
Struct vs. class - in C# this is a matter of passing data by value or by reference.
Interface vs. base-class, is a base-class, does an interface.
TDD - this is not OO, in fact, it can cause a lack of design and lead to a lot of rewriting. (Scrum for instance recommends against it, for XP it is a must).
C#'s Reflection in some ways overrides OO (for example reflection based serialization), but it necessary for advanced frameworks.
Make sure classes do not "know of" other classes unless they have to, dividing to multiple assemblies and being scarce with references helps.
AOP (Aspect Oriented Programming) enhances OOP, (see PostSharp for instance) in a way that is so revolutionary that you should at least look it up and watch their clip.
For C#, read MS guidelines (look up guidelines in VS's MSDN help's index),
they have a lot of useful guidelines and conventions there
Recommended books:
Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries
C# 3.0 in a Nutshell
Ok the great thing about programming to an interface is that it allows you to interchange specific classes as long as the new classes implement everything in that interface.
e.g. i program my dataSource object to an interface so i can change it between an xml reader and a sql database reader.
does this mean ideally every class should be programmed to an interface?
when is it not a good idea to use an interface?
When the YAGNI principle applies.
Interfaces are great but it's up to you to decide when the extra time it takes developing one is going to pay off. I've used interfaces plenty of times but there are far more situations where they are completely unnecessary.
Not every class needs to be flexibly interchanged with some other class. Your system design should identify the points where modules might be interchangeable, and use interfaces accordingly. It would be silly to pair every class with an additional interface file if there's no chance of that class ever being part of some functional group.
Every interface you add to your project adds complexity to the codebase. When you deal with interfaces, discoverability of how the program works is harder, because it's not always clear which IComponent is filling in for the job when consumer code is dealing with the interface explicitly.
IMHO, you should try to use interfaces a lot. It's easier to be wrong by not using an interface than by using it.
My main argument on this is because interfaces help you make a more testable code. If a class constructor or a method has a concrete class as a parameter, it is harder (specially in c#, where no free mocking frameworks allow mocking non-virtual methods of concrete classes) for you to make your tests that are REAL unit tests.
I believe that if you have a DTO-like object, than it's overkill to use an interface, once mocking it may be maybe even harder than creating one.
If you're not testing, using dependency injection, inversion of control; and expect never to do any of these (please, avoid being there hehe), then I'd suggest interfaces to be used whenever you will really need to have different implementations, or you want to limit the visibility one class has over another.
Use an interface when you expect to need different behaviours used in the same context. I.e. if your system needs one customer class which is well defined, you probably don't need to use an ICustomer interface. But if you expect a class to comply to a certain behaviour s.a. "object can be saved" which applies to different knids of objects then you shoudl have the class implement an ISavable interface.
Another good reason to use an interface is if you expect different implementations of one kind of object. For example if ypu plan an SMS-Gateway which will route SMS's through several different third-party services, your classes should probably implent a common interface s.a. ISmsGatewayAdapter so your core system is independent from the specific implementation you use.
This also leads to 'dependecy injection' which is a technique to further decouple your classes and which is best implemented by using interfaces
The real question is: what does your class DO? If you're writing a class that actually implements an interface somewhere in the .NET framework, declare it as such! Almost all simple library classes will fit that description.
If, instead, you're writing an esoteric class used only in your application and that cannot possibly take any other form, then it makes no sense to talk about what interfaces it implements.
Starting from the premise of, "should I be implementing an interface?" is flawed. You neither should be nor shouldn't be. You should simply be writing the classes you need, and declaring what they do as you go, including what interfaces they implement.
I prefer to code as much as possible against an interface. I like it because I can use a tool like StructureMap to say "hey...get me an instance of IWidget" and it does the work for me. But by using a tool like this I can programatically or by configuration specify which instance is retrieved. This means that when I am testing I can load up a mock object that conforms to an interface, in my development environment I can load up a special local cache, when I am in production I can load up a caching farm layer, etc. Programming against an interface provides me a lot more power than not programming against an interface. Better to have and not need than need and not have applies here very well. And if you are into SOLID programming the easiest way to achieve many of those principles sort of begins by programming against an interface.
As a general rule of thumb, I think you're better off overusing interfaces a bit than underusing them a bit. Err on the side of interface use.
Otherwise, YAGNI applies.
If you are using Visual Studio, it takes about two seconds to take your class and extract an interface (via the context menu). You can then code to that interface, and hardly any time was spent.
If you are just doing a simple project, then it may be overkill. But on medium+ size projects, I try to code to interfaces throughout the project, as it will make future development easier.