Wednesday, October 05, 2011

Book: The Pragmatic Programmer

"The Pragmatic Programmer", Hunt, A., Thomas, D., 1999, 321 pages is mainly about the practical technical aspects of programming like "don't repeat yourself (DRY) Principle". It also gives advice on how to improve yourself in general by recommending constant learning. A good book for people interested in software development.

My underlinings:

[p.127] Use exceptions for exceptional problems... an exception represents an immediate, nonlocal transfer of control-it's kind of cascading goto. Programs that use exceptions as part of their normal processing suffer from all the readibility and maintainability problems of classic spaghetti code.

[p.139-142] You want to let your users select a recorder and plot its data, labeled with the correct time zone. You might write
public void plotDate(Date aDate, Selection aSelection) {
TimeZone tz = aSelection.getRecorder().getLocation().getTimeZone();
...
}
But now the plotting routine is unnecessarily coupled to three classes-Selection, Recorder and Location. This style of coding dramatically increases the number of classes on which our class depends. Why is this a bad thing? It increases the risk that an unrelated change somewhere else in the system will affect your code. For instance, if Fred makes a change to Location such that it no longer directly contains a TimeZone, you have to change your code as well.
Rather than digging through a hierarchy yourself, just ask for what you need directly:
public void plotDate(Date aDate, TimeZone aTz) {
...
}
plotDate(someDate, someSelection.getTimeZone());
We added a method to Selection to get the time zone on our behalf: the plotting routine doesn't care whether the time zone comes from the Recorder directly, from some contained object within Recorder, or whether Selection makes up a different time zone entirely. The selection routine, in turn, should probably just ask the recorder for its time zone, leaving it up to the recorder to get it from its contained Location object.
Traversing relationships between objects directly can quickly lead to a combinatorial explosion of dependency relationships.
...The Law of Demeter for functions attempts to minimize coupling between modules.
...Using the Law of Demeter will make your code more adaptable and robust but at a cost: as a "general contractor," your module must delegate and manage any and all subcontractors directly, without involving clients or your module. In practice, this means that you will be writing a large number of wrapper methods that simply forward the request on to a delegate. These wrapper methods will impose both a runtime cost and a space overhead, which may be significant-even prohibitive-in some applications.

[p.145] ...program for the general case, and put the specifics somewhere else-outside the compiled code base. Put abstractions in code, details in metadata.
...You can customize the application without recompiling it.
...Metadata can be expressed in a manner that's much closer to the problem domain than a general purpose programming language might be.
...Because business policy and rules are more likely to change than any other aspect of the project, it makes sense to maintain them in a very flexible format.

[p.157] ...a good definition of a module (or class) is that it has a single, well-defined responsibility.

[p.172] ...good, safe drivers are constantly reviewing the situation, checking for potential problems, and putting themselves into good positions in case the unexpected happens.

[p.175] At all levels, people operate with many assumptions in mind-but these assumptions are rarely documented and often in conflict between different developers. Assumptions that aren't based on well-established facts are the bane of all projects.

[p.186-187] 1.Don't try to refactor and add functionality at the same time.
2.Make sure you have good tests before you begin refactoring.
3...Make sure If you keep your steps small, and test after each step, you will avoid prolonged debugging.

[p.203] It's important to discover the underlying reason why users do a particular thing, rather than just the way they currently do it. At the end of the day, your development has to solve their business problem, not just meet their stated requirements.

[p.210] Create and maintain a project glossary-one place that defines all the specific terms and vocabulary used in a project. All participants in the project, from end users to support staff, should use the glossary to ensure consistency. This implies that the glossary should be widely accessible-a good argument for Web-based documentation...

[p.211] Web-based distribution also avoids the typical two-inch-thick binder entitled Requirements Analysis that no one ever reads and that becomes outdated the instant ink hits paper.

[p.221] Never underestimate the cost of adopting new tools and methods. Be prepared to treat the first projects using these techniques as a learning experience.

[p.232] We want to check out, build, test, and ship with a single command.

[p.238] Tests that run with every build are much more effective than test plans that sit on a shelf.

[p.249] In general, comments should discuss why something is done, its purpose and its goal. The code already shows how it is done, so commenting on this is redundant...
Remember that you (and others after you) will be reading the code many hundreds of times, but only writing it a few times. Take the time to spell out connectionPool instead of cp.

[p.261] ...Pragmatic Programmers sould always be learning.

music :
Haddaway - What is Love
Esma Redzepova - Caje Sukarije

No comments: