Code Complete ---- (Part 5 Code Improvements)==========================================================================================1. The Software-Quality Landscape (概述)Improve quality---- Software-quality objectives---- Explicit quality-assurance activity---- Test strategy ---- Software-engineering guidelines---- Informal technical reviews---- Formal technicl reviews---- External audits==========================================================================================2. Collaborative ConstructionPair ProgrammingFomal Inspections (检查)Walk-ThroughsCode ReadingDog-and-Pony Shows(公开演示)==========================================================================================3. Developer TestingUnit testing Component testingIntegration testingRegression testingSystem testingdistinguish two activities---- Test is a means of detecting errors.---- Debugging is a means of diagnosing and correcting the root cause of errors that have already been detected.Bags of Testing TricksIncomplete testing---- structured basis testing In spite of the hairy name, structured basis testing is a fairly simple concept. The idea is that you need to test each statement in a program at least once. You can compute the minimum number of cases needed for basis testing in this straightforward way: ---- Start with 1 for the straight path through the routine. ---- Add 1 for each of the following keywords, or their equivalents: if, while, repeat, for, and, and or. ---- Add 1 for each case in a case statement. If the case statement doesn't have a default case, add 1 more.==========================================================================================4. Debugging==========================================================================================5. RefactoringReasons to Refactor---- Code is duplicated---- A routine is too long---- A loop is too long or too deeply nested---- A class has poor cohesion---- A class interface does not provide a consistent level of abstraction---- A parameter list has too many parameters---- Changes within a class tend to be compartmentalized---- Changes require a parallel modifications to multiple classes---- Inheritance hierarchies have to be modified in parallel---- case statements have to be modified in parallel---- Related data items that are used together are not organized into classes---- A routine uses more features of another class than of its own class---- A primitive data type is overloaded---- A class doesn't do very much---- A chain of routines passes tramp data---- A middleman object isn't doing anything---- One class is overly intimate with another---- A routine has a poor name---- Data member is public---- A subclass uses only a small percentage of its parents' routines---- Comments are used to explain difficult code---- Global variables are used---- A routine uses setup code before a routine call or takedown code after a routine call---- A program contains code that seems like it might be needed somedaySpecific RefactoringsData-level Refactorings---- 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 variable---- 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.Statement-level Refactoring---- 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---- Replace conditionals (especially repeated case statements) with polymorphism---- use break and return instead of a loop control variable---- retrun as soon as you know the answer instead of assigning a return value within nested if-then-else statements---- Create and use null objects instead of testing for null values.Routine-Level Refactorings---- Extract routine/extract 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 operation---- Combine similar routines by parameterizing 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 downcastingClass-Implementation-Level Refactoring---- Change value objects to reference objects---- Chage reference objects to value objects---- Replace virtual routines with data initialization---- Change member routine or data placement---- Extract specialized code into a subclass---- Combine similar code into a superclassClass-Interface-Level Refactoring---- Move a routine to another class.---- Convert one class to two.---- Eliminate a class.---- Hide a delegate.---- Remove a middleman.---- Replace inheritance with delegation.---- Replace delegation with inheritance.---- Introduce a foreign routine.---- Introduce an extension class.---- Encapsulate an exposed member variable.---- Remove Set() routines for fields that cannot be changed.---- Hide routines that are not intended to be used outside the class.---- Encapsulate unused routines.---- Collapse a superclass and subclass if their implementations are very similar.System-Level Refactoring---- Create a definitive reference source for data you can't control---- Unidirectional class <---> bidirectional class---- Provide a factory routine rather than a simple constructor---- Replace error codes with exceptions or vice versa==========================================================================================6. Code-Tuning Strategies==========================================================================================7. Code-Tuning TechniquesLogic---- Stop Testing When u Know the Answer---- Order Test by Frequency---- Compare performance of similar logic structures---- Substitute Table lookups for complicated expressions---- Use Lazy EvaluationLoop---- Unswitching <将判断外提>---- Jamming<合并>/fusion<融合>---- Unrolling <展开>---- Minimizing the work inside loops---- Sentinel Values <哨兵值> locate the value compared at the end of an array---- Putting the busies loop on the inside for ( 5 ) for ( 100 ) ----- 5+5*100 = 505 for ( 100 ) for ( 5 )----- 100+5*100 = 600---- Strength Reduction Adding rather than multiplyingData Transformations----- Use Integers rather than floating-point numbers----- Use the fewest array dimensions possible----- Minimize array references----- Use supplementary indexes '\0'----- Use Caching <declare a member variable to store a value which evaluation needs much time.>Expressions----- Exploit Algebraic Identities <利用代数恒等式>----- Use Stength Reduction ---- Replace multiplication with addition ---- Replace exponentiation with multiplication ---- Replace integer multiplication-by-two and division-by-two with shift operations.----- Initialize at Compile time unsigned int Log2( unsigned int x ) ...{ return (unsigned int) ( log( x ) / log( 2 ) ); } // // const double LOG2 = 0.69314718; ... unsigned int Log2( unsigned int x ) ...{ return (unsigned int) ( log( x ) / LOG2 ); } // // unsigned int Log2( unsigned int x ) ...{ unsigned int i = 0; while ( ( x = ( x >> 1 ) ) != 0 ) ...{ i++; } return i ; } ----- Use the Correct type of Constants----- Precompute results----- Elliminate Common Subexpressions Routines ----- Rewrite routines inlineRecording in a low-level language
发表于 @ 2007年01月05日 15:54:00|评论(loading...)|编辑