Fostering Product-Thinking Within Your Team

Fostering Product-Thinking Within Your Team

Pia Opulencia

Pia Opulencia

January 03, 2024

A Frequent Misdiagnosis

We’ve seen it before and what usually follows: Leadership wonders why software development velocity is slow (“Just ship it faster!”), customers are not adopting the product (“Make it cooler!”), and teams frequently miscommunicate or misunderstand requirements (“Provide more documentation!”). And yet, simply changing the mechanics of how the product is built may not achieve the desired result, making development slower or features less delightful.

The Certainty Effect

What levers can we pull to solve “slow delivery”? Is it the number of people on the team? The requirements process or lack thereof? Is it tooling and infrastructure? There is a wealth of information surrounding product development, delivery frameworks, and an industry of SaaS products that bake in their own development workflows as best practice. So, when faced with uncertainty about how to solve a problem like “slow delivery,” we often default to what is most known to us and thus perceived as less risky. We pull on the levers that we know and are tractable.

Organizations employ a myriad of software development practices and team structures with no two companies following the exact same form. The most successful software product companies master connecting their customers with the value their product offers. What do these companies have in common? Product mindset.

Mindset Mastery

Instead of focusing on processes and tools, organizations have shifted toward focusing on the mentality of approaching a problem to solve. The organizations able to hone this skill across their teams are more likely to achieve their desired outcomes.

A product mindset places the customer at the center of every decision, values continuous improvement, and emphasizes the long-term success and sustainability of a product. Before diagnosing your organization’s particular issues, observe how your teams work together, make decisions, and frame problems within four pillars of product mindset:

1. The necessity of prioritizing features based on customer feedback and market demand. Evaluate how priorities are defined within each workstream. Do the parameters being considered, such as level of effort and addressable market, fit the target customer?

2. The importance of delivering value to the customer. Has your team attended a user research call? Does your team see customer support tickets? Building empathy for the customer can improve how we decide what to build.

3. The need for a long-term vision for the product. Does your team make near-term technical decisions that balance the long-term vision? Does the long-term vision provide the team with tractable problems to solve?

4. The significance of cross-functional collaboration and teamwork. How are the teams communicating with each other? Is there transparency or siloes?

Value-driven Prioritization

Customer feedback is the lifeblood of a product-driven mindset. To develop this mindset, your teams should actively seek, analyze, and act upon customer feedback. This requires a shift from a "build it and they will come" mentality to a "listen, iterate, and improve" approach.

To prioritize customer feedback:

- Collect feedback through surveys, user interviews, and data analytics.

- Create a feedback loop that channels insights back to the development teams.

- Use feedback to prioritize feature development and product improvements.

- Continuously iterate based on customer input

Prioritization

Driving Toward a Vision

A product mindset requires a clear understanding of what success looks like. Establish key performance indicators (KPIs) and metrics that align with your product's objectives. This enables your teams to measure progress and make data-driven decisions incrementally. The continuous measurement and milestones towards the long-term vision allow for course corrections along the way.

To set clear goals and metrics:

- Define measurable objectives for your product.

- Establish realistic timelines and milestones.

- Monitor KPIs and adjust strategies accordingly.

- Celebrate achievements and learn from setbacks

Cultivating an Empowered Team

Fostering a product mindset starts with breaking down silos within your organization. Encourage cross-functional collaboration among product, design, development, and quality assurance teams. This multidisciplinary approach ensures that all stakeholders are aligned with the product vision and share responsibility for its success.

To promote collaboration:

- Create cross-functional teams where members work together on the same product.

- Establish clear communication channels to facilitate information sharing.

- Encourage regular meetings and brainstorming sessions.

- Celebrate team achievements rather than individual accomplishments.

By focusing our improvements around mindset and less on promoting “foolproof processes” we promote the agility of the team. This agility allows for organizations to react quickly to changing market conditions, leveraging the empowered team to extract and deliver continuous value to customers.

Interested in learning more about how your organization can adopt a product mindset? Give us a shout!

Pia Opulencia

Head of Product

Pia Opulencia has been a product executive at multiple technology companies and has taught Product Management for AI at Northwestern Kellogg University's MBA in AI program. With more than 15 years of experience working with teams and companies of all sizes, Pia specializes in creating valuable, tech-forward products and the operating systems for the teams that build them.

How to Find the Value in Legacy Code

How to Find the Value in Legacy Code

Brad Ediger

Brad Ediger

July 22, 2022

As software consultants, we work with a lot of legacy software systems. Although we serve clients seeking new custom software as well as those with maintenance needs, it's extremely common for us to do our work in "legacy" environments — ones which have requirements we might read as idiosyncratic due to the evolution of the system or organization.

There's a reason legacy has a pejorative connotation in the industry. Legacy systems are hard to work with. They put us under constraints we didn't choose; they spend time and money toward problems we didn't endeavor to solve in the first place; they complicate the path from problem to solution. So what value do they bring?

Old Code Works

In fact, they bring a great deal of value. A simplistic definition of "legacy code" could be:

Legacy code is code that delivers more in value than it costs to maintain.

This is almost so reductive as to be meaningless; it pushes a lot of the complexity into the definition. But I often find it provides a useful perspective on the legacy systems we engage with, because it motivates us to remain humble in approaching things that have been around longer than we have.

The value may not be immediately obvious. Not everyone may even agree on the value provided. We may even think that an organization is "wrong" in a choice to preserve a legacy system. But systems rarely become legacy systems without a legacy. If you're not confident you can describe that legacy, keep looking.

The Legacy of Working Effectively with Legacy Code

One of the books that structured the 8th Light approach to handling legacy systems was Michael Feathers's 2004 book Working Effectively with Legacy Code. Feathers defends an opinionated definition of legacy code:

To me, legacy code is simply code without tests. I've gotten some grief for this definition. What do tests have to do with whether code is bad? [...] With tests, we can change the behavior of our code quickly and verifiably. Without them, we really don't know if our code is getting better or worse.

—Michael Feathers, Working Effectively with Legacy Code (emphasis added)

We strongly agree here at 8th Light; we've been proponents of a test-first approach from our founding. We've seen how, in addition to building confidence in the behavior of code, a well-structured test suite can help drive a system's implementation toward more maintainable and understandable code. When we launch new work, we use test-driven design to kickstart projects into that virtuous cycle.

The power of the Feathers book is its pragmatism. It spends no time debating the premise that the lack of tests is a problem (the quote above is from the inside flap!). The entirety of the book is about what to do when you're not in the virtuous cycle.

The majority of the book is a playbook of common problems and solutions (e.g., "I'm Changing the Same Code All Over the Place," "This Class Is Too Big and I Don't Want It to Get Any Bigger"). It concludes with a catalog of safe, mostly mechanistic changes that can be made in the absence of tests to gain a foothold, which helps work around the chicken-and-egg problem where "untested code tends to be untestable."

Nearly 20 years after publication, Working Effectively with Legacy Code is still relevant and is still the book we use to teach this topic in our apprenticeship. This book was responsible for encouraging developers to take testing more seriously. It argued that the thing to do with code you're scared of is to find ways to become less scared of it.

The book removed the excuse that a system was "untestable" by demonstrating a bunch of ways to add tests. But it also provided a safety net and somewhat defanged the idea of working on legacy systems. And so, throughout our history, we've been able to explore the positive connotations of the word "legacy" without as much fear. Our consultants even talk about their legacy as a point of pride.

The Strength of Legacy Code and the Folly of the Easy Rewrite

There's a survivorship bias in the selection of legacy code we find ourselves talking about, which can cause problems. If legacy code is definitionally code that carries its own weight, we could talk ourselves into a sunk-cost fallacy: this code must be worth it, it's been here so long!

On the other end of the scale, when we all agree that the cost of maintaining a particular system clearly exceeds the value it delivers, nobody talks about it as "legacy code" — it gets quietly forgotten.

There is actually some theoretical foundation for this survivorship-bias approach in technology. The Lindy effect theorizes that for some artifacts — in particular technological ideas — future longevity is proportional to past longevity. Ideas that have been around longer are expected to stay around longer. This is equivalent to lifetimes being Pareto-distributed, which feels like a plausible and parsimonious model that could apply to the lifetimes of software systems:

Graph

If the Lindy effect indeed applies to systems in production, we should treat the fact that a system has existed for a long time as evidence of its fitness for purpose. This feels not just realistic, but somewhat obvious. Despite the lack of tests, "that system" that's been serving customers for 15 years has a much stronger claim at robustness and fitness for purpose than anything we would put in place today — entirely by virtue of its observed history of success.

So why are rewrites so tempting? Why are teams so drawn to finishing their analysis of a working system, dismissing it as irredeemable, and replacing things from scratch?

Part of the temptation of the rewrite is because it's much easier to engineer things from a blank page than to understand and safely change an existing system. Wouldn't it be nice to focus on a well-understood problem without being held back by unrelated problems and constraints? Empirically, we know that's not what happens with rewrites, but if it were possible, it would avoid seemingly unnecessary work.

We may fail to fully account for the cost of a rewrite because we have some unknown unknowns about the existing system. This underlines the importance of the Feathers approach to untested code: the right thing to do with valuable untested code is to find the fastest way to add tests.

Rewrites also tempt legacy code maintainers because of the planning fallacy. Humans display a consistent optimism bias when planning their own work. Because rewrites are usually much larger and less well understood than maintenance of suboptimal but robust software, this bias tends to systematically affect rewrites more than maintenance.

A Plea for Epistemic Humility

It's very hard to enumerate all the value that a complex organization gets out of a complex system, even when the functionality is well-characterized. And most of the time, the functionality is not well-characterized. This presents numerous opportunities to make mistakes if not working methodically.

I often use the parable of Chesterton's Fence to illustrate the importance of humility in new situations. Taking some creative liberties with the original 1929 quote, I usually explain it:

If you come across a fence that's getting in your way, you should figure out who put it there, and why, before advocating for its removal.

This also reminds me of the "Prime Directive" we use to remind participants in an agile software retrospective to assume good faith when talking about past events:

Regardless of what we discover, we understand and truly believe that everyone did the best job they could, given what they knew at the time, their skills and abilities, the resources available, and the situation at hand.

—Norman L. Kerth, Project Retrospectives: A Handbook for Team Reviews

This is a methodological commitment, not a philosophical one. You don't have to believe everyone always did their best, but it helps to try to always presume the best. It focuses our analysis on systems instead of people. Rather than criticizing the behavior of individuals, we're humbly looking for the systemic factors that weighed on the design of the system.

And that can take some ethnography.

Finding the Value in Legacy Systems

Start by asking people. Ask any and all with knowledge of the system — be expansive in your conception of who a "stakeholder" is. Think of all the people the system touches. If original developers are available, get all the information you can out of them.

If the stakeholders aren't directly accessible, you'll have to get more creative. Perhaps the product is an ecommerce site or consumer-facing SaaS product. In those cases, there are more passive behavioral measurements, such as analytics and logs, as well as more active methods such as A/B testing. Product owners are great subject-matter experts to query about the value the system was designed to deliver.

If you are able to take input from people who were involved in the design or development of the legacy system: fantastic! Treat it as a valuable opportunity to learn about the system. Be curious about the decisions, constraints, and pressure that produced the thing you're working with. But also be mindful that if there are ways in which the existing system doesn't serve users' needs; the input you receive may have the same biases that produced the original.

In legacy systems that are still undergoing active development, it may be useful to look at rates of change. Which parts of the system change most frequently and least frequently? But beware that there are a number of factors that drive rapidity of change:

- Rapidly changing code could be code that's delivering a lot of value, performs a function in high demand, or gets enough attention that it is frequently tweaked. But it could just as well be code that's difficult to get right, depends on a frequently changing collaborator, or is written by developers who lean on QA to find their bugs.

- Slow-changing code could be code nobody cares about, or it could be "bedrock" that does a simple function well enough that it doesn't need to change that often.

Source-control history can be a valuable source of collateral information. Often a "why did they do it this way" question about a localized spot in the code is easily resolved when seeing the change in the context of everything else that changed with it. Be curious of the code and its authors: "why did they do it this way" should always be asked in 100% sincerity, because it always has a sincere answer.

Make sure to also look upstream of the code to go beyond the substance of what changed and start identifying motivation. Issue trackers, helpdesk systems, and development roadmaps all help illuminate the ways in which parts of an organization see and use a system.

Be very hesitant to conclude "human error." At a large scale, the function of systems is a product of the organizations and processes that produce those systems. (It's not that it isn't human error. It's quite often human error! But a diagnosis of human error does nothing to change a system meant to be staffed by fallible humans.)

It's usually easier and safer to iterate on a working system than to replace it. If making the easy change doesn't feel safe, building that confidence is the first problem to solve.

It's possible to incrementally modernize legacy systems. It's possible to make code systematically better and improve its design while incrementally building an understanding of what it does. Doing so safely almost always requires comprehensive automated tests.

Legacy code is very often bad code — it is hard to understand, hard to modify, or not up to modern standards. But where it has evolved to serve a business purpose and has spent years delivering value: no matter how you may criticize it, there is always at least one sense in which it is good code.

Designing for AI: Unveiling a New Set of Personas

Designing for AI: Unveiling a New Set of Personas

Jeff Mielke headshot

Jeff Mielke

March 22, 2024

How do we tailor AI systems so they're more than just a fancy tool in our toolkit? It's not all about sleek designs or high-tech flair; it's about shaping moments that genuinely make life easier and more enjoyable. As designers, we're at a crossroads, figuring out how to blend AI seamlessly into our day-to-day products without making it feel like it's taking over.

This challenge is a call to action for us to ensure AI acts more like a supportive buddy than a bossy robot. Our aim is to lead with the needs of the people and to integrate AI, so it feels natural, ethical, and, above all, focused on enhancing human experiences. Let's step up to this exciting challenge, crafting AI systems that get us, help us, and maybe even surprise us in good ways.

Designing for AI

At first glance, designing for AI seemed straightforward. Why not just plug in a ChatGPT API and watch the magic happen? Content creation becomes a breeze, data aggregation a no-brainer, and suddenly, we're living in a design utopia, right? Well, as I ventured deeper into integrating with AI, I discovered it's more than just about making tasks easier. It's about reimagining the way we approach software design using some familiar techniques.

Unleashing the Power of AI Personas

In one of the first courses I took on Designing for AI, I heard about considering AI as another person to design for. It has its own needs and constraints that must be considered during the design process.

Enter the benefit of AI Personas: potential solutions for addressing these multifaceted challenges.

To better articulate this concept, let’s take an example of designing a new slide presentation app. The first step in our design process is to understand the domain and the pain points.

Let’s say research points to the following insights:

- Individuals in an organization spend 20-40% of their time each week tweaking visuals in slide presentations.

- Deck creation requires hours of research and coordination to create an effective presentation.

- Many presentations require weekly updates as data changes.

- A typical presentation deck receives 20-30 comments inline, via email, and chat, which delays content updates.

Now, we have a new tool in AI to help with some of these tasks. Let’s consider how we can leverage AI to address these concerns.

- Creative AI helps the user quickly create visually appealing and content-rich presentations.

- Optimizer AI helps the user create a more contextually relevant presentation and learns over time what works best for the user.

- Aggregator AI summarizes data sources, comments, related emails, and chat content for easier consumption and real-time updates.

Now, let's take a look at the needs of each of these personas.

Creativity AI 2 copy

Creative AI, as you might guess, excels at imaginative tasks — it generates compelling graphics and text, or offers design templates. However, it needs clear direction on brand guidelines and the audience in order to execute effectively (as we do as well!). Should the presentation be sparse and minimal like Apple’s design system or more colorful and playful like Lego’s?

This information needs to be provided by the user or some backend instruction. Is this meant to be presented to an audience or used as a reference document? If it’s for an audience, the text should be sparse, and speaker notes should be populated. If it’s a reference document, it can be structured more like a report with a more text-heavy layout.

Optimizerai 2 copy

Optimizer AI is the efficiency expert designed to streamline and automate mundane tasks, such as setting up slide transitions or formatting bulleted lists. However, it needs to understand the context of the presentation and have a history of past presentations to index. It also needs to understand feedback on each presentation. Maybe some presentations were better received than others. Maybe certain presentations would work better for certain goals. This data could guide the AI in making contextually relevant suggestions to polish the presentation.

I had never captured this type of feedback on a deck and recorded it anywhere, but now I see how it could be valuable.

Aggregator AI copy

Aggregator AI primarily focuses on pulling together disparate data and information. Imagine creating a presentation informed by a plethora of relevant, up-to-the-minute data sources, with Aggregator AI ensuring all data points are seamlessly integrated and intelligibly presented. No need to constantly update that monthly metrics presentation!

Besides external data sources, this persona also needs access to all user comments in the presentation and, ideally, any relevant emails or chats. This makes updates easier for the user by offering a summary of user feedback. It also can leverage its friend, Creative AI, to recommend changes.

Right away, you can see that a lot of integration is required between various systems. This insight can help get your engineering teams to work early on, ensuring data streams are in place to optimize output and minimize user input.

The Principles of Designing with AI

Although each of these personas may have different needs, some considerations must be made when designing around these components. Here are six fundamental principles:

1. Transparency and Explainability

The principle of transparency and explainability in AI design is about making the AI’s decision-making processes as clear as possible to the end user. It involves designing interfaces and experiences that not only reveal what the AI is doing but also why it's doing it. This principle is vital in building trust and ensuring that users feel comfortable and confident in how AI impacts their interaction with a product.

In the context of our app, an AI feature could be introduced to assist users in designing their presentations by suggesting design layouts or color schemes. This AI tool would not only provide suggestions but also explain why certain options are recommended. For example, if the AI suggests a specific layout, it could explain that this layout helps in achieving better audience engagement based on the content type or the user's past preferences. This could be implemented via a simple tooltip or a side panel that provides insights into the AI’s recommendation logic. This approach not only accelerates the creation of presentations but also educates users on solid design principles.

2. Adaptability and Personalization

AI systems excel in learning from interactions and adjusting their behavior to better serve individual user needs over time. This dynamic learning capability allows for the personalization of user experiences in unprecedented ways. Designing for adaptability means creating interfaces that can evolve, offering personalized experiences based on the user's interactions, preferences, and feedback.

For instance, in our app, if a user frequently opts for minimalist designs and a certain color palette, the AI could prioritize these options in future suggestions. Additionally, it could adapt the complexity and frequency of tips and tutorials based on the user's proficiency with the tool, enhancing the learning curve for new users while streamlining processes for experienced ones.

3. Ethical Considerations and Bias

Incorporating AI into design demands a rigorous examination of ethical considerations and the proactive mitigation of bias. This principle focuses on ensuring fairness, accountability, and inclusiveness in AI-driven solutions. Designers must consider the diversity of their user base and ensure that AI systems are trained on diverse datasets to prevent perpetuating existing biases. Several companies, such as Google and IBM, have established principles to follow.

The AI in our app could be trained on a dataset of presentations from various industries, cultures, and design preferences. Implementing this ensures that design recommendations are inclusive and cater to a diverse range of user preferences. Furthermore, an option could be included for users to provide feedback if they feel a certain recommendation is biased or not suitable, allowing the AI to learn and improve its suggestions.

4. Consistency and Reliability

Consistency and reliability are foundational to user adoption and satisfaction with AI-enabled products. This principle emphasizes the importance of repeatability and accuracy in AI responses and actions. Design strategies should include clear communication about the AI’s capabilities and limitations, avoiding overpromising or creating unrealistic expectations. Reliability also can be enhanced by ensuring that AI systems are robust and tested across a wide range of scenarios, reducing the likelihood of errors or misunderstandings.

Our app could include clear documentation and settings for the AI features. The AI's suggestions could be presented as options rather than directives, allowing users to choose whether or not to follow them. Ensuring the AI's recommendations are consistently high quality and relevant will also build trust over time.

5. Error Handling and Support

Despite advances in AI, errors and misinterpretations are inevitable. Effective error handling and support mechanisms are essential in maintaining user trust and engagement. This involves designing systems that recognize when they are failing and offer useful, accessible support options to the user.

For example, our app could detect when users are struggling with certain tasks and proactively offer targeted suggestions or the option to connect with a support agent. Additionally, incorporating a feedback loop where users can report issues directly related to the AI's suggestions helps improve the system's accuracy and reliability.

6. Sustainability

As AI models become more complex, their energy consumption and environmental impact grow. Designing for sustainability involves optimizing AI algorithms and their implementation for energy efficiency, minimizing the carbon footprint of digital products. This principle extends to user interactions, encouraging behaviors that reduce energy consumption (e.g., streamlining queries or interactions to minimize computational load). It also involves transparency about the environmental impact of using AI-enabled services, empowering users to make informed choices about their digital consumption.

One way our app could be optimized for energy efficiency is by by streamlining the AI's decision-making processes and reducing the computational load for common tasks. Moreover, users could be informed about the energy efficiency of different design choices, encouraging more sustainable practices. For instance, recommending design elements that are optimized for low-power devices or providing tips on efficient presentation delivery methods could contribute to this goal.

The Value of Incorporating AI in Design

By thoughtfully incorporating AI into product design, you can unlock many great benefits. It can boost efficiency and create improved user experiences, but it also can have a real, positive impact on business outcomes. Whether you’re trying to balance quality, innovation, and budget constraints or you need to fine-tune designs to specific environments, we know that AI can be a game-changer. However, it’s important to recognize that there’s a learning curve involved when you start using AI-based design tools.

Let’s Explore an AI Partnership

By embracing transparency, adaptability, and a commitment to ethical principles, we have the opportunity to forge a future where technology and humanity intersect in harmony. Together, we can navigate the complexities of this new frontier, crafting experiences that resonate deeply with the very essence of human interaction.

We invite you to reach out and discover how our expertise can help you embrace the opportunities of this new AI era.

Jeff Mielke headshot

Jeff Mielke

Design Director

Jeff Mielke serves as 8th’s Light’s Design Director, bringing a wealth of experience from his work with both prominent and emerging brands over the years. His expertise lies in tackling intricate challenges and infusing a user-centric approach to his design practices. His portfolio spans across a range of applications, from consumer-oriented to enterprise-level solutions.