Two uses of the term “Interface” in this course, what are they?
- The public or exposed parts of a module which allow it to interact with its environment (user/ header).
- A contract which defines the required preconditions and specifies the corresponding output. (programmer)
Two phrases to describe inheritance aggregation relationships?
- aggregation describes a ‘has-a’ relationship
- inheritance describes an ‘is-a’ relationship
What does high fan-in indicate?
High fan-in refers to having a high number of classes that use a given class. It implies that a system has been designed to make good use of utility classes at the lower levels in the system and promotes code reuse.
Up to what percentage of a program is devoted to error processing?
Up to 90% of a program can be devoted to error processing.
When do you stop dividing parts of a subsystem in top-down design?
You stop dividing parts of a subsystem in top-down design when it becomes trivial and breaking them down further is not productive.
What is the goal of preparation in a software design project?
The overarching goal of preparation is risk reduction.
Is there a situation when a sequential development process is better than an iterative process?
- When you have stable requirements (no need to iterate).
- When the design is well understood.
- When there is little risk.
- When long term predictability is important.
- When cost of later changes is high (ie. embedded hardware).
What is the most important technical topic, known as the primary imperative in software development?
Managing complexity is the most important technical topic and known as the primary imperative in software development.
How does encapsulation differ from abstraction?
Abstraction is used to identify essential information whereas encapsulation packages information in such a way which can hide the unimportant important details of an implementation.
One of the design heuristics presented during class was to avoid failure, what does this mean?
In order to avoid failure you must take into consideration all possible points of failure, you can’t just focus on previous successes.
What comprises of an ADT?
An ADT is comprised of a definition of a type and the operations defined on the type.
What does “Design is a wicked problem” mean?
A wicked problem is one that could be clearly defined only by solving it, or by solving part of it. This paradox implies, essentially, that you have to solve the problem once in order to clearly define it and then solve it again to develop a solution that works.
Draw a diagram for one of the two lifecycles for software after the first release.
- Debug ⇆
- ⇆ Test
- Add Feature
- Test ⇆
- ⇆ Debug
currentFont.attribute = current.attribute be reworked to be better?
- Should use getters and setters instead of letting the user access it directly.
currentFont = getFont(current)
Definitions from Code Complete
The primary goal of design should be to minimize complexity for all the reasons just described. Avoid making “clever” designs. Clever designs are usually hard to understand. Instead make “simple” and “easy-to-understand” designs. If your design doesn’t let you safely ignore most other parts of the program when you’re immersed in one specific part, the design isn’t doing its job.
Ease of maintenance
Ease of maintenance means designing for the maintenance programmer. Continually imagine the questions a maintenance programmer would ask about the code you’re writing. Think of the maintenance programmer as your audience, and then design the system to be self-explanatory.
Loose coupling means designing so that you hold connections among different parts of a program to a minimum. Use the principles of good abstractions in class interfaces, encapsulation, and information hiding to design classes with as few interconnections as possible. Minimal connectedness minimizes work during integration, testing, and maintenance.
Extensibility means that you can enhance a system without causing violence to the underlying structure. You can change a piece of a system without affecting other pieces. The most likely changes cause the system the least trauma.
Reusability means designing the system so that you can reuse pieces of it in other systems.
High fan-in refers to having a high number of classes that use a given class. High fan-in implies that a system has been designed to make good use of utility classes at the lower levels in the system.
Low-to-medium fan-out means having a given class use a low-to-medium number of other classes. High fan-out (more than about seven) indicates that a class uses a large number of other classes and may therefore be overly complex. Researchers have found that the principle of low fan-out is beneficial whether you’re considering the number of routines called from within a routine or the number of classes used within a class (Card and Glass 1990; Basili, Briand, and Melo 1996).
Portability means designing the system so that you can easily move it to another environment.
Leanness means designing the system so that it has no extra parts (Wirth 1995, McConnell 1997). Voltaire said that a book is finished not when nothing more can be added but when nothing more can be taken away. In software, this is especially true because extra code has to be developed, reviewed, tested, and considered when the other code is modified. Future versions of the software must remain backward-compatible with the extra code. The fatal question is “It’s easy, so what will we hurt by putting it in?”
Stratification means trying to keep the levels of decomposition stratified so that you can view the system at any single level and get a consistent view. Design the system so that you can view it at one level without dipping into other levels. For example, if you’re writing a modern system that has to use a lot of older, poorly designed code, write a layer of the new system that’s responsible for interfacing with the old code. Design the layer so that it hides the poor quality of the old code, presenting a consistent set of services to the newer layers. Then have the rest of the system use those classes rather than the old code. The beneficial effects of stratified design in such a case are (1) it compartmentalizes the messiness of the bad code and (2) if you’re ever allowed to jettison the old code or refactor it, you wont need to modify any new code except the interface layer.
The more a system relies on exotic pieces, the more intimidating it will be for someone trying to understand it the first time. Try to give the whole system a familiar feeling by using standardized, common approaches.