Section 12.2 Function Guidelines
Any kind of design is subjective and as much an art as a science. Design problems often have multiple solutions, and there is no single βrightβ solution. Different goals of a design problem will often be at odds with each other, and different solutions will have different trade-offs.
If we are designing a car, we might want it to be fast, comfortable, and fuel-efficient. However, these goals are often in conflict with each other. A car that is fast may need to be low and aerodynamic, which may make it less comfortable. An engine designed to generate more power may be less fuel-efficient. Good design is about deciding which goals are most important and making trade-offs accordingly. The design for a SUV that will be marketed to families will prioritize comfort and safety over speed and efficiency. The design for a sports car will prioritize performance and might
For any design domain, we can try to identify design guidelines that should shape our approach. A car design guideline might be βstart from an egg-like shapeβ. That is a very aerodynamic shape, so following it will likely improve both performance and fuel-efficiency. This guideline is not an absolute rule. For a particular car design, we might need to ignore that guideline to satisfy some other important goal. However, absent a clear reason to ignore the guideline, our design will likely benefit from following it.
Function design offers room for similar tradeoffs. For example, a design that allows a function to be reused in many different contexts may require it to be more complex, which can make it harder to understand (a less good abstraction). Or a function that is very efficient may be difficult to read and maintain. Our goal is to maximize some combination of the following factors:
-
The clarity of the code (the abstraction of the function)
-
The reusability of the code (how much it avoids repeating code)
-
The modularity of the code (how easy it is to work on one part at a time)
-
The efficiency of the code (how efficiently it performs its task)
Of those, efficiency will be the one that we worry about the least for now. If a design is clear, reusable, and modular, it will likely be efficient enough for most purposes. If it is not efficient enough, we can often optimize it later. Once you begin studying algorithms and data structures, we will have more tools at our disposal for improving efficiency.
Here are some guidelines that we can follow to help us achieve those goals:
-
Functions should have a single responsibility. A function should do one thing and do it well. If a function is trying to do too many things, it often becomes more complex and difficult to maintain. And, it ends up being harder to reuse in situations that only call for part of its functionality.
-
Functions should be modular. A function should be self-contained and not depend on the state of the rest of the program. This makes it easier to test and reuse the function in different contexts.
-
Functions should be small. A function that is too large is difficult to understand and maintain. βToo largeβ is a loosely defined term. The real goal is to avoid programmers having to keep too much information in their head at once. But a good rule of thumb is to keep functions under 10-15 lines of code when possible. If a function starts getting larger than that, it is time to take a look at breaking it up into smaller functions.
Checkpoint 12.2.2.
You have attempted of activities on this page.