CSC/ECE 517 Fall 2009/wiki3 9 lkf: Difference between revisions
Line 238: | Line 238: | ||
[8] Moving Forward, are we really?, Blog posting regarding the Non-redundancy principle, available at http://movingreally.blogspot.com/2007/05/non-redundancy-principle.html | [8] Moving Forward, are we really?, Blog posting regarding the Non-redundancy principle, available at http://movingreally.blogspot.com/2007/05/non-redundancy-principle.html | ||
[9] [http://fox.wikis.com/wc.dll?Wiki~DefensiveProgramming Defensive Programming], available at http://fox.wikis.com/wc.dll?Wiki~DefensiveProgramming | [9] [http://fox.wikis.com/wc.dll?Wiki~DefensiveProgramming Defensive Programming], Wiki page available at http://fox.wikis.com/wc.dll?Wiki~DefensiveProgramming | ||
[10] P.L. Nico, C.S. Turner, and K.K. Nico, Insecurity by Contract, | [10] P.L. Nico, C.S. Turner, and K.K. Nico, Insecurity by Contract, Proceedings of the Software Engineering and Applications Conference, 2004, available at http://www.actapress.com/Abstract.aspx?paperId=17535 | ||
[11] Advanced C++ Design without Compromise, available at http://synesis.com.au/publishing/monolith/glossary.html | [11] Breaking Up The Monolith: Advanced C++ Design without Compromise, web resource available at http://synesis.com.au/publishing/monolith/glossary.html | ||
[12] [http://computingcareers.acm.org/?page_id=12 Computing Degrees and Careers], available at http://computingcareers.acm.org/?page_id=12 | [12] [http://computingcareers.acm.org/?page_id=12 Computing Degrees and Careers], web resource available at http://computingcareers.acm.org/?page_id=12 | ||
Revision as of 02:52, 19 November 2009
This is currently work in progress, please do not review yet
The Non-Redundancy Principle
Topic: Non-Redundancy Principle
Topic Description: Programming by contract, and design by contract, are well covered in Wikipedia and across the Web. But the Non-Redundancy Principle, an important part of programming by contract, is not. Explore the applications and implications of the principle that says that the body of a routine should never test for the routine's precondition.
Introduction
The Non-redundancy principle is part of the programming by contract and design by contract software design methodologies [1, 2]. The most widely used definition of the principle is given by Meyer, who states that "under no circumstances shall the body of a routine ever test for its precondition" [3].
The purpose of this Wiki page is to describe and explain the non-redundancy principle as it applies to the field of software design. Additionally, benefits and implications of applying the principle are discussed. Examples using the C# object-oriented programming language are used to better illustrate the principle in practice.
The Non-Redundancy Principle Explained
The Non-Redundancy principle indicates that subroutines must never test for the validity of that which is stated as a precondition for the subroutine's execution [4]. A precondition is a property that must be true for a subroutine to execute successfully. The subroutine itself should not include code to verify that the preconditions for its execution are met by the given input. According to the non-redundancy principle, checking for preconditions is the responsibility of the client code [5].
For example, a routine that calculates the square root of a number would violate the Non-Redundancy principle if its code tests to make sure that the input given is not a negative number, as shown in the following code fragment [6].
// This method returns the square root of a floating point number private static double squareRoot(double input) { if (input >= 0) { return Math.Sqrt(input); } else { throw new Exception("The number provided does not have a square root."); } } static void Main(string[] args) { double input; double root; input = -4; if (input >= 0) { root = squareRoot(input); Console.WriteLine("The square root of {0} is {1}", input, root); } else { Console.WriteLine("The number provided does not have a square root."); } Console.ReadKey(); }
According to the Non-Redundancy principle, testing for the same precondition should not occur more than once in the code-base, hence eliminating redundant code. The Non-Redundancy principle is part of the Design by Contract methodology, which proposes that the relationship between a class and its clients must be defined in terms of a formal agreement that clearly states the responsibilities and duties of each party [2]. The agreement may be enforced or guaranteed with the use of preconditions in the form of assertions or additional code that checks for specific values.
Proper application of the non-redundancy principle to the code shown above results in the code shown in the next example, notice that the subroutine no longer checks the validity of the input:
// This method returns the square root of a floating point number private static double squareRoot(double input) { return Math.Sqrt(input); } static void Main(string[] args) { double input; double root; input = -4; if (input >= 0) { root = squareRoot(input); Console.WriteLine("The square root of {0} is {1}", input, root); } else { Console.WriteLine("The number provided does not have a square root."); } Console.ReadKey(); }
Preconditions may be of two types: demanding and tolerant [7]. Demanding preconditions place the burden on the client routine to ensure that the precondition for correct execution of the subroutine is met, i.e. the validation code is in the calling routine. Tolerant preconditions place the burden on the subroutine to ensure that the precondition for correct execution of the subroutine is met, i.e. the validation code is inside the subroutine [8]. Adherence to the non-redundancy principle stipulates that the same condition should only be tested by either demanding or tolerant preconditions but not by both.
The following code fragment illustrates the use of a demanding precondition:
// This method returns a given string after removing trailing and leading spaces private static string removeWhiteSpace(string input) { string output; output = input.TrimStart(); output = output.TrimEnd(); return output; } static void Main(string[] args) { string input; string output; input = " Have a nice day! "; Console.WriteLine("The input is: {0}", input); if (!string.IsNullOrEmpty(input)) { output = removeWhiteSpace(input); Console.WriteLine("The output without whitespace is: {0}", output); } else { Console.WriteLine("A valid string must be provided."); } Console.ReadKey(); }
The following code fragment illustrates the use of a tolerant precondition:
// This method returns a given string after removing trailing and leading spaces private static string removeWhiteSpace(string input) { string output; if (!string.IsNullOrEmpty(input)) { output = input.TrimStart(); output = output.TrimEnd(); } else { return string.Empty; } return output; } static void Main(string[] args) { string input; string output; input = " Have a nice day! "; Console.WriteLine("The input is: {0}", input); output = removeWhiteSpace(input); Console.WriteLine("The output without whitespace is: {0}", output); Console.ReadKey(); }
The use of tolerant preconditions is more in accordance with the application of defensive programming techniques [9]. Note how the subroutine in the previous code handles the presence of inadequate input, making it more forgiving or tolerant. The use of demanding preconditions is in agreement with the non-redundancy principle.
Applications of the Non-Redundancy Principle
Among the reasons for adhering to the non-redundancy principle we can count the following:
- Ease of maintenance due to simplified code.
- Less complexity because a particular condition is only checked once rather than in multiple places throughout the code. The expectation is that by having components adhere to contracts that clearly define each component's responsibilities the code will be less complex.
- More reliable code because there are less places where the same validation can be incorrect.
- More reliability is expected because the number of points where failures can occur, i.e. incorrect code, is reduced.
Implications of the Non-Redundancy Principle
Although the use of the non-redundancy principle on software design has definite advantages, its application has certain implications which must be considered. Possible consequences or implications that result from the application of the Non-Redundancy principle in a software development effort include the following:
- The application of the principle may result in the introduction of vulnerabilities.
- The resulting software may me more prone to having faults.
- The principle is in opposition to the recommendations provided by the Defensive Programming techniques that are part of traditional software engineering methodologies. Defensive programming states that code should be written to include the necessary validations and preventive code to ensure its correct operation.
- Supporters of the non-redundancy principle argue that the use of defensive programming techniques could possibly result in too much code that checks for errors; however, the expectation is that such additional code makes the code more robust and that it will not introduce additional faults [9, 10].
Summary
The non-redundancy principle is used in software design to propose software where preconditions are not checked at the subroutine level but rather at the calling routine. The advantage of such design is code that is simpler and easier to maintain. The non-redundancy principle diverges from the defensive programming techniques that are proposed by traditional software engineering methodologies. One could argue that the former approach results in code that is simpler and easier to maintain while the latter results in code that is more robust and free of faults [10, 11].
References
[1] Programming by Contract, Lecture Notes, University of San Francisco, Department of Computer Science, available at http://www.cs.usfca.edu/~parrt/course/601/lectures/programming.by.contract.html
[2] Design by Contract, Wiki page available at http://fox.wikis.com/wc.dll?Wiki~DesignByContract
[3] Meyer, Bertrand, Object - Oriented Software Construction, Prentice Hall, Englewood Cliffs, NJ, 1997.
[4] Non-RedundancyPrinciple, Wiki page available at http://fox.wikis.com/wc.dll?Wiki~NonRedundancyPrinciple
[5] Pre-Condition, Wiki page available at http://fox.wikis.com/wc.dll?Wiki~PreCondition
[6] Design by Contract, Lecture Notes, CalTech, Department of Computer Science, available at http://www.cs.caltech.edu/~cs141/2003/lectures/lecture5.pdf
[7] Programming by Contract, Lecture notes, Software Design Course, Technion---Israel institute of Technology, Department of Computer Science, available at: http://www.cs.technion.ac.il/Courses/OOP/slides/export/236700/yoav/eiffel_programming_by_contract_new.ppt
[8] Moving Forward, are we really?, Blog posting regarding the Non-redundancy principle, available at http://movingreally.blogspot.com/2007/05/non-redundancy-principle.html
[9] Defensive Programming, Wiki page available at http://fox.wikis.com/wc.dll?Wiki~DefensiveProgramming
[10] P.L. Nico, C.S. Turner, and K.K. Nico, Insecurity by Contract, Proceedings of the Software Engineering and Applications Conference, 2004, available at http://www.actapress.com/Abstract.aspx?paperId=17535
[11] Breaking Up The Monolith: Advanced C++ Design without Compromise, web resource available at http://synesis.com.au/publishing/monolith/glossary.html
[12] Computing Degrees and Careers, web resource available at http://computingcareers.acm.org/?page_id=12
CSC 517 Fall 2009
Wiki 3 Assignment
Author: Newwolf