Beruflich Dokumente
Kultur Dokumente
7 March 2008 2
TCS Internal
Scope of the Course
• Test-Driven Development, a practice that facilitates better learning and less defects
• Basic skills to improve understandability of programs
• A few skills and strategies to reduce defects in programs
• Table-Driven Methods, a skill which dramatically improves adaptability in many situations
7 March 2008 3
TCS Internal
State of Programming
• 31% of Software Projects will get cancelled before they get completed
• 52% of Software Projects will cost 189% of their original estimates
7 March 2008 4
TCS Internal
Challenges in Programming
7 March 2008 5
TCS Internal
What is Required to meet the Challenges
7 March 2008 6
TCS Internal
The Importance of Good Programming Skills
The gap between the best software engineering practice and the average practice is
very wide - perhaps wider than in any other engineering discipline. A tool that
disseminates good practice would be important.
7 March 2008 7
TCS Internal
Variations in Programming Productivity
• The ratio of the productivity between the "best" programmers and “worst"
programmers in a group is estimated at ten to one!
• It is feasible to improve the productivity of programmers
7 March 2008 8
TCS Internal
Feedback from Project Leaders
In a survey in TCS, 89 Project Leaders & Group Leaders ranked important skills for
entrants to ILP as follows:
1. Good Programming Practice
2. Process Mindset
3. Communication Skills
4. Adaptability & Teamwork
5. Concern for Quality
6. Knowledge of Core Computer Science Topics
7 March 2008 9
TCS Internal
Test-Driven Development - Why?
All in all, I think test-first programming is one of the most beneficial software
practices to emerge during the past decade and is a good general approach.
7 March 2008 10
TCS Internal
What is Test-Driven Development?
• A process or methodology
• Prepare small (sub-unit) automated tests before you code
• Develop code to pass one test at a time
• Pass all the prior tests with each increment of code
• Improvise the design with each increment of code
7 March 2008 11
TCS Internal
Steps of Test Driven Development Part 1 of 2
1 Prepare a "to-do" list of all the incremental tests that must pass to fulfill the
requirements for the feature (these can be code or learning objectives). Get
the tests reviewed for correctness and completeness by the person who
assigned you the task.
2. Choose a test from the list based on what seems logically the next thing to do or
what is simple or what is more risky
3. Code the test; compile and run the test. The test must fail as the code is not yet
developed. The test failure assures us that the test is legitimate and that the
feature is not currently available.
7 March 2008 12
TCS Internal
Steps of Test Driven Development Part 2 of 2
4. Code, in a quick manner, to pass the test. This will clarify that we have
understood the functionality required to pass the test.
5. Improve the code. This can be in the form of removing duplicate lines of code, or
making the program more understandable or adaptable. Ensure that the
functionality is still correct by "passing all the tests".
6. Loop to step 2 while there is at least one more test remaining.
7 March 2008 13
TCS Internal
Differences with Traditional Programming
Code full feature at a time Code a small sub-task of the feature at a time
Test after the full feature is coded Test before developing the sub-task and after each
sub-task
Develop the full design prior to code Develop light-weight design and improvise the
design through development
7 March 2008 14
TCS Internal
Benefits of TDD vis-à-vis Traditional Programming
1 of 2
• Preparing the tests first helps to clarify the requirements of each sub-task and
enables better design
• Running a test for each sub-task provides quick feedback on the correctness of a
few lines of code; this facilitates more effective learning leading to improved
productivity. Also, if a defect is found in the sub-task, it is easier to debug the same
as the defect is located in the few lines of additional code that were modified since
the last passed test
• The focus on tests helps to reduce undetected defects in unit-tested code leading to
smoother passage through integration, system, & user-acceptance tests and
implementation
7 March 2008 15
TCS Internal
Benefits of TDD vis-à-vis Traditional Programming
2 of 2
• We learn more about the program as we proceed and are able to utilize the learning
by improving the design
• Automated tests run quickly and so are more likely to be run often thus helping to
discover "unintended" consequences of additional code changes
• Automated tests facilitate learning of functionality by those who will maintain the
program later and enable a quick “confirmation" of the functionality provided by the
program
7 March 2008 16
TCS Internal
Drawback of Test-Driven Development vis-à-vis Traditional
Programming
7 March 2008 17
TCS Internal
Some experiences of Test-Driven Development
7 March 2008 18
TCS Internal
Influence Diagram of Pressure, Manual Testing and Errors –
a reinforcing loop!
7 March 2008 19
TCS Internal
Improving Understandability
• Importance of understandability
• Self-review is easier leading to less defects
• Debugging takes less time
• Another developer will find it easier to maintain your program
7 March 2008 20
TCS Internal
Improving Understandability
7 March 2008 21
TCS Internal
Improving Understandability
• IF REC-TXN-TYPE = ‘APS’ AND REC-TXN = ‘EP’
PROCESS P1
ELSE
IF REC-TXN-TYPE = (‘EXAM’ OR ‘ECG’) AND REC-TXN = ‘EA’
PROCESS P2
ELSE
IF REC-TXN-TYPE = ‘XRAY’ AND REC-TXN = ‘EP’
PROCESS P3
ELSE
PROCESS ERROR
END-IF
END-IF
END-IF
____________________________________________________________
• The above code can be made clearer with appropriate conditional statements as follows:
________________________________________________________________
• EVALUATE REC-TXN-TYPE ALSO REC-TXN
WHEN ‘APS’ ALSO ‘EP’
PROCESS P1
WHEN ‘EXAM’ ALSO ‘EA’
WHEN ‘ECG’ ALSO ‘EA’
PROCESS P2
WHEN ‘XRAY’ ALSO ‘EP’
PROCESS P3
WHEN OTHER
PROCESS ERROR
END-EVALUATE
7 March 2008 22
TCS Internal
Improving Understandability
7 March 2008 23
TCS Internal
Improving Understandability
Comment judiciously
• Every class must provide its purpose
• Every public method must provide its function from a “user of the method”
perspective
• For java, Javadoc is a good choice for “documentation” as
- it is generally adequate
- easy to understand and use
- it is popular
7 March 2008 24
TCS Internal
Improving Understandability
7 March 2008 25
TCS Internal
Improving Understandability
7 March 2008 26
TCS Internal
Improving Understandability
Running javadoc
This will create html files of documentation for the MIPC and MIPCTest classes in
the doc folder.
Will display “Medical Insurance Premium Calculator” in the heading.
7 March 2008 27
TCS Internal
Improving code correctness – Why?
7 March 2008 28
TCS Internal
Practices
Automate regression tests
• It is not enough that the program works correctly when you first release it. It
must work later after you or someone else has modified it.
• Automated and comprehensive regression tests are very important to ensure
a robust system for mission-critical systems both during development and
later.
• Develop “good” tests
• Use automated testing framework for developing automated tests
7 March 2008 29
TCS Internal
Practices
7 March 2008 30
TCS Internal
Defensive Programming
Tips
1. Protect program from invalid inputs
• Check the values of all data from external sources
• Check the values of all routine input parameters
• Check all return values from all methods to be in the acceptable range
• Always have an “otherwise” or “default” clause in conditional statements to
catch those cases that are “not expected” and so “not processed”
• Do not ignore exceptions!
• Ensure that your code is not used inappropriately
• Source: Code Complete, Second Edition by Steve McConnell
7 March 2008 31
TCS Internal
Defensive Programming
2. Assertions
Have you used assertions to document assumptions, including preconditions and
postconditions?
Have assertions been used only to document conditions that should never occur?
Assertion takes two arguments: a boolean expression that describes the assumption that’s
supposed to be true, and a message to display if it isn’t.
Java Example of an Assertion
assert denominator !=0 : “denominator is unexpectedly equal to 0.”;
Assertions flushout contradictory assumptions, unexpected conditions, bad values passed to
routines during development. During production, they can be compiled out of the code.
7 March 2008 32
TCS Internal
Defensive Programming
Guidelines for using assertions
• Use error-handling code for conditions you expect to occur;use assertions for
conditions that should never occur.
• Avoid putting executable code into assertions
7 March 2008 33
TCS Internal
Defensive Programming
Guidelines for using assertions
• For highly robust code, assert and then handle the error anyway
7 March 2008 34
TCS Internal
Defensive Programming
Guidelines for using assertions
• For highly robust code, assert and then handle the error anyway
7 March 2008 35
TCS Internal
Defensive Programming
3. Error-Handling Techniques
Does the architecture or high-level design specify a specific set of error-handling techniques?
Does the architecture or high-level design specify whether error-handling should favor
robustness or correctness ?
• Return a neutral value
• Substitute the next piece of valid data
• Return the same answer as the previous time
• Substitute the closest legal value
• Log a warning message to a file
• Return an error code
• Call an error-processing routine/object
• Display an error message wherever the error is encountered
• Handle the error in whatever way works best locally
• Shut down
7 March 2008 36
TCS Internal
Defensive Programming
4. Exceptions
Has your project defined a standardized approach to exception handling?
Have you considered alternatives to using an exception?
• Use exceptions to notify other parts of the program about errors that should not be
ignored
• Throw an exception only for conditions that are truly exceptional
• Don’t use an exception to pass the buck
• Avoid throwing exceptions in constructors and destructors unless you catch them in the
same place
• Throw exceptions at the right level of abstraction
Class Employee
{
…
Public TaxID GetTaxID() throws EOFException
{..}
}
7 March 2008 37
TCS Internal
Defensive Programming
Exceptions
Throw an exception at a consistent level of abstraction
Class Employee
{
…
Public TaxID GetTaxID() throws EmployeeDataNotAvailable
{..}
}
• Include in the exception message all information that led to the exception
• Avoid empty catch blocks
try{
..
}catch(AnException exception){
}
Good example of ignoring an exception
try{
..
}catch(AnException exception){
LogError(“Unexpected exception”);
}
7 March 2008 38
TCS Internal
Defensive Programming
Exceptions
• Know the exceptions your library code throws
• Considering building a centralized exception reporter
Sub ReportException(
ByVal className,ByVal thisException As Exception)
Dim message As String
Dim caption As String
Message=“Exception: “ & thisException.Message & “.”&ControlChars.Crlf & “Class: “ & className &
ControlChars.Ctrf & “Routine: “ & thisException.TargetSite.Name & ControlChars.Crlf
Caption=“Exception”
MessageBox.Show(message,caption,MessageBoxButtons.OK,MessageBoxIcon.Exclamation)
End Sub
Centralized Exception Reporter
Try
…
Catch exceptionObject As Exception
ReportException(CLASS_NAME,exceptionObject)
End Try
7 March 2008 39
TCS Internal
Defensive Programming
6. Debugging Aids
Have debugging aids been used in the code?
Have debugging aids been installed in such a way that they can be activated and deactivated
without a great deal of fuss?
7 March 2008 40
TCS Internal
Defensive Programming
8. Is the amount of defensive programming code appropriate –neither too much nor too little
7 March 2008 41
TCS Internal
Defensive Programming
7 March 2008 42
TCS Internal
Practices
Refactor Code
As refactoring costs effort and does not add anything to the functionality it must
be justified on the basis of the expected value from the effort versus the
costs.
7 March 2008 43
TCS Internal
Refactoring
• These factors must be balanced with the effort and time required for the
refactoring.
7 March 2008 44
TCS Internal
Refactoring
7 March 2008 45
TCS Internal
Refactoring Test Code
7 March 2008 46
TCS Internal
Specific Refactorings
• Data-Level
• Statement-Level
• Routine-Level
• Class Implementation
• Class Interface
• System-Level
7 March 2008 47
TCS Internal
Specific Refactorings
Data-Level
• Replace a magic number with a named constant
• Rename a variable with a clearer or more informative name
• Move an expression inline
• Replace an expression with a routine
• Introduce an intermediate variable
• Convert a multiuse variable to multiple single-use variables
• Use a local variable for local purposes rather than a parameter
• Convert a data primitive to a class
• Convert a set of type codes to a class or an enumeration
• Convert a set of type codes to a class with subclasses
• Change an array to an object
• Encapsulate a collection
• Replace a traditional record with a data class
7 March 2008 48
TCS Internal
Specific Refactorings
Statement-Level
• Decompose a boolean expression
• Move a complex boolean expression into a well-named boolean function
• Consolidate fragments that are duplicated within different parts of a conditional
• Use break or return instead of a loop control variable
• Return as soon as you know the answer instead of assigning a return value within
nested if-then-else statements
• Replace conditionals with polymorphism
• Create and use null objects instead of testing for null values
7 March 2008 49
TCS Internal
Specific Refactorings
Routine-Level
• Extract routine/method
• Move a routine ‘s code inline
• Convert a long routine to a class
• Substitute a simple algorithm for a complex algorithm
• Add/Remove a parameter
• Separate query operations from modification operations
• Combine similar routines by parameterizating them
• Separate routines whose behavior depends on parameters passed in
• Pass a whole object rather than specific fields
• Pass specific fields rather than a whole object
• Encapsulate downcasting
7 March 2008 50
TCS Internal
Refactor safely
7 March 2008 51
TCS Internal
Table-Driven Methods
Logic statements (if, switch, case tests) result in many lines of code and tend to
be complex, difficult to test and difficult to adapt to changes.
7 March 2008 52
TCS Internal
Table-Driven Methods
Solution
• Code these choices in the form of values in rows of a table. Code locates the
matching row and performs its function (including logic) based on the column
values in the row.
• The table data, preferably, resides in external tables
7 March 2008 53
TCS Internal
Table-Driven Methods
Benefits
7 March 2008 54
TCS Internal
Table-Driven Methods
MIPC as Sample
Age Premium
0-18 4,000
19-30 5,000
31-999 6,000
7 March 2008 55
TCS Internal
Table-Driven Methods
7 March 2008 56
TCS Internal
Table-Driven Methods
Exercise 1 – Requirements
When provided the April salary, provide the "amount to be paid" to the employee. Assume:
Annual salary = “April salary” multiplied by 12 & Income Tax is the only deduction. Round all
amounts to the nearest integer. The income tax rules are:
Annual Income range Rates of Income Tax
Upto Rs. 50,000/= Nil
Rs. 50,001 - Rs. 60,000 10 per cent of the amount by which the total income exceeds
Rs. 50,000.
Rs. 60,001 - Rs. 1,50,000 Rs. 1,000 plus 20 per cent of the amount by which the total
income exceeds Rs. 60,000.
Rs. 1,50,001 and above Rs. 19,000 plus 30 percent of the amount by which the total
income exceeds Rs. 1,50,000.
7 March 2008 57
TCS Internal
Table-Driven Methods
Develop Exercise 1 (the “net salary” calculation program) using “table-driven method”.
Steps:
• Prepare suitable tests
• Prepare a suitable table:
- table must correspond as closely as feasible to the statement of the business rule
- must be adequate to obtain a correct result
7 March 2008 58
TCS Internal
Table-Driven Methods – Exercise 2
7 March 2008 59
TCS Internal
Table-Driven Methods
Step 2: Prepare an appropriate table
50000 0 0 0
60000 50000 10 0
7 March 2008 60
TCS Internal
Table-Driven Methods
7 March 2008 61
TCS Internal
Table-Driven Methods
7 March 2008 62
TCS Internal
Table-Driven Methods
Externalize the table: Read the table from an external text file.
textFile2ArrayInt( )
– Populates the data from a file into a 2-dimensional int array. Each line of
the file corresponds to a row. Data separated by commas is written as
column values
– Parameters:
• textFileName - the String name of the text file
• maxColumns - the int value of the number of columns in the array
– Returns: int[][] array containing the values from the text file
7 March 2008 63
TCS Internal
Table-Driven Methods
7 March 2008 64
TCS Internal
Table-Driven Methods – Exercise 2
7 March 2008 65
TCS Internal
Table-Driven Methods – Exercise 2
7 March 2008 66
TCS Internal
Exercise 3
ABC Company wishes to take Fixed Deposits from the public on the
following terms.
Interest Rate for Deposit Period of
7 March 2008 67
TCS Internal
Review Exercise 3
7 March 2008 68
TCS Internal