<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Kieran Bond</title>
    <description>The latest articles on Forem by Kieran Bond (@kieran).</description>
    <link>https://forem.com/kieran</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F223799%2Fc403f6a9-c43d-4a6c-82a6-f050c5dcf853.jpg</url>
      <title>Forem: Kieran Bond</title>
      <link>https://forem.com/kieran</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/kieran"/>
    <language>en</language>
    <item>
      <title>This is a well-written, technical post. It also features some excellent external links, making it highly recommended reading for everyone developing!</title>
      <dc:creator>Kieran Bond</dc:creator>
      <pubDate>Tue, 15 Jul 2025 15:17:36 +0000</pubDate>
      <link>https://forem.com/kieran/this-is-a-well-written-technical-post-it-also-features-some-excellent-external-links-making-it-1edm</link>
      <guid>https://forem.com/kieran/this-is-a-well-written-technical-post-it-also-features-some-excellent-external-links-making-it-1edm</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/isaachagoel/are-sync-engines-the-future-of-web-applications-1bbi" class="crayons-story__hidden-navigation-link"&gt;Are Sync Engines The Future of Web Applications?&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/isaachagoel" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F329991%2F11cf0248-ec4f-4417-856f-ba9b74d7a5a6.png" alt="isaachagoel profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/isaachagoel" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Isaac Hagoel
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Isaac Hagoel
                
              
              &lt;div id="story-author-preview-content-1889465" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/isaachagoel" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F329991%2F11cf0248-ec4f-4417-856f-ba9b74d7a5a6.png" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Isaac Hagoel&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/isaachagoel/are-sync-engines-the-future-of-web-applications-1bbi" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jun 17 '24&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/isaachagoel/are-sync-engines-the-future-of-web-applications-1bbi" id="article-link-1889465"&gt;
          Are Sync Engines The Future of Web Applications?
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/webdev"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;webdev&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/svelte"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;svelte&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/javascript"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;javascript&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/programming"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;programming&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/isaachagoel/are-sync-engines-the-future-of-web-applications-1bbi" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;233&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/isaachagoel/are-sync-engines-the-future-of-web-applications-1bbi#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              25&lt;span class="hidden s:inline"&gt; comments&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            15 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>webdev</category>
      <category>svelte</category>
      <category>javascript</category>
      <category>programming</category>
    </item>
    <item>
      <title>I'm investigating the pain points people are having with conducting user interviews/research! Help me out and fill out my survey? https://tally.so/r/wop2BX Thanks in advance!</title>
      <dc:creator>Kieran Bond</dc:creator>
      <pubDate>Thu, 08 May 2025 19:36:32 +0000</pubDate>
      <link>https://forem.com/kieran/im-investigating-the-pain-points-people-are-having-with-conducting-user-interviewsresearch-2hm4</link>
      <guid>https://forem.com/kieran/im-investigating-the-pain-points-people-are-having-with-conducting-user-interviewsresearch-2hm4</guid>
      <description></description>
      <category>ux</category>
      <category>discuss</category>
      <category>productivity</category>
      <category>career</category>
    </item>
    <item>
      <title>Why you want cross-cutting product teams</title>
      <dc:creator>Kieran Bond</dc:creator>
      <pubDate>Tue, 03 Sep 2024 14:24:46 +0000</pubDate>
      <link>https://forem.com/kieran/why-you-want-cross-cutting-product-teams-d63</link>
      <guid>https://forem.com/kieran/why-you-want-cross-cutting-product-teams-d63</guid>
      <description>&lt;p&gt;I've recently been reading/listening to '&lt;a href="https://www.amazon.co.uk/hz/audible/mlp/mfpdp/B005MR4NCC?actionCode=AMN30DFT1Bk06604291990WX&amp;amp;tag=thoughtsofkb-21" rel="noopener noreferrer"&gt;The Lean Startup&lt;/a&gt;' and '&lt;a href="https://www.amazon.co.uk/hz/audible/mlp/mfpdp/B07KFJB6G7?actionCode=AMN30DFT1Bk06604291990WX&amp;amp;tag=thoughtsofkb-21" rel="noopener noreferrer"&gt;The Making of a Manager&lt;/a&gt;' (Disclaimer: Associate links!), so this may be the impact of thinking about startups a lot and how they function. However, I think that in more 'established' companies, we do things inefficiently and don't ever try to get better. Startups are great at getting ahead and disrupting because they need to be impactful instead of stagnant.&lt;/p&gt;

&lt;p&gt;In traditional 'enterprise' software companies, you can almost guarantee that everybody works solely within their area of expertise: their ‘silo of expertise’. They are isolated from each other. Engineers work exclusively on engineering tasks, salespeople focus solely on sales, etc. Each department operates separately, leading to a lack of collaboration. For example, in developing a product, engineers write the code without involving designers until much later, when they ‘throw it over the fence’ to the other ‘silo’. The ‘silo’s’ never really interact or collaborate, and nothing is done promptly. &lt;/p&gt;

&lt;p&gt;We should strive for something more akin to startups. Cross-functional teams designed around a product to focus on that one product and not their 'silo of expertise'. Let's call a simplified version of this structure the 'Product Silo' (aka, a cross-cutting product team).&lt;/p&gt;

&lt;h2&gt;
  
  
  Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;What it means to have a cross-cutting product team&lt;/li&gt;
&lt;li&gt;Why would I want a cross-cutting product team?&lt;/li&gt;
&lt;li&gt;Why don’t companies adopt a cross-cutting product team structure?&lt;/li&gt;
&lt;li&gt;The unsolved problems&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What it means to have a cross-cutting product team
&lt;/h2&gt;

&lt;p&gt;So what? What does it mean to have a cross-cutting team? Just another name for the team building the product, right?&lt;/p&gt;

&lt;p&gt;Nah. It's foundational; it's cutting down the barriers. It's a way of working.&lt;/p&gt;

&lt;p&gt;When you're in a silo of expertise, your team is other experts in your domain. In a cross-functional team, your team is only the people needed for the product to succeed. Rapport and collaboration are different - we are all biased toward working better with our team than with generic colleagues.&lt;/p&gt;

&lt;p&gt;There's no throwing shit over the fence and blaming the salespeople now, you're one team. It's like &lt;a href="https://devops.com/devops-shift-left-avoid-failure/" rel="noopener noreferrer"&gt;the shift-left movement of DevOps&lt;/a&gt;; you become one team with one focus.&lt;/p&gt;

&lt;p&gt;Instead of putting in a request to design to mock up the UI flow, you sit with them and build it together. Instead of sales selling every product the company makes, they sit with the product owner and engineers to have deep product knowledge and know all about the upcoming features they can convince prospective clients they want.&lt;/p&gt;

&lt;p&gt;So, what does it mean to have a cross-cutting product team? It means having a team of experts dedicated to one product.&lt;/p&gt;

&lt;h3&gt;
  
  
  Who's in this supposed team, then?
&lt;/h3&gt;

&lt;p&gt;Everybody who needs to be to make and sell the best damn product you can.&lt;/p&gt;

&lt;p&gt;The non-exhaustive list, if you need somewhere to start:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Product owner&lt;/li&gt;
&lt;li&gt;Product engineers&lt;/li&gt;
&lt;li&gt;Product support&lt;/li&gt;
&lt;li&gt;Sales&lt;/li&gt;
&lt;li&gt;Marketing&lt;/li&gt;
&lt;li&gt;Design&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why would I want a cross-cutting product team?
&lt;/h2&gt;

&lt;p&gt;Great question.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You’ll have a product that users want, with fewer issues.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But you don't just get that automatically by forming the team. The team gets there (eventually) for multiple reasons.&lt;/p&gt;

&lt;h3&gt;
  
  
  Feedback loops are shorter.
&lt;/h3&gt;

&lt;p&gt;You'll get the right product in the hands of the right people quicker.&lt;/p&gt;

&lt;p&gt;It's easier to get direct user feedback to the correct people because they're the teammates of the ones who hear it first - Sales, product support and the product owner. They can pass a note over as they're on the call; it's that quick. There's no barrier to break, no having to go through multiple team leads or jump through hoops that make you give up. Tap them on the shoulder (as they probably sit next to you now) and tell them. Better yet, take them out to clients with you - and no hoops to jump through to get that approved.&lt;/p&gt;

&lt;p&gt;Sales can get all the metrics/insights they need to help sell the product directly from the engineers - or even be given hands-on ability to get the data because they're a trusted team member. They can hear from the team what's in the pipeline and are ready to start telling clients about it, and they can say to the product owner right after a call what the clients are screaming for before they can make the sale.&lt;/p&gt;

&lt;p&gt;Support can work with the product owner to ensure they have the proper domain knowledge to help customers. Work with engineering to eliminate the biggest problems that keep occurring or get playbooks in place that make the resolutions quicker.&lt;/p&gt;

&lt;p&gt;Marketing, design, and engineering work side-by-side to build the best damn-looking product out there - and the iteration is tenfold quicker because there are no scheduling issues.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quicker feedback loops lead to teams being more efficient and more agile.&lt;/strong&gt; The whole team can pivot and shift focus on what's most essential to the product without any roadblocks or re-alignments needed across multiple teams - it just happens.&lt;/p&gt;

&lt;h3&gt;
  
  
  Deep knowledge base
&lt;/h3&gt;

&lt;p&gt;Everybody on the team will have a deep knowledge base about the product; they'll be able to chat your ear off about it.&lt;/p&gt;

&lt;p&gt;What this translates to in value, however, is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No bus factors in knowledge&lt;/li&gt;
&lt;li&gt;A team of product experts, people who can knowledge-share with others and answer questions&lt;/li&gt;
&lt;li&gt;A team of people who think differently can contribute to solving a complex problem - instead of lots of people who think like engineers (for example)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cross-cutting expertise
&lt;/h3&gt;

&lt;p&gt;Let's take &lt;a href="https://alexkondov.com/the-t-shaped-engineer/" rel="noopener noreferrer"&gt;T-shaped engineers&lt;/a&gt; to another level. Let's build a T-shaped team.&lt;/p&gt;

&lt;p&gt;Okay, maybe not—that's too much of an ask. But we can get a team of experts with basic cross-domain understanding instead.&lt;/p&gt;

&lt;p&gt;When you have a team of people with varying expertise, you'll find that everybody starts to be able to speak the same language. That's because they all develop foundational skills for each expertise they interact with.&lt;/p&gt;

&lt;p&gt;Suddenly, sales can have a more technical discussion with the CTO they're trying to convince to be a client.&lt;/p&gt;

&lt;p&gt;Marketing can use the domain lingo with an understanding that entices users while collaborating with design to provide consistency across their advertisements and products.&lt;/p&gt;

&lt;p&gt;Engineers can better support users and experience &lt;a href="https://deviq.com/practices/dogfooding" rel="noopener noreferrer"&gt;dogfooding&lt;/a&gt; the product and support pressures while cross-training their support peers to have a deeper understanding of the technical details that enable them to help users better. They can join sales on a call with a prospective client and demo the product without blundering and putting them off.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fewer distractions
&lt;/h3&gt;

&lt;p&gt;What slows down a lot of delivery? Distractions and context switching.&lt;/p&gt;

&lt;p&gt;What causes distractions and context switching?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Needing to interact with other people, particularly those outside of the team.&lt;/li&gt;
&lt;li&gt;Different projects/products requiring your input&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Bring the people into the team and the inherent trust circle, and put their sole focus on one product.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By having one sole product to focus on, there's no real need to context switch. You don't need to learn about another domain or product regularly so that you can contribute your expertise to it; you just contribute to the one you're now an expert in.&lt;/p&gt;

&lt;p&gt;You become an expert in the two things that matter and need execution: The product and your skillset. You're efficient when an expert, so keep the expert's experts.&lt;/p&gt;

&lt;p&gt;Being in the circle of trust of the team also has its advantages; there's less back-and-forth. For example, the engineering team can teach sales how to use the analytics tool and only need to teach two people - then they can be trusted to have full access and not break it. They don't need to distract engineering ever again for this data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Better business understanding
&lt;/h3&gt;

&lt;p&gt;When working in silos of expertise, it's effortless to fall into the trap of focusing solely on your 'craft'. For example, engineers may chase 'perfect code' instead of recognising &lt;a href="https://thoughtsofkb.substack.com/p/the-cost-of-refactoring?r=5jvvo" rel="noopener noreferrer"&gt;the cost of refactoring&lt;/a&gt; because they're focused exclusively on producing the perfection of their craft.&lt;/p&gt;

&lt;p&gt;By contrast, a cross-cutting product team has a broader view of the business—it becomes easier to see and understand the product's impacts on the company.&lt;/p&gt;

&lt;p&gt;As a team, you're all closer to the impact of decisions, and you can see the pressures every team member has to face. You'll hear the sales experts talking about how they still need to find £0.5m to hit revenue targets for the product, and you can help them get on top of that because now these targets hit closer to home. If your product doesn't hit its goals, you're closer to the chopping block than when you are merely in a silo of expertise.&lt;/p&gt;

&lt;p&gt;A significant problem existing in ‘silo of expertise’ companies is that everybody is disconnected from focusing on making the business/product profitable. It’s not their responsibility, and they have no direct impact on the bottom line (or so they believe).&lt;/p&gt;

&lt;h2&gt;
  
  
  Why don’t companies adopt a cross-cutting product team structure?
&lt;/h2&gt;

&lt;p&gt;Why isn't everybody doing it if it’s so great ‘KB’? Great question!&lt;/p&gt;

&lt;h3&gt;
  
  
  Inertia
&lt;/h3&gt;

&lt;p&gt;Inertia is required to make an idea come to life. Once the ball gets rolling, it’s much easier to get buy-in from others.&lt;/p&gt;

&lt;p&gt;Gathering inertia in a company requires political capital, especially for a change like this, which is probably controversial, ‘unknown’, and challenges egos.&lt;/p&gt;

&lt;p&gt;‘Unknown’ ideas are feared as they can cause disruption, making it hard to get buy-in from people with the capital to spare.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cost of change
&lt;/h3&gt;

&lt;p&gt;Rome wasn’t built in a day, and there’s no Trojan horse. &lt;/p&gt;

&lt;p&gt;Changing tact across a whole org is costly, and many companies don’t like experiments—especially when they take a lot of time to prove. &lt;/p&gt;

&lt;h3&gt;
  
  
  Cultural barriers
&lt;/h3&gt;

&lt;p&gt;Some cultures don’t care for teamwork and are more finger-pointy. Cross-cutting product teams require collaboration, trust, and selflessness to work. &lt;/p&gt;

&lt;p&gt;Everybody shifts away from the comfort zones of their silos/departments and has to learn to work closely with other experts. They’re no longer ‘the’ expert. Some will struggle with this shift from focusing on being top-dog, particularly those in top-down cultures. &lt;/p&gt;

&lt;h3&gt;
  
  
  Good enough is good enough.
&lt;/h3&gt;

&lt;p&gt;Sometimes, chasing perfection isn’t worth it, and companies are happy with ‘good enough’.&lt;/p&gt;

&lt;p&gt;Why risk changing something that already works(ish)?&lt;/p&gt;

&lt;h2&gt;
  
  
  The unsolved problems
&lt;/h2&gt;

&lt;p&gt;I think cross-cutting product teams are more effective than silos of expertise. But look, perfect doesn't exist. There are problems with every approach.&lt;/p&gt;

&lt;p&gt;My unsolved issues are either unsolved because I don't know the answer or because I'm not sure I'm right.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cost
&lt;/h3&gt;

&lt;p&gt;These teams are going to cost more to run than traditional silos of expertise, in a sense.&lt;/p&gt;

&lt;p&gt;'One salesperson per product?! We're going to need 5 salespeople per client!!'&lt;/p&gt;

&lt;p&gt;On paper, you're going to want more people. However, there are tradeoffs.&lt;/p&gt;

&lt;p&gt;While you may need more of each role, like the above sales example, you will have more efficient teams. Does this mean you can run leaner overall as an organisation? Possibly!&lt;/p&gt;

&lt;p&gt;You may also reduce labour hours. If you've got experts focusing on problems (such as a member of support dealing with a client outage), they can find the solution quicker than a non-expert. That reduced labour time could add up to less cost overall.&lt;/p&gt;

&lt;h3&gt;
  
  
  Multiple teams for one product
&lt;/h3&gt;

&lt;p&gt;Extensive products may be too big for one team to handle. It then becomes tricky, as you don't want large teams - it'll likely fall back into silos of expertise.&lt;/p&gt;

&lt;p&gt;The question is: Do you need multiple teams?&lt;/p&gt;

&lt;p&gt;You're trying to do too much if you answered yes. You don't. You should make smaller, more focused products - split your 'big' product into multiple, more defined products.&lt;/p&gt;

&lt;p&gt;If &lt;a href="https://aws.amazon.com/executive-insights/content/amazon-two-pizza-team/" rel="noopener noreferrer"&gt;Amazon's two-pizza team size&lt;/a&gt; is accurate, then most AWS products are owned by a team of 10 or fewer people. If they can build things like S3, Lambda, etc., with that few people - why can't you?&lt;/p&gt;

&lt;p&gt;Splitting products up will cost money, so it’s probably a significant deterrent for companies that already have their products tied together.&lt;/p&gt;

&lt;h3&gt;
  
  
  Team growth is more challenging.
&lt;/h3&gt;

&lt;p&gt;How do you grow your team of experts professionally? Being mentored by experts is a big part of learning to perfect your craft. Your team will be filled with experts but not with the expertise the mentee needs.&lt;/p&gt;

&lt;h4&gt;
  
  
  More senior teams are needed.
&lt;/h4&gt;

&lt;p&gt;It is harder to grow teams professionally, so you probably need more senior teams. Hiring juniors is now less effective (fewer mentors), and thus:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The teams cost more to hire and run.&lt;/li&gt;
&lt;li&gt;Juniors are not coming up through the ranks, making the team less sustainable in the long term.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Cross-cutting product teams are a strategy you can use to change how work works in your company. Move the focus away from expertise and to the product - align the right people to the work, leading to better outcomes from a leaner team.&lt;/p&gt;

&lt;p&gt;I'll add a cheeky disclaimer here, too. I've never &lt;em&gt;fully&lt;/em&gt; experienced working in a cross-cutting team, so some of this is hypothetical, but I have tasted the forbidden fruit. It works.&lt;/p&gt;

&lt;p&gt;However, I'm just an engineer trying to do things right and efficiently. I'm probably deluded and drinking the Kool-Aid.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>agile</category>
      <category>leadership</category>
      <category>collaboration</category>
    </item>
    <item>
      <title>Measure twice, cut once</title>
      <dc:creator>Kieran Bond</dc:creator>
      <pubDate>Thu, 01 Aug 2024 14:42:50 +0000</pubDate>
      <link>https://forem.com/kieran/measure-twice-cut-once-4dl</link>
      <guid>https://forem.com/kieran/measure-twice-cut-once-4dl</guid>
      <description>&lt;p&gt;While renovating my house, my partner's dad guided and assisted me. It was my first real foray into DIY, but he had plenty of experience. The apprentice meets the master.&lt;/p&gt;

&lt;p&gt;One thing drilled into my head throughout the renovation was that you go faster when you make fewer mistakes, which resonates generally in life. One of the easiest ways to avoid mistakes is to 'measure twice, cut once' — a popular saying taught to apprentice tradesmen, I'm sure.&lt;/p&gt;

&lt;p&gt;We should take this approach with software: Make fewer mistakes by measuring. Too often, we make assumptions and act on them before validating them - these acts are mistakes because they lead to wasted effort.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1676559161408-986bb40d3bf2%3Fcrop%3Dentropy%26cs%3Dtinysrgb%26fit%3Dmax%26fm%3Djpg%26ixid%3DM3wzMDAzMzh8MHwxfHNlYXJjaHw1OHx8Y2FycGVudGVyJTIwY3V0dGluZ3xlbnwwfHx8fDE3MjI1MjMzMzN8MA%26ixlib%3Drb-4.0.3%26q%3D80%26w%3D1080" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1676559161408-986bb40d3bf2%3Fcrop%3Dentropy%26cs%3Dtinysrgb%26fit%3Dmax%26fm%3Djpg%26ixid%3DM3wzMDAzMzh8MHwxfHNlYXJjaHw1OHx8Y2FycGVudGVyJTIwY3V0dGluZ3xlbnwwfHx8fDE3MjI1MjMzMzN8MA%26ixlib%3Drb-4.0.3%26q%3D80%26w%3D1080" title="a person measuring a piece of wood with a ruler" alt="a person measuring a piece of wood with a ruler" width="1080" height="1111"&gt;&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
&lt;em&gt;Photo by Loren Biser on Unsplash&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;When should we measure?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How do we measure?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Counter Arguments&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When should we measure?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;To measure, or not to measure?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you're making decisions based on assumptions or incomplete information, it's time to pause and measure. Rushing into action without proper validation can lead to costly mistakes. If you can't measure yet, the best decision might be to do nothing.&lt;/p&gt;

&lt;p&gt;We're wired to believe that inaction is terrible; spoiler - it's not.&lt;/p&gt;

&lt;p&gt;Let's take a look at two examples:&lt;/p&gt;

&lt;h3&gt;
  
  
  The trading system
&lt;/h3&gt;

&lt;p&gt;You're building a system for trading stocks. It has two components: a front end (UI) and a ‘backend’ that accomplishes the work for the UI.&lt;/p&gt;

&lt;p&gt;Your UI needs to allow users to create requests to trade stocks. They range from wanting to create one to one thousand requests at a time but average ten (according to product owners!). You already have the ability to create these requests on your backend, but you need to trigger this functionality one request at a time. To improve the user experience, we’ve been tasked with creating a UI that allows users to create many requests to trade at once.&lt;/p&gt;

&lt;p&gt;Engineers are discussing creating new functionality on the backend to allow the creation of multiple trades simultaneously, with two purposes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Simplifying the work for the engineers trying to 'bulk' create trades on the UI.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reduce performance concerns of calling the create functionality thousands of times.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, what do you do?&lt;/p&gt;

&lt;p&gt;I understand the instant urge to say, 'Create the ‘bulk create’ functionality on the backend, easy.' I've felt that urge; it's an easy answer and sounds like it solves the problems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stop&lt;/strong&gt;. Do nothing. Breathe and measure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before you commit to any action, validate your hypothesis.&lt;/strong&gt; You will save time, prevent technical debt, and provide facts about system use and user behaviours. It's time to start adding measuring to your software development processes.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do we measure?
&lt;/h2&gt;

&lt;p&gt;First, we need to start fresh and remove both bias and assumption. We need to be analytical here and remove emotion.&lt;/p&gt;

&lt;p&gt;Different hypotheses require different methods of measuring - Users might need surveys, and systems might need specific tooling.&lt;/p&gt;

&lt;p&gt;Refrain from making assumptions about what to measure. Find evidence that the metric will answer your question.&lt;/p&gt;

&lt;p&gt;Let’s work through the above example. First, let’s reiterate what we’re trying to solve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Simplify the work for the engineers trying to 'bulk' create trades.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reduce performance concerns of calling the create functionality thousands of times.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are two assumptions here, so let’s actively call them out. &lt;strong&gt;Assumption one&lt;/strong&gt; : Enabling users to create bulk trades if there’s a specific endpoint is simpler for engineers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Assumption two&lt;/strong&gt; : Designated bulk create functionality will be more performant (latency and throughput) than calling the single create functionality individually each time.&lt;/p&gt;

&lt;p&gt;If we don’t highlight these assumptions more factually, it’s easy to get lost in what we are trying to analyse - we are discovering the hypothesis’. &lt;/p&gt;

&lt;p&gt;There are four assumptions. Did you spot the third and fourth?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Assumption three&lt;/strong&gt; : Users create bulk orders regularly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Assumption four&lt;/strong&gt; : Users create large (1000+) quantities of orders in bulk.&lt;/p&gt;

&lt;p&gt;Without assumptions three and four, one and two cannot be accurate, and without assumption three, four cannot be true. We should understand this pattern of dependency to avoid over-investigating when not needed. Let’s investigate assumption three first, as it’s the root of all others.&lt;/p&gt;

&lt;h3&gt;
  
  
  Assumptions three and four
&lt;/h3&gt;

&lt;p&gt;We must understand user behaviours and measure how often orders are created singularly or in bulk - &lt;strong&gt;assumption three&lt;/strong&gt;. Then we can investigate &lt;strong&gt;assumption four&lt;/strong&gt; - How many orders are made per ‘bulk’?&lt;/p&gt;

&lt;p&gt;If you have an observability system connected to the API, it should be as simple as recording every time each endpoint is used and which user it relates to. You can then aggregate orders over a short period, grouping by user, to see how many orders are being created in bulk. If you have access to observability on the system producing these ‘bulk’ orders, you can more accurately observe there instead.&lt;/p&gt;

&lt;p&gt;If assumption three, that users create bulk orders, is satisfied, and assumption four is satisfied (the quantitative number is now confirmed), we can justify spending time examining the remaining assumptions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Assumption two
&lt;/h3&gt;

&lt;p&gt;Next, we need to determine if there’s acceptable latency at the expected throughput— &lt;strong&gt;assumption two&lt;/strong&gt;. Thanks to assumption four, we should know the expected throughput. So, the question we need to answer is: What’s acceptable latency?&lt;/p&gt;

&lt;p&gt;It’s subjective and depends on many factors. The easy answer would be ‘whatever the product owner decides’, and that’s ok if they have that answer. Otherwise, it’s complex and requires a lot of research. &lt;/p&gt;

&lt;p&gt;Some things to consider might be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Does the user care about individual requests succeeding? Or is it only about the whole bulk succeeding?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How time-critical is this functionality? Are users blocked from doing further things until it is complete and they have visual confirmation?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Where does the latency requirement sit? Is it in the confirmation for users in the UI (the whole process), or is it just in the sending of the request to another system (a sub-process)?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this example, latency isn’t too high on our priorities as it requires manual (other) user input on another downstream system, and our user is not blocked waiting for that confirmation. This means we can essentially throw away the need to satisfy this assumption.&lt;/p&gt;

&lt;p&gt;In another world, where we have a latency requirement, this comes down to observability and performance testing. You need to set up scenarios that stress test the system to see if it meets the determined latency requirement. The great thing about that is that you will then be able to performance test your system at will because you built the ability to when proving this out.&lt;/p&gt;

&lt;h3&gt;
  
  
  Assumption one
&lt;/h3&gt;

&lt;p&gt;Our last assumption ( &lt;strong&gt;assumption one&lt;/strong&gt; ) to review is that enabling users to create bulk trades through a specific endpoint is simpler for engineers. &lt;a href="https://newsletter.pragmaticengineer.com/p/measuring-developer-productivity" rel="noopener noreferrer"&gt;Engineering productivity is really hard to measure,&lt;/a&gt; so maybe that is the case, or maybe it’s not—you’ll need to do your own measuring/study here, I’m afraid.&lt;/p&gt;

&lt;p&gt;Where does that leave us?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Assumption three -&lt;/strong&gt;  Users create bulk orders regularly ✅&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Assumption four&lt;/strong&gt;  &lt;strong&gt;-&lt;/strong&gt; Users create large (1000+) quantities of orders in bulk ✅&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Assumption two -&lt;/strong&gt; Designated bulk create functionality will be more performant (latency and throughput) than calling the single create functionality individually each time ❌&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Assumption one -&lt;/strong&gt; Enabling users to create bulk trades if there’s a specific endpoint is simpler for engineers. ❓&lt;/p&gt;

&lt;p&gt;Depending on which way assumption one swings, you need to make a decision. Here are my thoughts: &lt;/p&gt;

&lt;p&gt;If assumption one turns out not to be true, then just stop caring. You’ve measured and determined it’s not worth the effort. Win.&lt;/p&gt;

&lt;p&gt;If assumption one is true, then you still need to weigh up the cost. It costs to build the required functionality to ‘simplify’ the work. Does that cost more than the (technical debt) cost of leaving it as it is?&lt;/p&gt;

&lt;p&gt;Weighing up technical debt cost against engineering cost is hard and probably subjective. I don’t know how to measure that, but I’m sure somebody on the internet has something less subjective than gut feeling.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pitfalls to avoid
&lt;/h3&gt;

&lt;p&gt;Before you get going on measuring everything everywhere, there are some pitfalls to be aware of.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Measuring only once&lt;/strong&gt;. Look at the title; it doesn’t say measure one. It says to measure twice—in fact, measure continuously. Don’t just measure twice and call it done; keep measuring after the cut and see what you can learn. The secondary impact of all this measuring is the learning.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Measuring for perfection&lt;/strong&gt;. Sometimes, it’s just not worth measuring absolutely everything. Do you need to invest time measuring productivity when working in a specific codebase to know if it’s worth refactoring to something more manageable? That’s a big investment upfront, and it's hard to measure the impact - especially on something as subjective as code. How do you measure the effectiveness of the action? My point is that it’s okay to trust your gut and let your brain do that automatic thing where it tells you the answer without spending brain cycles deliberating it. Previous experiences do still count as long as we make sure to take lessons from them.&lt;/p&gt;

&lt;p&gt;A subset of measuring for perfection is spending too long deciding what to measure or how to measure. You’ll reach analysis paralysis, get nowhere, and just waste time. Make sure it’s going to have a worthwhile impact if you’re going to spend a long time deliberating it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Measuring the wrong thing.&lt;/strong&gt; In counter to not measuring for perfection, don’t measure the wrong thing. This isn’t the worst thing in the world if you still learn from it and can use the measurements, but it’s still a waste of time. Do spend &lt;em&gt;some&lt;/em&gt; time trying to make sure you’re measuring the correct metrics!&lt;/p&gt;

&lt;h2&gt;
  
  
  Counter Arguments
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Measuring may take longer than implementing (I can't measure it, I need to build the tooling to measure it, or it's very complex to measure).&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Yes, it might. But with it in place, you'll be able to measure more things and objectively discuss other pieces in the future. It has a further impact than ‘just now’.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Yes, it might. But you won't build something unneeded and won't have to remove it / have the tech debt of maintaining it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If it's too complex, you may be trying to measure too much at once or measuring the wrong thing.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;My previous experience tells me that I am right in my assumptions. It’s a waste of time to measure it all first.&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;How did you find out that you were right last time? You measured.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Where’s the harm in proving it out? Having definitive evidence is always better when staring down the barrel.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There are great learning opportunities for everybody involved in measuring - it’s not just about you being right.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Stop and measure once in a while.&lt;/strong&gt; Commit to knowledge before action to make informed decisions - It’s easier to account for when things go wrong, and hopefully, things should go wrong less frequently because you’re using real data to form your actions. If it’s too expensive to measure, then take no action. Measure once the expense of measuring is less than that of not.&lt;/p&gt;

&lt;p&gt;Figuring out what to measure is hard and involves confronting our biases and assumptions, but it’s worthwhile. &lt;strong&gt;Data is hard to argue with&lt;/strong&gt;. You’ll save yourself a lot of time and work in the long run to make better products for your users, which is what we’re here for at the end of the day.&lt;/p&gt;

&lt;h3&gt;
  
  
  The conclusion to the example
&lt;/h3&gt;

&lt;p&gt;So what happened in the end? We did nothing. It wasn’t worth measuring because we had nothing causing us to need to measure - we didn’t have users complaining, and the engineers could still easily build their functionality. So, we didn’t measure and took no action.&lt;/p&gt;

&lt;p&gt;The ‘issue’ just went away.&lt;/p&gt;

</description>
      <category>innovation</category>
      <category>agile</category>
      <category>engineering</category>
      <category>development</category>
    </item>
    <item>
      <title>Maximising one-to-one effectiveness</title>
      <dc:creator>Kieran Bond</dc:creator>
      <pubDate>Fri, 02 Feb 2024 15:33:56 +0000</pubDate>
      <link>https://forem.com/kieran/maximising-one-to-one-effectiveness-3439</link>
      <guid>https://forem.com/kieran/maximising-one-to-one-effectiveness-3439</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1604881989793-466aca8dd319%3Fcrop%3Dentropy%26cs%3Dtinysrgb%26fit%3Dmax%26fm%3Djpg%26ixid%3DM3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxjb2xsZWFndWVzJTIwY2hhdCUyMHdhbGt8ZW58MHx8fHwxNzA2MTgyNDQxfDA%26ixlib%3Drb-4.0.3%26q%3D80%26w%3D1080" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1604881989793-466aca8dd319%3Fcrop%3Dentropy%26cs%3Dtinysrgb%26fit%3Dmax%26fm%3Djpg%26ixid%3DM3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxjb2xsZWFndWVzJTIwY2hhdCUyMHdhbGt8ZW58MHx8fHwxNzA2MTgyNDQxfDA%26ixlib%3Drb-4.0.3%26q%3D80%26w%3D1080" title="a group of people sitting around a white table" alt="a group of people sitting around a white table" width="1080" height="720"&gt;&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
&lt;em&gt;Photo by Priscilla Du Preez 🇨🇦 on Unsplash&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As I've grown in my career, I've realised that one-to-ones are a critical aspect. You can accelerate your career and capabilities with effective one-to-ones, but making one-to-ones productive is challenging and ever-changing.&lt;/p&gt;

&lt;p&gt;There are a few different types of one-to-one meetings. I'm going to focus on the kind of one-to-one you have with your team lead - often used or seen as a 'reporting' meeting. People usually tell their boss exactly what they've been up to since the last one, hoping to portray themselves as productive - but that's different from what your one-to-ones should be about. &lt;strong&gt;Using it as a reporting meeting is an antipattern and not worth wasting time doing&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The reality is that one-to-ones should be a helpful and productive use of time - they’re short bursts of focus from your team lead, which you can maximise. Do so by keeping them about these three things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Your career.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Your relationship with your team lead. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Contents&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Topics of focus&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;One-to-one environments&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Frequency of one-to-ones&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Topics of focus&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;As I said above, you should aim to have productive one-to-ones, and the most productive things to focus on are you, your career, and your relationship with your team lead.&lt;/p&gt;

&lt;p&gt;Having a rapport with your team lead allows you to build trust, which goes both ways. You trust them; they trust you. With trust, you can have more open and frank conversations and don't spend time dancing around trying to avoid offending or upsetting. It allows for more truthful insights from both ways, expanding how you can help each other.&lt;/p&gt;

&lt;p&gt;So, what do you talk about in your one-to-one? In a non-definitive order of importance:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Goals - career and personal&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Things going on with and around you&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Feedback&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Opportunities&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Frustrations&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Recent achievements&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The business - context, goals, things happening&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The team&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Goals - career and personal&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Having goals is essential for both your career and your self-growth. &lt;strong&gt;Goals help give direction&lt;/strong&gt; (in and out of work). These can be as simple as 'Getting to the gym every day' or as stretched and ambiguous as 'Accelerating development across the org'. You're good if you have achievable objectives that you both agree to and feel are worthwhile pursuing. Talk about creating new goals, progress towards current goals, and what support you need to achieve your goals.&lt;/p&gt;

&lt;p&gt;When looking to create new (career-oriented) goals, think about your key areas of growth - where is there the opportunity to grow, and what areas are worthwhile growing in? Ensure they’re measurable and achievable goals, so you know how well it’s going. It’s also worthwhile having the goal be something you’re intrinsically motivated to achieve, as otherwise, it’s very easy to let it slip.&lt;/p&gt;

&lt;p&gt;For example, technical writing may be a worthwhile skill in your job - perhaps write regular blog posts to practise and improve.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Things going on with and around you&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;It's good to keep your team lead in the loop about your life - if you feel comfortable sharing it. &lt;/p&gt;

&lt;p&gt;If you keep your team lead in the know, they can offer you personal support or support from the company and provide air cover if needed.&lt;/p&gt;

&lt;p&gt;An example of things happening with you could be something as simple as your kid having trouble sleeping recently or as complex as a medical diagnosis. It doesn’t have to be something big. Just keep them in the loop - otherwise, you risk an assumption being made when it starts visibly affecting you. &lt;/p&gt;

&lt;p&gt;Keeping your team lead in the loop will also contribute towards a trusting relationship as they’ll be more empathetic towards you. &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Feedback&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A big one! &lt;strong&gt;Feedback is hard for everybody, but remember that the intention is to improve&lt;/strong&gt;. Sometimes, asking for advice or perceiving feedback as advice will yield better results; advice feels less formal and can change the tone perceived. &lt;/p&gt;

&lt;p&gt;Feedback is another topic heavily driven by goals but less so than opportunities. As I said above, your team lead must be helping you grow; offering feedback is a big part of that.&lt;/p&gt;

&lt;p&gt;Feedback can be as simple as something your team lead has observed, or it can be an opportunity for you to ask for specific feedback, such as asking them to observe you in a meeting coming up so that they can offer targeted feedback - if one of your goals centres around involvement in meetings, for example.&lt;/p&gt;

&lt;p&gt;Feedback/advice is a significant topic in itself and is tricky. A better relationship with your team lead might offer more insight, as they may feel more comfortable giving you direct feedback. Ideally, you don't need this, but as we're all human, having that relationship there will make it easier for everybody involved.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Opportunities&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Goals really help drive this conversation. If your team lead has their ear to the ground (hopefully they will!), they'll know about things happening around the company that may align with your goals and can get you involved. You can then start discussing these together, as a critical team-lead responsibility is ensuring you grow professionally and personally - even if it means transferring you to another team offering better goal alignment.&lt;/p&gt;

&lt;p&gt;An example would be that you want to learn more about cloud infrastructure, and a role has just opened up in the newly founded platform team. Your team lead heard about this vacancy and has suggested you go for it to get closer to your goals.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Frustrations&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;We all get frustrated; it's inevitable. Some more than others (I'm pretty bad at this!). Letting out your frustration is important as otherwise, it builds up and becomes resentment. Venting some of this frustration to your team lead can be productive if it's something they can help with. However, keep this from eating up your one-to-ones, as it can turn into a negative feedback loop.&lt;/p&gt;

&lt;p&gt;Try to vent to your team lead privately instead of publicly, as otherwise, you risk demoralising those around you, again causing a negative feedback loop and making the team unpleasant.&lt;/p&gt;

&lt;p&gt;Don’t linger on venting frustrations for too long if you can. Remember what you aim to achieve in your one-to-one so you can refocus the session.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Recent achievements&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;As much as your team lead may try, it can be easy for them to miss everything of worth that you do - especially if you're part of a big team.&lt;/p&gt;

&lt;p&gt;Your one-to-ones are an excellent opportunity to highlight your recent achievements, ideally ones with tangible outcomes. Highlighting achievements helps ensure that when your team lead gives feedback or considers performance reviews, they have a better picture to paint.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The business - context, goals, things happening&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Akin to opportunities for you, your team lead likely has more context around decisions made and what's happening where.&lt;/p&gt;

&lt;p&gt;One-to-ones are an opportune time to get more clued up on anything you're unsure about within the business, primarily how it feeds into your growth and goals. This is also the ideal situation to ask questions you’re uncomfortable asking or may be riskier in a public forum.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The team&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Talking about the team in a one-to-one is tricky and is only sometimes a good use of time - as the one-to-one should be focused on you and your team lead. &lt;/p&gt;

&lt;p&gt;However, if your relationship with your team lead is ‘high trust’, you can offer more genuine feedback about your team members - your team lead may even expect this as your seniority increases. As mentioned above, feedback is a significant topic and probably warrants its own post - especially &lt;em&gt;giving&lt;/em&gt; feedback.&lt;/p&gt;

&lt;p&gt;If you have less granular feedback about team members to offer or the relationship isn’t ‘high trust’, then keep feedback high level here rather than getting into the details - it takes less time and reduces the chance of putting your foot in it. Some high-level things to discuss can include the team's ways of working or milestones being worked towards.&lt;/p&gt;

&lt;p&gt;Don’t forget - this is also a great chance to praise your team members!&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;One-to-one environments&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Where your one-to-one takes place can impact the effectiveness of your one-to-one as it affects the tone/atmosphere from the get-go. Sometimes, it's even worth choosing the environment per meeting based on what you're looking to get out of the session. &lt;/p&gt;

&lt;p&gt;I'm not a fan of choosing a meeting room as it makes the session feel very formal and feels like a meeting with 'management', which always puts me on edge. If I need a laptop or notepad, I'll choose a more open and communal space with somewhere to sit, and we'll chat over a coffee.&lt;/p&gt;

&lt;p&gt;If you're unsure, going for a short walk is a great default. The exercise and fresh air are good for you and will make you feel more engaged. Also, the lowered formality of walks themselves, coupled with walking side-to-side instead of sitting face-to-face, may make you feel more at ease and make any long pauses less uncomfortable. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Frequency of one-to-ones&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;How often should you have a one-to-one with your team lead? That's up to you and them to discover. &lt;/p&gt;

&lt;p&gt;Start more frequently, like once per week, and work backwards from there. I like the interval of once a fortnight as enough time passes between catch-ups that things worthwhile discussing happen, yielding a productive session without being so far apart that things get missed.&lt;/p&gt;

&lt;p&gt;Even if you have a scheduled one-to-one, you can cancel it. As a rule of thumb, it’s better to organise more frequent one-to-ones and cancel when not wanted - just make sure to avoid this becoming a habit, however.&lt;/p&gt;

&lt;p&gt;Conversely, you can organise extra one-to-ones ad-hoc, given you both can find time. If something has come up that you want to ensure you discuss, then put a meeting in. Don't just sit on it until the next one-to-one if it's important.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;In Summary&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Everybody has different one-to-ones, with different goals and ideals for productivity. Don't just follow what I've said here; take a deep look at what you want to get from them and tailor it to your needs. The time allocated for the one-to-one is your time, so you should aim to maximise it. &lt;/p&gt;

&lt;p&gt;Treating a one-to-one as a formality and not planning ahead (or at least having an informal agenda) to get the most from it isn’t worthwhile for either of you attending. You’re missing out on opportunities if you don’t maximise it. You have your team lead's full attention; use it.&lt;/p&gt;

&lt;p&gt;So, try customising the format/style until you think they're successful. Mix up the environment, too; it has a more significant impact than you think.&lt;/p&gt;

&lt;p&gt;Have any tips for having more effective one-to-ones? Let me know; I'm always looking to improve mine.&lt;/p&gt;

</description>
      <category>management</category>
      <category>beginners</category>
      <category>productivity</category>
      <category>career</category>
    </item>
    <item>
      <title>Succeeding with the 3 Musketeers pattern</title>
      <dc:creator>Kieran Bond</dc:creator>
      <pubDate>Fri, 19 Jan 2024 22:14:23 +0000</pubDate>
      <link>https://forem.com/kieran/succeeding-with-the-3-musketeers-pattern-1nef</link>
      <guid>https://forem.com/kieran/succeeding-with-the-3-musketeers-pattern-1nef</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1611288875785-f62fb9b044a7%3Fcrop%3Dentropy%26cs%3Dtinysrgb%26fit%3Dmax%26fm%3Djpg%26ixid%3DM3wzMDAzMzh8MHwxfHNlYXJjaHwxNHx8dG9vbHxlbnwwfHx8fDE2OTk4MTI3MDJ8MA%26ixlib%3Drb-4.0.3%26q%3D80%26w%3D1080" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1611288875785-f62fb9b044a7%3Fcrop%3Dentropy%26cs%3Dtinysrgb%26fit%3Dmax%26fm%3Djpg%26ixid%3DM3wzMDAzMzh8MHwxfHNlYXJjaHwxNHx8dG9vbHxlbnwwfHx8fDE2OTk4MTI3MDJ8MA%26ixlib%3Drb-4.0.3%26q%3D80%26w%3D1080" title="person holding gray and black metal tool" alt="person holding gray and black spanner" width="1080" height="1579"&gt;&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
&lt;em&gt;Photo by Recha Oktaviani on Unsplash&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Why use the 3 Musketeers?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What is the 3 Musketeers pattern?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When can you use the 3 Musketeers?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An example of using the 3 Musketeers pattern&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Why use the 3 Musketeers?
&lt;/h2&gt;

&lt;p&gt;The 3 Musketeers pattern has, to me, three (funnily enough!) primary reasons to use it:&lt;/p&gt;
&lt;h3&gt;
  
  
  Consistency
&lt;/h3&gt;

&lt;p&gt;All environments you use it in should(!) behave the same. Developer machines, CI/CD pipelines, etc. Debugging issues that arise, such as in your pipeline, is considerably more accessible when it behaves identically locally. Rather than pushing code up and waiting for your pipeline to tell you it's incorrect, you can test it out locally first in an identical manner and save yourself some time.&lt;/p&gt;
&lt;h3&gt;
  
  
  Ease of use
&lt;/h3&gt;

&lt;p&gt;One command to rule them all - &lt;code&gt;Make doThing&lt;/code&gt;. No worrying about every developer fully understanding the madness under the hood. Your onboarding Engineers can get straight into the thick of it, and your team can easily embrace your latest addition.&lt;/p&gt;
&lt;h3&gt;
  
  
  Speed
&lt;/h3&gt;

&lt;p&gt;Development is much quicker when you work consistently across the whole team, ideally org. When you have a pattern to follow for new commands, there's no thinking about exactly how to implement it - you follow the pattern. Following the pattern speeds up others, too; they don't have to learn a new toolchain for every new command.&lt;/p&gt;
&lt;h2&gt;
  
  
  What is the 3 Musketeers pattern?
&lt;/h2&gt;

&lt;p&gt;I won't do a better job than &lt;a href="https://3musketeersdev.netlify.app/" rel="noopener noreferrer"&gt;this&lt;/a&gt; website, but I'll take a go at summarising here for those wanting a TL; DR.&lt;/p&gt;

&lt;p&gt;'3 Musketeers' is a method that aims to keep your development repeatable and consistent by using three tools: (GNU) Make, Docker, and Docker Compose. &lt;/p&gt;

&lt;p&gt;Using Make as an orchestrator and entry-point, you can use docker/compose to provide the environment where you then execute your code.&lt;/p&gt;

&lt;p&gt;I’ve also recently come across a replacement to Make (as this isn’t Make’s real purpose) called &lt;a href="https://just.systems/" rel="noopener noreferrer"&gt;Just&lt;/a&gt;. It seems to focus more on why we use Make in the 3 Musketeers pattern, so maybe it will replace it one day.&lt;/p&gt;
&lt;h2&gt;
  
  
  When can you use the 3 Musketeers?
&lt;/h2&gt;

&lt;p&gt;So now that we understand what the pattern is and the benefits of it, when should we use it?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;All the time.&lt;/strong&gt; (Mostly). The 3 Musketeers is best when used for commands or functional tasks.&lt;/p&gt;

&lt;p&gt;Its primary use case is for making your build pipelines simpler to follow and easy to develop locally. Any time you have a step that runs in your CI/CD pipeline, you should define it as a Make command and follow the pattern. Creating and updating the step behaves the same locally as your pipeline, so it should be a quick iterative process.&lt;/p&gt;

&lt;p&gt;Another great scenario is whenever you need to run services in conjunction - such as for local testing. Have a microservice architecture and want to run all the services simultaneously to develop a new feature? Use the musketeers.&lt;/p&gt;

&lt;p&gt;Onboarding a new Engineer to the team can be tricky and convoluted. Why not set up the environment using the 3 Musketeers? You can host most services (such as Databases) in a container, spin up the service they will work on, and then seed it with a bash script - all from one command.&lt;/p&gt;

&lt;p&gt;Any other tooling scenarios are great candidates, too. Seeding, resetting, uploading, testing, you name it.&lt;/p&gt;
&lt;h3&gt;
  
  
  When not to use it
&lt;/h3&gt;

&lt;p&gt;Sometimes, it’s really easy to get lost in the weeds with a new pattern and try to use it everywhere. Looking at you, design patterns.&lt;/p&gt;

&lt;p&gt;While I highly recommend the 3 Musketeers for many things, don’t use it for everything. That’s an anti-pattern.&lt;/p&gt;

&lt;p&gt;It's a lot less useful when it’s just one or two people working on a project or there’s a project with not many repeated ‘commands’.&lt;/p&gt;

&lt;p&gt;The 3 Musketeers is also not great if all it’s doing is overcomplicating things. If all you’re doing is adding &lt;em&gt;another&lt;/em&gt; place to run commands from, maybe don’t add them. For example - If you’re just in a Javascript environment (where you likely use Yarn/Node/NPM) and all of your commands for building, testing, etc., are already in a ‘package.json’ file, then unless you plan to add more automation across the project outside of your javascript I would just leave it be. You’re just adding confusion and another place that needs updating.&lt;/p&gt;
&lt;h2&gt;
  
  
  An example of using the 3 Musketeers pattern
&lt;/h2&gt;

&lt;p&gt;We primarily use the pattern for our build pipelines, as it enables running and testing them locally before committing and pushing code up to the repository.&lt;/p&gt;

&lt;p&gt;Let's review an example command for running tests on a .NET project in the build pipeline. I’ll omit the pipeline file to keep this as minimal as possible, but I’m afraid a small amount of prerequisite knowledge around Docker/compose will be required, and you’ll need to install &lt;a href="https://www.gnu.org/software/make/" rel="noopener noreferrer"&gt;Make&lt;/a&gt; and &lt;a href="https://www.docker.com/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; if you want to do a hands-on follow along.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gist.github.com/KieranBond/ea2c1d6416a7fc10a9bfbb00b0f4e152" rel="noopener noreferrer"&gt;Here's a gist link&lt;/a&gt; for those who want to see the example pieced together. &lt;a href="https://github.com/KieranBond/Net-Musketeer-Base" rel="noopener noreferrer"&gt;Here’s&lt;/a&gt; an example .NET project which you can follow along with.&lt;/p&gt;

&lt;p&gt;So, the premise for the example is this: 'I want to run the unit tests for my .NET project in a CI/CD pipeline and locally as part of my development cycle.'. A very common scenario.&lt;/p&gt;

&lt;p&gt;First, we need to figure out how to run our unit tests. It's very straightforward with .NET, luckily. In a realistic scenario, we would add extra things, such as static analysis, but I want to keep this simple enough. In my team, we would usually add this in by extrapolating the command into a Bash script.&lt;/p&gt;

&lt;p&gt;So, to run unit tests in dotnet, we simply need to run this command in a terminal (with the .NET SDK installed):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s straightforward. It works on my machine; it's all good, right? Commit, push, watch it run…&lt;/p&gt;

&lt;p&gt;Oh, wait, our build pipeline doesn’t know the dotnet command. It doesn’t have the .NET SDK installed, and I can’t install dependencies on the agent. Hmm. Now what? Dockerise it!&lt;/p&gt;

&lt;p&gt;So, let’s use Docker to provide a consistent environment. Microsoft offers an official Docker image with the .NET SDK, which we’ll use. We’ll put it in a ‘docker-compose.yaml’ file like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: "3.8"

services:
    dotnet:
        image: mcr.microsoft.com/dotnet/sdk:latest
        working_dir: /app/app/src
        volumes:
            - .:/app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, we’ve added the ability to spin up a container with .NET installed and mounted our source code to the container when it runs.&lt;/p&gt;

&lt;p&gt;Now, we could just call it a day there and, in our pipeline, run this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker-compose run --rm dotnet dotnet test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But let’s simplify it for everybody as there’s a bit to unpack there, and a big advantage of Make is simplicity.&lt;/p&gt;

&lt;p&gt;So, let’s create our Make file. I’ll call it ‘Makefile’. Here’s the first draft:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;test:
    echo "Running Make test"
    docker compose run --rm dotnet dotnet test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, all we have to do in our terminal and pipeline is run the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;make test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isn’t that so much simpler? You can add that to your team documentation, where it will likely never change. If you had added the previous command, what happens when you want to change the behaviour? You might need to extend your test command to perform static code analysis, but then you’ll have to update your docs and pipeline and ensure your team knows they must run the commands the new way.&lt;/p&gt;

&lt;p&gt;Once your Makefile expands to contain other commands, particularly similar ones, you might want to tidy up and follow some best practices. I’ve expanded the Makefile in the linked gist to include a build command and a slight refactor to improve the file. I’ve also extended it to utilise a bash script so you can see how to utilise it in a similar scenario.&lt;/p&gt;

&lt;p&gt;In my team, we utilise Bash scripts alongside the 3 Musketeers. We use Bash scripts because most Docker images can execute them (maybe with a tweak), we want to do several things in a command, and we are comfortable with Bash.&lt;/p&gt;

&lt;p&gt;I suspect a more traditional use of the pattern is to chain multiple Make commands together instead. The expanded gist does both of these.&lt;/p&gt;

&lt;h2&gt;
  
  
  In Summary
&lt;/h2&gt;

&lt;p&gt;You might not need the 3 Musketeers; it has its &lt;a href="https://alexharv074.github.io/2019/11/07/when-3-musketeers-are-two-too-many.html" rel="noopener noreferrer"&gt;downsides&lt;/a&gt; - including added complexity in small projects. But, if you have yet to use it or want some order to your chaos, I recommend trying it.&lt;/p&gt;

&lt;p&gt;You don't need to use it for everything - we don't, but I strongly suggest it for your CI/CD pipelines at the minimum and anything automated that is repeatedly needed in your local development process.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>development</category>
      <category>tooling</category>
      <category>automation</category>
    </item>
    <item>
      <title>Integration tests are king</title>
      <dc:creator>Kieran Bond</dc:creator>
      <pubDate>Thu, 18 Jan 2024 11:22:29 +0000</pubDate>
      <link>https://forem.com/kieran/integration-tests-are-king-fck</link>
      <guid>https://forem.com/kieran/integration-tests-are-king-fck</guid>
      <description>&lt;p&gt;&lt;em&gt;Stop writing so many unit tests and join me on the dark side. Focus on integration testing instead of unit testing, and bask in the saved time and superiority.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Originally posted on my Substack &lt;a href="https://open.substack.com/pub/thoughtsofkb/p/integration-tests-are-king?r=5jvvo&amp;amp;utm_campaign=post&amp;amp;utm_medium=web&amp;amp;showWelcome=true" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffvz317wgn18ezp76a6f5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffvz317wgn18ezp76a6f5.png" alt="Testing Diamond model" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A caveat before we get into the meat of it:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Most of the test suites I work in are for Web APIs and deployed systems - especially recently, so I am biased. Writing integration tests for Web APIs is more accessible than other ‘systems’. When building other systems, such as libraries, consider ‘big unit’ tests but know that unit tests do still have their place. &lt;/p&gt;

&lt;h1&gt;
  
  
  Contents
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Test suite composure&lt;/li&gt;
&lt;li&gt;Why integration tests are king&lt;/li&gt;
&lt;li&gt;The downfalls of integration testing&lt;/li&gt;
&lt;li&gt;What makes an excellent integration test&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Test suite composure
&lt;/h1&gt;

&lt;p&gt;The ‘&lt;a href="https://martinfowler.com/articles/practical-test-pyramid.html" rel="noopener noreferrer"&gt;Testing Pyramid&lt;/a&gt;’ concept advises that most automated tests you create are the quickest to write and execute - often considered your unit tests. You have fewer tests as you move up the pyramid, but they are more integrated with the whole service. The three tiers from top to bottom are &lt;a href="https://en.wikipedia.org/wiki/Unit_testing" rel="noopener noreferrer"&gt;Unit testing&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/Integration_testing" rel="noopener noreferrer"&gt;Integration testing&lt;/a&gt;, and &lt;a href="https://microsoft.github.io/code-with-engineering-playbook/automated-testing/e2e-testing/" rel="noopener noreferrer"&gt;E2E testing&lt;/a&gt;. Most people will refer to the testing pyramid as why you should have more unit tests than anything else. However, there are other options.&lt;/p&gt;

&lt;p&gt;Unit tests are, generally, very targeted tests. They’ll often test a specific function with a particular input, expecting an output that exhibits a behaviour - or &lt;a href="https://open.substack.com/pub/thoughtsofkb/p/unit-testing-behaviours-and-critical?r=5jvvo&amp;amp;utm_campaign=post&amp;amp;utm_medium=web" rel="noopener noreferrer"&gt;they should&lt;/a&gt;. This style of unit testing is a ‘small unit’ test. &lt;/p&gt;

&lt;p&gt;These ‘small unit’ tests are perfect for critical behaviours/functions but quickly become cumbersome for comprehensive coverage. Most functional changes lead to you updating tests because these tests struggle to avoid implementation details, so at which point, why bother with them? You’ve fallen into an anti-pattern. Consider something better if you find yourself in this situation. Enter ‘large unit’ tests and integration tests.&lt;/p&gt;

&lt;p&gt;One model called the ‘Testing Diamond’ or ‘Testing Honeycomb’ is more powerful (see the photo at the top!). &lt;a href="https://engineering.atspotify.com/2018/01/testing-of-microservices/" rel="noopener noreferrer"&gt;Spotify highlights it&lt;/a&gt; as particularly great for testing Microservices. The main difference between the diamond and the pyramid is that Integration testing is where you focus most of your tests. &lt;/p&gt;

&lt;p&gt;As a de facto, I believe the testing diamond model to be better than the testing pyramid - even outside microservices. The critical reason the diamond is better is that it moves you away from implementation details and you go ‘bigger’; you move to behaviour testing at the most controlled and significant scale, interacting with the users’ boundaries with the system.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is integration testing?
&lt;/h3&gt;

&lt;p&gt;The key focus in integration testing is to check how the system-under-test (SUT) behaves with the systems it integrates with. For example, my service may interact with another service - I want to test some behaviours dependent on this other service without it being there. If I rely on the service being there, I may end up with flaky tests that randomly fail when it is offline or when it has been broken. Creating a stub you can control and inspect for the other service is standard - a fake upstream system.&lt;/p&gt;

&lt;p&gt;Integration testing allows us to test user flow through our system within our control bounds - at a high level. We can focus on how they interact with the system, from input to output, thus allowing us to determine if the behaviours we have built are correct without knowing implementation details. These tests have the added benefit of enabling us to assert there have been no side effects on other systems, as we usually have control over the ‘integrated’ systems via stubs/mocks. &lt;/p&gt;

&lt;h1&gt;
  
  
  Why integration tests are king
&lt;/h1&gt;

&lt;p&gt;Integration testing reduces the ability to involve implementation details in your testing. They focus a lot more on input and output and thus are much less prone to failure and are easier to keep up-to-date.&lt;/p&gt;

&lt;p&gt;You see, you’re doomed to fail when your tests involve implementation details. Implementation details require constant upkeep and lead to biased tests. Whenever your related feature changes, you need to update your tests, and it’s effortless to ‘cheat’ with your test and do the easiest thing (such as faking behaviour) rather than testing a flow thoroughly.&lt;/p&gt;

&lt;p&gt;By doing tests at a larger scale, you don’t mock out everything that makes the function behave the way it does - you get a true reflection of the behaviour in your system. You write fewer mocks, and so there are fewer mocks to maintain. You write tests against genuine entry points to your system from a user perspective and assert against the same output your user would receive.&lt;/p&gt;

&lt;p&gt;Another bonus to writing tests at the integration level is that they are generally ‘cleaner’. There’s rarely much setup because a stub already has defined behaviour and doesn’t need setting up for specific tests, so it’s simply the case of calling the entry point to your service and asserting on the result. I’ve had some tests be as small as two simple lines at this level.&lt;/p&gt;

&lt;p&gt;If you’re writing behaviour tests at this scale, you’ll ideally need fewer of these tests than you do ‘small unit’ tests. This can be easier to manage than the (probably) thousands of ‘small unit’ tests you write in every project. It’s also quicker to get off the ground.&lt;/p&gt;

&lt;p&gt;A great, overlooked advantage of integration testing is that you have service stubs. You need them for your tests, but have you considered that you can also host them in lower-release environments? &lt;/p&gt;

&lt;p&gt;Hosted stubs allow you to have development environments that don’t have dependencies on other teams or systems. You can release more quickly into these environments and perform any manual testing you fancy in a controlled manner. This control is also great for introducing &lt;a href="https://en.wikipedia.org/wiki/Chaos_engineering" rel="noopener noreferrer"&gt;chaos engineering&lt;/a&gt; or performance testing. You’ve got no risk of breaking other systems, can alter your stubs to suit the situation, don’t need to talk to other teams when experimenting and have control of the observation on these dependent systems to ensure they’re not causing the trouble you’re investigating in higher environments.&lt;/p&gt;

&lt;h1&gt;
  
  
  The downfalls of integration testing
&lt;/h1&gt;

&lt;p&gt;As always, it’s not all roses. When is it? If you find some silver bullets, let me know.&lt;/p&gt;

&lt;p&gt;Integration tests can, and often are, slower to run. You need to start systems before testing, which is much more work than exercising a small unit. As the test suite grows, the execution time does too. Not that unit testing is exempt from that, however. I’m keen to discover whether this becomes negligible at a big enough test suite scale; as mentioned above, you don’t need as many integration tests as you do unit tests. The most considerable slowdown in integration tests is the startup process.&lt;/p&gt;

&lt;p&gt;The beauty of being a ‘big unit’ is also a downfall. You’re not testing things at such a granular level; thus, it’s easier for tiny bugs to slip through the net. Arguably, they may not be bugs if they’re not affecting the overall behaviour - or your tests don’t cover enough behaviours.&lt;/p&gt;

&lt;p&gt;Sometimes, depending on how your suite is made to run, it can be harder to debug/write integration tests - especially without clear thought on the Developer Experience (DevXP) when building the framework. The difficulty usually comes from running the SUT in a docker container to emulate a genuine service (dependent on your architecture, etc.). You’ll either need tools to attach debugging to this container or spend the time ensuring you can run it locally when testing. This ability is essential; otherwise, writing tests can be slow, bugs can be hard to investigate, and you’ll be limited in your ability to use TDD. &lt;/p&gt;

&lt;p&gt;The most considerable downside of integration testing is that you now need system-level stubs. In most testing frameworks, creating mocks for ‘small unit’ tests is simple; thus, you don’t need to invest much time in getting them working for your tests. However, creating system-level stubs takes more time - often considerably more. &lt;/p&gt;

&lt;p&gt;These stubs are more complex, and ideally, you want them to replicate the other systems’ behaviours, which means they take time to build - even if simplified. You can mitigate this by making an integration test framework one of your top priorities when starting a project - you can then evolve it over time with your system as needed. &lt;/p&gt;

&lt;p&gt;Another downside to needing a stub - how do you know it behaves the same as the system it’s pretending to be? You can quickly instil false confidence in your system if you’re not careful. Mitigate this using E2E tests in your suite, potentially even having some that validate your stubs.&lt;/p&gt;

&lt;p&gt;One problem you can sometimes experience when creating integration tests for a Web API is static typing. If you build your test suite in a separate repository, you may need help referencing the static types you use in the API. It would be best to keep the tests colocated to make them easier to work with as part of the development process; otherwise, people will not contribute.&lt;/p&gt;

&lt;h3&gt;
  
  
  What makes an excellent integration test
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Short and sweet.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I’ve seen tests be as small as two lines (alongside some setup used for all integration tests). Keeping your test small and focused on a target behaviour is essential - making it readable and easy to comprehend. You can take a quick look at the test and understand the exact behaviour it is focused on and if it’s even being tested correctly (very useful for peer reviews). Make the call to your user interface and validate that the output/behaviour is seen correctly. That’s it.&lt;/p&gt;

&lt;p&gt;Try to do most of the data seeding in your framework before running any tests. Ideally, the SUT is already configured before any tests are run to behave more like a real system - The closer to realism, the better. How often does your system get called without any data set up, really?&lt;/p&gt;

&lt;h3&gt;
  
  
  How I like to create them
&lt;/h3&gt;

&lt;p&gt;I like to try writing integration tests first as part of TDD (and often skip unit tests altogether), so next time you’ve got a new feature or bug to write - give that a go. Before creating your new feature, define your behaviour in the integration test, specify the user interface in the test, and assert the output from your interface. Then, write your feature. The idea here is you’re focusing on the interactivity that matters - the users. If you concentrate on that up front, I find it makes the implementation more straightforward and is an easy point to start from.&lt;/p&gt;

&lt;p&gt;I like using the Arrange, Act, Assert methodology in my tests to keep them focused and clear - as I do in my unit testing (see &lt;a href="https://open.substack.com/pub/thoughtsofkb/p/unit-testing-behaviours-and-critical?r=5jvvo&amp;amp;utm_campaign=post&amp;amp;utm_medium=web" rel="noopener noreferrer"&gt;this&lt;/a&gt; post for more). &lt;/p&gt;

&lt;p&gt;Once that test passes, you can refactor as much as you like. You can then decide what might also be worthwhile unit tests to write. Don’t forget that you can always delete tests - you can use them to reassure yourself without adding them permanently to the test suite.&lt;/p&gt;

&lt;h3&gt;
  
  
  An example
&lt;/h3&gt;

&lt;p&gt;Suppose a trading system that depends on the market’s stock prices (market data). When an ‘order’ (trade) is created in this system, it wants to annotate the order with the current market price alongside the price it was executed at - this might be done to see the ‘improvement’ that the seller or buyer has achieved, aka profit.&lt;/p&gt;

&lt;p&gt;So, the behaviour I want to test is: An order is annotated with market data prices, and the user receives the data correctly in the output.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;CreateOrder_Annotates_With_MarketData_Touch&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Arrange&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;orderRequest&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;CreateOrderRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;42&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Act&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;PostCreateOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orderRequest&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;    

    &lt;span class="c1"&gt;// Assert&lt;/span&gt;
    &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TouchPrice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Should&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;Be&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MarketDataStub&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AskTouchPrice&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You would probably need a few unit tests to cover the same scenario, as it’s likely to encompass considerable parts of the system. However, you do need a stub to represent the market data integration, and depending on how you integrate with that system, this can be simple or tricky to create. In the example above, there’s a presumption the market data stub has already seeded the trading system. &lt;/p&gt;

&lt;p&gt;You would want one (or many) unit tests to verify that market data updates are fed correctly through the system from ingress; you would want another (or more) to confirm that an order is annotated with market data. You would want at least one more to ensure the API returns an order object correctly. &lt;/p&gt;

&lt;p&gt;Because that’s a lot of tests to write, I generally prefer integration tests when using TDD, as I think it helps me move quicker and just as accurately without compromise.&lt;/p&gt;

&lt;h1&gt;
  
  
  In Summary
&lt;/h1&gt;

&lt;p&gt;If you want to feel closer to the authentic experience of using your service, write more integration/‘big unit’ tests. Do them first with TDD, and you’ll make the system better for users.&lt;/p&gt;

&lt;p&gt;Try replacing some of your unit test suites with integration tests - you’ll hopefully see reduced coupling (to implementation behaviour) in your tests and a significant reduction in the number of tests that need to be written. &lt;/p&gt;

&lt;p&gt;If you’re not creating a web API, you can still write larger unit tests focused on functional/behaviour flow. Try moving some code towards that instead of small, focused units. &lt;/p&gt;

&lt;p&gt;Just don’t forget that other tests are still necessary; a well-rounded suite helps avoid the pitfalls of each test type.&lt;/p&gt;

</description>
      <category>testing</category>
      <category>programming</category>
      <category>productivity</category>
      <category>learning</category>
    </item>
    <item>
      <title>Strong opinions, loosely held</title>
      <dc:creator>Kieran Bond</dc:creator>
      <pubDate>Tue, 02 Jan 2024 15:39:38 +0000</pubDate>
      <link>https://forem.com/kieran/strong-opinions-loosely-held-1gal</link>
      <guid>https://forem.com/kieran/strong-opinions-loosely-held-1gal</guid>
      <description>&lt;p&gt;Repeat after me: &lt;em&gt;&lt;strong&gt;Strong opinions, loosely held.&lt;/strong&gt;&lt;/em&gt; This is your mantra.&lt;/p&gt;

&lt;p&gt;Forming a strong opinion is essential, and it's equally important to keep an open mind and listen to others. It’s a pivotal strategy for growing as an Engineer and pushing forward decisions. Form an argument you can back, but be willing to accept someone else's opinion if it's better, or respectfully &lt;a href="https://en.wikipedia.org/wiki/Disagree_and_commit" rel="noopener noreferrer"&gt;disagree and commit&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A fundamental rule before we dive in: Ensure you believe any opinion you take and are not using it to play devil’s advocate - you need to believe it enough to execute it, as you may have the top opinion. Playing devil’s advocate generally causes more resentment and wastes time than productive discussion. It has a place, but it isn't worthwhile 90% of the time.&lt;/p&gt;

&lt;p&gt;Credit where credit is due: I learned this from one of my team leads, who liked to repeat it often - and it's helped me a lot. Hopefully, it's helped my team, too, as we all try to follow the practice.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1512314889357-e157c22f938d%3Fcrop%3Dentropy%26cs%3Dtinysrgb%26fit%3Dmax%26fm%3Djpg%26ixid%3DM3wzMDAzMzh8MHwxfHNlYXJjaHwxMXx8dGhpbmtpbmd8ZW58MHx8fHwxNzAyNDkxMzkzfDA%26ixlib%3Drb-4.0.3%26q%3D80%26w%3D1080" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1512314889357-e157c22f938d%3Fcrop%3Dentropy%26cs%3Dtinysrgb%26fit%3Dmax%26fm%3Djpg%26ixid%3DM3wzMDAzMzh8MHwxfHNlYXJjaHwxMXx8dGhpbmtpbmd8ZW58MHx8fHwxNzAyNDkxMzkzfDA%26ixlib%3Drb-4.0.3%26q%3D80%26w%3D1080" title="photo of bulb artwork" alt="photo of bulb artwork" width="1080" height="720"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Why it’s essential to have an opinion&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Traps to avoid&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Generating an opinion on short notice&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why it's essential to have an opinion
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Opinions are easy to come by&lt;/strong&gt;, and just like assholes - everybody has one! You can form one in minutes. You have no excuse not to have one, and we'll discuss how to generate one later in this post.&lt;/p&gt;

&lt;p&gt;The most helpful thing about having an opinion is that they are great for starting discussions. Even inaccurate opinions can do this well - sometimes better.&lt;/p&gt;

&lt;p&gt;It's easy to face analysis paralysis when staring down the barrel and figuring out where to start. Enter the opinion, the conversation starter. &lt;em&gt;The fire starter&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;One of the quickest ways to form ideas when collaborating is to propose an idea. Just watch how quickly it will get picked apart and improved on. It's the same with opinions; defending an opinion will generate the most momentum. You want a 'defendable' opinion because it provokes thought and discussion and can lead to divergent thinking. As long as you genuinely believe in your opinion, it’s okay not to be 100% sold on it. You need some genuine belief to defend it for this provocation and creativity and see which way the conversation takes your opinion - it’s perfectly fine to defect to somebody else’s side after debating.&lt;/p&gt;

&lt;p&gt;It seems borderline human nature for people to want to prove why your opinion is wrong, so give them one they have to work for. You'll end up with a much better decision that has been validated and discussed in detail as to why it's better, with actual data points - and you'll probably have garnered agreement from the team during this discussion.&lt;/p&gt;

&lt;h3&gt;
  
  
  Opinion essentials
&lt;/h3&gt;

&lt;p&gt;When you want to have a strong opinion on something and back it in a discussion, I think it’s important to hit this checklist:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Enough believe that if you have to run with the idea, you’re happy to.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Empirical evidence over anecdotal evidence, if possible.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deep enough understanding to carry thoughtful discussion&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you can’t tick these off, maybe you shouldn’t argue about it. You’ll probably just be wasting people’s time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Traps to avoid
&lt;/h2&gt;

&lt;p&gt;Don't just pick an opinion from the internet. Come to an informed opinion that you understand.  &lt;strong&gt;If you don't understand the opinion, you can't defend it&lt;/strong&gt;  and thus can't trigger a good discussion - in which case, you're just wasting time and causing aggravation.&lt;/p&gt;

&lt;p&gt;For less experienced engineers, it can be daunting to go into a meeting and strongly voice an opinion that goes against your seniors. &lt;strong&gt;Have courage.&lt;/strong&gt; Don’t back down immediately because they’re more ‘senior’ than you. You’ll develop quite a few skills doing this. In a high-trust environment, this is a great way to grow - you’re not just learning from repetition but through understanding, which is fundamental. Listen to their arguments against your opinions carefully; hopefully, you can learn a lot! You may get proven wrong sometimes, but through having the discussions, you’ll get much better insight. Believe in yourself; you may teach them something new, too!&lt;/p&gt;

&lt;p&gt;Know when to back down; don't be stubborn. If you've caused some good discussion, you don't need to keep returning to your opinion, especially if you've been proven wrong enough - start rolling with the leading opinion and continue the conversation. Once the discussion has progressed enough, bringing up the opinion restarts the clock and slows additional progress - so just let it go.&lt;/p&gt;

&lt;p&gt;If this is an opinion you can't let go of and it determines a decision, consider agreeing to disagree and commit. Everybody on the team needs to be on board with the disagree and commit methodology before using it. Otherwise, it won’t play out well, and people will feel burnt. It can also be worth discussing if some method of veto is in place - For example, is the tech lead allowed to do so to ensure a terrible mistake isn’t made? Be careful with this, as it can easily lead to resentment, but consider putting something in place. Another thing might be that everybody is allowed &lt;em&gt;one&lt;/em&gt; veto (ever), so you can ensure it’s only used when truly needed.&lt;/p&gt;

&lt;p&gt;Disagree and commit: vote on which way to go when the team is butting heads and at an impasse. Sometimes an agreement just can’t be come to, so if you've said your piece, but the team has decided to go another way, then suck it up and roll with the team. You won't win every battle, but you can win the war as a team - you need some trust. Worst case? You're mistaken, and the team/everybody learns a lesson. Again, consider a veto method to ensure that truly is the worst case.&lt;/p&gt;

&lt;p&gt;In low trust, low maturity, or toxic environments, it can be risky to follow the mantra due to the chance of backlash from others. Work with your team to build trust and maturity in discussions, or consider changing jobs/teams instead! Don’t risk it all to follow the practice; pick your timing. Sometimes, it’s not always worth the fight in these environments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generating an opinion on short notice
&lt;/h2&gt;

&lt;p&gt;I just said not to pick an opinion from the internet, but maybe you should. Sort of.&lt;/p&gt;

&lt;p&gt;If you've got a meeting coming up, and you know the agenda but aren't informed enough to get involved in the discussion, then you have two options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Don't go.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Get an opinion quickly.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both are good choices. If you don't go, you save some time and avoid wasting others. If you go with an opinion, you can actively contribute and make it worthwhile.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to
&lt;/h3&gt;

&lt;p&gt;So you've chosen option two - Get an opinion quickly. Ideally, you've got at least 15 minutes. Anything less than that timespan, and you're going to struggle. How do we do it?&lt;/p&gt;

&lt;p&gt;Here are my tips:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Ask your colleagues (all of them) and put something together that is a mash-up of the opinions and that you can get behind and understand.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Search the vast resource known as the internet. Put together a few higher-trust sources or popular views and use those as your backbone.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do some mind-mapping and quickly come to something - Ensure you have facts backing it up, though! Combine this with the tip above to get a strong base opinion.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As I’ve said a few times, make sure you can get behind this opinion - truly. You may end up executing it. It can be hard on short notice, but it’s crucial as otherwise you risk wasting everybody’s (including your) time. Devils advocates are a waste of brainpower.&lt;/p&gt;

&lt;h2&gt;
  
  
  In Summary
&lt;/h2&gt;

&lt;p&gt;Always have an opinion for the meeting you're heading into, or don't go. It takes little time to form an argument, especially with practice.&lt;/p&gt;

&lt;p&gt;You should be willing to carry your opinion high and drive discussion with it, even willing to execute it. However, you'll help everybody if you're ready to back down when defeated (or disagree and commit). Just don’t play devil’s advocate.&lt;/p&gt;

&lt;p&gt;There’s a lot of nuance around this subject, so I hope you’ll form your strong opinion on it and maybe not agree with it all! I do think, however, that opinions are what drive forward you and your team, so I encourage everybody to follow the strong opinions loosely held adage and bring that into every meeting. Try it out, and get your team into it, too.&lt;/p&gt;

</description>
      <category>career</category>
      <category>beginners</category>
      <category>collaboration</category>
      <category>productivity</category>
    </item>
    <item>
      <title>The cost of refactoring</title>
      <dc:creator>Kieran Bond</dc:creator>
      <pubDate>Fri, 08 Dec 2023 14:17:10 +0000</pubDate>
      <link>https://forem.com/kieran/the-cost-of-refactoring-4pn1</link>
      <guid>https://forem.com/kieran/the-cost-of-refactoring-4pn1</guid>
      <description>&lt;p&gt;Originally posted on my Substack &lt;a href="https://open.substack.com/pub/thoughtsofkb/p/the-cost-of-refactoring?r=5jvvo&amp;amp;utm_campaign=post&amp;amp;utm_medium=web" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Most engineers have actively refactored code they're responsible for, and a lot think there's no cost to refactoring - but there is. Let's explore and understand, what is it?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Many teams like to live by the 'boy scouting' mantra - leave an area cleaner than you found. Thus, refactoring is widespread in software engineering teams - but at what cost?&lt;/p&gt;

&lt;p&gt;There's always a cost. Everything done, every decision made, has tradeoffs. It's essential to remember this when making decisions - whether architecture decisions, when and what to refactor, work prioritisation, or even just delaying replying to a message from somebody until later.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj28avxpbftehf92hudwf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj28avxpbftehf92hudwf.png" alt="Engineer looking at a laptop and thinking" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Photo by Tim van der Kuip on Unsplash&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;When is a good time to refactor?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What are the costs of refactoring?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What is the cost of NOT refactoring?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How to refactor well&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When is a good time to refactor?
&lt;/h2&gt;

&lt;p&gt;Deciding when to refactor is subjective - and relies heavily on context. &lt;strong&gt;You have to make an informed decision&lt;/strong&gt; where you have weighed the tradeoffs (costs) in refactoring something, and the cost is worth the price. &lt;/p&gt;

&lt;p&gt;I can't make that decision for you, but I can inform you when there are good scenarios to consider refactoring.&lt;/p&gt;

&lt;p&gt;The two most prominent ticks to go ahead with refactoring, in my mind, are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The team is hurting from an earlier decision (such as architecture), and refactoring can remove or reduce the pain.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There is a business case (user requirement) to be working in the area that is giving your team pain.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Many engineers often make it apparent that they want to refactor an area. Generally, engineers are more vocal about this than anything and are persistent about it - but this doesn't mean it's an actual pain point that needs to be addressed, and that's an easy trap to fall into. &lt;/p&gt;

&lt;p&gt;One way to ensure you/the team (truly) feel the pain of an area is to choose a priority area to refactor and provide reasons for it. If there's even data to back it up, then it's a pain point - not to say you need this data, but it helps validate the concern. &lt;/p&gt;

&lt;p&gt;Before you go off and do any refactoring, ensure the team is on board - there's nothing worse than all the cost and no reward because the team disagrees the area needs refactoring.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dedicate time to refactoring, or do it ad hoc?
&lt;/h3&gt;

&lt;p&gt;I'm not a fan of etching out dedicated time for refactoring - putting that out there now.&lt;/p&gt;

&lt;p&gt;The best time to refactor is ad hoc when you meet both criteria above. Having a user need gives you a reason to be in the area and feel the pain, which means you have work to do in the area - so you can refactor as part of business-as-usual (BAU) work without putting dedicated time aside, reducing one cost of refactoring and optimising time utilisation. &lt;/p&gt;

&lt;h2&gt;
  
  
  What are the costs of refactoring?
&lt;/h2&gt;

&lt;p&gt;Many engineers find refactoring code rejuvenating work, so they vocalise this desire and overplay the importance of it. We must ensure we're pragmatic and consider the tradeoffs before committing. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Time is such a costly thing.&lt;/strong&gt; When you are refactoring, what are you not doing? Revenue (features, infra, etc.) generating work. I know it's not black and white; it never is, but that's an easy way to look at it here. Time spent refactoring is time spent not building new features - but it's more than that. When you make a change (refactor), somebody has to use their time to review that change, and then somebody has to spend time ensuring no behaviours have changed or bad ones have been introduced. You should &lt;a href="https://open.substack.com/pub/thoughtsofkb/p/unit-testing-behaviours-and-critical?r=5jvvo&amp;amp;utm_campaign=post&amp;amp;utm_medium=web" rel="noopener noreferrer"&gt;use behaviour-driven tests&lt;/a&gt; to help with the last one, but that only slightly reduces costs.&lt;/p&gt;

&lt;p&gt;Knowledge is lost, and confusion is added when we refactor - this is prone to being glossed over because we usually focus on the benefits of the refactoring. In the long run, your change may bring more clarity to a codebase, but your refactor breaks the mental map others have in the short term. Time needs to be expended to familiarise/learn the new codebase - this mental map that has been eradicated is costly to replace and essential. Without a mental map, everything in this area takes longer. If a new, severe bug is found and needs to be fixed, then there are potentially fewer people who understand the codebase and can quickly execute the changes required to fix the bug.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/There_are_unknown_unknowns" rel="noopener noreferrer"&gt;Unknown unknowns.&lt;/a&gt; What was known is now unknown. Akin to the mental map lost in the above point, you suddenly don't know what you don't know about the code section. As systems grow, bugs are discovered (as is almost inevitable) and often classified as 'won't fix'. These are known knowns. Your refactor may have fixed or hidden them deeper - but we don't know that now. We need to determine if they exist or are gone and if new bugs will appear. Time is required to discover these things (if you're lucky to find them). Tests can help, particularly behaviour-driven tests, but we only catch some bugs.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the cost of NOT refactoring?
&lt;/h2&gt;

&lt;p&gt;It's not all doom and gloom. Refactoring is almost inevitable in software; it's a constant, like the speed of light (and it seems to come up as often, too!), and there is usually a good reason it's wanted. It can be expensive not to refactor.&lt;/p&gt;

&lt;p&gt;The three most significant costs of not refactoring:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Bus_factor" rel="noopener noreferrer"&gt;Bus factor&lt;/a&gt; remains a risk.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Technical debt persists.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Morale steadily declines.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All three costs go hand in hand. Technical debt can lead to poor 'working conditions', declining morale and people moving on from the project/company, increasing the bus factor and creating a higher risk.&lt;/p&gt;

&lt;p&gt;One trick here is that refactoring may not altogether remove the technical debt, but it can still alleviate morale (temporarily) - reducing chances of a high bus factor. Sometimes, taking a more minor cost and performing a smaller refactor is the better tactical choice. Smaller cost, smaller reward.&lt;/p&gt;

&lt;h3&gt;
  
  
  The excitement fallacy
&lt;/h3&gt;

&lt;p&gt;One of the worst reasons to refactor is because 'it's exciting' or 'energising' work. You're at most going to increase morale minutely but incur all the costs - not a worthy tradeoff. &lt;/p&gt;

&lt;p&gt;Most reasons behind refactoring are emotional, but this is the one to avoid. Pain and data are your friends, not excitement. Find other ways to sate the desire for exciting work - do personal development and try out a new technology (as a POC, not production work!).&lt;/p&gt;

&lt;h2&gt;
  
  
  How to refactor well
&lt;/h2&gt;

&lt;p&gt;So, given we know when and why - how do you refactor excellently?&lt;/p&gt;

&lt;p&gt;Small increments - just like good old-fashioned trunk-based development recommends (&lt;a href="https://en.wikipedia.org/wiki/Accelerate_(book)#:~:text=Use%20Trunk%2DBased%20Development%20Methods" rel="noopener noreferrer"&gt;we all know how important trunk-based is&lt;/a&gt;). Small, concise, targeted changes are ideal because they're easy/quick for somebody to review. When you make small changes, it's easier to determine the scope of their impact.&lt;/p&gt;

&lt;p&gt;Highly focused refactors are essential. If you try to bite off more than you can chew, you'll fix nothing and break everything. Remember, the most considerable cost of refactoring is time. If you are highly focused, you reduce the scope and thus time investment. You can choose the higher priority refactor targets, and once they have been completed, you can re-evaluate. Things move fast, and having small targets means you can pivot more successfully. &lt;/p&gt;

&lt;p&gt;Use (behavioural) tests to minimise the risk/cost of introducing unknown unknowns - another cost. You should ensure you have tests in place before you touch the code. Use TDD to guide you here. Understand the behaviours expected in the part of the system you are modifying, put tests in place, and then execute the refactor.&lt;/p&gt;

&lt;p&gt;Another way of mitigating this pain is to pair/mob on the refactor. You'll also reduce the cost of knowledge loss because more people will be close to the changes and understand the new code.&lt;/p&gt;

&lt;h2&gt;
  
  
  In summary
&lt;/h2&gt;

&lt;p&gt;Refactoring isn't as perfect as it's made out to be, and we should be conscious of the cost before doing it. It’s important work, but it’s not always important enough.&lt;/p&gt;

&lt;p&gt;So, next time you want to do some refactoring, pause and take your time to find reasoning and break down the work with a focus on small deliverables in the highest priority areas.&lt;/p&gt;

</description>
      <category>refactorit</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Unit Testing - Behaviours and critical units</title>
      <dc:creator>Kieran Bond</dc:creator>
      <pubDate>Tue, 05 Dec 2023 20:16:57 +0000</pubDate>
      <link>https://forem.com/kieran/unit-testing-behaviours-and-critical-units-3jo6</link>
      <guid>https://forem.com/kieran/unit-testing-behaviours-and-critical-units-3jo6</guid>
      <description>&lt;p&gt;Originally posted on &lt;a href="https://open.substack.com/pub/thoughtsofkb/p/unit-testing-behaviours-and-critical?r=5jvvo&amp;amp;utm_campaign=post&amp;amp;utm_medium=web" rel="noopener noreferrer"&gt;my substack&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;How I like to write automated tests&lt;/li&gt;
&lt;li&gt;Critical Unit testing&lt;/li&gt;
&lt;li&gt;Why I think what I think&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How I like to write automated tests
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Preface&lt;/em&gt;&lt;/strong&gt;: I don't always work this way. It takes patience and discipline; my natural behaviour is to be gung-ho and write the implementation first. It's a constant battle and situation dependant. This methodology may not work for you, but it works for me.&lt;/p&gt;

&lt;p&gt;My workflow looks something like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Picking a specific user behaviour to implement.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Thinking about how this behaviour is interacted with - What does the API look like?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Defining the API for the behaviour in code - Focusing on the inputs and outputs specifically.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write this into a test scenario - using the AAA (Arrange, Act, Assert) pattern.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write the bare minimum code required to compile/run the test - ensuring it fails.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make the test pass - using hardcoded values, the bare minimum&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Refactor/clean - constantly checking the test still passes, still only writing the bare minimum needed&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Repeat for different scenarios related to the behaviour; if required - specific input scenarios may need to be tested.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This workflow is close to the classic red/green TDD testing pattern if not precisely that. &lt;/p&gt;

&lt;p&gt;It works well for me, but I think it is essential to be incredibly fussy about focusing on a particular behaviour that is well-defined and singular. Concentrating on precise behaviours ensures that the test is focused and has minimum code. This makes it easier to reason about, as well as to maintain.&lt;/p&gt;

&lt;p&gt;I like to ensure my tests avoid as much implementation detail as possible so that they are easily understood and maintained. Any time you leak implementation details into a test, you add tight coupling to the implementation and stray further from a focus on behaviours.&lt;/p&gt;

&lt;p&gt;I also like to ensure that any API I design only provides access to functional behaviours. If the API is not for a specific behaviour, it is trying to do too much and needs to be split into multiple, more focused interfaces. It can sometimes be easier to think about user behaviours - what exactly are they trying to achieve when interacting with this API?&lt;/p&gt;

&lt;h3&gt;
  
  
  Advantages of this methodology
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You only write the code you need.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A focused test is easier to debug when your implementation has failed to make it pass.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Your API is more straightforward to reason about - A focus on behaviours leads to simple APIs with simple tests. There should not be any unknown or unexpected behaviours when using it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Your tests should catch regressions in behaviour.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Your tests are loosely coupled to implementations; thus, the implementation is easy to refactor.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Disadvantages of this methodology
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;It requires discipline and time to avoid leaking implementation details into your tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Using it can feel slow and unnatural (like TDD often does).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Using it is more challenging in 'established' codebases.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It can require more planning/design up front.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It can struggle when being used for fixing bugs and writing regression tests for those bugs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It is not great for 'negative' tests - ensuring something did not happen (I generally disagree with this test style). &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Critical Unit testing
&lt;/h2&gt;

&lt;p&gt;Sometimes, we have things that are hard to test from an API perspective - such as a complicated algorithm.&lt;/p&gt;

&lt;p&gt;Often, these are 'units' that are critical to the system. Think of a part of your system that needs to be performant; this is likely a good example.&lt;/p&gt;

&lt;p&gt;In these cases, I lean more towards 'typical' unit testing - Plaster it in tests that make you confident it works correctly. With the caveat: only do this if the unit is genuinely critical!&lt;/p&gt;

&lt;p&gt;Covering a 'unit' in many tests has disadvantages - it's harder to maintain and often harder to reason about. You will likely leak implementation details. This is why it's only reasonable if it's a very critical unit and complex to test behaviorally.&lt;/p&gt;

&lt;p&gt;The advantage of covering the 'unit' in tests is that it's easier to test the complex scenarios and branches, easier to catch regressions, and gives you high confidence. &lt;/p&gt;

&lt;p&gt;Confidence matters most here - after all, that's why we write tests. We want to feel confident about what we have implemented, changed, broken.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I think what I think
&lt;/h2&gt;

&lt;p&gt;How did I get to this style of automated testing? What makes me think this is the right way for me?&lt;/p&gt;

&lt;h3&gt;
  
  
  TDD
&lt;/h3&gt;

&lt;p&gt;To me, the essence of TDD is: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Design and define an API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write a test against the API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write the bare minimum code required to make your test pass.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Repeat.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The simplicity and focus of TDD leads to well-designed software.&lt;/p&gt;

&lt;p&gt;I highly recommend reading 'Test Driven Development: By Example', written by Kent Beck. This book helped shape how I use TDD. It's a bit basic, but so is TDD.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ian Cooper
&lt;/h3&gt;

&lt;p&gt;Ian Cooper is great. He transformed how I looked at unit testing and TDD, which helped me enjoy the TDD process.&lt;/p&gt;

&lt;p&gt;I highly recommend this talk by Ian:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/EZ05e7EMOLM"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  In Summary
&lt;/h2&gt;

&lt;p&gt;Give this ‘methodology’ a go. Experiment with it; try it in a pairing session.&lt;/p&gt;

&lt;p&gt;The key point is to focus on the behaviours of the system and user. That’s the whole reason we’re building these things, right?&lt;/p&gt;

</description>
      <category>testing</category>
      <category>programming</category>
      <category>productivity</category>
      <category>tdd</category>
    </item>
    <item>
      <title>Living with an 'Emerging Architecture' philosophy</title>
      <dc:creator>Kieran Bond</dc:creator>
      <pubDate>Thu, 26 Oct 2023 14:43:05 +0000</pubDate>
      <link>https://forem.com/kieran/living-with-an-emerging-architecture-philosophy-2aji</link>
      <guid>https://forem.com/kieran/living-with-an-emerging-architecture-philosophy-2aji</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1557804506-669a67965ba0%3Fcrop%3Dentropy%26cs%3Dtinysrgb%26fit%3Dmax%26fm%3Djpg%26ixid%3DM3wzMDAzMzh8MHwxfHNlYXJjaHwxMzN8fHNvZnR3YXJlJTI1MjB0ZWFtJTI1MjB3aGl0ZWJvYXJkaW5nfGVufDB8fHx8MTY5ODMzMTI5MHww%26ixlib%3Drb-4.0.3%26q%3D80%26w%3D1080" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1557804506-669a67965ba0%3Fcrop%3Dentropy%26cs%3Dtinysrgb%26fit%3Dmax%26fm%3Djpg%26ixid%3DM3wzMDAzMzh8MHwxfHNlYXJjaHwxMzN8fHNvZnR3YXJlJTI1MjB0ZWFtJTI1MjB3aGl0ZWJvYXJkaW5nfGVufDB8fHx8MTY5ODMzMTI5MHww%26ixlib%3Drb-4.0.3%26q%3D80%26w%3D1080" title="three men sitting while using laptops and watching man beside whiteboard" alt="three men sitting while using laptops and watching man beside whiteboard" width="1080" height="810"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;How we define 'Emerging Architecture'&lt;/li&gt;
&lt;li&gt;How we got here and why we needed to&lt;/li&gt;
&lt;li&gt;How we use this philosophy&lt;/li&gt;
&lt;li&gt;Advantages of an 'Emerging Architecture'&lt;/li&gt;
&lt;li&gt;Disadvantages of 'Emerging Architecture'&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How we define 'Emerging Architecture'
&lt;/h2&gt;

&lt;p&gt;'Emerging Architecture', as my team uses the term, is: 'Designing the system as minimally as possible, only changing the design when completely required for a user requirement. Keep the system simple, with no over-designing for the current needs.'&lt;/p&gt;

&lt;p&gt;This philosophy means we only change the system's design when we have a reason, with zero over-engineering (in theory). The need for change can only be driven by user requirements so that we keep a clear focus on what's important.&lt;/p&gt;

&lt;h2&gt;
  
  
  How we got here and why we needed to
&lt;/h2&gt;

&lt;p&gt;Our team has been using this design philosophy for around ~6 months at the time of writing, but it took some hardships to find it was suitable for us.&lt;/p&gt;

&lt;p&gt;Around the beginning of 2023, we started on a project codenamed 'Bifrost'. The aim of Bifrost is simple: make the access and developer experience of using specific ancient but central systems considerably better. It takes way too long for teams to integrate with this system, and we want to enhance the quality and speed (of development) of the many teams/systems wanting to use it.&lt;/p&gt;

&lt;p&gt;Whilst simple in theory, there are a lot of challenges - primarily with the upstream system. We created a '&lt;a href="https://flylib.com/books/en/1.315.1.25/1/" rel="noopener noreferrer"&gt;Tracer Bullet&lt;/a&gt;' to try and crack some of the challenges early.&lt;/p&gt;

&lt;p&gt;We struggled. We were trying to do a big design up front, and we had yet to agree on anything. We also disagreed on the tracer bullet's purpose; the combining two factors led to failure. There were too many unknowns we wanted to discover and too many ways we could attack the problem. Analysis paralysis then kicks in, too.&lt;/p&gt;

&lt;p&gt;So, how do you move forward? We regrouped. The team had been working in fragments, and the solution was to mob together and design something that works for the known situation. We agreed that the best thing was to build something simple that worked for the current user needs and that moving forward, we should keep this approach - an 'Emerging Architecture'. &lt;/p&gt;

&lt;p&gt;Once we agreed on this simple design, we also did some '&lt;a href="https://en.wikipedia.org/wiki/Divergent_thinking#:~:text=Divergent%20thinking%20is%20a%20thought,in%20an%20emergent%20cognitive%20fashion." rel="noopener noreferrer"&gt;divergent thinking&lt;/a&gt;' exercises to develop a guiding design that our solution may look like at the end of our milestones. I'm not sure how helpful this part was, but it did allow everybody to collaborate, build interpersonal relations, and stretch our architecture design legs.&lt;/p&gt;

&lt;h2&gt;
  
  
  How we use this philosophy
&lt;/h2&gt;

&lt;p&gt;We do all our planning as a team, which is JIT (Just-In-Time) with a particular use case focus. When planning, we consider if there needs to be system design changes - the answer is almost always no. If yes, then we work together to ensure we only make the most minimal change in design required - absolutely zero over-engineering allowed. By doing this designing together, we will collectively ensure that no over-designing happens.&lt;/p&gt;

&lt;p&gt;Our use case suits 'Emerging Architecture' exceptionally well, as we're building an API gateway with success milestones containing expected user count/load. &lt;/p&gt;

&lt;p&gt;Our milestones allow us to design iteratively, as we only need to develop with the following user milestone in mind. We can run performance/load tests against our API to see how we fare against our milestone. If our tests indicate that we aren't ready for the next milestone, then we plan the design (and work) that will get us there. Once implemented, we can rerun the tests and prove our design is good for the milestone we're working towards.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Here’s an example&lt;/em&gt;: Our first milestone in the team is to enable 100 users at the same time (concurrently). We know that the milestone after that is ~3,000 users concurrently.&lt;/p&gt;

&lt;p&gt;Our design is built with 100 users in mind. Our session management is all done in memory, in one running service instance. We purposefully chose only to have one instance of our service running because we think it will handle this milestone. We suspect it won’t work for the next milestone, and for the milestones after, we’re almost certain it won’t scale.&lt;/p&gt;

&lt;p&gt;We’ve run load/performance testing and fixed bugs that arose in the session management area, bugs that would go away if we changed our design to handle the next few milestones, as we are confident this is the area that doesn’t scale. However, we know it’s easier to hit this milestone with this design. It takes less time to build with this design and gives us more time to focus on everything else. For this milestone, we are also building the rest of the system. We know there’s no point focusing on scale if we don’t have a working system first, so we make our lives easier and choose our battles. Scale is a complex problem down the road; our problem now is a usable system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advantages of an 'Emerging Architecture'
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Caveat:&lt;/strong&gt;&lt;/em&gt; We are still in the midst of delivering our project using this philosophy, so we have yet to discover everything great and not-so-great about it.&lt;/p&gt;

&lt;p&gt;So far, the 'Emerging Architecture' philosophy we've been using is working well for us. Here are some advantages that I think have come from following it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It creates space that allows you and the team to dedicate time to the most important things that your users need (features).&lt;/li&gt;
&lt;li&gt;Lack of over-engineering leads to less refactoring when you inevitably go too far in the wrong direction. &lt;/li&gt;
&lt;li&gt;It's easy to pivot and change direction as you become more practised.&lt;/li&gt;
&lt;li&gt;Your design is more flexible, making tackling unknowns easier.&lt;/li&gt;
&lt;li&gt;Iterative design allows for iterative feedback.&lt;/li&gt;
&lt;li&gt;Iterative feedback (and design) means you can solve the challenging problems individually when they appear rather than all simultaneously.&lt;/li&gt;
&lt;li&gt;It's easier to catch the problems in your design if only small parts change at any time. You can be more confident that a solution change will work with fewer moving parts.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Disadvantages of an 'Emerging Architecture'
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Greater chance of system design rework - The changes that get you to your next milestone may not be the correct change for the milestone after. Sometimes, certain choices don’t scale as well as others but are better at lower user counts.&lt;/li&gt;
&lt;li&gt;Greater chance of feature rework - If you design for more significant user numbers early, it can affect how a feature is implemented. You may choose to do something in-memory because of the scale requirement but later need to move to a separate service for higher throughput/user counts - leading to other changes, such as how you get data into a system. You may have to rework multiple features between milestones. &lt;/li&gt;
&lt;li&gt;You must be mindful of costly/irreversible design decisions, or you can find yourself in a challenging situation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  In Summary
&lt;/h2&gt;

&lt;p&gt;'Emerging Architecture' is a philosophy that we follow. It has advantages and disadvantages, but it's working for us, and the trade-offs seem worth it. We're keen to see where it takes us and hope we make the right decisions - and when we don't, at least we'll learn some things on the way.&lt;/p&gt;

&lt;p&gt;Let me know what you think in the comments below. Have you tried this philosophy? How did it work for you?&lt;/p&gt;

</description>
      <category>agile</category>
      <category>architecture</category>
      <category>development</category>
      <category>software</category>
    </item>
    <item>
      <title>Introducing TinYard - Your next .NET IoC framework</title>
      <dc:creator>Kieran Bond</dc:creator>
      <pubDate>Fri, 11 Dec 2020 20:48:22 +0000</pubDate>
      <link>https://forem.com/kieran/introducing-tinyard-your-next-net-ioc-framework-1bo7</link>
      <guid>https://forem.com/kieran/introducing-tinyard-your-next-net-ioc-framework-1bo7</guid>
      <description>&lt;h1&gt;
  
  
  TinYard
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://github.com/TinYard/TinYard" rel="noopener noreferrer"&gt;TinYard Repository&lt;/a&gt;. Source Code and DLL's available here!&lt;/p&gt;

&lt;h2&gt;
  
  
  Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;What is TinYard?&lt;/li&gt;
&lt;li&gt;Why use it?&lt;/li&gt;
&lt;li&gt;How do I use it?&lt;/li&gt;
&lt;li&gt;Inspiration&lt;/li&gt;
&lt;li&gt;Contributing&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is TinYard?
&lt;/h2&gt;

&lt;p&gt;TinYard is an IoC framework written in C# for .NET that brings more features than your bog-standard IoC-container.&lt;/p&gt;

&lt;p&gt;TinYard aims to improve your code by providing an easy-to-use IoC container and more through its powerful but simple extensibility. The framework provides a few tools to help you create awesome things, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dependency Injection (DI)&lt;/li&gt;
&lt;li&gt;Event System&lt;/li&gt;
&lt;li&gt;MVC Suite&lt;/li&gt;
&lt;li&gt;Easy Plug and Play Extensions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can use it in your projects by adding the .dll as a dependency, or by adding the source code into your project. It's available both as binaries from the Github repository releases, or &lt;a href="https://www.nuget.org/packages/TinYard/" rel="noopener noreferrer"&gt;you can find it on NuGet&lt;/a&gt;. One of the great things about TinYard is that almost any .NET project can use it as it's compiled for .NET Standard 2.0.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why use it?
&lt;/h2&gt;

&lt;p&gt;Use TinYard because it's a straightforward and simple IoC-container that lets you do more, when you want to. It's modular and gives you only what you want from it, when you want it.&lt;/p&gt;

&lt;p&gt;Due to its modularity, it's a tool that allows you to add whatever you want to it to speed up and enhance your workflow. &lt;/p&gt;

&lt;p&gt;Aside from that.. to help build something awesome with me. Whether that's helping by informing me of bugs, requesting features, adding to it or just simply using it and advocating for it!&lt;/p&gt;

&lt;h2&gt;
  
  
  How do I use it?
&lt;/h2&gt;

&lt;p&gt;Have a look at the ReadMe! I've spent some time working on the ReadMe in the hope that it is useful.&lt;br&gt;
There's some examples written up and linked to in the repository too!&lt;/p&gt;

&lt;h2&gt;
  
  
  Inspiration
&lt;/h2&gt;

&lt;p&gt;TinYard was an inspired product. I was encouraged by wanting to further understand the framework that I use at work and in personal projects at a deeper level than simply how to use it. I wanted to understand the design reasons behind it, as well as how to do the cool bits like DI.&lt;/p&gt;

&lt;p&gt;The framework that inspired me is &lt;a href="https://github.com/robotlegs-sharp/robotlegs-sharp-framework" rel="noopener noreferrer"&gt;Robotlegs-Sharp&lt;/a&gt;. A framework built on top of an IoC container known as &lt;a href="https://github.com/robotlegs-sharp/swiftsuspenders-sharp" rel="noopener noreferrer"&gt;SwiftSuspenders-Sharp&lt;/a&gt; that aims to provide an easy to use MVC framework. Whilst I didn't use the original &lt;a href="https://robotlegs.tenderapp.com/" rel="noopener noreferrer"&gt;Robotlegs&lt;/a&gt;, I do use the version that was ported to C# by some past colleagues and mentors regularly linked above.&lt;/p&gt;

&lt;h2&gt;
  
  
  Contributing
&lt;/h2&gt;

&lt;p&gt;If you would like to contribute, whether that's by letting me know of features you want or bugs you encounter or even going as far as adding directly to the codebase then please do! There's a contribution guideline on the repository, have a look at that or just open up an issue if there's features wanted or bugs encountered.&lt;/p&gt;

&lt;p&gt;Any contribution at all would be highly appreciated! And, on the off chance that the project receives a sponsor or donation, you might find a chunk comes your way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Let me know what you think about TinYard. &lt;br&gt;
Code look good? Code look bad? Project seem pointless? I'll listen to it! &lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>tooling</category>
      <category>ioc</category>
    </item>
  </channel>
</rss>
