With all the conversations about SAFe, you would think programs were a new idea. Actually, they have been used for many decades to manage very large efforts. This article discusses lessons learned from the past about how to set up a program at the beginning so it will run more smoothly throughout.
A program is one kind of construct to organize and coordinate the work of a large number of people on the same deliverable. Other constructs include value streams, products, product families/lines, and the open source model (community ownership of software with rules and governance). I have heard of programs as small as 40 people contained within one company and I have been personally involved with programs involving hundreds of people, sometimes across several companies or countries. Programs are used to manage big efforts.
Programs were developed in the defense industry to manage efforts such as putting a man on the moon, creating a new submarine, or creating an overall battlefield management system. Programs were adopted in commercial enterprises to manage efforts such as SAP implementations or creating a new tractor. Creating a mobile app does not require a program.
Programs are used to manage large complex efforts. A key technique to managing complexity is to structure the work in such a way as to get rid of as much complexity as possible. Simplify as much as possible, then manage the rest.
When planning your program, assign work to individual teams in such a way as to reduce or remove dependencies between teams. Each team should work as independently as possible. There should be little or no dependencies based on time, code, functionality or any other factor.
You can achieve this independence by assigning complete independent work packages (for example use case, user story, subsystem, component, or task) to each team. If the work packages are truly independent, you should not have very many cases where multiple teams need to work in the same code base, nor should you care much about what order the work is completed.
Any points where the teams need to cooperate should be well defined using tools such as contracts, interfaces, services, or API’s. Test harnesses and stubs can be effectively used to keep the work of the various teams as independent as possible, allowing each team to test their own code even if code they need to use from another team does not yet exist.
Teams should NOT be set up around the SDLC, i.e. a requirements team, design team, coding team, and testing team. This creates unnecessary dependencies between teams such as the coding team is waiting on designs, the testing team is waiting for code, etc. Each team should be responsible for the complete life-cycle for the work package they are assigned.
You do have to plan coordination points for releases. Teams cannot work on whatever they please. Each team has to make a commitment to deliver certain functionality at a certain time with specified quality. This is a commitment to their co-workers on the other teams. There may be other work a team does as well, but there has to be a minimum set of code they complete by a specific scheduled date in order for everything to fit together. You have to carefully manage the teams so they deliver what they promised the other teams at the time they promised to deliver it. If you do a good job defining the integration points between teams and managing their work to complete on time, then integration of the work of the various teams should be fairly straight forward.
There has to be a program level management team whose job it is to create the appropriate work packages, set up the release schedule, assign the work to the teams, define the minimum each team is required to deliver to make the release, coordinate the work of the teams, remove obstacles between teams, and be the final arbiter in situations of disagreement. People managing the program may include architects (software, system, network, data, UI, business) as well as those in more traditional management roles. You may need people at the program level to create (or help create) code that coordinates the work between teams such as test harnesses, stubs, interfaces, services, or API’s.
While you can do a whole program with one release at the end, this is very high risk. Programs tend to be lengthy and much can change from beginning to end. It is much better to plan a series of releases with time scheduled to make any needed adjustments due to change or lessons learned.
In a well structured program, you do not have to care about how each team does their work. As long as the team delivers according to their contract, it does not matter if they are onshore, offshore, or vendor, or whether they use an Agile or Waterfall type of SDLC.
Finally, the key to a well-run program is monitoring the teams and their progress with appropriate metrics, regular meetings with a representative from each team to coordinate efforts, management by walking around when you can, and quick resolution of problems when they arise.