309 ;;Quote: resource acquisition is initialization. Resources, like objects, are released in the reverse order of their acquisition; works well with exception handling
|
309+;;Quote: an object is not constructed until its constructor has completed; an exception calls a destructor only for constructed objects
|
313 ;;Quote: an exception should minimize the amount of conveyed information; otherwise changes may be difficult to make
|
313+;;Quote: resource allocation should be organized in levels of abstraction with minimal dependencies between levels
|
313+;;Quote: successful, large systems tend to be organized in layers or levels of abstraction
|
316 ;;Quote: avoid using exceptions as a control structure; keep ordinary code and error-handling code separate
|
316+;;Quote: simplify error handling by keeping it separate from normal code
|
318 ;;Quote: an explicit declaration of an exception makes the exception visible to its callers
|
318+;;Quote: you do not want to look at source code even if it is readily available
|
322 ;;Quote: an overall strategy is needed to use exception handlers effectively; e.g., successful fault-tolerant systems are multi-level
|
323 ;;Quote: it is difficult to design functions that either succeed or fail in a well defined way; but, it is essential to divide a program into subsystems that either succeed or fail in a well defined way
|
323 ;;Quote: error handling should be strictly hierarchical; otherwise get cycles of system dependencies if a function asks its caller for help with recovery or resource acquisition
|
326 ;;Quote: stream I/O converts typed objects into untyped character sequences, and vice versa. Stream I/O is fundamental
|
333 ;;Quote: every I/O stream has a state associated with it; used for handling errors and non-standard conditions
|
344 ;;Quote: an I/O stream manipulator is a function that takes a stream as input and returns a stream; use it to insert functions like 'flush()' and 'skipspacing()' in a list of input or output operations
|
344+;;Quote: the behavior of an I/O stream manipulator is determined partially by its creator and partially by its caller
|
363 ;;Quote: it is important to remember that design and programming are human activities
|
364 ;;Quote: use divide and conquer to handle complexity
|
364+;;Quote: simplify a problem by splitting it into two
|
364+;;Quote: a module or class separates a program into an implementation and its interface to users
|
364+;;Quote: organize programming as distinct activities with clearly defined interactions
|
364 ;;Quote: for both people and programs separating implementation from interface is easy; the hard part is organizing effective communication between the different sides of the interface
|
365 ;;Quote: every successful major piece of software will be worked on by a succession of programmers and designers, ported to new platforms, adapted to new uses, and reorganized. Must plan for multiple versions
|
367 ;;Quote: both design and implementation are interleaved in a real project. Design is usually re-design from the previous design, experience, and constraints
|
369 ;;Quote: C++ development consists of repeatedly: create a design, find and customize standard components, create and customize new standard components, and assemble the results
|
370 ;;Quote: with traditional software, a system is not made of discrete components; and if discrete components exist, they are not used elsewhere
|
371 ;;Quote: a system must be designed to remain as simple as possible under a sequence of changes that cannot all be foreseen
|
371 ;;Quote: design for change by making a system flexible, extensible, and portable. Encapsulate the areas that are likely to change
|
371+;;Quote: ideally, each class is responsible for the maintenance of all information relating to a single concept. If so, a change in a concept effects one class only
|
373 ;;Quote: a good design models some aspect of reality. Concepts are classes with inheritance to show relationships. Multiple levels of abstraction
|
375 ;;Quote: it is much easier to add a function that is clearly needed for a class than to remove a function that has become a liability
|
375 ;;Quote: unnecessary functions in a class constrain the system's evolution
|
375+;;Quote: if functions directly read or write members, they can make a class an implementation instead of an abstraction
|
375 ;;Quote: a virtual function defines an interface to yet-to-be-defined classes, and it depends on yet-to-be defined classes
|
375+;;Quote: when designing a class, it is important to specify the expected behavior of virtual functions
|
375 ;;Quote: types of operations on a class: foundation operators, selectors, modifiers, conversion operators, iterators
|
376 ;;Quote: every class should support at least two significantly different implementations; otherwise the class is an implementation in disguise
|
376 ;;Quote: all operations of a class should support the same level of abstraction; e.g., separate operations on file descriptors from operations on file names
|
378 ;;Quote: program design is a social activity where designs are developed through presentation and discussions; e.g., discuss design and implementation alternatives
|
378+;;Quote: often, the most important design tool is a blackboard; for developing and sharing embryonic concepts
|
380 ;;Quote: an untested program does not work
|
380+;;Quote: in practice, can not design and verify a program to work the first time
|
381 ;;Quote: more resources should be spent on testing a system than on constructing the initial implementation
|
381 ;;Quote: first order efficiency must be kept in mind throughout the design and implementation effort; avoid gargantuism and inherently inefficient constructs that can not be optimized
|
382 ;;Quote: non-portable constructs and tools restrict a project to older computers
|
383 ;;Quote: reuse is a social phenomenon: it must work, be comprehensible, be supported, be economical, co-exist with other software, and be found
|
383 ;;Quote: reuse works only if someone takes the responsibility; use a standard components group
|
384 ;;Quote: common sense can be lost when an individual or organization tries to follow proper procedures
|
385 ;;Quote: every approach works for a small project, and with enough time and money, for a large project
|
394 ;;Quote: the procedure-oriented and object-oriented views of programming are fundamentally different for both design and implementation
|
394+;;Quote: you can not simultaneously focus a design on both the entities and their actions
|
394 ;;Quote: functional decomposition is insufficient for data abstraction because interesting data needs to be global; like single inheritance
|
396 ;;Quote: a strongly typed interface helps ensure that only compatible pieces of software are linked together; allows strong assumptions, minimizes run-time tests, assists system integration
|
396 ;;Quote: static type checking is akin to physical plug compatibility which works well despite many standards; dynamic checking is like protection/adaptation circuitry
|
397 ;;Quote: the difference between dynamic and static type checking is the difference between "x must be a car" and "x is a car"
|
397+;;Quote: dynamic type checking underspecifies an interface; it makes an assumption that is checked at runtime
|
397 ;;Quote: dynamic type checking can make a program run 3 to 10 times slower than the same program with static type checking
|
402 ;;Quote: object-oriented classes either reflect the concepts of an application domain or they are artifacts of the implementation
|
411 ;;Quote: use inheritance ("D is a kind of B") for well-defined relationships and membership ("D has a B") whenever multiple members are possible
|
412 ;;Quote: use public derivation (with implicit conversions to a base class) when derivation represents an "isa" relationship of a concept
|
417 ;;Quote: the state, or value, of an object is the value of its members and the objects it references
|
417+;;Quote: a class maintains an invariant, i.e., a piece of code that checks the state of an object
|
417+;;Quote: in a well-defined class, an initialized object satisfies a simple invariant that is maintained by all operations until the object is destroyed
|
418 ;;Quote: use private and protected functions whenever an object does not satisfy the class invariant
|
419 ;;Quote: check routines for class invariants are an invaluable help during debugging and class definition
|
419+;;Quote: check routines for class invariants provide an alternative viewpoint of the class and its implementation
|
419+;;Quote: production code should include some of the check routines for class invariants
|
420 ;;Quote: use a stylized representation for design concepts that do not match the programming language; e.g., delegation in C++
|
431 ;;Quote: a concrete type such as 'date' is closely matched to an efficient, complete implementation without dependencies on other classes
|
431+;;Quote: concrete types do not express commonality of concepts; e.g., a 'set' is not a concrete type because it may be an 'slist' or a 'vector' with different performance characteristics
|
436 ;;Quote: an abstract type is an interface defined by pure virtual functions and no data members; most operations are virtual function calls
|
436+;;Quote: an abstract type is implemented with concrete types
|
437 ;;Quote: use concrete types for efficiency and abstract types for flexibility; neither are useful for inheritance
|
439 ;;Quote: a node class belongs to a type hierarchy. It provides an interface and services. It relies on base classes
|
439+;;Quote: a node class usually has a non-trivial constructor; unlike abstract types that rarely have constructors
|
450 ;;Quote: switch statements with run-time type inquires destroys the modularity of a program; it is error-prone and not object-oriented
|
450+;;Quote: use virtual function calls rather than run-time type inquiries even though the later may be easier and more efficient
|
452 ;;Quote: a fat interface is a class that provides all functions for a set of concepts, e.g., a universal 'container' class
|
452+;;Quote: avoid fat interfaces: slow implementation, difficult to prove, weak correspondence between concepts and classes, encourages the use of derivation for implementation convenience
|
453 ;;Quote: an application framework defines a complete application without content; the programmer supplies application-specific code as building blocks
|
453+;;Quote: the classes in an application framework have fat interfaces that are hardly types in the traditional sense
|
453+;;Quote: build applications from a library of building blocks
|
457 ;;Quote: an interface class specializes the appearance of some service. Need not generate code, e.g., a template for a type-safe list from a list of 'void*' pointers
|
457 ;;Quote: use inline functions to make interface classes affordable; e.g., an inline forwarding function that adjusts the type without generating additional code
|
460 ;;Quote: to use an abstract type as part of a concrete type, separate the abstract object into two parts: a handle providing the user interface and a representation holding the object's state
|
463 ;;Quote: sometimes it is necessary to extract the representation pointer from a handle, pass it to a function, or perhaps, rebind it as a new handle
|
466 ;;Quote: actions performed "at garbage-collection time" may occur any time between the object's last use and program termination; must execute under an unknown state
|
466+;;Quote: use a registration server instead of garbage-collection; register an object for cleanup at program termination; remove registration if object is explicitly terminated
|