David Scott Bernstein's Blog, page 4
June 9, 2021
Radiators and Silos
In the old days of corporate America, the way you got ahead was through hard work and perseverance. You strove to become an expert in some area that was valuable so the people would come to you for your expertise. This is how you got ahead. This is how you got into management. You got there by having people depend on you.
But this has a downside. Becoming an indispensable resource makes you, well indispensable. That means that you can’t get sick or take vacations and so you become a slave to your own knowledge.
In today’s world of Agile software development, we define those characteristics that get us ahead as exactly the opposite. Instead of withholding specialized knowledge to become the “sage on the stage” we share our knowledge and become the “guide on the side.” Being a team player holds more value today and sharing knowledge within and across teams helps everyone to be successful in the future.
Agile encourages cross-functional teams, which means that we want everyone on the team to be able to work in any part of the code. This may sound inefficient at first, but it helps create consistency and diversity within the team so that there is no one critical resource on the team and everybody is able to take vacations or get sick without all of the development grinding to a halt.
Let’s face it, being in silo is no fun. Being a radiator is far more exciting. You get to share and help others. You get to be appreciated and supported. People like team players.
The other thing that I can tell you about being a radiator and sharing information with others, which is what I built my career on, is that it is not just supremely satisfying but also teaching others is one of the very best ways of learning yourself. I’ve learned an enormous amount by being able to articulate ideas in many different ways so that a variety of people can understand them. We don’t all learn and assimilate information in the same way and having flexibility in being able to present ideas can help make them more valuable to a wider range of people. It’s exciting to help people learn and understand and this is how we build excellent teams.
Of course, we can still have specialties. Some developers specialize in testing, other developers specialize in databases or front-end but ultimately, it is good for all developers to gain experience in all of the major areas of software development, including databases and testing. It’s okay to start on the path from different directions but ultimately, if we are career software developers, we will learn to become full-stack developers.
There is so much to learn in our field. It seems like every week a new framework or technology is coming out. Things are fast-paced and ever-changing in the field of software development and that’s a good thing because it means that we are growing and advancing at a rapid rate. It is some consolation for me to know that the fundamentals don’t change. When we have a good sense of the basics of software development then we can recognize what’s different and what’s the same about new tools and techniques from what we already know and this helps us grasp new concepts more easily.
The post Radiators and Silos appeared first on To Be Agile.
May 12, 2021
Makers and Menders
I’ve been getting back into some research interests of mine that require data acquisition from a variety of sensors so naturally, I’ve gravitated towards using the Raspberry Pi. If you’re unfamiliar with the Raspberry Pi, is a full-blown computer on a card about the size of a cigarette pack and offers a graphical user interface, several programming environments, and a range of other applications, all for forty bucks.
The thing that I really like about the Raspberry Pi is that it makes interfacing hardware very accessible. The GPIO bus can plug in a variety of different sensors and actuators to interface with the outside world. It’s been a lot of fun.
They call us makers. There’s even a national community with a local chapter in Seattle where you can go and learn about electronics or use their 3D printer. This is a national movement so there is a lot of people who call themselves makers.
There’s another movement that I identify with as well but they’re a much smaller group. We call ourselves menders. When I asked developers in my classes if they prefer building new features or integrating features into existing systems the vast majority of them tell me that they prefer greenfield projects as opposed to working on legacy code. The reasons are obvious, legacy code is often not ideal. It requires learning the existing system which invariably doesn’t do things the way we would do them. Oftentimes, integrating software is a matter of shoehorning it in any way we can because we weren’t taught discipline techniques for extending software safely.
But there is another group of people. We are in the minority. We call ourselves menders and we actually like working in legacy code. It’s kinda like being thrown into the deep end of the pool. If you don’t know how to swim, then you run the risk of drowning but if you have the tools to keep yourself afloat then it can be a pleasurable experience.
Menders have techniques that allow them to safely work with legacy code and then once you understand these techniques the same code that terrifies most developers is actually exciting to a mender because we know how to safely transform it into something better and that is a valuable skill.
How do we get this magical skill of mending? This is a path that has been well illuminated. Martin Fowler wrote a book called “Refactoring: Improving the Design of Existing Code”. This book shows simple code transformations that are safe, incremental, and repeatable.
Knowing how to refactor code in a consistent and disciplined way is a critical skill that I believe every developer should have not just because it helps us get ourselves out of tight spots that we find ourselves in but also because it teaches us not to make the same mistakes that others have made.
What I noticed after I’ve refactored bad code into something better is that my own code started to improve, and I don’t make those same mistakes myself. I realized some of the benefits of refactoring other people’s code. Instead of it being drudgery to refactor code it turns out to be great practice for me to improve my skills as a developer and this is what I want to encourage other developers to do. Use refactoring as a way to propel yourself into writing better code.
The post Makers and Menders appeared first on To Be Agile.
April 13, 2021
Core Developer Practices
Every field of engineering has a core set of practices that they follow and software engineering is no different. But what are they?
The answer seems to depend upon who you ask. There is no overall consensus in our field about what the right standards and practices should be. We have many languages, many frameworks, and many programming paradigms to draw from. Part of the reason for this is that we use software for many different reasons. The tools and techniques that you use for simulating physical properties such as gravity a very different from the techniques you use when constructing an accounting system. Yes, there are some fundamentals that most problems have in common but there are also differences. So, what are those fundamentals?
I’ve written a lot about some of the fundamental practices that I’ve learned which have helped me and others as software developers but there is so much more yet to be discovered. The way we build software today is radically different than the way we build software in the 1990s. Sometimes progress seems gradual when you’re in the middle of it but looking back we see that the prior generation of software development was very different than how we build software today.
Incremental software development where we build features in iterations and emerge our designs as we go has proven itself to me to be an efficient way of building software and produces a far better end result that’s more maintainable and costs far less to extend later. This should be the real goal of software development, to build software that’s resilient and extensible. It’s not enough just to make the computer do something if the way we do this makes it difficult to change later.
Procedural code like the kind I used to build 30 years ago in C, Fortran, and Basic was mostly unencapsulated. Every subroutine shares data from a common source and this is manageable for the small kinds of systems that I was building three decades ago. But building an enterprise system in this way can become a nightmare. This is why we’ve moved to the object-oriented paradigm. We can more accurately and completely encapsulate processes and we can use that to minimize the impact of future change in a system if we understand that that’s the purpose of building systems in this way.
Object-oriented programming is a magic key that gives us this rarefied gift of extensibility but only if we use it correctly. We must take that key and apply it to unlock the tight bonds of coupling in our systems because the root of all software problems can be seen as coupling issues.
Building decoupled systems is both an art and a science. It involves a series of technical skills as well as a strong design sensibility. We have to be able to apply logic as well as abstraction, the two fundamental processes in human thought. Object-oriented programming gives us a development paradigm where we can model anything that we can imagine and name.
All of the developer practices that I advocate help us more accurately create models that represent the domain that we are working in. As I often say in my software design classes, if I only had to give you one piece of advice for developing extensible, resilient systems it would be this: create your designs to reflect the nature of the problem as accurately as possible by building a detailed and consistent domain model. That means that all the concepts, ideas, and entities in the problem domain are represented in separate classes in your domain model. This is how we build robust software and when you follow this advice it can help you discover many of the core developer practices.
The post Core Developer Practices appeared first on To Be Agile.
March 16, 2021
SO what?
When I asked professional software developers in companies what software development and design principles, they follow I oftentimes get a blank stare. Our industry has not matured enough to be able to extract out the major principles of constructing software the way civil engineering has been able to extract out the major principles of constructing physical structures. However, we are a young industry.
Perhaps the best-known principles in software development are the SOLID principles that were described by Robert C Martin in his book Agile Software Development. I find these principles are invaluable, especially the first two: The Single Responsibility Principle (SRP) and The Open-Closed Principle (OCP). The other three SOLID principles are still valuable, but I find the first two give me the biggest bang for the buck. Let’s take a look at them.
The Single Responsibility Principle is perhaps the best advice for building accurate and resilient domain models. It simply says that each responsibility in the system should be encapsulated within its own entity. This may be a module or function, or it could be a class or method in an object-oriented system. Every programming paradigm provides some mechanism for encapsulation and the Single Responsibility Principle is saying to use it to encapsulate responsibilities in a system.
But what is a responsibility? It’s a thing. Something that you can name. Software development is after all a linguistic activity and being able to name something accurately and precisely is a strong indicator of its cohesion. The Single Responsibility Principle is saying that software should be cohesive, that each encapsulated entity should be about one thing–something that we can easily name.
Bob Martin describes a responsibility as a “reason to change” and I find that a useful definition. We want to spread out the reasons to change our code for any possible situation so that it has a minimal impact on the program that we are changing. In order to do this, we spread the responsibilities out across classes so that every class is about one thing. This also helps clarify the domain model because you can see the groups of classes and the relationship to each other and that should give you insight as to the design of your system, what it’s resilient to in terms of changes, and where it’s rigid and inflexible.
This leads us to the second principle, the O in SO. This stands for the Open-Closed Principle and to me, it is the guiding light in software development. Bertrand Myers defines the Open-Closed Principle as “…software entities should be open for extension but closed for modification.” What this means is that we should construct software in such a way that when we go to extend it we are minimally changing existing code. To do this we typically don’t write code in the most expeditious way instead, we come up with an appropriate design that encapsulates the right things to minimize the future impact on the system.
Indeed, these principles reinforce each other so a system that is following the Single Responsibility Principle is also more open for extension. Whenever I think about a design or a piece of code I asked myself where is it open for extension and where is it close for modification. This is a valuable question to ask when evaluating a design so that you understand its strengths and weaknesses.
Flexibility is great but it often comes at a cost. Performance, clarity, and flexibility can end up at odds with each other, so we have to make trade-offs. The trick is making the right trade-offs. To me, these two principles, The Single Responsibility Principle and The Open-Closed Principle represent the core of a disciplined software development practice. They are lenses by which I can view software and evaluate their strengths and weaknesses so that I can make the best tradeoffs in each situation I’m in.
The post SO what? appeared first on To Be Agile.
February 10, 2021
Still XP After All These Years
Are you humming in your head Paul Simon’s “Still Crazy After All These Years”? I am. And it does seem crazy. Crazy that some ideas that came out over 20 years ago in the fast-paced software industry are still relevant and valuable today. But they are.
Kent, Ron, Ward, and many others who were early innovators of Extreme Programming (XP) really nailed it. XP was the basis for Agile software development. It is a set of technical practices for incrementally building software and that’s how Agile started. Agile and Scrum have applications beyond the world of software and understanding its roots can give us greater insights on how to use it universally.
I personally believe that the technical practices of XP are where the real treasures lie. Practices like refactoring and test-first development, which sound complicated initially but when you boil them down to common sense, reveal wholly different ways of approaching problems that have vast value and utility both for developing software and for just thinking clearly.
The practices that XP discovered for building extensible code incrementally can be useful in many other domains because what we are really talking about are mental tools and techniques that help us think and model our understanding more clearly. This has obvious benefits in software development but thinking and modeling are things that we do all the time, and so these same tools can be applied in many other areas and disciplines.
Our goal in software is to build models that allow us to go back later and extend them because in reality, that’s what we need to do with software. The only software that doesn’t need to change is the software that is never used. If people use software, then invariably they will want it to change because they will see better ways of doing things. This is good. We want to encourage this in the industry because that’s how we improve.
Traditionally in Waterfall software development, we have resisted change because we had the notion that is more beneficial and efficient to build in batches. This is true in the physical world but not in the virtual world. Building software in batches is shockingly inefficient. We want to find ways of removing barriers to change when building software so we can “welcome changing requirements, even late in the development cycle,” as the Agile Manifesto says.
Extreme Programming includes several critical and fundamental practices to allow us to build software that is more understandable and extensible so code is more straightforward to change. Many of these ideas are actually not foreign to us but we haven’t really thought of applying them to software.
For example, triangulation is a technique that has been used from the early days of maritime navigation to modern-day GPS devices and it represents a fundamental way of achieving clarity. If your reference is only a single point on the horizon it may be difficult to plot an accurate course at sea but if you have multiple points that you can triangulate from then you can establish a much more accurate course heading. This was true for early maritime navigation and is also true in today’s GPS satellite networks. If your GPS device has only two satellites that it’s receiving pings from then you’ll get a rough estimate of where you are but the more satellites that it can triangulate from the more accurate the location will become.
This is also true in thought. We talk about it as gaining perspective and really the very definition of understanding is being able to see from multiple perspectives or points of view. This is exactly what test-first development does. It gives us the ability to see the services that we build from an outside perspective. All too often developers think about what they are building from an internal perspective and designing software in this way makes code more difficult to integrate later.
Extreme Programming centers around iterative development. Instead of designing an entire system, building it, and then validating it, which turns out to be a hugely wasteful process, we incrementally built our software, one feature at a time, starting with whatever is most important or valuable to the customer. We then create many interim releases so that we can get feedback and validation that our software works as expected.
A lot of the people outside of the software industry really don’t understand the kind of trouble that we make for ourselves in software development by trying to tackle problems that are too big and unwieldy. Extreme programming is all about taking big problems and breaking them down into smaller more manageable problems that can be dealt with more easily and with more opportunity for feedback. XP strives to fulfill the first principle of the Agile Manifesto, which is “our highest priority is to satisfy the customer through early and continuous delivery of valuable software.” That really says it all.
I used to think that building complex enterprise systems required a great deal of architecture so that common libraries would be created first and there would be a sequence or order of development, just like there is in physical construction where you dig out the basement before you put up the walls. It’s taken me decades to recognize that software development is different and that by merely focusing on building the highest value features first–the ones the customer will get the most value from first–we oftentimes end up with happier customers and are able to deliver code in a fraction of the time it would take using Waterfall development.
Practicing XP for the last two decades has taught me many refinements on these basic practices but the foundation was there from the start. Thank you, Kent. Thank you, Ron. Thank you, Ward. And thank you, the many others who have helped develop, refine, and utilize the practices of Extreme Programming.
The post Still XP After All These Years appeared first on To Be Agile.
January 13, 2021
How I Use User Stories
When I write user stories, in addition to the story itself, I like to help define edge cases in my stories and I typically do this as acceptance tests.
There are automated acceptance test tools such as FIT and Cucumber that not only allow me to define acceptance tests but also help me run them against the code that I’m building to see when they’re complete.
There’s always something more to do or some condition lurking out there we might not have thought of, so developers spend a lot of time trying to figure out if they’ve done enough on a project or on a particular feature. Having an acceptance test that is well-defined helps us know when we’re done implementing a feature.
When the acceptance test passes, we’re finished, and we can move on to the next feature. This helps us avoid gold plating and we spend more of our time building valuable features instead of needlessly enhancing the ones we’re currently working on.
I’m also not opposed to adding anything else that would help us when writing the story. If there are special security concerns or concerns that require operations, I’ll jot that down on my story card as well. When I teach writing stories, I typically teach using three by five cards to keep my stories short. My colleague, Greg Smith, typically teaches story writing using an eight and a half by eleven sheet of paper and he has several other support items that you can add to help when you’re writing a story. I like the “Smith Method” of story writing in practice, but generally, when I’m teaching I try to start out using three by five cards to emphasize how simple stories can be.
There are times I don’t use stories. They aren’t the appropriate tool for every kind of software development—I don’t believe anyone tool is. If I’m writing something highly procedural that involves a series of steps then I’ll go ahead and draw it up as a use case, but if I can take advantage of the OO paradigm I tend to use stories as my first way of defining what I want to build.
Once a story is written, depending upon how involved it is to implement, I’ll begin breaking it down into a series of tasks. Each task will give me a measurable step toward the overall implementation that I can then demonstrate as progress to my customer.
Development tasks should be as short as possible. I like them to be anywhere from a few hours to a few days. When a task is complete, another test passes in my acceptance test suite, and I’m one step closer to completing the story.
All of these may seem strange to you if you’re not familiar with building software in this way, but really, it’s just common sense. If you have any big problem that’s hard to figure out, breaking it down into a series of smaller problems often helps make each one more manageable. This is essentially what we’re doing when we build software incrementally. We still have to plan, design, and think very carefully about what we’re doing but we’re restricting the problem domain so it’s simpler to solve.
Agile is not a prescription to go on automatic pilot. In fact, just the opposite is true. Agile gives us opportunities to get more feedback than traditional software development and as long as we’re able to take advantage of that feedback and change our course of action when needed, we can use Agile to our advantage.
The post How I Use User Stories appeared first on To Be Agile.
December 9, 2020
User Stories Support Object-Oriented Development
The number one worst practice I see consistently in object-oriented software development is writing procedural code. Even object-oriented programming projects contain code that is highly procedural. You’ve probably seen code like this yourself where it’s basically a series of steps that prescriptively describe a process that is then wrapped within a class.
This is really not taking advantage of OO and it has some serious consequences for maintainability. Object-oriented languages gave us the capability of doing better but I rarely see developers take advantage of using objects. Encapsulation is useful and important and most of us understand the notion of hiding data through access modifiers or hiding behavior through interfaces but there are subtler parts of the object paradigm that tends to escape many of us.
I call it a paradigm because it really is a different way of thinking and not just a new set of keywords. When we model problems that reflect the domain that we’re working in rather than reflecting implementation details that are part of the way a computer processes information, we can take better advantage of the tools in object-oriented languages and write more extensible code.
I don’t do use case modeling when I’m doing object-oriented programming. While use cases are appropriate for many kinds of programs or processes, they are not appropriate for doing true object modeling. Use cases define tasks as a series of steps, which translates into procedural code. For this reason, I focus particular attention on the “so that” clause of user stories instead.
You will recall that a user story is typically made up of three pieces: the role, the desire, and the so that clause. For example: “As a job seeker, I want to search for matching positions in my area so that I can find potential employers.”
This is the full extent of the user story, but it doesn’t mean I can code with only this information. We refer to user stories as the ‘promise of a conversation.’ The conversation is between the developer and the user, or user representative—our Product Owner.
Notice all the context that comes with a user story. The user states who they are, what they want, and why they want it. This context helps us, as developers, stay focused as we discuss the story with the user. Now I can have a meaningful conversation about the best ways of allowing a job seeker to find potential jobs, and I have a whole raft of questions to ask such as how we define “in my area” or what “matching positions” really means. These things are best left to a conversation because each feature has so many details that writing them down in a long-winded specification can easily devolve into mind-numbing drudgery.
I spent more than half of my life as a developer, including many years where I was managing other developers, and the sad truth is that far too often we simply don’t read specifications. We’d much rather just write code, so having a story for a feature that is only a sentence long gives us a higher probability that the developer will actually read it.
But far more important is that we engage users in the process of finding the best way to do what they want. We think we’re being hired to build a software system but that’s only part of the story. We’re really being hired to understand our customers’ business, or whatever it is we’re writing a program about, and then we memorialize that understanding in code.
Software development is a discovery process, and this is as true for our customers as it is for us. By engaging our customers in the process, we can get the best of their attention because as much as we hate having to figure things out upfront, they probably hate it more and have far less experience doing it. As we start to engage with our users, we gain new insights and so do they. That helps us build a better system for everyone.
The post User Stories Support Object-Oriented Development appeared first on To Be Agile.
November 11, 2020
How Small should a Story Be?
Stories should be as small as possible while still providing some value to the user. Usually, we strive to create the smallest increment of value possible but this is sometimes not as straightforward as it may seem.
Sometimes we write stories with the intention to build upon them later or combine pieces of common stories so that when the first story is done other subsequent similar stories are much easier to complete.
Every story should provide some measurable value or at least some measurable result. Having a repeatable, measurable result for each story helps us define acceptance criteria for our stories that tell us when we are done building them so we can move on.
On enterprise projects involving several teams, we may want to build out some infrastructure or libraries in service to other teams. Scrum says that it is generally better to do the most important stuff first. I resisted such a simplistic approach but it usually works out that focusing on building the most important stuff first ends up building the best system possible with the resources I have.
When we build the most important stuff first, we end up ignoring a lot of the unimportant stuff so we only build the stuff that is most needed. If you can see a way to make a big story, into smaller stories then generally, it’s a good idea to do it. Alternatively, you can start with a simple story and add additional stories to enhance the original story. This works well in iterative development.
When I work on projects that use automated acceptance tests, I find that oftentimes stories are naturally centered around acceptance criteria and the value to the user. Even if these stories are larger, they can often be decomposed into smaller component stories.
A story should be focused and provide a single value to a single type of user for a single reason. Enhancement stories can be added to improve the feature.
So keep it small and that’s all I have to say about that.
The post How Small should a Story Be? appeared first on To Be Agile.
October 21, 2020
Polymorphism
Polymorphism is a big word for an important technique in object-oriented programming to help make code extendable. Rather than expressing business rules as conditional statements in code, we move them into factories and use them to instantiate objects that do the actions we want to take.
We need to know different things when we create an object versus when we use an object so separating these two activities can improve encapsulation and code cohesion. To create an object, you must know the object’s type. To use it you must know the signature of the methods you want to call, but you don’t have to know the object’s type, you could know the type of its parent or an interface that it implements. Polymorphism can give you the freedom to extend a type without breaking existing code.
This is also one of the key techniques in doing emergent design because it’s natural for a lot of good design to come out of refactoring when we build software in this way. We can come up with a better implementation for code that we already have under test so it’s far easier and more reliable to refactor than to write new code that’s not under test.
This is very much in line with my views on how to do test-first development where we write a test that fails and then try to make it succeed as quickly as possible, using the simplest implementation necessary, then work on refactoring it to make it more robust and maintainable. This is definitely a far easier and less error prone approach to writing code but few developers make use of it.
Of course, there’s a lot more to emergent design than just putting business rules in factories, although that is an important and not well understood aspect of good object-oriented programming, if not Agile development, in general. The reason for this is that the more differences we can handle as an issue of instantiation, the less we have to do with it in our production code, and that greatly simplifies the production code.
For example, a circle, a square, and a triangle are very different shapes and the way they’re drawn is completely different, but if I can handle those differences and draw them up on the screen as an issue of instantiation then I can treat them all the same way in my production code and move them or erase them or fill them with the same calls.
We refer to this as type encapsulation because we’re hiding the specific type that we’re working with from the one who’s using it. For example, the drawing program is unaware if it’s working with a circle or rectangle, all it needs to know is that it’s dealing with a shape and that a shape can be moved or resized. This not only simplifies the drawing code tremendously but it also makes the code far more general purpose because we can add new shapes and as long as they’re able to be moved and resized, they can interact with and be manipulated by the drawing program without having to change the drawing program at all. This type of extensibility is essential for emerging software.
The way object-oriented systems achieve this level of extensibility is through polymorphism. A polymorphic method is simply a method that shares its name with methods in other objects, which are typically sibling objects.
For example, a rectangle and a circle may have a polymorphic method called resize. The way we resize a rectangle versus a circle are different so each of the shapes will be responsible for resizing themselves in a different way that’s appropriate for them. But because each of them has a resize method, the drawing program can simply tell the shape to resize and not be involved in the specific implementation details of resizing because all shapes have the ability to resize.
A triangle is a shape, as is a circle and a rectangle. They are kinds of shapes because they share a common interface to polymorphic behavior. Circles and triangles and rectangles are represented in software as classes. There’s also the notion of an abstract class that represents a group of concrete classes. For example, a shape can be an abstract class. Abstract classes typically have some abstract methods that represent the method signature, or the way it’s called, but not what it does. The body of an abstract method is defined in the subclasses of the abstract class, for example a rectangle or a circle or a triangle.
Callers, like the drawing program, can only use concrete classes such as rectangles or circles or triangles, but they can hold those concrete classes in an abstract upcast type like shape and not have to know what specific derivation they’re using. This gives us a way of decoupling callers from the specific implementations they use. It’s one of the main ways that we “design to interfaces” in software development.
It helps to know the principles of good object-oriented programming. And it helps to know about design patterns and refactoring. All of these things together help us do emergent design efficiently. The most valuable part of doing emergent design is employing good techniques around breaking dependencies and encapsulating details. By mastering these techniques, we can be armed with tools that will help us in many situations, especially when we don’t know some of the requirements, or they’re likely to change in the future.
The post Polymorphism appeared first on To Be Agile.
October 14, 2020
Pair Programing Paradoxes
Of all the software developer practices I teach, the one I get the most resistance from managers is pair programming. They tell me they have too much work for their team to do and if they paired then their developers’ throughput would be cut in half.
There is a naïve assumption in that statement. The assumption is that the limiting factor in software development is typing. I think most developers would disagree.
When developers pair they produce significantly less code to do the same job as they would on their own, which drops the cost of maintenance. They also produce significantly fewer defects so there is less time spent debugging, which is usually where the real bottleneck in software development is.
Some tasks are more efficient to do in pairs. If we had to move a 100-pound desk from ten offices to the offices across the hall and we had two people to do it, it would probably be more efficient if they worked in pairs. In software development, I find lots of activities that are good to do with a partner—initial design, naming variables, debugging, refactoring, etc. If you believe that code reviews are a good thing then pairing is a code review as it is being written.
There are many ways to practice pairing. Generally, it involves two people sharing one computer who take turns “driving” and “navigating”. The driver is the one using the keyboard and mouse. The navigator is looking over their shoulder and thinking about what is next. They work for a while and then switch, taking turns anywhere from every 2 minutes to every few hours, but shorter is better so we recommend swapping driver and navigator every 4-6 minutes.
There’s also Ping-Pong pairing where one person writes a test and the other person implements it and then writes a test for the first person. Pairs rotate throughout the team one or more times throughout the day or by story or iteration. How it is configured depends and has an impact on its success. I recommend trying all configurations and seeing what works best for your team.
As a developer, I have a love/hate relationship with pairing. I love pairing on development projects because I learn so much but it is also harder work than if I was on my own. I have someone watching over me the whole time so I can’t be slacking and I can’t be falling back on bad habits.
So pair programming is a great way to help teams adopt new practices, such as TDD because if we fall back on old ways and start to write our code before we write our tests, there is someone there to catch us and remind us. The secret that managers are not aware of with pairing is that we will tend to work a lot harder when we are pairing. The good news is that our extra efforts are usually rewarded by learning from other developers by seeing the way they do things.
For a lot of developers, programming is a solitary activity. When we pair we learn little tricks that others have figured out that can help boost our productivity. Pairing also promotes collective code ownership. No one piece of code is “owned by” a specific individual. It also helps spread knowledge across a team. In fact, I know of no other faster way to propagate knowledge throughout a team than pair programming, except perhaps good training.
Like with most technical practices, it has to be done correctly in order to gain the most value from it. I recommend frequent swapping within pairs and frequent reforming of pairs to keep things interesting. We naturally gravitate to people who are like us but I find the best pairs are composed of people who are different from us–an introvert and an extrovert, a pragmatic thinker and an abstract thinker, etc.
Pairing is the fastest way I know to propagate knowledge and good habits across a team. It promotes collective code ownership and helps get everyone on the same page when building systems that require a team effort. These are just some of the reasons that I consider pair programming to be an essential practice.
The post Pair Programing Paradoxes appeared first on To Be Agile.


