Was: Design by contract: predict
methods needed, discipline yourself
and deal with code that comes to mind
I like the idea of designing by contract a lot (at least, as far as I understand the principal). I believe it means you define intefaces first before you start implementing actual code, right?
However, from my limited experience (3 OOP years now) I usually can’t resist the urge to start coding pretty early, for several reasons:
- because my limited experience has shown me I am unable to predict what methods I will be needing in the interface, so I might as well start coding right away.
- or because I am simply too impatient to write out the whole interfaces first.
- or when I do try it, I still wind up implementing bits of code already, because I fear I might forget this or that imporant bit of code, that springs to mind when I am designing the interfaces.
As you see, especially with the last two points, this leads to a very disorderly way of doing things. Tasks get mixed up. I should draw a clear line between designing interfaces and actual coding.
If you, unlike me, are a good/disciplined planner, as intended above, how do you:
- …know the majority of methods you will be needing up front so well? Especially if it’s components that implement stuff you are not familiar with yet.
- …resist the urge to start coding right away?
- …deal with code that comes to mind when you are designing the interfaces?
UPDATE:
Thank you for the answers so far. Valuable insights! And… I stand corrected; it seems I misinterpreted the idea of Design By Contract. For clarity, what I actually meant was: “coming up with interface methods before implementing the actual components”.
An additional thing that came up in my mind is related to point 1):
- b) How do you know the majority of components you will be needing. How do you flesh out these things before you start actually coding?
For arguments sake, let’s say I’m a novice with the MVC pattern, and I wanted to implement such a component/architecture. A naive approach would be to think of:
- a front controller
- some abstract action controller
- some abstract view
… and be done with it, so to speak.
But, being more familiar with the MVC pattern, I know now that it makes sense to also have:
- a request object
- a router
- a dispatcher
- a response object
- view helpers
- etc..
- etc..
If you map this idea to some completely new component you want to develop, with which you have no experience yet; how do you come up with these sort of additional components without actually coding the thing, and stuble upon the ideas that way? How would you know up front how fine grained some components should be? Is this a matter of disciplining yourself to think it out thoroughly? Or is it a matter of being good at thinking in abstractions?
Design by Contract != Interface based design
There are differences although I will grant that the use of interfaces is commonly called a contract (of sorts) in software. That being said I think I understand where you are going with the question and have some thoughts on this. I’m about 2 weeks into a new project that I am designing and I have had some of these same thoughts recently with regard to interfaces.
Accept the fact that you will (or almost) never get the interface completely right the first time. To be honest trying to design an interface to account for all cases without exercising it will probably fail. Instead define your interfaces to have a very specific purpose and only initially provide the most basic of methods necessary to meet that purpose. As an example you might have an interface define the object and another that defines a simple set of crude operations on the object. As the project matures you may add additional methods as they are identified to facilitate get/search operations. Keep in mind as the design is refined then you can add to the interface; this is (generally) fine for development purposes since an interface typically isn’t versioned until it’s in production.
You will probably be well served by implementing a little bit of code and unit tests to exercise it. This will help identify weaknesses in your overall approach. The trick to this is to only do enough to identify issues without making a gold plated shit house (sorry if that offended anyone, but it’s a common phrase). I would recommend thinking of this as prototyping code THAT SHOULD NOT BE USED FOR PRODUCTION without a lot of thought.
Honestly this depends on the situation. A snippet file somewhere may work for this. Generally I’ll just use a post-it note to capture the thought or idea versus any specific code since I haven’t written anything (noteworthy) to this point. Occasionally I will go ahead and start a implementation of the class that I intend to use for production.
Updated response:
I don’t think there is any one answer to this question. Honestly I think it comes down to experience as a software developer/engineer and knowing what you are ultimately trying to do/solve. For instance I certainly would not expect someone fresh from college with no practical experience to design an application from scratch without some significant design help. Mostly I think that if you don’t understand the problem you are trying to solve then you most likely will spin your wheels trying to design the wrong solution.
My gut feeling is that the less you understand the technology being used and/or the problem to be solved the more readily you should accept that your refactor(s) will be more significant. I honestly also think that if you feel you can design an entire application without ever refactoring anything then you should probably not be the one designing the application. How significant the refactor is though is the question.