1

I am trying to write Stack code using the two techniques i.e Design by Contract vs Defensive Programming but I am not sure if I am doing right or not.I am not throwing any kind of exception or error in design by contract assuming all the inputs will be correct.

Design By Contract VS Defensive Programming

  • 3
    Must be some kind of new tablet... :) – Erik Eidt Oct 8 '16 at 0:01
  • 1
    I wrote the code on paper by myself so took a picture of it . Is it not readable ? – Grad student Oct 8 '16 at 0:14
  • 2
    It's a joke, since it is really an old tablet, not a new one. ar ar. But since you ask, it is polite to type a nicely formatted question instead of taking a picture of a notebook page(s) (or of a screenshot). This helps those answering in that they can copy/paste more easily, and since you're asking for their help... (Further, it would give onlookers more confidence that your code compiles and works, since we don't write or debug your code here (though your question is about coding style not debugging).) – Erik Eidt Oct 8 '16 at 0:22
  • Design by Defensive Contracting -- let's embrace both! – mlvljr Oct 8 '16 at 0:47
  • 1
    What are you even asking? – whatsisname Oct 8 '16 at 4:30
1

Design by contract

In your example 1, no check is done. The implementation assumes that the client respects the terms of the contract. So yes, you could be tempted to claim that it's DBC.

However what's missing is the expression of your contract: there's no clue of pre-conditions, post-conditions and invariants in the code. This is missing.

In C++ you would put some assert() at the begin and the end of each function. These would do hard check (and abort in case of infrigement) during debugging, but would be skipped in production release.

In Java, you would annotate your code with javadoc tags @pre, @post and @inv in the comments for documentation, but also for processing as explained here with tools like jContracts or similar tools/libraries.

Defensive programming

In your second example, you actively enforce the check if the expectations of the contract are met and take an alternate path of execution to handle the unexpected case (here with exceptions). This seems to correspond to the anticipation expected from defensive programming.

4
  1. It helps to know what language you're working in, especially as to whether that language is providing you with some safety features, like array bounds checking. For example, if you're working in Java or C#, you'll get array bounds checking which will automatically throw when things are wrong, but if you're working in C/C++, your program may work for a while like a wounded animal then run off and die somewhere else.

  2. The notion of Design by Contract goes beyond interface (mere method signatures) to preconditions and post-conditions that must be specified, which you haven't done. For example, you have not specified what the behavior is if the stack is full (should it grow the storage or throw an exception or other), or popping when it is empty. Further, in Design by Contract, we fully expect the preconditions and post-conditions to be monitored, so testing for them is valid. (A Design by Contract language would support that with linguistic constructs, but you can do it in other languages via asserts or conditional throws.) For example, whether popping an empty stack yields null vs. an exception. Design by Contract doesn't use reading an implementation to determine that contract, so you should be explicitly stating that kind of information somewhere (e.g. in the JavaDoc, maybe). There were no constructors documented so we can't really tell what that end of the contract might be even from a method signature point of view.

  3. All you've done with Defensive is check for errors that some languages would do for you anyway (or not depending on your choice of language). So, this is either good or not fully necessary depending on the language, yet also depending on the method of logging you want to do (println's are not the best form of logging, though). Still, you might want to throw some more specific exception rather than letting the runtime choose one, but in this simple case, I would probably let the runtime do bounds checking and throwing for me.

  4. If you're really programming defensively, you'll program to protect against your own bugs, not just those of your callers. That means your push operation should check for >= size, not == size, because who knows if your code otherwise allowed the size to be arbitrarily set.

  5. If you're using a language with zero-based arrays, you should post increment (in push) and pre-decrement (in pop), otherwise you'll be wasting the first element in the array. (And if you adjust that, then the size check should be offset by 1.) Unexpected waste, resulting in the inability to offer the advertised capacity, could just as well be a violation of the contract as the caller popping too many times.

  • Got it !! Thanks :) I am still thinking about some other conditions that I can put in defensive programming that distinguishes from Design by Contract. One possibility would be to check the type of "value" passed through parameter in push function since it should only support integer. Apart from that I cannot think about anything else that actually distinguishes defensive form Design by contract in this particular example. – Grad student Oct 8 '16 at 1:04
  • 2
    The thing that distinguishes Design by Contract is the Contract. You need to have the contract written down somewhere, preferably in machine-checkable form as part of the language (e.g. Eiffel, Spec♯, Cobra, D) or a contract system (Code Contracts for .NET), or at least in the documentation. – Jörg W Mittag Oct 8 '16 at 1:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.