James Course - Data Over Code Flashcards
Why Git has been more successful at adding features over time related to other VCS?
A lot of version control systems change their data format relatively regularly in order to support new features. When you upgrade to get the new feature, you often have to run some sort of tool to convert the database as well.
In contrast, despite an explosion of features in git, its underlying data structures have barely changed at all. Worry about the data structures first, and your code will naturally be cleaner.
I will, in fact, claim that the difference between a bad programmer and a good one is whether he considers his code or his data structures more important.
Why Parnas modularization around data structures made possible to change the program touching fewer modules?
The data structures are hiding some secret from the remaining of the program, so every time a feature change request changes the secret, the remaining of the program doesn’t have to change.
How can you show that two implementations are equivalent? (counter example)
You can create a bisimulation where you list all possible states in each implementation and create a correspondence between them. The next step is to show that the transitions between states (methods calls) are the same in both implementations as well.
What is the secret of a module?
A secret of a module is anything that can be changed without a change in behavior from any possible program linked with this module. (Remember about the int counter vs bool counter).
Secrets give us modularity, they allow us to change something without changing another.
Why decomposition around data structures are better than functional decomposition?
The data is much more stable than the code.
The code for an architectural component may take many forms. But the dataflow will remain stable.
By focusing on decomposition around data structures we end up with a data flow that has less connection between modules. (I need to refine this idea)
Design Build Read a program around the data structures. Everything else will follow
.
Summary
Focus on the data structures
Always ask “What secret is hiding?”
Think in terms of dataflow
When designing a data structure should you start with the use cases that the data structure might handle, or with the inherent properties of the data structure?
With the inherent properties, because those will change way less than the use cases, and because the number of use cases will be way large then the number of inherent properties in the data structure.
Don’t confuse secret hiding with data access.
Remember about the line storage interface.
LineStorage1 { String getWord(int linen, int wordn) }
LineStorage2 { String getLine(int linen) }
LineStorage3 { List getLines() }
The number of possible implementations for LineStorage3 is way more restricted, it is not hiding too much, thus, constraining the space of possible implementations.
When designing a program what strategy should you use to select what will become a secret?
You should prioritize things that are more likely to change or things that you don’t want the programmer to know (e.g. details about some hardware implementation or about some protocol).
The less solid is your reasoning for making some decision the more likely it is to change.
In Parnas words: “We propose instead that one begins (his decomposition) with a list of difficult design decisions or design decisions which are likely to change.”
In Parnas paper, what are the benefits of modular programming?
(1) managerial - development time should be shortened because separate groups would work on each module with little need for communication:
(2) product flexibility - it should be possible to make drastic changes to
one module without a need to change others;
(3) comprehensibility - it should be possible to study the system one module at a time. The whole system can, therefore, be better designed because it is better understood.
What is Parnas definition of modules?
In this context “module” is considered to be a responsibility assignment rather than a subprogram. The modularizations include the design decisions which must be made before the work on independent modules can begin.
A well-defined segmentation of the project effort ensures system modularity. Each task forms a separate, distinct program module. At implementation time each module and its inputs and outputs are well-defined, there is no confusion in the intended interface with other system modules. At checkout time the integrity of the module is tested independently; there are few scheduling problems in synchronizing the completion of several tasks before checkout can begin. Finally, the system is maintained in modular fashion; system errors and deficiencies can be traced to specific system modules, thus limiting the scope of detailed error searching.
What are the two criteria used to decompose the system in Parnas paper?
In the first decomposition, the criterion used was to make each major step in the processing a module. One might say that to get the first decomposition one makes a flowchart. The second decomposition was made using “information hiding” [4] as a criterion. The modules no longer correspond to steps in the processing. The line storage module, for example, is used in almost every action by the system. Alphabetization may or may not correspond to a phase in the processing according to the method used. Similarly, circular shift might, in some circumstances, not make any table at all but calculate each character as demanded. Every module in the second decomposition is characterized by its knowledge of a design decision which it hides from all others. Its interface or definition was chosen to reveal as little as possible about its inner workings.
When are modules in a system decomposed in a hierarchy and what are the benefits gained from this?
We have a hierarchical structure if a certain relation may be defined between the modules or programs and that relation is a partial ordering.
The partial ordering gives us two additional benefits. First, parts of the system are benefited (simplified) because they use the services of lower levels. Second, we are able to cut off the upper levels and still have a usable and useful product. For example, the symbol table can be used in other applications; the line holder could be the basis of a question answering system. The existence of the hierarchical structure assures us that we can “prune” off the upper levels of the tree and start a new tree on the old trunk. If we had designed a system in which the “low level” modules made some use of the “high level” modules, we would not have the hierarchy, we would find it much harder to remove portions of the system, and “level” would not have much meaning in the system.
Since it is conceivable that we could have a system with the type of decomposition shown in version 1 (important design decisions in the interfaces) but retaining a hierarchical structure, we must conclude that hierarchical structure and “clean” decomposition are two desirable but independent properties of a system structure.
What was the difference between beautiful and ugly systems at Philips noted by Parnas?
The difference between the designs that I found “beautiful” and those that I found ugly was that the beautiful designs encapsulated changeable or arbitrary information. Because the Interfaces contained only “solid” or lasting information, they appeared simple and could be called beautiful. To keep the interfaces “beautiful”, one needs to structure the system so that all arbitrary or changeable or very detailed information is hidden.