- A Pragmatic Philosophy
- Intro
- think about big picture
- context lets you know how good software needs to be
- you work with people so communicate!
- The cat ate my source code
- Don’t be afraid to admit ignorance or error
- Must actively agree to responsibility but will be held accountable
- Should nota agree if impossible or extremely high risk
- Provide options not just excuses
- software entropy
- broken window theory
- fix something as soon as its discovered or take some action to prevent further damage
- neglect can accelerate rot
- if everything is pristine, others will try extremely hard to not be first one to make a mess
- stone soup and boiled frogs
- act as catalyst for change, there is startup inertia
- start with something you can reasonably ask for
- do it well and let people marvel and request for features you wanted to do anyway
- don’t get caught up in small details and let things snowball out of control
- good enough software
- quality depends on requirements
- usually better to have working version sooner and get in front of users
- getting early feedback will allow eventual solution to be better
- know when to stop
- knowledge portfolio
- invest regularly
- diversify
- balance conservative with high risk
- buy low / sell high
- rebalance
- learn one language a year
- read a technical book once a quarter or month
- take classes
- participate in user groups
- experiment with different environments
- process of learning expands thinking and opens new ways of doing things. cross pollination of ideas is important
- if you don’t know something track down the answer or someone who does
- think critically about what you read. different people have different motivations (commercial)
- communicate
- having best ideas doesn’t matter if you can’t communicate them
- make sure you are getting across what you want
- know your audience and form a strong mental picture
- use appropriate pitch for appropriate group
- make it look good / great content can be ruined by poor presentation
- involve audience in early draft / process can be just as important
- listen even if you have all the info
- follow up with people
- A Pragmatic Approach
- The Evils of Duplication
- requirements and the world are constantly changing
- duplication causes maintenance nightmares
- DRY: every piece of knowledge must have a single unambiguous, authoritative representation within a system
- If you don’t DRY, will be required to make changes in multiple places and you will forget
- Imposed duplication
- may have shared structure across languages / can use code generator from common meta data representation
- documentation
- Inadvertent Duplication
- mistakes
- unnormalized data
- use calculated field if you can
- use accessors to read or write so you can modify implementation details
- Inpatient duplication / shortcuts make for longer delays
- Inter-developer duplication: need strong technical lead, someone who can facilitate knowledge, make things easy to reuse
- Orthogonality
- represent independence / decoupling
- changes in one module or component shouldn’t affect others
- increased productivity because small / localized and no need to change existing code
- promotes reuse and more functionality per unit of effort
- isolate bad code
- system less fragile
- easier to design and test
- not as tightly coupled to outside vendors or 3rd party libraries
- non-orthogonal teams results in confusion over responsibilities
- separate components e.g. infrastructure, db, application, etc
- to measure: see how many people are needed when discussing a change
- if you have to drag large parts of your system to test a component, it’s probably not decoupled
- orthogonal systems are easier to debug, test and maintain
- if people are struggling to make changes, time to refactor
- Reversibility
- usually in projects, critical decisions are not easily reversible
- have to assume things constantly change
- there are no final decisions / always plan for contingencies
- try to keep architecture pliable
- Tracer Bullets
- Can plan and spec to death
- try to get immediate feedback
- provides structure, get early feedback, demo-able, feel progress
- easy to change when small
- working but no fully functional
- Prototypes and post-it notes
- try out idea without committing
- designed to answer a few questions
- is about learning
- can prototype architecture on whiteboard
- code is disposable
- Domain Languages
- Lets you program closer to problem domain
- data language produces some data structure
- imperative language is executed
- simple language might be easier to write but less flexible
- language with more complex grammar harder to implement but more extendable and easier for people to understand
- Estimating
- can give you an idea of feasibility
- context matters for accuracy
- break models into components and understand critical components
- run multiple cases and get ranges
- make iterations a formal part of estimates. If you don’t and try to do everything up front, you are guessing
- Basic Tools
- Power of Plain Text
- Knowledge is base material for programmer
- plain text best format for storing
- plain text is self-describing and will outlive application
- more portable across environments
- easier to modify, test data, and analyze diffs
- is common standard
- Shell Games
- Can invoke commands for manipulating files of text
- might be obscure and terse but powerful and concise
- invest energy and will become more productive
- Power Editing
- Need to be able to modify text effortlessly
- Better to know one editor well
- should be configurable, extensible, programmable
- can streamline many common operations
- Source Code Control
- gives you serious undo capability as well as tracking changes by who
- can manage branches and work concurrently
- can track in central repository
- always use source control
- make builds automatic and repeatable
- can run regression tests
- Debugging
- Think about is as a problem solving activity
- doesn’t matter who introduced it, it’s your problem
- Think about what could be causing problems, may be a few steps removed from where you are observing
- try to reproduce and figure out what is going on
- tracing can help you step through a program
- try rubber ducking
- usually your application code is the issue
- re evaluate your assumptions, don’t assume, prove correctness
- determine why not caught earlier and think if other areas are susceptible
- Text Manipulating
- unix like awk or sed
- python, perl, or ruby
- Code Generators
- To avoid duplication across contexts can have a language agnostic representation
- passive: generate once
- active: consistently reproduced from a source
- Pragmatic Paranoia
- Intro
- No one can write perfect software
- Can waste time and resource for an impossible dream
- pragmatic programmers don’t trust themselves either
- Design by contract
- define rights and responsibilities
- pre-conditions: routine should never get called with incorrect input
- postcondition: what routine is guaranteed to do
- class invariants: check conditions will always be true when routine exits
- be strict with inputs and promise as little as possible
- Dead Programs Tell No Lies
- things can go wrong
- if you run into an impossible scenario exit early
- Assertive Programming
- Programmers often think things can’t happen
- Use assertions to ensure they won’t
- dev/test environments may be different from production
- for performance, make ones affecting performance optional
- When to use exceptions
- can make normal flow of control more clear
- should be rarely used
- should be able to remove and run fine under normal circumstances
- using for normal processing breaks encapsulation and makes more tightly coupled
- How to balance resources
- routine that allocates resources should free it
- deallocate resources in opposite order in which you allocate
- when allocating same resources, always allocate in same order to avoid deadlocks
- write modules that provide standard allocation and deallocation facilities for structures
- check that resources are freed appropriately
- Bend or Break
- Decoupling and the law of demeter
- should not reach into multiple classes
- ask for what you need directly
- call methods that belong to itself, param, obj it created
- code is more adaptable but at cost of wrapper methods that forward requests
- Meta programming
- good to make systems highly configurable
- put specifics in meta data
- forces decoupled design
- can even put business logic in a flexible format
- Temporal coupling
- sequential instructions are not always realistic
- think about actions that can be performed in parallel
- design for concurrency
- results in cleaner design and interfaces
- can keep standalone or scale up
- It’s just a view
- pub/sub can be used to let objects receive messages
- mvc: model shouldn’t know about controller or view
- can connect multiple views to a model or a common view to multiple models
- Blackboards
- distributed data gathering process
- decouple objects from each other
- removes need for multiple interfaces
- if too complex, partition
- While you are coding
- Programming by coincidence
- need to know why code is working
- for code others will call, hide implementation details
- need well-specified contract
- for routines you call, rely on doc behavior
- if you can’t, document your assumptions
- proceed with a plan and if you can’t tell if its circumstance assume the worst
- test / assert your assumptions
- all code can be replace or refactored
- Algorithm Speed
- estimations around time, processor and memory
- big o notation shows how it scales as function of input
- O(n) loops
- O(m*n) nested
- O(log n) binary
- O(n log n) divide and conquer
- O(n!) combinatorial
- estimate and test them
- make sure the algorithm is the bottleneck before investing precious time
- Refactoring
- programming is more organic like gardening vs construction
- refactor when there is duplication, nonorthogonal design, outdated knowledge, performance
- need to understand its about removing issues when they are small and easy to fix before blows up
- refactor early and often
- don’t refactor and add functionality at the same time
- takes short deliberate steps
- Code that’s easy to test
- build testability into software from beginning and test each piece thoroughly
- check 1) meets contract 2) contract is what we think it is
- test subcomponents so you can concentrate on likely sources of problems
- tests should be conveniently located
- tests also act as examples of functionality
- testing frameworks allow
- setup/cleanup
- selecting individual or all
- analyzing output
- std failure reporting
- test window: access to logs, status or even debug control panel
- testing is more cultural than technical
- Evil Wizards
- must be wary of code generators
- need to understand what they generate
- they become an integral part of the application and are interwoven into the functionality we write
- must be able to maintain and adapt
- Before the project
- The Requirements Pit
- requirements may be buried in deep layers of assumptions, misconceptions, and politics
- could require digging
- system should be well factored to support meta data
- work with users to think like them or become a user
- think of use cases
- use whatever method best communicates to your audience
- good requirements are abstract they represent a need
- abstractions live longer than details
- track requirements and changes (feature creep) and who is responsible for each
- maintain a project glossary
- Solving Impossible Puzzles
- understand absolute constraints vs preconceived notions
- need to recognize the degrees of freedom you have
- don’t think outside the box, find the box
- don’t dismiss anything. if you are certain a path can’t be taken, prove it
- reinterpreting requirements can make a whole set of problems go away
- is there easier way?
- is this the right problem?
- why is it a problem?
- what is making this hard?
- does it have to be done this way?
- does it have to be done at all?
- Not until you’re ready
- if you having nagging doubts about starting could be instincts telling you something is not right
- Try prototyping
- if you feel like you are wasting time, get started on real development
- otherwise, you may discover a premise was wrong
- Specification trap
- impossible to capture every detail / nuance of a system
- if no room in specification, implementation can’t adapt and provide inform design
- some things are better done than described
- main thing is the delivery of a quality system
- Circles and arrows
- many methodologies try to come up with a precise process
- don’t blindly follow
- don’t be a slave to formal methods
- charts/diagrams are meaningless to end users
- focus on getting them a prototype
- formal methods encourage specialization
- formal methods may not be dynamic
- there are costs with adopting new tools / methods
- evaluate each method critically and take the best from each
- Pragmatic Projects
- Pragmatic teams
- Quality is a team issue
- no broken windows
- make sure everyone actively monitors the environment for changes
- team must communicate within and outside of groups / have a brand
- avoid duplication / organize by functionality
- automate things / appoint a tool builder
- Ubiquitous Automation
- don’t use manual procedures
- use things like makefiles for compilation
- automate builds and run full tests
- push documentation to web automatically
- Ruthless testing
- test early, test often, test automatically
- unit tests, integration tests
- try under real world conditions and environments
- GUI: if decoupled application logic can be tested separately
- test tests
- think in terms of number of states not just code coverage
- run automatically or schedule tests if they can’t be
- add new tests for each bug / should only find a bug once
- It’s all writing
- make documentation an integral part of development process
- code comment should explain why not how
- don’t use misleading names
- don’t have multiple sources of truth
- can generate other files from one
- make things easily publishable
- Great expectations
- need to communicate and manage expectations
- users should have accurate view and understanding of development process, what is possible and what they will get
- don’t just meet expectation, go above and beyond
- think of easy features that will delight
- Pride and prejudice
- don’t shirk from responsibility / accept challenges
- sign your work / accountability / ownership
- anonymity can breed sloppiness, mistakes, and bad code
- stand by your work
Like this:
Like Loading...