Skip to content

Instantly share code, notes, and snippets.

@neenjaw
Last active July 2, 2023 01:09
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save neenjaw/cd3baab1caed364fcf97385299224063 to your computer and use it in GitHub Desktop.
Save neenjaw/cd3baab1caed364fcf97385299224063 to your computer and use it in GitHub Desktop.
Notes for The Pragmatic Programmer

The Pragmatic Progammer

Tips

  1. Care about your craft
  2. Think! About your work
  3. You Have Agency
  4. Provide Options, Don't Make Lame Excuses
  5. Don't Live with Broken Windows
  6. Be a Catalyst for Change
  7. Remember the Big Picture
  8. Make Quality a Requirements Issue
  9. Invest Regularly in Your Knowledge Portfolio
  10. Critically Analyze What you Read and Hear
  11. English is just another programming language
  12. It's Both What You Say and the Way You Say It
  13. Build Documentation in, don't bolt it on
  14. Good Design is Easier to Change than Bad Design
  15. DRY -- Don't Repeat Yourself
  16. Make it Easy to Reuse
  17. Eliminate Effect Between Unrelated Things
  18. There are No Final Decisions
  19. Forgo Following Fads
  20. Use Tracer Bullets to Find the Target
  21. Prototype to Learn
  22. Program close to the Problem domain
  23. Estimate to avoid surprises
  24. Iterate the schedule with the code
  25. Keep knowledge in plain text
  26. Use the power of command shells
  27. Achieve editor fluency
  28. Always use version control
  29. Fix the problem, not the blame
  30. Don't panic
  31. Failing test before fixing code
  32. Read the damn error message
  33. "Select" isn't broken
  34. Don't assume it -- prove it
  35. Learn a text manipulation language
  36. You can't write perfect software
  37. Design with contracts
  38. Crash Early
  39. Use assertions to prevent the impossible
  40. Finish what you start
  41. Act locally
  42. Task small steps -- always
  43. Avoid Fortune-Telling
  44. Decoupled code is easier to write
  45. Tell, Don't Ask
  46. Don't chain [accessing] method calls
  47. Avoid global data
  48. If it's important enough to be global, wrap it in an API
  49. Programming is about code, but Programs are about data
  50. Don't heard state; Pass it around
  51. Don't Pay Inheritance Tax
  52. Prefer interfaces to Express Polymorphism
  53. Delegate to Services: Has-A Trumps Is-A
  54. Use Mixins to Share Functionality
  55. Parameterize Your App Using External Configuration
  56. Analyze Workflow to Improve Concurrency
  57. Shared State Is Incorrect State
  58. Random Failures Are Often Concurrency Issues
  59. Use Actors For Concurrency Without Shared State
  60. Use Blackboards to Coordinate Workflow
  61. Listen To Your Inner Lizard
  62. Don't Program by Coincidence
  63. Estimate the Order of your Algorithms
  64. Test Your Estimates
  65. Refactor Early, Refactor Often
  66. Testing Is Not About Finding Bugs
  67. A Test Is the First User of Your Code
  68. Build End-To-End, Not Top-Down or Bottom-Up
  69. Design to Test
  70. Test Your Software, or Your Users Will
  71. Use Property-based Tests to Validate Your Assumptions
  72. Keep It Simple and MInimize Attack Surfaces
  73. Apply Security Patches Quickly
  74. Name Well; Rename When Needed
  75. No One Knows Exactly What They Want
  76. Programmers Help People Understand What They Want
  77. Requirements Are Learned in a Feedback Loop
  78. Work with a User to Think Like a User
  79. Policy Is Metadata
  80. Use a Project Glossary
  81. Don't Think Outside the Box -- Find the Box
  82. Don't Go into the Code Alone
  83. Agile Is Not a Noun; Agile Is How You Do Things
  84. Maintain Small Stable Teams
  85. Schedule It to Make It Happen
  86. Organize Fully Functional Teams
  87. Do What Works, Not What's Fashionable
  88. Deliver When Users Need It
  89. Use Version Control to Drive Builds, Tests, and Releases
  90. Test Early, Test Often, Test Automatically
  91. Coding Ain't Done 'Til All the Tests Run
  92. Use Saboteurs to Test Your Testing
  93. Test State Coverage, Not Code Coverage
  94. Find Bugs Once
  95. Don't use Manual Procedures
  96. Delight Users, Don't Just Deliver Code
  97. Sign Your Work
  98. First, Do No Harm
  99. Don't Enable Scumbags

Goals

  • Learn at least one new language each year
  • Read a technical book each month
  • Read non-technical books too
  • Take classes
  • Participate in local user groups and meetings
  • Experiment with different environments
  • Stay Current

Ch 1 - Pragmatic Philosophy

  • think beyond the immediate problem
  • place problems in their larger context
  • take responsibility
    • instead of excuses, provide options
    • what can be done
  • embrace change
  • software entropy
    • Don't leave "broken windows"
    • neglect accelerates "software rot"
    • Things creep on us, specs drift feature by feature, patches change the code over time, accumulation of small things break moral and teams

Good-Enough Software

  • not sloppy or poorly produced
  • Allow users to be involved when it is 'Good-Enough'
    • Good software today is better than perfect software tomorrow
  • know when it is good enough

Your Knowledge Portfolio

  • knowledge and experience are most important professional assets

  • expiring, since it becomes out of date as new techniques, languages, and environments are dev'd

  • Invest Regularly

    • The habit is as important as the return
  • Diversify

    • The face of computing cahnges rapidly
  • Manage Risk

  • Buy Low, Sell High

  • Review and Rebalance

Critical Thinking

  • Ask the five whys
  • Who does this benefit
  • What's the context
  • Wehn or Where would this work?
  • Why is this a problem?

Communicate!

  • Know what you want to say

    • Plan it out, write an outline, refine
  • Know your audience

    • You're communicating only if you are conveying information.

    • Need to understand the needs, interests, and capabilities of your audience

                          -W-hat do you want them to learn?
            What is their -i-nterest in what you've got to say?
                      How -s-ophisticated are they?
                 How much -d-etail do they want?
      Whom do you want to -o-wn the information?
              How can you -m-otivate them to listen to you?
      
  • Choose your moment

    • When understanding audience, work out their needs
    • Listeners will be more receptive if relevant in time and content
  • Choose a style

  • Make it Look Good

  • Involve your audience

  • Be a Listener

  • Get Back to People

Ch. 2 - A Pragmatic Approach

Duplication

Four I's of Duplication:

  • Imposed Duplication -- feels like no choice but to duplicate.
    • Multiple representations
    • Documentation in code
    • Documentation and code
    • Language Issues
      • C and C++ have header files that duplicate the names and type information of eported variables
  • Inadvertant Duplication -- don't realize it
    • Line class example: initially had props for start, end, and length, but only need 2 of three to calcuate the third
  • Impatient duplication -- lazy and easier
    • "short cuts make for long delays"
  • Interdeveloper duplication

Orthogonality

  • Code independence or decoupling
  • Change in one area doesn't affect others (easier to change)

Benefits

Gain Productivity

  • Changes are localized, Simpler components
  • Promotes reuse
  • More functionality per unit of effort

Reduce Risk

  • Diseased sections of code are isolated
  • Reduces system fragility
  • Better tested
  • Not as tightly coupled to vendor/product/platform

Applications

Project Teams

  • overlap slows down teams because changes affect others
  • how to organize with well-defined responsibilities and minimal overlap
    • separate infrastructure from application

Design

  • Systems should be compose of a set of cooperating modules
  • Components organized into layers
  • layers only use abstractions provided by layers below it

Coding

  • Tips
    • Keep your code decoupled
      • Law of Demeter
    • Avoid Global data
      • Singleton Pattern is a way to share common data, but overuse can increasing unnecessary linkages
    • Avoid similar function
      • Strategy Pattern
  • Get into the habit of being constantly critical of your code

Testing

  • Unit testing is easier with orthagonal code

Reversability

  • Critical design decisions are usually not easily reversible.
  • Contingencies might arise causing you to have to change that decision.
  • Instead of thinling of them in stone, think of them as sand at the beach, a big wave can come and wipe them out at any time.

Flexible Architecture

  • Flexibility in:
    • Code
      • CORBA/REST technologies
    • Architecture
    • Deployment
      • Stand-alone, client-server, n-tier
    • Vendor integration
      • Use Well-defined, abstract interfaces

Tracer Bullets

  • tracer code evolves with the project
  • some times they don't hit their target, but we can learn something from that too

Advantages

  • Users get to see something working early
    • If have communicated what you are doing, users will be thrilled to see progress understanding its immaturity.
    • Helps tehm contribute as the project progresses, increasing buy-in
  • Developers build a structure to work in
    • Makes it easier to write more code if the end-to-end pattern is worked out
  • You have an integration platform
    • It creates an environment to add new code to, gradually integrating it
  • You have something to demonstrate
    • Let's you show off at a moments notice
  • You have a better feel for progress
    • Devs can tackle use cases one-by-one. When one is done, they move to the next.

Tracer Code versus Prototyping

  • prototypes explore specific aspects of the final system
  • prototypes are thrown away and recoded using the lessons learned
  • tracer code is lean but incomplete, forming a part of the final skeleton

Prototypes and Post-it Notes

  • prototype things that carry risk
    • architectures
    • new functionality in existing systems
    • structure or contents of external data
    • 3rd party tools/components
    • performance issues
    • UI design

How to use Prototypes

What to ignore when building:

  • Correctness (use dummy data where appropriate)
  • Completeness (may function in very limited sense)
  • Robustness (Error checking incomplete/missing)
  • Style (lack comments and/or documentation)

Prototyping Architecture

Looking for is how the system hangs together as a whole, deferring details:

  • Are the responsibilities of the major components well defined?
  • Is coupling minimized?
  • Can you identify sources of duplication?
  • Are interface definitions and constraints acceptable?
  • Does every module have an access path to the data it needs during execution?
  • Does it have that access when it needs it?

How not to use prototypes

  • Everyone needs to understand that this code is disposable

Domain Languages

  • Domain languages allow you to capture business logic close to the problem space

Implementing a Mini-Language

  • YACC/Bison
  • JavaCC
  • Say (Python)

Data Languages and Imperative Languages

  • Data Languages produce some form of data structure used by an application
    • e.g. configuration
  • Imperative Languages produce code to be executed

Stand-Alone and Embedded Languages

  • Mini-lanuges doesn't have to be used directly by the application to be useful.

Estimating

How accurate is accurate enough?

  • Do they need high accuracy or a ballpark figure?
  • What the value of p?

Where do estimates come from?

Tip: Ask someone who has done this before. How long did it take them?

  • all estimates are based on models of the problem.
  • understand what is being asked
    • scope of the domain
  • build a model of the system
    • rough picture of the implemetations
    • steps that the organization uses during development
    • creative process
      • leads to discoveries of underlying patterns and processes that werent initially apparent
    • models inherantly introduce inaccuracies into the estimating process
      • inevitable and beneficial
  • break the model into components
  • give each parameter a value
  • calculate the answers
  • keep track of your estimating prowess

Estimating project schedules

  • check requirements
  • analyze risk
  • design, implement, integrate
  • validate with the users

What to say whyen asked for an estimate

I'll get back to you

  • switch need to always have default
  • A dead program normally does a lot less damage than a crippled one
  • use assertions **
    • leave them on in production
  • separate methods that are tightly coupled are not better separate (pg 121 example)
  • allocate, use, deallocate
  • code that allocates is responsible to deallocate
  • deallocate in opposite order to not leave orphans

Bend, or Break

  • Signs of coupling:

    • Wacky dependencies between unrelated module sor libraries
    • "Simple" changes to one module that propagate through unrelated modules in the system or break stuff elsewhere in the system
    • Devs who are afraid to change code because aren't sure what might be affected
    • meetings everyone has to attend because no one is sure who will be affected
  • Train wrecks (chains of method calls)

    • code that "knows" about the deep format of objects and other code and read/writes to them
    • don't reach deep into an object to ask for information, tell the object to perform an operation
    • law of demeter
      • class should only call:
        • other instance methods in C
        • its parameters
        • methods in objects hat it creates, both on the stack an din ghte heap
        • global vars
  • The evils of globalization

    • globals couple all code to eachother
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment