My Three Principles of Product Development

George Lutz
5 min readMar 5, 2022

Focus. Simplify. Deliver continuously. These are my three guiding principles of software development. Slipping away from any of these causes disappointment to follow.

These three principles may apply to any type of product development. I do software development, hence the context.

When we encounter a team that is struggling to deliver results, we want to understand why and then fix it. I immediately consider these three principles. Inevitably, they are missing on at least one of them.

In contrast, whenever I see teams with proper focus of scope, who are actively driving toward systemic simplicity, and who are delivering change incrementally, I can nearly guarantee that they are delivering good results overall.

Focus

Have you ever started a project, then started another one, then got interrupted to fix something else, then had some priority change again? Have you seen a manager who is managing three or four projects at once? Have you seen cases where people on one team are managing people working on something else entirely? Or when someone has no guidance at all? This is all the opposite of focus. Over time and at scale, it leads directly to wasted effort.

You can do anything, but you can’t do everything.

Focus means stacking the team with the right people for as long as needed. Focus often means making difficult (even if temporary) tradeoffs — possibly even having some customer wait longer than they want to. Focus may require changing the org structure. Focus means scoping the work of even the managers such that they are not also managing several other projects, thrashing their focus every hour of every day. Even minor thrashing is very impactful, if it’s consistent.

Focus means that people on the project are not also moonlighting on other projects. Focus means working on version 1, before working on version 3. And finishing version 1 before speculating on version 5. It means that we can serve a single user before we try to serve 10,000 users.

When focus is achieved, then, and only then, is the team truly empowered. And only then can the team be held accountable for delivering good results. Focus eliminates excuses. When you are allowed to focus, either you deliver or you don’t.

Every manager and every team should know their top two goals at any given time.

Focus and finish. And finishing may end up meaning that the project is cancelled because it’s not going to succeed. Even that is fine — everyone can move on to other work now.

Kill the zombie projects and focus on what matters.

Simplicity

The principal job of a software architect or a software creator of any kind is to contain complexity.

“The most fundamental problem in software development is complexity. There is only one basic way of dealing with complexity: divide and conquer.” — Bjarne Stoustrup

There are 5 categories of potential complexity:

  • Technological complexity. Unnecessarily complex design patterns, empty layers of code, lack of system documentation, reliance on the unproven tools, and high cyclomatic or cognitive code complexity as defined by a static code analyzer.
  • Integration complexity. Too many components are communicating without constraints. This is easily possible in a microservices environment.
  • Organizational complexity. Conway’s Law states that software architecture will reflect the structure of the organization which built it. It’s therefore important to create focused teams, empowered and accountable to deliver complete logical parts of a system with minimal dependencies on other people and other teams. Organizational structure matters a lot. It has to reflect reality and imply the focus of people and teams. Every person should be on the right team with their true manager.
  • Operational complexity. Complexity in a system which is already in use. For example, deployments that are not automated and take hours to validate. Or 20 people are needed to sign off on changes.
  • Marketplace complexity. Let’s not worry about it for now.

We need strategies for complexity containment! Here’s a few:

  1. Automation that works. We must consider build, test, and deployment automation as if it is the product itself. Because it is. Code is code. It all has to meet the same standards.
  2. Investment in system transparency and observability. We must be able to see what is happening inside of our systems, not just what are the inputs and outputs.
  3. Rigid identification of the problem being solved. Such that you minimize the capabilities of a system. One line problem statements are key here.
  4. SOLID coding principles. Use them relentlessly.
  5. Enforcement of communication constraints in a system with many nodes. For example, one master data management service accesses a data store, not 100 services accessing a data store.
  6. Investing in clarity of communication. This might even mean hiring different people with different skills.
  7. Breaking down large tasks into smaller tasks.
  8. Containerization
  9. Removal of the unnecessary: code, tools, data stores, meetings, frameworks, features, UI, or even people on the team. Remember, the goal is to deliver a product that the business needs. That’s it.

Deliver Continuously

This is a primary reason for Agile methodology so I’m certainly not inventing something new here. I’m simply making it even more concise. I believe that this first Agile principle is derived in many of the other Agile principles. I believe that this principle is the essential aspect of Agile:

Satisfying customers through early and continuous delivery of valuable work.

I don’t get overly concerned about the specifics of process: three stand-ups per day or three per week. Different teams have different people and different styles. Every team must deliver continuously though.

Sometimes you may not have a real customer to deliver to. This is common. For example, you are a stealth mode startup and you are doing a year of development before going live. There are a few options in such cases. Making excuses for not having a real customer is not one of them. Here are the options:

  1. Find real customers
  2. Find internal customers
  3. Pretend that you are the customer
  4. Build an automation system which acts as the customer

Deliver to someone or something continuously. Even every day. This forces you to keep the software working. It let’s you fail fast. And it may let you bail fast if the project isn’t going to make it.

One team I work with delivers mobile application updates internally upon every single code commit. Good for them. We will find problems fast this way.

Work hard and work smart

You may have experienced a time when everyone was working hard and with the right intentions, yet the results were not good. Everyone thinks they are doing well and that others are too. Yet the results stink. This is a good time examine the team’s focus, the simplicity (or lack of simplicity) of the systems being built, and whether the team is delivering continuously.

--

--