230 likes | 249 Views
Programming Issues Code Complete (Roger S. Pressman). Comparison to assembler. Assembler 1 to 1 Ada 1 to 4.5 Quick/Turbo Basic 1 to 5 C 1 to 2.5 Fortran 1 to 3 Pascal 1 to 3.5 C++ 1 to ??. Type of program. Structured data
E N D
Programming IssuesCode Complete(Roger S. Pressman) (c) Ian Davis
Comparison to assembler • Assembler 1 to 1 • Ada 1 to 4.5 • Quick/Turbo Basic 1 to 5 • C 1 to 2.5 • Fortran 1 to 3 • Pascal 1 to 3.5 • C++ 1 to ?? (c) Ian Davis
Type of program • Structured data • (Good) Ada, C/C++, Pascal (Bad) Assembler, Basic • Quick and dirty project • (Good) Basic (Bad) Pascal, Ada, Assembler • Fast execution • (Good) Assembler, C (Bad) Interpreted Languages • Mathematical calculation • (Good) Fortran (Bad) Pascal • Easy to maintain • (Good) Pascal, Ada (Bad) C, Fortran (c) Ian Davis
Types of program • Dynamic memory use • (Good) Pascal, C (Bad) Basic • Limited available memory • (Good) Basic, Assembler C (Bad) Fortran • Real-time requirements • (Good) Ada, Assembler, C (Bad) Fortran, Basic • String manipulation • (Good) Basic, Pascal (Bad) C (c) Ian Davis
Standards • ADA • Since 1986 Ada has been mandated for use in all DoD and NATO mission critical, embedded systems. • C/C++ • 1988 ANSI standard codified C. • Defacto standard for microcomputer and workstation programming. (c) Ian Davis
Reduce complexity Avoid duplication Anticipate change Hide sequences Hide data structures Improve performance Promote reuse Improve readability Improve portability Isolate complexity Multiple languages Simplify boolean tests Reasons to create routines (c) Ian Davis
Cohesion • Relationship of code within a routine. • How “strong” are the relationships. • Routines should do a single thing and do it well. • Goal: Create routines with internal integrity • 50% of highly cohesive routines fault free. • 18% of low cohesion routines fault free. (c) Ian Davis
Types of cohesion • Functional cohesion (BEST) • Routine performs a single function • Verb + object { eg. GetFileData() } • Sequential cohesion (WEAK) • Routine performs set of steps in right order. • Share data from step to step • Wishy washy { eg. DoStep1(), DoStep2() } (c) Ian Davis
Types of cohesion • Communicational cohesion (WEAK) • Does lots of things with the same data • Complex {eg. GetNameUpdatePhoneNo() } • Temporal cohesion (REASONABLE) • Lots of things done at the same time • Employ with functional cohesion • Focus on time {eg. Startup(), Shutdown() } (c) Ian Davis
Unacceptable cohesion • Procedural cohesion • Like sequential cohesion • BUT sequential parts are unrelated • (Ill)Logical cohesion • Separate logic conditioned by control flag • Flow of logic only thing which units code • Coincidental cohesion • Logic in same place coincidentally (c) Ian Davis
Coupling • The “usefulness” and “effectiveness” of the connection between routines. • Compliment of cohesion. • Want small, direct, meaningful, visible, flexible relations. • Want “loose” coupling. (c) Ian Davis
Coupling • Routines should not depend on their caller. • They should be detached and self contained. • They should be sufficiently general. • Routines should not share global data. • Routines should fulfill a purpose rather than be viewed as performing specific actions. (c) Ian Davis
Coupling criteria • Size of interface • Lots of complex parameters are bad • Lots of reference to global data bad • Intimacy • Immediacy of method of communication • Parameter and return result (GOOD) • Via messages (WEAKER) • Global data (DUBIOUS) • Via mediator/database etc (WEAK) (c) Ian Davis
Coupling criteria • Visibility • How are results manifest • By parameter (GOOD) • By side effect (BAD) • Flexibility • How easy is it to pass the right parameters • Is routine plug and play or overly specific • Clarity • Routines should have sensible names (c) Ian Davis
Coupling criteria • Routines should be able to call other routines easily. • The consequences of such calls should be both clear and straightforward. • Break up a program along lines of minimal interconnectedness. • Split with the grain; not against the grain. (c) Ian Davis
Levels of coupling • Simple-data coupling (SIMPLEST/BEST) • Only non-structured data shared • All data passed as parameters/return result • Strong data-structure coupling (OK) • Structured data passed between routines • All data passed as parameters/return result • Most/all of structures passed relevant • Weak data-structure coupling (WEAK) • Little information in structures passed relevant (c) Ian Davis
Levels of coupling • Control coupling (POOR) • Parameters tell called routine how to behave • Caller understands internal workings of callee • Global data coupled (HORRIBLE) • Two routines operate on same global data • Connection neither intimate nor visible • Pathologically coupled (DISASTER) • One routine directly uses another routines code • One routine directly alters another routines data (c) Ian Davis
Additional coupling consideration • Identify all constant parameters. • Use constant pointers whenever the structure pointed at will not be changed. • Consider in-lining very short routines. • Use generic names rather than return codes. • Use objects to encapsulate functionality. • Access objects via complete interfaces. • Use compilers which do full type checking. (c) Ian Davis
Size of a routine • Routine size inversely correlated with error • As size to 200 lines errors per line (Basili) • Routine size not correlated with errors • Structural complexity and amount of data far more significant than routine size (Shen) • Larger routines (65+ lines) cheaper and no less reliable (Card) • Small routines (<143lines) has 23% more errors than larger routines. (c) Ian Davis
Size of a routine • Code in which all routines about 10 lines long, as incomprehensible as code without routines at all (Conte). • Code required less change when routines averaged 100 to 150 lines of code. (Lind). • Practical upper limit on routine size about 200 lines of hard code (without comments). • Most buggy routines had > 500 lines code. (c) Ian Davis
Defensive programming tips • Use lots of assertions. • Avoid creating assertions with side-effects. • Check correctness of inputs. • Anticipate unexpected types in case statements, etc. • Document changes and use version control • Monitor memory leakage. • Employ firewalls between sections of code. • Check for error returns. (c) Ian Davis
Defensive programming tips • Use macros to support / facilitate change. • Nest macros using brackets. • Order parameters as input, update, output. • Use same parameter order for similar tasks. • Compare with fprintf() and fputs() • Use all parameters; optionally default some. • Don’t use parameters as working variables. • Hard to debug when viewing stack. (c) Ian Davis
Defensive programming tips • Prefix global and object state variables • eg. m_pointer, g_counter • Designate data private when appropriate. • Distinguish pointers from non-pointers. • Identify levels of indirection to arrive at an element using a pointer. • Use comments to explain what is clear as well as what is unclear. (c) Ian Davis