What is missing?

We have dozens more cards we can write and post, so were not running short on ideas even though we can be short on time to get them all written up. Still, I wonder, if you could pick the next card for me, what would you want it to be about? Is there an area we've not addressed at all? Topics of interest to you that might be interesting to others? Guest authors we should contact? I'm all ears.

Pairing Workstation Configuration


(font is SD Marker still)

Teams beginning to use pair-programming often struggle because of poor workstation configuration as they attempt to use their individual programming space. There is more to it than merely adding a second chair. Take a moment to review Pair Programming Smells and recall that there are physical limitations as well as psychological limitations to overcome.

  • Chairs sit comfortably side-by-side so developers can have equal access. If either person is physically limited from grabbing the keyboard and mouse, then the setup is wrong. Pair programming is about sharing the editing of code together. It is necessary that both have equal access. Beware corners: if you have a monitor in desk/cubicle corner, then necessarily one person has better access than the other and pairing breaks down.
  • Add an extra monitor (or two!), preferably a nice, thin LCD or plasma screen. An extra monitor can be placed where the pair members can both see it equally well. A thin screen doesn't need a desk corner. Also, all of the annoying popups (mail, chat, etc) can be placed on the monitor where the code is not displayed, where it can be ignored. Finally, it is useful to run a countdown timer on one screen while programming on the other, to enable pomodoro-like techniques. Pairing is best done in time boxes with regular breaks.
  • Get some USB keyboard(s) for pairing. You should have a comfortable keyboard with a long cord. If one of you requires/prefers an ergonomic keyboard, then carrying around their favorite keyboard is a reasonable concession.
  • One mouse per keyboard is best. This is again about equal access for editing.
  • Get docking stations for notebook computers because shoving the computer back and forth is a pain, and because docking stations can give you extra USB ports and VGA ports. There really is not a lot of cost involved, and it really helps keep the pairing "fair".
  • Pens, scrap paper, and index cards should be in reach. You might be surprised how often you need to take a note now and come back as soon as the code is passing all the tests again. With two people, there are more ideas to choose from, and each learns tricks from the other. Writing things down allows each partner to process it when he is not pairing.
  • IDE/editor of choice with shared configuration is a contentious bit. We need to use the same tools if we are to have equal access for editing. In some teams, the emacs/vim/eclipse/scite wars will erupt, but it is better if the team chooses and all members learn to get by in the chosen environment. If they won't decide which editor to use, how are they going to make group decisions about design and architecture? It is better to learn use an "inferior" editor than to have to wrestle the editing environment from each other several times a session. When it comes to coding standards and standard editors, it is a good practice to "be a sport" and choose to make the team work better even if it will cost you a little in the short term.


  • Pair programming is not a utopian practice. Some people don't enjoy it at first, and some never warm up to it. Regardless, it makes the code better. If your team wants to make the code better through pair-programming, then it is important that their attempts are not hobbled by a poor workstation configuration. For a little bit of money, a leader can make a big difference in the way a company puts out software.

    SMART goals


    Font: Sterofidelic

    The best lists never die. The SMART mnemonic has been around for at least half a century, per Wikipedia. SMART is similar to INVEST, evaluating criteria for goals and objectives instead of for stories.


    SMART has generated many different word expansions over the years. Sometimes M is meaningful, manageable, or even motivational(!). Our Agile in a Flash card uses the supposedly preferred words. But as a result of this inconsistency, I struggled yesterday to recall the best choice for the letter R. "Realistic?" No, that's too close in meaning to attainable. A quick search revealed relevant (duh!). I supplanted my mild self-annoyance (at my inability to remember the better choice) with elation at the prospect for a new, relevant agile card!


    In the context of agile, I've found SMART goals to be useful when discussing action items to come out of retrospectives. True, there's no reason these couldn't be treated just like INVEST stories. But I've found that selling something half-a-century-tried-and-true can be a little easier with some crowds.


    Here are my thoughts about the relevance of the SMART criteria with respect to retrospectives.


    • Specific - Vague promises of improvement usually don't generate results. Think of the 5 W's: who, what, when, where, and why. Instead of "we'll try to get stories done earlier in the iteration," how about "the developers will deliver at least one story every two to three days to QA, who will complete testing of them within a day of delivery, so that we can ensure stories are 'done done' by iteration end." (And don't forget that "try" is a word you want to banish.)

    • Measurable - Attainment of our specific example goal might be validated by answering some questions: What was the average number of stories completed within two to three days? How many stories did not complete in this time? You can think of iterations as fixed time periods in which to run experiments; you can express a hypothesis that validates or disproves the value of each experiment by capturing relevant data.

    • Attainable - It's important that a team can check off completed goals, to reinforce the sense of achievement. Obviously goals that your team can complete in an iteration best meet this criterion, but you don't want to have only short-term goals. There's nothing wrong with long-term goals; just make sure there's a way to measure incremental progress.

    • Relevant - Too many trivial goals can give a bloated sense of achievement. Shortening daily stand-up meetings by limiting them to five minutes might seem beneficial, but does it really change anything? What's the real problem? Don't hesitate to attempt dramatic changes, and don't hesitate to think outside the box that pseudo-agile dogmatists might otherwise paint you in.

    • Time bound - Like stories, many teams tend to have a problem with letting things creep past iteration boundaries. "We just need a little more time." Set up the experiment, define completion and success criteria, and grade the experiment: it was either completed or abandoned, and the hypothesis either held true or was disproved.


    Get SMART today!

    Team Smells for Coaches




    Every agile coach will have a number of factors they monitor constantly. Many are barely aware of the "smells" they are looking for, but will have a constant awareness of issues that indicate that a transition is not progressing well. We provide a short list of common smells that indicate your agile project is not going as well as you hoped:

    • Heaping piles of unfinished work will appear when assigned work is not being finished as quickly as new work is being assigned. This is generally a problem when the velocity is not being respected. The Theory of Constraints tells us that we have to subordinate the business to the bottleneck, a simple idea which is very hard to sell. Work may pile up in development or QA, especially if it is also piled up in sales.

    • Individual work assignments are typical in non-agile shops, but agile developers team up and pair on production code. Managers may demand that individuals are assigned work prior to starting an iteration so that they may track the productivity of individuals. This is a disincentive for agile teams, because pairing with a colleague risks the work one is personally assigned. By pitting team members against each other in the fight for individual rankings, work assignments can destroy true productivity.

    • Back-channeling is occurring if certain interests outside the development team (Customer or outsider) go directly to programmers and give them individual work assignments. This prevents the programmer from applying his abilities to the completion of the iteration. It also damages true productivity as others are required to pick up the slack, and the targeted programmer is forced to task-switch unpredictably. Back-channeled communications are a complex flow with political complications that prevent a team from doing their best work. It is better to work with a simpler, transparent management and communication structure. Note that sometimes back-channeling is an attempt by a leader whose work has been de-prioritized to get it pushed through anyway in defiance of the management structure.

    • Blame-avoidance behaviors cause programmers to fear refactoring, redesign, and any important practice outside of a narrow job description. In fearful organizations, blame-avoidance prevents both productivity-wasting activities and productivity-enhancing activities. Fear is a reason to stay wrong, or at least to be right only in familiar ways.

    • The urge to matrix-manage the team is a result of a lack of trust in the team by outside forces. When pressure is on any team, the certain leaders may seek to control other teams. When managers from outside a team try to manage the team by force or fiat instead of through normal channels (planning, prioritizing, etc) then it is clear that there are unaddressed problems in the management chain. These problems need to be resolved before they break down the team.

    • Cargo-cult ceremonies are ceremonies carried out for the sake of the ceremony, rather than performed for good effect. Examples are planning ceremonies where estimates are not accepted and stories are not scoped to the iteration, scheduled retrospectives where no problems are really solved, iteration boundaries where work is carried over to the next iteration with full credit for "completion", etc. These are signs that the team is "seeming" agile, rather than "becoming" agile. It shows a lack of real change in values.

    • Test negligence is a particularly nasty sign of an team's lack of agility. It shows that work is not being done by testing, and any pairing that is occurring does not support the agile practice. Agile teams depend on copious automated tests to accelerate their production. If tests are not being written, or not being run, then the team is not going to expand its capacity to produce. It is common that this happens in conjunction with back-channeling and/or work piling up. Skipping testing is a time honored way to seem to cut corners while actually making the software harder and harder to modify.

    • Guarded speech is a sign that the real values and the spoken values of the team are not the same. It may be that the team is trying to be agile, but certain leaders or managers are not willing to hear it or else that the management is bought into Agile development and the developers are not buying it. It may be that there is some barrier to productivity that is being held in place by political or personal power of some leaders. Barriers to transparency tend to be political. It may be necessary to change the team's political situation so that they may work openly.

    Acceptance Tests



    Font: Complete In Him

    The word "acceptance" implies that we have a high level of confidence that we can ship quality product. The goal for acceptance tests is to provide self-verifying, self-documenting executing examples of how the system is intended to be used. In a rough sense, they are use cases taken to the next level.

    • Define “done done” for stories. The acceptance tests for a story provide a contract for completion. As programmers, we know we are truly done when the code passes all of the acceptance tests. As consumers of the system, we know we can accept it when all of its tests pass. Progress in an iteration is often best tracked by the number of acceptance tests passing.

    • Are automated. Our Automating Tasks card provides detailed recommendations on when and when not to automate. Most importantly, this directive doesn't preclude the existence of tests that aren't automated!

    • Document all uses of the system. Think about the tests as examples that demonstrate valid uses of the system. This mindset will help you develop tests that can be read and understood by people wanting to understand the system. Such documentation never becomes stale (although it requires good effort to design the tests to be so expressive).

    • Don't just cover "happy paths." Stories usually require a family of tests to comprehensively cover alternate cases and exceptional situations. Inevitably, you will ship a defect that an automated test would have prevented. This previously "missed" acceptance test now becomes part of the complete test suite.

    • Do not replace exploratory tests. We will always want some manual testing above and beyond the tests that define acceptance criteria for a new story. Exploratory testing highlights the more creative aspects of how a user might choose to interact with a new feature. It also helps teach testers how to improve their test design skills. Don't forget to knee test!

    • Run in a near-production environment. How many nickels have you earned for hearing the phrase "It worked fine on my machine!?" Acceptance tests must execute in an environment that emulates production as closely as possible. This means they hit a real database and external API calls, as much as possible. By definition, then, acceptance tests are slow.

      Still, minute to minute, I might want my suite of acceptance tests to run as fast as possible, as part of a continuous integration build. As a developer, I want rapid feedback, to provide high short-term confidence that I can move on. I know we'll still run the full suite in a proper environment overnight; having this fallback allows me to look at tactics such as using an in-memory database.

    • Are defined by the customer. Hopefully we know who the customer is. Agile acceptance tests are an expression of customer need (aka requirements). While all parties can contribute to statements of requirements, it's important that a "single customer voice" defines their interests as an unambiguous set of tests. (This also means that it's perfectly ok for a programmer to help with testing--they just can't be the one defining the tests.)



    I'm often asked, "what about regression tests?" Most people define regression tests as "tests that make sure we didn't break something already in the system." My answer is that they imagine we had built this entire system in an agile, acceptance-test-driven fashion, i.e. where we ship only code that passes pre-defined acceptance tests. In this world, regression testing can thus happen every iteration--we simply run the entire suite of automated tests for all stories delivered to date.

    Four Options for Agile Projects



    Source: Extreme Programming Explained, chapter 3, The Economics of Software Development.

    Kent Beck, et al, say that XP makes a lot of sense if you examine the options that it gives management. These options are less open to managers whose teams follow a more traditional, specification-heavy method, but become feasible with early and continual feedback.

    With XP, there is regular measurement of progress in running, tested features. Because running, tested, demo-ed features is a concrete and meaningful kind of completion, the data can be used as the basis for making decisions.

    This from www.dmst.aueb.gr:
    The theoretical basis for XP is an options-based pricing model of software development. As software is developed in an environment where technological, business, and human risk abounds, investing for the future through careful architectural design, elaborate code structures that will support all possible future requirements, and producing matching documentation can be a waste of effort. Changing requirements or technology may render parts of the system obsolete; design and coding energy expended in those parts will have been wasted. Kent Beck's insight lies in discounting elaborate design for future needs in favor of today's simplicity. Big and important design decisions are deferred until a particular feature is needed. Most important features are developed first, rapidly providing the customer with the functionality required and minimizing the risk of total project failure. As code evolves it can always be refactored in response to new needs. Surprisingly, Beck takes for granted that current technology state-of-the-art and programmer skills will not stand in the way of these continuous design changes.

    The options an XP customer or development organization is granted through early, accurate management:
    • Option to abandon the software project. If the team is not gaining traction, or the functionality provided by the software is not a useful as expected, the project can be canceled. The ability to "fail fast" is a benefit of XP.
      This has the additional advantage of allowing XP advocates to refer to canceled projects as "agile successes". :-)
    • Option to switch direction. Because the software is ready for use so early, there is an opportunity for the business to decide that they don't really want the system they specified. Agile teams can change direction because they don't have a lot of investment in the system "as specified", only in the system "as built".
    • Option to defer before investing. Since building is done incrementally and interatively, the business can choose not to produce features that may not have the same potential as others. Does the social networking bit have to be done before e-commerce? Should the e-commerce bit happen before we have full catalog capability? Being able to defer means that we can have the pieces we want most now. Of course, we can defer indefinitely (AKA: abandon) some features for further savings.
    • Option to grow to take advantage of a market that is taking off. This includes building scalability into the application as needed. It clearly also can mean growing the app in the direction of its uptake, such as adding social networking features or commerce features if those are drawing people to the application or SAAS.

    Programmer Practices for Agility


    font: Another
    source: Beck, Kent. Extreme Programming Explained, 2e.

    This card lists programmer practices, both team and individual (or pair!), that can help us meet some of the rather daunting challenges of agile: How do we continually deliver increments of quality software that meet the changing and evolving needs of our customer, at a reasonable cost?


    • Continuous integration (CI) - Agile promotes continual forward progress. We expect programmers to frequently update the system with code changes, so that we can verify that the complete, integrated system is still working.

    • Test driven development (TDD) - TDD tells us to break down programming into technical tasks, each specified by tests that document small pieces of behavior. TDD provides us with feedback that we've built code that does what the tests specify. Most importantly, TDD supports the practice of design improvement.

    • Design improvement - With each change, programmers must reflect upon the code's new state, and correct any design deficiencies. Continual holistic attention to the system's design helps keep development costs from rising dramatically.

    • Coding standard - Navigating a code base without standards is like riding on a rough road: At the end of the day, the constant battle against all the little bumps, nuisances, and noise simply wears you down. A team that can't establish workable standards is a weak team. In addition to including naming and formatting, coding standards should include things like handling of build system warnings, build output standards (e.g. no stdout/stderr or stack dumps!), build timing standards, and test standards.

    • Collective code ownership - Uncle Bob's prime directive for agile development is "never be blocked." Class ownership standards create unnecessary blocking issues. We should all be comfortable with anyone touching any area of the code--as long as they're following all of these other programmer practices!

    • Simple design - Keeping the design as simple as possible allows for easier incorporation of new changes. Introducing unnecessary abstractions or complexities increases the cost of development. You ain't gonna need it! (YAGNI) More specifically, the practice of simple design is best described by Kent Beck's four rules.

    • System metaphor - A global understanding of the system and its concepts is essential for an agile team. We all need to build a common, ubiquitous language that helps us communicate with each other, and that includes non-programmers. The system metaphor is a system of names for its primary entities (classes) and how they relate.

    • Pair programming - How in the world will your team ensure that other developers are adhering to the common practices if no one reviews what is done? How will we ensure that we keep on track, and developer on time, if developers are left to suffer their own insecurities in their cubes? How can we shift from finding bugs to preventing them? Try it. If you have a real team, you'll like it.
    The placement of practices on the card is not random. CI, the foundational practice for any agile programming effort, appears at the bottom. The left side represents more "community" practices--the things we practice more at a team level (technically, all of these elements are practiced as a team). The right side emphasizes design-oriented practices (similarly, however, all of the other practices have an impact on the design and vice versa). And pair programming is the best way to ensure we adhere to all of the practices.

    Hmm, this card looks suspiciously like the technical practices of XP. How about that!

    Priority Mechanisms



    Font is Marker SD

    Setting priority for tasks is essential to agile/lean software development. Agile teams strictly limit the number of tasks in flight in order to have greater efficiency and effectiveness. The improved focus means code is completed sooner (not faster) and that product may be delivered to production more often. This focus is frustrated if we have too many "#1 priority" items and "emergency" items thrown in on top. Controlling the flow makes teamwork possible, and actually speeds the process.

    We sometimes refer to the system that filters tasks into priority order as the magic funnel. All tasks and features are metaphorically dumped into the top of the big funnel. Ideally, the first (or next) item that falls out of the bottom of the funnel is the absolute most important thing we could possibly be doing. It has won the prize. It is the task we should be working on.

    Setting priority is unsurprisingly one of the hardest things a customer can do. Do you pick the story that satisfies the most "important" customer (where "important" varies daily, almost hourly, and by which person you ask), or the greatest number of customers? Do you pick tasks that you think will bring the greatest number of new customers, or please the existing customers? Do you streamline processing or go with aesthetics? What makes one story more valuable than another?

    Since the problem is large, and depends on local standards, there are many ways of prioritizing stories. The method shouldn't be something a team should agonize about for weeks. The most important point is that the product owners are able to reach a consensus, and that the features they pick are truly important. Tactics can vary, provided the strategy is good.

    Here are some schemes and techniques that might help build a working "magic funnel":
    • A simple priority triage system (one short sentence) was reported by Mary Poppendieck in Lean Software Development as one of the simplest things that could possibly work. The rule doesn't have to be subtle or obscure. A maintenance team might adopt a three-part rule, where production crises came first, followed by bugs on the release-in-testing, followed by everything else. Features that affect all customers may come first, followed by those that primarily affect million-dollar customers, followed by those that affect half-million dollar customer, followed by whatever. It is possible that product stakeholders already have a rule of thumb that suffices 80% of the time. The other 20% of the time is settled through escalation.
    • Determine "The Constraint" as in Goldratt's writings The Goal and Critical Chain. If you can define the one thing that inhibits you from being successful, then you can prioritize all outstanding bugs and backlog items in such a way that those that remove the primary obstacle become top priorities. Goldratt was speaking of process steps and production, but why not apply it to features that sell or flaws that inhibit? It may be that scalability of your web application is more important right now than enhanced functionality. It may be that a difficult feature is the primary reason you are losing sales or even customers. It may be that one issue prevents you from expanding, growing, producing. Critical Chain shows us that we need to solve this one big problem. And then the one after it.
    • Covey's Quadrants from First Things First will have us divide work into quadrants, so that #1 are those things that are both important (to the future of the company or product) and urgent, #2 are those that are important but not urgent, #3 are those that are urgent but have little long-term impact, and any unimportant non-urgent work is simply eliminated from the backlog. These items are taken in quadrant order, so that important, non-urgent tasks are done before urgent, non-important tasks are considered. Covey, et al, were talking about personal importance and daily tasks, but why not apply it forward to planning other work that has potential value and obvious levels of urgency? Remember that urgency and (to a lesser degree) importance are dynamic properties, to be revisited frequently.
    • Value-First is the rather like the Covey and Goal approaches, where the work that provides the greatest value (frequently represented in customer satisfaction or decreased support) goes first. This sounds easy, but of course the problem is defining "value" and dealing with "value to whom?" One could place value to the customers or to the sponsors or to the shareholders first.
    • Risk-First would tell us to start on those things that need the most research and testing sooner. High-risk items have unpredictable schedules, and may not pan out at all. Such stories would be prioritized earlier because they cannot reliably be produced on a schedule. Alternatively, some will choose to use risk-last planning, so that the so-called "low hanging fruit" may be completed before moving on to less predictable work. Some organizations may want to plan a mix (70/30 or 80/20) of low-risk to high-risk features. 
    • Greatest Good to the Greatest Number works like the other "value first" kinds of schemes, but adds voting to the scenario. Each customer, role, or market segment that would benefit from a change votes for it (consider dot-voting). Among items of the same importance/urgency quadrant, those with the greatest number of votes would go first. Changes with fewer stakeholders would be done later. This is a customer-focused version of "Bargain for Success."
    • Fixed-length action queue would work by using a short list of only a few bug fixes or marketable features. This list would be overseen by executives, and to push an item from "backlog" to "action queue" requires high-level approval. Items in "action queue" can be retracted only by executive order, since stopping a feature-in-progress represents a financial decision to throw away development dollars. The customer works to push items into the fixed queue as other things are completed or redacted. Customers will have a list of two or three items that might be next if approved. This tight focus helps the Customer not lose focus on immediate delivery. It is a lot like the Biblical "Law of the Medes and Persians", famous for being unrevokable.
    • “Only One Thing” is a little game best used when the priority rule is more intuitive than explicit. The stakeholders are given a hypothetical situation that only one feature can be reliably developed in the next iteration/month/quarter, and are tasked with picking which one feature it would be. Once they have picked the solitary feature, they are asked why it is important to them. This game can be played with "only three" or "only five" for a larger sample size. Most organizations, having argued through the exercise, will have a Simple Triage System they can use for future priority meetings.
    • Bargain for success is another game-like system. Each product stakeholder is given a number of votes/dollars/tokens/chips to spend. They are allowed to buy into features in order to bring their priority up in the queue. Stakeholders can make deals with each other ("I'll give 7 tokens to your feature Y this time if you'll give 7 to my feature Z next month"). The game-like nature of the exercise may cause some to see personal "winning" as the goal, rather than the greatest good for the company, but it will drive consensus nonetheless. Ultimately, the stakeholders have decided either way.
    Some of these techniques (Bargain for Success, Only One Thing, Fixed-Length Queue) may qualify this card as a "Power Card". They are not guaranteed to result in happy handshakes and back-patting among all stake holders. Some may even resent their work being treated as a game (though in my experience they usually prefer to work in a game-like system with some rules and a fair degree of bargaining authority).

    The ultimate power card (not included) is "CEO/Owner Demands". Most development organizations will pitch in and do all they can to get the feature completed well and soon. As long as the demands are within reason it should not be a problem. Most executives should understand the realities of development hours and sustainable pace, and are pretty hard-working guys themselves. The CEO DEMANDS power card is rightfully used sparingly and in cases most deserving of it.

    Overplayed, all power cards will result in demotivation, loss of quality, slowed pace, and/or attrition. Coaches, managers, stakeholders, and product owners should move cautiously.

    Principles of Package Coupling





    Principles: Robert C. Martin

    Post: Tim Ottinger and Jeff Langr

    These three principles, devised by Uncle Bob, describe how to structure relationships between packages (arbitrary collections of classes). A related (forthcoming) card, Principles of Package Design, talks about the forces that bear on how to optimally group classes.

    There arise occasional shouts of "But that was in C++!" Yet we find that these principles can apply also to dynamic languages, where abstraction works rather differently than in interface-declaring languages.

    • Acyclic-Dependencies Principle (ADP) - You stay late to finish up some work, but come in the next morning only to find that your code is broken--someone else stayed later and checked in changes that make your code very unhappy. Fixing your code breaks a third developer's code, and his fixes break yours again. This "morning-after syndrome" can be an unending nightmare of changes breaking other code, which in turn must be changed, which in turn...

      Cycles begin to make all packages dependent upon all other packages in the system. They dramatically increase build times to the point of pain (something one of us lives with daily on the C++ project he's working).

      Some languages, like C#, have facilities to prevent circular dependencies among packages. But even modern, dynamic languages like Python can suffer in surprising ways from round-trip dependencies.

      Dependency cycles among modules are a very serious problem, slowing development and wrecking deadlines. Note that mutual dependencies among classes are usually a problem if the classes are split across modules/packages/assemblies.

    • Stable-Dependencies Principle (SDP) is based on the understanding that code has volatility, and that changes ripple through a system along dependency lines. From the point-of-view of volatility, dependency is transitive.

      If the majority of the system's classes are dependent upon a volatile bit of code, then we can expect a high frequency of system breakage and rippling changes. If, instead, a system depends on nonvolatile code, then breakage should not ripple through the system very often at all.

      Some modules should change frequently, and should be volatile. Other modules are essential core abstractions and should not change very often.

      Therefore the package dependency graph should flow from instable packages (packages that are easy to change) to stable or "responsible" packages (packages that are hard to change). In a sense, this is the dependency inversion principle applied to packages: You should depend only upon things that are unlikely to change.

    • Stable-Abstractions Principle (SAP) - Per Uncle Bob, this principle sets up a relationship between stability and abstraction. A stable package should be as abstract as possible, thus ensuring that its "stability does not prevent it from being extended." In contrast, an instable (not responsible) package should contain lots of concrete classes whose details can be easily changed.

      This further reflects the Stable Dependencies principle, with the added observation that the reason for interfaces is to give safe, stable dependencies to clients of an abstraction. This drives us to the understanding that we should depend on the parts of the system built specifically to provide freedom from volatile bits (implementations).

      In dynamic languages, SAP is a harder metric to automate. Clearly the principle still applies. There will be classes whose purpose is to provide a stable interface and other classes that provide easily-changeable behaviors. The only problem is that not having declared interfaces makes it harder to automate the process of assessing abstractness.

    A "benefit" of working in C++ is that poor package coupling choices are all the more noticeable. Build times of several hours are not uncommon, yet these wasteful cycles can be quickly brought down with a bit of appropriate package reorganization. Without dramatically increasing build times, developers in languages like Java might not notice as quickly the cause of their morning-after sicknesses.

    So how do we figure out where the problems are and what to do about them? The flip side of the card provides metrics that you can use as the basis for graphing the relationships between packages. Such a graph can point out nonsensical packages, such as maximally abstract packages that no other packages depend upon, or maximally concrete packages that all other packages depend upon. Uncle Bob's stability article provides some detail on how to put this graph together (but there are also tools that can help!).

    Software Craftsmanship Ethics



    Source: Doug Bradbury, Dave Hoover, Robert Martin, cast of dozens

    This is the outgrowth of a conversation among Doug Bradbury and a number of Craftsman Manifesto signers. The goal of the collaboration was to come up with a statement of the Ethics of Software Craftmanship. In the course of the conversation, one of our participants suggested the pillars shown here (the brainchild of Jason Gorman). 

     The long form is quite beautiful, and presented here in entirety as an explanation of the four points above:
    • We consider it our responsibility to gain the trust of the businesses we serve; therefore, we take our customer's problems as seriously as they do and stake our reputation on the quality of the work we produc.
    • We consider it our responsibility to write code that is defect-free, proven, readable, understandable and malleable; therefore, we follow our chosen practices meticulously even under pressure and practice our techniques regularly.
    • We consider it our responsibility to hone our craft in pursuit of mastery; therefore, we continuously explore new technologies and read and study the work of other craftsmen.
    • We consider it our responsibility to perpetuate the craft of Software; therefore, we enlist apprentices to learn it and actively engage other craftsmen in dialogue and practice.