Skip to content

Instantly share code, notes, and snippets.

@sidwarkd
Last active April 23, 2020 20:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sidwarkd/7117e7e559efa1c4709d07c9e4cccfb7 to your computer and use it in GitHub Desktop.
Save sidwarkd/7117e7e559efa1c4709d07c9e4cccfb7 to your computer and use it in GitHub Desktop.
Code Complete Notes

Code Complete Notes

Requirements

Before any requirements are drafted you MUST come up with a problem statement to help focus all future requirement discussions. "How does this relate to the problem definition.

Functional Requirements

  • Are all the inputs to the system specified, including their source, accuracy, range of values and frequency?
  • Are all the outputs from the system specified, including their destination, accuracy, range of values, frequency and format?
  • Are all output formats specified?
  • Are all the external hardware and software interfaces specified?
  • Are all the external communication interfaces specified, including handshaking, error-checking, and communication protocols?
  • Are all the tasks the user wants to perform specified?
  • Is the data used in each task and the data resulting from each task specified?

Quality Requirements

  • Is the expected response time, from the user's point of view, specified for all necessary operations?
  • Are other timing considerations specified, such as processing time, datatransfer rate, and system throughput?
  • Is the level of security specified?
  • Is the reliability specified, including the consequences of software failure, the vital information that needs to be protected from failure, and the strategy for error detection and recovery?
  • Are minimum machine memory and free disk space specified?
  • Is the maintainability of the system specified, including its ability to adapt to changes in specific functionality, changes in operating environment, and changes in its interfaces with other software?
  • Is the definition of success included? Of failure?

Quality of the Requirements Themselves

  • Are the requirements written in the user's language? Do the users think so? No computer/tech talk here.
  • Does each requirement avoid conflicts with other requirements?
  • Are acceptable tradeoffs between competing attributes specified-for example between robustness and correctness?
  • Do the requirements avoid specifying the design? <---- VERY IMPORTANT
  • Are the requirements at a fairly consistent level of detail? Should any requirement be specified in more detail? Should any requirement be specified in less detail?
  • Are the requirements clear enough to be turned over to an independent group for construction and still be understood? Do the developers think so?
  • Is each item relevant to the problem and its solution? Can each item be traced to its origin in the problem environment?
  • Is each requirement testable? Will it be possible for independent testing to determine whether each requirement has been satisfied?
  • Are all possible changes to the requirement specified including the likelihood of each change?

Requirements Completeness

  • Where information isn't available before development begins, are the areas of incompleteness specified?
  • Are the requirements complete in the sense that if the product satisfies every requirement, it will be acceptable?
  • Are you comfortable with all the requirements? Have you eliminated requirements that are impossible to implement and included just to appease your customer or your boss?

Architecture

  • Is the overall organization of the program clear, including a good architectural overview and justification?
  • Are major building blocks well defined, including their areas of responsibility and their interfaces to other building blocks?
  • Are all the functions listed in the requirements covered sensibly, by neither too many nore too few building blocks?
  • Are the most critical classes described and justified?
  • Is the data design described and justified?
  • Is the database organization and content specified?
  • Are all key business rules identified and their impact on the system described?
  • Is a strategy for the user interface design described?
  • Is the user interface modularized so that changes in it won't affect the rest of the program?
  • Is a strategy for handling I/O described and justified?
  • Are resource-use estimates and a strategy for resource management described and justified for scarce resources like threads, database connections, handles, network bandwidth, and so on?
  • Are the architecture's security requirements described?
  • Does the architecture set space and speed budgets for each class, subsystem, or functionality area?
  • Does the architecture describe how scalability will be acheived?
  • Does the architecture address interoperability?
  • Is a strategy for internationalization/localization described?
  • Is a coherent error-handling strategy provided?
  • Is the approach to fault tolerance defined if needed?
  • Has technical feasibility of all parts of the system been established?
  • Is an approach to overengineering specified?
  • Are necessary buy-vs.-build decisions included?
  • Does the architecture describe how reused code will be made to conform to other architectural objectives?
  • Is the architecture designed to accommodate likely changes?
  • Does the architecture account for all requirements?
  • Is any part overarchitected or underarchitected? Are expectations in this area set out explicitly?
  • Does the whole architecture hange together conceptually?
  • Is the top-level design independent of the machine and language that will be used to implement it?
  • Are the motiviations for all major decisions provided?
  • Are you, as a programmer who will implement the system, comfortable with the architecture?

Design in Construction

Heuristics

  • Find real-world objects
  • Form consistent abstractions
  • Encapsulate implementation details
  • Inherit when possible
  • Hide Secrets (ALL OF THEM)
  • Identify areas likely to change
  • Keep coupling loose
  • Look for common design patterns
  • Aim for strong cohesion
  • Build hierarchies
  • Formalize class contracts
  • Assign responsibilities
  • Design for test
  • Avoid failure
  • Choose binding time consciously
  • Make central points of control
  • Consider using brute force
  • Draw a diagram
  • Keep your design modular

Practices

  • Have you iterated, selecting the best of several attempts rather than the first attempt?
  • Have you tried decomposing the system in several different ways to see which way will work best?
  • Have you approached the design problem both from the top down and from the bottom up?
  • Have you protyped risky or unfamiliar parts of the system, creating the absolute minimum amount of throwaway code needed to answer specific questions?
  • Has your design been reviewed, formally or informally, by others?
  • Have you driven the design to the point that it's implementation seems obvious?
  • Have you captured your design somehow (document, graph, UML)?

Goals

  • Does the design adequately address issues that were identified and deferred at the architectural level?
  • Is the design stratified into layers?
  • Are you satisfied with the way the program has been decomposed into subsystems, packages and classes?
  • Are you satisfied with the way the classes have been decomposed into routines?
  • Are classes designed for minimal interaction with each other?
  • Are classes and subsystems designed so that you can use them in other systems?
  • Will the program be easy to maintain?
  • Is the design lean? Are all of its parts strictly necessary?
  • Does the design use standard techniques and avoid exotic, hard-to-understand elements?
  • Overall, does the design help minimize both accidental and essential complexity?

Classes

Abstract Data Types

Have you thought of the classes in your program as abstract data types and evaluated their interfaces from that point of view?

Abstraction

  • Does the class have a central purpose?
  • Is the class well named, and does its name describe its central purpose?
  • Does the class's interface present a considstent abstraction?
  • Does the class's interface make obvious how you should use the class?
  • Is the class's interface abstract enough that you don't have to think about how its services are implemented? Can you treat the class as a black box?
  • Are the class's services complete enough that other classes don't have to meddle with it's internal data?
  • Has unrelated information been moved out of the class?
  • Have you thought about subdividing the class into component classes, and have you subdivided it as much as you can?
  • Are you preserving the integrity of the class's interface as you modify the class?

Encapsulation

  • Does the class minimize accessibility to its members?
  • Does the class avoid exposing member data?
  • Does the class hide its implementation details from other classes as much as the programming language permits?
  • Does the class avoid making assumptions about its users, including its derived classes?
  • Is the class independent of other classes? Is it loosely coupled?

Inheritance

  • Is inheritance used ONLY to model "is a" relationships?
  • Does the class documentation describe the inheritance strategy?
  • Do derived classes avoid "overriding" non-overridable routines?
  • Are common interfaces, data, and behavior as high as possible in the inheritance tree?
  • Are inheritance trees fairly shallow?
  • Are all data members in the base class private rather than protected?

Other

  • Does the class contain about 7 data members or fewer? (general rule, not hard and fast. If more consider breaking the class down further)
  • Does the class minimize direct and indirect routine calls to other classes?
  • Does the class collaborate with other classes only to the extent absolutely necessary?
  • Is all member data initialized in the constructor?
  • Is the class designed to be used as deep copies rather than shallow copies unless there is a measured reason to create shallow copies?

Routines

Big Picture

  • Is the reason for creating the routine sufficient?
  • Have all parts of the routine that would benefit from being put into routines of their own been put into routines of their own?
  • Is the routine's name a strong, clear verb-plus-object name for a procedure or a description of the return value for a function?
  • Does the routine's name describe everything the routine does?
  • Have you established naming conventions for common operations?
  • Does the routine have strong, functional cohesion - doing one and only one things and doing it well?
  • Do the routines have loose coupling - are the routine's connections to other routines small, intimate, visible, and flexible?
  • Is the length of the routine determined naturally by its function and logic, rather than by an artificial coding standard?

Parameters

  • Does the routine's paramater list, taken as a whole, present a consistent interface abstraction?
  • Are the routine's parameters in a sensible order, including matching the order of parameters in similar routines?
  • Are interface assumptions documented?
  • Does the routine have seven or fewer parameters?
  • Is each input parameter used?
  • Is each output parameter used?
  • Does the routine avoid using input parameters as working variables?
  • If the routine is a function, does it return a valid value under all possible circumstances?
  • Does the routine check parameters for validity?

Variables

  • Are variables declared as close as possible to where they are first used?
  • Are variables initialized as they're declared, if possible?
  • Are variables initialized close to where they are first used if it isn't possible to declare and initialize them at the same time?
  • Are counters and accumulators initialized properly and, if necessary, reinitialized each time they are used?
  • Are variables reinitialized properly in code that's executed repeatedly?
  • If the language uses implicit declarations, have you compensated for the problems they cause?
  • Do all variables have the smallest possible scope?
  • Are references to variables as close together as possible, both from each reference to a variable to the next reference (span) and in total live time?
  • Do control structures correspond to the data types(sequential, selective, iterative)?
  • Are all declared variables being used?
  • Are all variables bound at appropriate times (code, compile-time, load-time, run-time (jit))?
  • Does each variable have one and only one purpose?
  • Is each variable's meaning explicit, with no hidden meanings (hybrid coupling)?

Other Notes

  • Macros should be used sparingly if at all.
  • The primary reason to create a routine is to improve the intellectual manageability of a program.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment