The Pragmatic Programmer: Your Journey to Mastery, 20th Anniversary Edition
Rate it:
Open Preview
3%
Flag icon
Care About Your Craft We feel that there is no point in developing software unless you care about doing it well.
4%
Flag icon
“Kaizen” is a Japanese term that captures the concept of continuously making many small improvements.
4%
Flag icon
As Martin Fowler says, “you can change your organization or change your organization.”[3]
5%
Flag icon
When disorder increases in software, we call it “software rot.” Some folks might call it by the more optimistic term, “technical debt,” with the implied notion that they’ll pay it back someday. They probably won’t.
5%
Flag icon
Don’t leave “broken windows’’ (bad designs, wrong decisions, or poor code) unrepaired. Fix each one as soon as it is discovered. If there is insufficient time to fix it properly, then board it up. Perhaps you can comment out the offending code, or display a “Not Implemented” message, or substitute dummy data instead. Take some action to prevent further damage and to show that you’re on top of the situation.
6%
Flag icon
Work out what you can reasonably ask for. Develop it well. Once you’ve got it, show people, and let them marvel. Then say “of course, it would be better if we added…’’ Pretend it’s not important. Sit back and wait for them to start asking you to add the functionality you originally wanted. People find it easier to join an ongoing success. Show them a glimpse of the future and you’ll get them to rally around.
8%
Flag icon
Learn at least one new language every year Different languages solve the same problems in different ways. By learning several different approaches, you can help broaden your thinking and avoid getting stuck in a rut.
8%
Flag icon
Read a technical book each month
8%
Flag icon
It’s not just what you’ve got, but also how you package it. Having the best ideas, the finest code, or the most pragmatic thinking is ultimately sterile unless you can communicate with other people. A good idea is an orphan without effective communication.
9%
Flag icon
English is Just Another Programming Language
9%
Flag icon
Probably the most difficult part of the more formal styles of communication used in business is working out exactly what it is you want to say.
9%
Flag icon
Plan what you want to say. Write an outline. Then ask yourself, “Does this communicate what I want to express to my audience in a way that works for them?” Refine it until it does.
9%
Flag icon
Make what you’re saying relevant in time, as well as in content. Sometimes all it takes is the simple question, “Is this a good time to talk about…?’’
9%
Flag icon
Too many developers (and their managers) concentrate solely on content when producing written documents. We think this is a mistake. Any chef (or watcher of the Food Network) will tell you that you can slave in the kitchen for hours only to ruin your efforts with poor presentation.
9%
Flag icon
After awl, their are spelling miss steaks that the chequer can knot ketch.
Alexander Bandukwala
Kill me
9%
Flag icon
There’s one technique that you must use if you want people to listen to you: listen to them.
9%
Flag icon
Always respond to emails and voicemails, even if the response is simply “I’ll get back to you later.’’
9%
Flag icon
Build Documentation In, Don’t Bolt It On It’s easy to produce good-looking documentation from the comments in source code, and we recommend adding comments to modules and exported functions to give other developers a leg up when they come to use it.
Alexander Bandukwala
How can we make documentation and literate programming feel more natural?
9%
Flag icon
So restrict your non-API commenting to discussing why something is done, its purpose and its goal. The code already shows how it is done, so commenting on this is redundant—and is a violation of the DRY principle.
10%
Flag icon
Keep code and documentation together.
Alexander Bandukwala
We need a way to do this while allowing non-technical docentation to link to implementation
10%
Flag icon
Keep quoting to a minimum. No one likes to receive back their own 100-line email with “I agree” tacked on.
10%
Flag icon
The Mythical Man-Month: Essays on Software Engineering [Bro96] and Peopleware: Productive Projects and Teams [DL13]. Make it a point to try to read these over the next 18 months. In addition, Dinosaur Brains: Dealing with All Those Impossible People at Work [BR89] discusses the emotional baggage we all bring to the work environment.
10%
Flag icon
Good Design Is Easier to Change Than Bad Design
Alexander Bandukwala
Malleability and changeability seem to be intimately related
11%
Flag icon
Also think about languages and programming paradigms (OO, FP, Reactive, and so on). Do any have either big positives or big negatives when it comes to helping you write ETC code? Do any have both?
11%
Flag icon
maintenance is not a discrete activity, but a routine part of the entire development process.
11%
Flag icon
Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.
11%
Flag icon
DRY is about the duplication of knowledge, of intent. It’s about expressing the same thing in two different places, possibly in two totally different ways.
14%
Flag icon
Our data structures represent knowledge, and they can fall afoul of the DRY principle.
15%
Flag icon
This example also illustrates an important issue: whenever a module exposes a data structure, you’re coupling all the code that uses that structure to the implementation of that module. Where possible, always use accessor functions to read and write the attributes of objects. It will make it easier to add functionality in the future.
Alexander Bandukwala
This is because the functions and data are coupled together
15%
Flag icon
Meyer’s Uniform Access principle, described in Object-Oriented Software Construction [Mey97]
15%
Flag icon
All services offered by a module should be available through a uniform notation, which does not betray whether they are implemented through storage or through computation.
Alexander Bandukwala
I think this means you dont need to know if i cached it. But it could mean a lot more. Not sure if its mainly about syntax or also semantics
15%
Flag icon
There’s another option, and one we often prefer. Rather than writing code that represents external data in a fixed structure (an instance of a struct or class, for example), just stick it into a key/value data structure (your language might call it a map, hash, dictionary, or even object). On its own this is risky: you lose a lot of the security of knowing just what data you’re working with. So we recommend adding a second layer to this solution: a simple table-driven validation suite that verifies that the map you’ve created contains at least the data you need, in the format you need it. Your ...more
15%
Flag icon
However, at the module level, the problem is more insidious. Commonly needed functionality or data that doesn’t fall into an obvious area of responsibility can get implemented many times over.
Alexander Bandukwala
Auto suggestions and search by type address this. Being intentional about the contract and programmatically expose it.
15%
Flag icon
What you’re trying to do is foster an environment where it’s easier to find and reuse existing stuff than to write it yourself. If it isn’t easy, people won’t do it. And if you fail to reuse, you risk duplicating knowledge.
Alexander Bandukwala
Encourage composition to increase velocity
15%
Flag icon
“Orthogonality’’ is a term borrowed from geometry. Two lines are orthogonal if they meet at right angles, such as the axes on a graph. In vector terms, the two lines are independent.
16%
Flag icon
(what Yourdon and Constantine call cohesion in Structured Design: Fundamentals of a Discipline of Computer Program and Systems Design [YC79]).
16%
Flag icon
You get two major benefits if you write orthogonal systems: increased productivity and reduced risk.
16%
Flag icon
It is easier to write relatively small, self-contained components than a single large block of code.
Alexander Bandukwala
Composability
16%
Flag icon
An orthogonal approach also promotes reuse. If components have specific, well-defined responsibilities, they can be combined with new components in ways that were not envisioned by their original implementors. The more loosely coupled your systems, the easier they are to reconfigure and reengineer.
16%
Flag icon
An orthogonal system will probably be better tested, because it will be easier to design and run tests on its components.
16%
Flag icon
Alexander Bandukwala
I really question if these layers are orthogonal or if we’d be better with vertical slices
16%
Flag icon
Don’t rely on the properties of things you can’t control.
16%
Flag icon
The Enterprise Java Beans (EJB) system is an interesting example of orthogonality. In most transaction-oriented systems, the application code has to delineate the start and end of each transaction. With EJB, this information is expressed declaratively as annotations, outside the methods that do the work. The same application code can run in different EJB transaction environments with no change.
16%
Flag icon
Avoid global data Every time your code references global data, it ties itself into the other components that share that data.
17%
Flag icon
Perhaps surprisingly, orthogonality also applies to documentation. The axes are content and presentation. With truly orthogonal documentation, you should be able to change the appearance dramatically without changing the content. Word processors provide style sheets and macros that help. We personally prefer using a markup system such as Markdown: when writing we focus only on the content, and leave the presentation to whichever tool we use to render it.[17]
Alexander Bandukwala
I’m not convinced content and presentation are orthogonal
17%
Flag icon
C++ supports multiple inheritance, and Java allows a class to implement multiple interfaces. Ruby has mixins. What impact does using these facilities have on orthogonality? Is there a difference in impact between using multiple inheritance and multiple interfaces? Is there a difference between using delegation and using inheritance?
17%
Flag icon
What are the differences in orthogonality between object-oriented and functional languages? Are these differences inherent in the languages themselves, or just in the way people use them?
18%
Flag icon
While many people try to keep their code flexible, you also need to think about maintaining flexibility in the areas of architecture, deployment, and vendor integration.
19%
Flag icon
Tracer code is not disposable: you write it for keeps. It contains all the error checking, structuring, documentation, and self-checking that any piece of production code has. It simply is not fully functional. However, once you have achieved an end-to-end connection among the components of your system, you can check how close to the target you are, adjusting if necessary. Once you’re on target, adding functionality is easy.
20%
Flag icon
But if you find yourself in an environment where you cannot give up the details, then you need to ask yourself if you are really building a prototype at all. Perhaps a tracer bullet style of development would be more appropriate in this case (see Topic 12, ​Tracer Bullets​).
« Prev 1 3 4