Apprenticeship Patterns: Guidance for the Aspiring Software Craftsman - by Dave Hoover, Adewale Oshineye

The strongest patterns are the ones that are applied productively over and over again. Patterns don’t have to be new to be useful. In fact, it’s better if they are not new. Just knowing the names for established patterns is a big help too. Identifying a pattern lets you discuss it without having to retell the whole story every time.

When we use the phrase software craftsmanship we’re talking about a community of practice united and defined by overlapping values, including:

  • An attachment to Carol Dweck’s research, which calls for a “growth mindset.” This entails a belief that you can be better and everything can be improved if you’re prepared to work at it. In her words, “effort is what makes you smart or talented” (Mindset, p. 16), and failure is merely an incentive to try a different approach next time. It is the opposite of the belief that we’re all born with a given amount of talent, and that failure is an indication that you don’t have enough of it.

  • A need to always be adapting and changing based on the feedback you get from the world around you. Atul Gawande refers to this as a willingness to “recognize the inadequacies in what you do and to seek out solutions” (Better, p. 257).

  • A desire to be pragmatic rather than dogmatic. This involves a willingness to trade off theoretical purity or future perfection in favor of getting things done today.

  • A belief that it is better to share what we know than to create scarcity by hoarding it. This is often connected to an involvement in the Free and Open Source Software communities.

  • A willingness to experiment and be proven wrong. This means we try stuff. We fail. Then we use the lessons from that failure in the next experiment. As Virginia Postrel puts it: “not every experiment or idea is a good one, but only by trying new ideas do we discover genuine improvements. And there is always more to be done. Every improvement can be improved still further; every new idea makes still more new combinations possible” (Future Enemies, p. 59).

  • A dedication to what psychologists call an internal locus of control. This involves taking control of and responsibility for our destinies rather than just waiting for someone else to give us the answers.

  • A focus on individuals rather than groups. This is not a movement with leaders and followers. Instead, we are a group of people who want to improve our skills and have discovered that debate, dissent, and disagreement rather than blind deference to self-proclaimed authority are the way to get there. We believe that we are all on the same journey and that the change we seek is in ourselves, not the world. This is why this book doesn’t focus on how to fix your team, but rather on ways to improve your own skills.

  • A commitment to inclusiveness. We don’t reject enterprise software development, or computer science or software engineering (in fact, Ade has the word “engineer” in his current job title). Instead, we think that a useful system should be able to identify and absorb the best ideas from all elements of the software development community.

  • We are skill-centric rather than process-centric. For us, it is more important to be highly skilled than to be using the “right” process. This idea has consequences. Gawande asked, “Is medicine a craft or an industry? If medicine is a craft, then you focus on teaching obstetricians to acquire a set of artisanal skills.... You do research to find new techniques. You accept that things will not always work out in everyone’s hands” (Better, p. 192). This idea suggests that no process or tool is going to make everyone equally successful. Even though we can all improve, there will always be discrepancies in our skill levels.

  • A strong preference for what Etienne Wenger calls “situated learning.” This is an idea that the software community has tried to capture with patterns like Expert in Earshot. Its essence is that the best way to learn is to be in the same room with people who are trying to achieve some goal using the skills you wish to learn.

Chapter 2: Emptying the Cup

Expose Your Ignorance. Show the people who are depending on you that the learning process is part of delivering software. Let them see you grow.

Tell people the truth. Let them know that you’re starting to understand what they want and you’re in the process of learning how to give it to them. If you reassure them, reassure them with your ability to learn, not by pretending to know something you don’t. In this way, your reputation will be built upon your learning ability rather than what you already know. The most obvious way to expose your ignorance is to ask questions.

With practice and time, you will find that asking direct questions to the most knowledgeable people on your team will become second nature.

Action: Write down a list of five things you really don’t understand about your work. Put that list where others can see it. Then get in the habit of refreshing this list as your work changes.

Chapter 3: Walking the Long Road

Craft over Art

I would describe programming as a craft, which is a kind of art, but not a fine art. Craft means making useful objects with perhaps decorative touches. Fine art means making things purely for their beauty. —Richard Stallman in “Art and Programming”

The things we build for customers can be beautiful, but must be useful. Part of the process of maturation encompassed by this pattern is developing the ability to sacrifice beauty in favor of utility if and when it becomes necessary. Indulging in the creation of beautiful but useless artifacts is not craftsmanship.

Working on real problems for real people is what hones the craft, not just doing it for self-satisfaction.

Nurture Your Passion. Take steps to protect and grow your passion for software craftsmanship. To become a journeyman, you will need to have a passion for software craftsmanship. Unfortunately, your daily activities often work to diminish this passion.

Work on what you like. Find something at work that interests you, identify it as something you enjoy, and pour yourself into it. If you can’t spare enough time during the workday for this activity, consider putting in some extra time. If this isn’t feasible, dedicate some time outside of work to build some Breakable Toys.

Seek out Kindred Spirits. Join a local user group that focuses on something you want to learn more about. Start a weblog and read blogs that interest you. Participate in online forums and mailing lists and Share What You Learn.

Draw Your Own Map. Identify a logical but ambitious next step for your career. Understand that it’s not up to your employer, your career counselor, or your professors to give you a hand up. Arriving at your next step and charting the course to ultimately arrive at your ideal destination is your responsibility. With your next career step identified, visualize the smaller, interim steps you need to take to move forward. It is vitally important that you take the first step even if it doesn’t seem that significant. That first step will generate the momentum that will help carry you toward your goals.

You should continuously reassess your map as your circumstances and values change. Sometimes your map will be in accord with that of those around you, and sometimes your map will require you to chart your own path through the wilderness. Some apprentices we’ve spoken to have found that being open about their current map has enabled them to find Kindred Spirits while maintaining healthy relationships with current and past employers. The only constant is that the map is always yours, and you’re free to redraw it at any time.

Chapter 4: Accurate Self-Assessment

Be the Worst. Surround yourself with developers who are better than you. Find a stronger team where you are the weakest member and have room to grow.

It’s only when you work on your own that you will see how much your team increases your productivity and realize how much you have learned. This makes Reflecting as You Work and building Breakable Toys particularly important for people who are the worst on their team. Both provide opportunities to take a step back from the team environment to see what habits, techniques, and knowledge you’re picking up from Rubbing Elbows with your more experienced teammates.

There is a selfish aspect to purposely joining a team as the worst member. To counter this, complement Be the Worst with Sweep the Floor and Concrete Skills. Sweep The Floor means to explicitly seek out menial tasks in order to directly add value to the project. Developing Concrete Skills will increase your contributions to the development effort and is fundamental to your role as an apprentice.

Kindred Spirits. To keep your momentum going, especially in the absence of a full-time mentor, you need to be in frequent contact with people who are walking a similar road. Therefore you should seek out people like yourself who are also looking to excel.

List all the communities you could potentially join based on the tools you use, the languages you know, the people you have worked with, the blogs you read, and the ideas you are intrigued by. Identify which of those groups gather in the real world in your city. One by one, attend all these gatherings, and decide which groups seem most interesting.

Rubbing Elbows. Find ways to sit with another software developer and accomplish a hands-on task together, side-by-side. There are some things that can only be learned while you are sitting with another software developer to accomplish a shared objective.

There will always be certain micro-techniques that you will only learn when collaborating closely with a colleague. These are usually seen as too trivial to mention when teaching, but their impact adds up.

The development practice of Pair Programming is a concrete example of this pattern, and apprentices should look for opportunities to work on teams that use this technique.

The applications of this pattern are not limited merely to pair programming. The goal is to find ways to expose yourself to the daily working habits of other skilled people, and observe the ways in which they gradually refine those habits into even greater skill. These habits extend beyond coding and into all aspects of software development.

Sweep the Floor.

Context: You are a new apprentice on a project. Problem: You’re unsure of your place on the team, and the team is unsure of you. You wish to find a means of contributing to the team’s work, earning the team’s trust, and growing in stature as a craftsman. Solution: Volunteer for simple, unglamorous, yet necessary, tasks. This is a good way to contribute to the team’s success early on by showing that you can do a high-quality job even when it doesn’t seem to matter.

Examples of these tasks include maintaining the build system, production support, responding to maintenance requests, bug fixing, code review, eliminating technical debt, setting up the project wiki, updating documentation, acting as a sounding board for other people’s ideas, and so on. Typically, you’ll want to focus on the edges of the system where there is less risk, rather than the core where there are usually many dependencies and lots of complexity.

What’s the grungiest task that your team has been putting off for months? It will be the one that everybody complains about and that no one wants to tackle. Tackle it. And don’t just hold your nose and force yourself to do it; see if you can creatively resolve the problem in a way that exceeds people’s expectations and makes it fun for you.

Chapter 5: Perpetual Learning

Practice, Practice, Practice. Take the time to practice your craft without interruptions, in an environment where you can feel comfortable making mistakes. Short feedback loops need to be incorporated into your practice sessions.

Breakable Toys. Budget for failure by designing and building toy systems that are similar in toolset, but not in scope to the systems you build at work. If experience is built upon failure as much as success, then you need a more or less private space where you can seek out failure.

When implementing the Breakable Toys pattern, make your systems relevant and useful to your life as an apprentice. For example, build your own wiki, calendar, or address book. Your solutions might be massively overengineered for the problem they’re solving, and probably could easily be replaced by something off the shelf. However, these projects are where you are allowed to fail. They’re the projects where you can try ideas and techniques that might lead to catastrophic failure.

When implementing the Breakable Toys pattern, make your systems relevant and useful to your life as an apprentice. For example, build your own wiki, calendar, or address book. Your solutions might be massively overengineered for the problem they’re solving, and probably could easily be replaced by something off the shelf. However, these projects are where you are allowed to fail. They’re the projects where you can try ideas and techniques that might lead to catastrophic failure. But the only one who can be hurt by their failure is you.

Reflect As You Work. Become a reflective practitioner of software development. This involves regular introspection into how you are working. Consider whether your practices are novel, innovative, or outdated. Ask yourself questions about the things that the rest of your team takes for granted. If there is something particularly painful or pleasant about your current work, ask yourself how it got that way, and if things are negative, how can they be improved? The goal is to extract the maximum amount of educational value from every experience by taking it apart and putting it back together in new and interesting ways.

Unobtrusively watch the journeymen and master craftsmen on your team. Reflect on the practices, processes, and techniques they use to see if they can be connected to other parts of your experience. Even as an apprentice, you can discover novel ideas simply by closely observing more experienced craftsmen as they go about their work.

This process of observation, reflection, and change isn’t limited to just your own activities. Unobtrusively watch the journeymen and master craftsmen on your team. Reflect on the practices, processes, and techniques they use to see if they can be connected to other parts of your experience. Even as an apprentice, you can discover novel ideas simply by closely observing more experienced craftsmen as they go about their work.

Your goal should be to become skilled rather than experienced. The increase in your skill level is the only meaningful testament to the effort you have spent inspecting, adapting, and improving your working habits.

Record What You Learn.

Context: You learn the same lessons again and again. They never seem to stick. You often find yourself repeatedly doing things such as setting up CruiseControl, modeling hierarchies in SQL, or introducing patterns to a team. You remember doing very similar things in the past, but the exact details escape you. Problem: Those who do not learn from history are doomed to repeat it. Solution: Keep a record of your journey in a journal, personal wiki, or blog. A chronological record of the lessons you have learned can provide inspiration to those you mentor, since it makes your journey explicit, but it can also give you a vital resource to draw upon. Those who use this pattern sooner or later experience a moment when they’re searching for the answer to a tricky problem and their search engine gives them a link to their own wiki or blog. Using a blog to record the lessons you’ve learned also has the side benefit of helping you meet Kindred Spirits, while a wiki that has accidental linking allows you to see the connections between your experiences. Try to avoid falling into the trap of just writing down your lessons and forgetting them. Your notebook, blog, or wiki should be a nursery, not a graveyard—lessons should be born from this record, rather than going there to die. You make this happen by regularly going back to read what you’ve written. Try to make new connections every time you review the material.

Share What You Learn.

Context: You have been an apprentice for a little while. You know a few things and people are starting to look to you as a source of knowledge. Problem: Up until now, you have focused exclusively on your own improvement as a craftsman. To become a journeyman you will need the ability to communicate effectively and bring other people up to speed quickly. Solution: Early in your apprenticeship, develop the habit of regularly sharing the lessons you have learned. This may take the form of maintaining a blog or running “brown bag” sessions amongst your Kindred Spirits. You can also make presentations at conferences or write tutorials for the various technologies and techniques that you are learning. At first this will be difficult. After all, you are not a master or even a journeyman: surely you should wait for someone more experienced to put themselves forward? However, you will find that your fellow apprentices will appreciate one of their own trying to demystify complex topics. You may know only a tiny amount about category theory or prototype-based programming languages, but the little knowledge you have is still more than most. Since you know only a little bit, your explanations will be simple and straight to the point without assuming prior knowledge. This will make them better explanations. You may find that it helps to write the tutorial you wish you had been given when you were first learning a particular topic or technology.

Chapter 6: Construct Your Curriculum

Reading List.

Problem: The number of books you need to read is increasing faster than you can read them. Solution: Maintain a Reading List to track the books you plan to read, and remember the books you’ve read. In the spirit of the Share What You Learn pattern, consider storing your list in a public space. This will allow other people to benefit from the things you learn.

Study the Classics.

Context: You are self-taught, or had a highly practical education that valued skills training over theory. Problem: The experienced people you collaborate with are constantly referencing concepts such as Brooks’ law from books that they assume you—and any self-respecting software developer—have read. Solution: Expose Your Ignorance and ask about the unknown concept and the book it came from. Add this book to your Reading List.