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
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
@inv in the comments for documentation, but also for processing as explained here with tools like jContracts or similar tools/libraries.
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.
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.
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.
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.
If you're really programming defensively, you'll program to protect against your own bugs, not just those of your callers. That means your
pushoperation should check for
>= size, not
== size, because who knows if your code otherwise allowed the size to be arbitrarily set.
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.