A Philosophy of Software Design
Rate it:
Kindle Notes & Highlights
5%
Flag icon
The most fundamental problem in computer science is problem decomposition:
7%
Flag icon
The overall goal is to reduce complexity;
7%
Flag icon
The first approach is to eliminate complexity by making code simpler and more obvious.
7%
Flag icon
The second approach to complexity is to encapsulate it, so that programmers can work on a system without being exposed to all of its complexity at once. This approach is called modular design.
8%
Flag icon
design was concentrated at the beginning of a project,
8%
Flag icon
The extreme of this approach is called the waterfall model,
8%
Flag icon
divided into discrete phases such as requirements definition, design, coding, t...
This highlight has been truncated due to consecutive passage length restrictions.
8%
Flag icon
in which the initial design focuses on a small subset of the overall functionality. This subset is designed, implemented, and then evaluated.
8%
Flag icon
Each iteration exposes problems with the existing design, which are fixed before the next set of features is designed.
8%
Flag icon
Incremental development means that software design is never done.
8%
Flag icon
Design happens continuously over the life of a system:
9%
Flag icon
The ability to recognize complexity is a crucial design skill.
9%
Flag icon
Complexity is anything related to the structure of a software system that makes it hard to understand and modify the system.
10%
Flag icon
Isolating complexity in a place where it will never be seen is almost as good as eliminating the complexity entirely.
10%
Flag icon
Complexity is more apparent to readers than writers. If you write a piece of code and it seems simple to you, but other people think it is complex, then it is complex.
10%
Flag icon
Change amplification: The first symptom of complexity is that a seemingly simple change requires code modifications in many different places.
10%
Flag icon
Cognitive load: The second symptom of complexity is cognitive load, which refers to how much a developer needs to know in order to complete a task.
10%
Flag icon
Sometimes an approach that requires more lines of code is actually simpler, because it reduces cognitive load.
11%
Flag icon
Unknown unknowns: The third symptom of complexity is that it is not obvious which pieces of code must be modified to complete a task, or what information a developer must have to carry out the task successfully.
11%
Flag icon
An unknown unknown means that there is something you need to know, but there is no way for you to find out what it is, or even whether there is an issue.
11%
Flag icon
One of the most important goals of good design is for a system to be obvious.
11%
Flag icon
Complexity is caused by two things: dependencies and obscurity.
11%
Flag icon
For the purposes of this book, a dependency exists when a given piece of code cannot be understood and modified in isolation;
12%
Flag icon
In many cases, obscurity comes about because of inadequate documentation;
12%
Flag icon
However, obscurity is also a design issue. If a system has a clean and obvious design, then it will need less documentation.
12%
Flag icon
Dependencies lead to change amplification and a high cognitive load. Obscurity creates unknown unknowns, and also contributes to cognitive load.
12%
Flag icon
The incremental nature of complexity makes it hard to control.
13%
Flag icon
In the tactical approach, your main focus is to get something working,
13%
Flag icon
kludge
13%
Flag icon
that working code isn’t enough.
13%
Flag icon
The most important thing is the long-term structure of the system.
13%
Flag icon
Your primary goal must be to produce a great design, which also happens to work.
13%
Flag icon
it’s worth taking a little extra time to find a simple design for each new class;
14%
Flag icon
Writing good documentation is another example of a proactive investment.
14%
Flag icon
I suggest spending about 10–20% of your total development time on investments.
15%
Flag icon
“Move fast with solid infrastructure”
15%
Flag icon
developers only need to face a small fraction of the overall complexity at any given time. This approach is called modular design,
15%
Flag icon
a software system is decomposed into a collection of modules that are relatively independent.
15%
Flag icon
The goal of modular design is to minimize the dependencies between modules.
16%
Flag icon
Typically, the interface describes what the module does but not how it does it. The implementation consists of the code that carries out the promises made by the interface.
16%
Flag icon
The best modules are those whose interfaces are much simpler than their implementations.
16%
Flag icon
First, a simple interface minimizes the complexity that a module imposes on the rest of the system.
16%
Flag icon
The formal parts of an interface are specified explicitly in the code,
16%
Flag icon
An abstraction is a simplified view of an entity, which omits unimportant details.
17%
Flag icon
First, it can include details that are not really important;
17%
Flag icon
The second error is when an abstraction omits details that really are important. This results in obscurity:
17%
Flag icon
The best modules are those that provide powerful functionality yet have simple interfaces.
18%
Flag icon
a shallow module is one whose interface is relatively complex in comparison to the functionality that it provides.
19%
Flag icon
interfaces should be designed to make the common case as simple as possible
20%
Flag icon
The most important technique for achieving deep modules is information hiding.
« Prev 1 3 6