Pragmatic Programmer

Pragmatic Programmer - Quick Reference Guide

1. Care about your craft: Why spend your life developing software unless you care about doing it well?

2. Think! About your work: Turn off the autopilot and take control. Constantly critique and appraise your work.

3. Provide Options, don’t make lame excuses: Instead of excuses, provide options. Don’t say it can’t be done; explain what can be done.

4. Don’t live with broken windows: Fix bad designs, wrong, decisions, and poor code when you see them.

5. Be a catalyst for change: You can’t force change on people. Instead, show them how the future might be and help them participate in creating it.

6. Remember the big picture: Don’t get so engrossed in the details that you forget to check what’s happening around you.

7. Make quality a requirements issue: Involve your users in determining the project’s real quality requirements.

8. Invest regularly in your knowledge portfolio: Make learning a habit.

9. Critically analyze what you read and hear: don’t be swayed by vendors, media hype, or dogma. Analyze information in terms of you and your project.

10. It’s both what you say and the way you say it: There’s no point in having great ideas if you communicate them effectively.

11. DRY – don’t repeat yourself: Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.

12. Make it easy to use: If it’s easy to reuse, people will. Create an environment that supports reuse.

13. Eliminate effects between unrelated things: design components that are self contained, independent, and have single, well-defined purpose.

14. There are no final decisions: no decision is cast in stone. Instead, consider each as being written in the sand at the beach, and plan for change.

15. Use tracer bullets to find the target: tracer bullets let you home in on your target by trying things and seeing how close they land.

16. Prototype to learn: prototyping is a learning experience. Its value lies not in the code you produce, but in the lessons you learn.

17. Program close to the problem domain: design and code in your user’s language.

18. Estimate to avoid surprises: estimate before you start. You’ll spot potential problems up front.

19. Iterate the schedule with the code: use experience you gain as you implement to refine the project time scales.

20. Keep knowledge in plain text: Plain text won’t become obsolete. It helps leverage your work and simplifies debugging and testing.

21. Use the power of command shells: use the shell when graphical user interfaces don’t cut it.

22. Use a single editor well: the editor should be an extension of your hand: make sure your editor is configurable, extensible, and programmable.

23. Always use source code control: source code control is a time machine for your work – you can go back.

24. Fix the problem, not the blame: It doesn’t really matter whether the bug is your fault or someone else – it is still your problem, and it still needs to be fixed.

25. Don’t panic when debugging: take a deep breath and think! About what could be causing the bug.

26. “select” Isn’t broken: it is rare to find a bug in the OS or the compiler, or even a third-party product or library. The bug is most likely in the application.

27. Don’t assume it – prove it: Prove your assumptions in the actual environment with real data and boundary conditions.

28. Learn a text manipulation language: you spend a large part of each day working with text. Why not have the computer do some of it for you?

29. Write code that writes code: code generators increase your productivity and help avoid duplication.

30. You can’t write perfect software: Software can’t be perfect. Protect your code and users from the inevitable errors.

31. Design with contracts: use contracts to document and verify that code does no more and no less than it claims to do.

32. Use assertions: a dead program normally does a lot less damage than a crippled one.

33. Use assertions to prevent the impossible: assertions validate your assumptions. Use them to protect your code from an uncertain world.

34. Use exceptions for exceptional problems: exceptions can suffer from all the readability and maintainability problems of classic spaghetti code.

35. Finish what you start: where possible, the routine or object that allocates a resource should be responsible for deallocating it.

36. Minimize coupling between modules: avoid coupling by writing “shy” code and applying the law of Demeter.

37. Configure, don’t integrate: Implement technology choices for an application as configuration options, not through integration or engineering.

38. Put abstractions in code, details in metadata: program for the general case, can put the specifics outside the compiled code base.

39. Analyze workflow to improve concurrency: exploit concurrency in your user’s workflow.

40. Design using services: Design in terms of services – independent, concurrent objects behind well-defined, consistent interfaces.

41. Always design for concurrency: allow for concurrency, and you’ll design cleaner interfaces with fewer assumptions.

42. Separate views from models: gain flexibility at low cost by designing your application in terms of models and view.

43. Use blackboards to coordinate workflow: use blackboards to coordinate disparate facts and agents, while maintaining independence and isolation with a purposeful plan.

44. Don’t program by coincidence: rely only on reliable things. Beware of accidental complexity, and don’t confuse a happy coincidence with a purposeful plan.

45. Estimate the order of your algorithms: get a feels for how long tings are likely to take before your write code.

46. Test your estimates: mathematical analysis of algorithms doesn’t tell you everything. Try timing your code in its target environment.

47. Refactor early, refactor often: just as you might weed and rearrange a garden, write, rewrite, rework , and rearchitect code when it needs it. Fix the root of the problem.

48. Design to test: start thinking about testing before your write a line of code.

49. Test your software, or your users will: test ruthlessly. Don’t make your users find bugs for you.

50. Don’t use wizard code you don’t understand: wizards can generate reams of code. Make sure you understand all of it before your incorporate it into your project.

51. Don’t gather requirements – dig for them: Requirements rarely lie on the surface. They’re buried deep beneath layers of assumptions, misconceptions, and politics.

52. Work with a user to think like a user: It’s the best way to gain insight into how the system will really be used.

53. Abstractions live longer than details: Invest in the abstraction, not the implementation. Abstractions can survive the barrage of changes from different implementations and new technologies.

54. Use a project glossary: create and maintain a single source of all the specific terms and vocabulary for a project.

55. Don’t think outside the box – find the box: When faced with an impossible problem, identify the real constraints. Ask yourself: “Does it have to be done this way? Does it have to be done at all?”

56. Start when you’re ready: you’ve been building experience all your life. Don’t ignore niggling doubts.

57. Some things are better done than described: don’t fall into the specification spiral – at some time you need to start coding.

58. Don’t be a slave to formal methods: don’t blindly adopt any technique without putting it into the context of your development practices and capabilities.

59. Costly tools don’t produce better designs: beware of vendor hype, industry dogma, and the aura of the price tag. Judge the tools on their merits.

60. Organize teams around functionality: don’t separate designers from coders, testers from data modelers. Build teams the way you build code.

61. Don’t use manual procedures: A shell script or batch file with execute the same instructions, in the same order, time after time.

62. Test early, test often, test automatically: tests that run with every build are much more effective that test plans that sit on a self.

63. Coding ain’t done until all the tests run: enough said.

64. Use test cases in your testing: In a separate copy of the source have a set of regression tests to verify that testing testing will catch the bugs.

65. Test state coverage, not code coverage: Identify and test significant program states. Just testing lines of code isn’t enough.

66. Provide an incident management database to find bugs once: Once a human tester finds a bug, it should be the last time a human tester finds a bug. Automatics tests should check for it from then on.

67. English is just a programming language: write documents as you write code: honor the dry principle, use metadata, mvc, automatic generations, and so on.

68. Build documentation in, don’t bolt it on: documentation created separately from code is less likely to correct and be up to date.

69. Gently exceed your user’s expectations: come to understand your user’s expectations, then deliver just that little more.

70. Sign your work: craftsmen of an earlier age were proud to sign their work. You should be, too.