This is a nice book on the now common-place wisdom of programming or software engineering discipline. As a software engineer for 13 years I found it not so useful but nevertheless good in reviewing what are today well understood and common practices in the industry like the DRY principle (Don’t repeat yourself), Fix the broken windows today, refactoring etc. I highlighted some points as I was reading this book and I am reproducing them below (more for myself to be able to review these once in a while):
- Every day, work to refine the skills you have and to add new tools to your repertoire.
- The greatest of all weaknesses is the fear of appearing weak. • J. B. Bossuet, Politics from Holy Writ, 1709
- Don't leave "broken windows" (bad designs, wrong decisions, or poor code) unrepaired. Fix each one as soon as it is discovered.
- People find it easier to join an ongoing success. Show them a glimpse of the future and you'll get them to rally around.
- It's often the accumulation of small things that breaks morale and teams.
- Striving to better, oft we mar what's well. • King Lear 1.4
- As Ed Yourdon described in an article in IEEE Software [You95], you can discipline yourself to write software that's good enough—good enough for your users, for future maintainers, for your own peace of mind. You'll find that you are more productive and your users are happier. And you may well find that your programs are actually better for their shorter incubation.
- We are simply advocating that users be given an opportunity to participate in the process of deciding when what you've produced is good enough.
- Great software today is often preferable to perfect software tomorrow. If you give your users something to play with early, their feedback will often lead you to a better eventual solution.
- Don't spoil a perfectly good program by over-embellishment and over-refinement. Move on, and let your code stand in its own right for a while. It may not be perfect. Don't worry: it could never be perfect.
- An investment in knowledge always pays the best interest. • Benjamin Franklin
- Learn at least one new language every year.
- Read a technical book each quarter.
- Once you're in the habit, read a book a month.
- After you've mastered the technologies you're currently using, branch out and study some that don't relate to your project.
- Read nontechnical books, too.
- Take classes.
- Participate in local user groups.
- Start learning a new language this week.
- Start reading a new book
- Get out and talk technology with people who aren't involved in your current project, or who don't work for the same company. Network in your company cafeteria, or maybe seek out fellow enthusiasts at a local user's group meeting.
- I believe that it is better to be looked over than it is to be overlooked.
- You're communicating only if you're conveying information.
- Encourage people to talk by asking questions, or have them summarize what you tell them.
- Always respond to e-mails and voice mails, even if the response is simply "I'll get back to you later." Keeping people informed makes them far more forgiving of the occasional slip, and makes them feel that you haven't forgotten them.
- Where possible, always use accessor functions to read and write the attributes of objects.
- Two or more things are orthogonal if changes in one do not affect any of the others.
- Our preference is to start by separating infrastructure from application. Each major infrastructure component (database, communications interface, middleware layer, and so on) gets its own subteam. Each obvious division of application functionality is similarly divided. Then we look at the people we have (or plan to have) and adjust the groupings accordingly.
- There is an easy test for orthogonal design. Once you have your components mapped out, ask yourself: If I dramatically change the requirements behind a particular function, how many modules are affected? In an orthogonal system, the answer should be "one."
- Prototyping generates disposable code. Tracer code is lean but complete, and forms part of the skeleton of the final system.
- Prototyping is a learning experience. Its value lies not in the code produced, but in the lessons learned
- We think it's a great idea to record your estimates so you can see how close you were.
- Iterate the Schedule with the Code
- To ensure that we never lose any of our precious work, we should always use a Source Code Control system—even for things such as our personal address book!
- you can't be a great programmer until you become highly skilled at Debugging.
- Keep Knowledge in Plain Text
- Clearly the list could go on. The shell commands may be obscure or terse, but they are powerful and concise. And, because shell commands can be combined into script files (or command files under Windows systems), you can build sequences of commands to automate things you do often. Tip 21 Use the Power of Command Shells.
- Ideally, the shell you use should have keybindings that match the ones used by your editor. Bash, for instance, supports both vi and emacs keybindings.
- Choose an editor, know it thoroughly, and use it for all editing tasks.
- As one of the new languages you are going to learn this year, learn the language your editor uses. For anything you find yourself doing repeatedly, develop a set of macros (or equivalent) to handle.
- Try to accomplish any given editing task in as few keystrokes as possible.
- Progress, far from consisting in change, depends on retentiveness. Those who cannot remember the past are condemned to repeat it. • George Santayana, Life of Reason
- sounds simple, but in explaining the problem to another person you must explicitly state things that you may take for granted when going through the code
- Debugging Checklist -
- Is the problem being reported a direct result of the underlying bug, or merely a symptom?
- Is the bug really in the compiler?
- Is it in the OS? Or is it in your code?
- If you explained this problem in detail to a coworker, what would you say?
- If the suspect code passes its unit tests, are the tests complete enough?
- What happens if you run the unit test with this data?
- Do the conditions that caused this bug exist anywhere else in the system?
- Learn a Text Manipulation Language like perl.
- Good fences make good neighbors. • Robert Frost, "Mending Wall"
- Organize your code into cells (modules) and limit the interaction between them. If one module then gets compromised and has to be replaced, the other modules should be able to carry on.
- Traversing relationships between objects directly can quickly lead to a combinatorial explosion[1] of dependency relationships.
- We want to configure and drive the application via metadata as much as possible. Our goal is to think declaratively
- We need to allow for concurrency[3] and to think about decoupling any time or order dependencies. In doing so, we can gain flexibility and reduce any time-based dependencies in many areas of development: workflow analysis, architecture, design, and deployment.
- All functions related to the fulfillment of business logic fall into the category of core concerns.
- You can support multiple views of the same data model. You can use common viewers on many different data models. You can even support multiple controllers to provide nontraditional input mechanisms.
- Model. The abstract data model representing the target object. The model has no direct knowledge of any views or controllers. View. A way to interpret the model. It subscribes to changes in the model and logical events from the controller. Controller. A way to control the view and provide the model with new data. It publishes events to both the model and the view. Let's look at a nongraphical
- Each model may have many viewers, and one viewer may work with multiple models.
- Use Blackboards to Coordinate Workflow
- Network monitoring tool. The system gathers performance statistics and collects trouble reports. You'd like to implement some agents to use this information to look for trouble in the system.
- Sometimes we come up with fairly complex O() functions, but because the highest-order term will dominate the value as n increases, the convention is to remove all low-order terms, and not to bother showing any constant multiplying factors. O(n2/2+ 3n) is the same as O(n2/2), which is equivalent to O(n2).
- Rewriting, reworking, and re-architecting code is collectively known as refactoring.
- Workflow can be captured with UML activity diagrams, and conceptual-level class diagrams can sometimes be useful for modeling the business at hand.
- Teams as a whole should not tolerate broken windows—those small imperfections that no one fixes. The team must take responsibility for the quality of the product, supporting developers who understand the no broken windows philosophy.
- Make sure everyone actively monitors the environment for changes. Maybe appoint a chief water tester. Have this person check constantly for increased scope, decreased time scales, additional features, new environments—anything that wasn't in the original agreement.
- Divide your people into small teams, each responsible for a particular functional aspect of the final system. Let the teams organize themselves internally, building on individual strengths as they can.
- The project needs at least two "heads"—one technical, the other administrative. The technical head sets the development philosophy and style, assigns responsibilities to teams, and arbitrates the inevitable "discussions" between people. The technical head also looks constantly at the big picture, trying to find any unnecessary commonality between teams that could reduce the orthogonality of the overall effort. The administrative head, or project manager, schedules the resources that the teams need, monitors and reports on progress, and helps decide priorities in terms of business needs.
- To ensure that things get automated, appoint one or more team members as tool builders to construct and deploy the tools that automate the project drudgery. Have them produce makefiles, shell scripts, editor templates, utility programs, and the like.
- Remember that teams are made up of individuals. Give each member the ability to shine in his or her own way. Give them just enough structure to support them and to ensure that the project delivers against its requirements.
- Civilization advances by extending the number of important operations we can perform without thinking. • Alfred North Whitehead