00:00:18.400
Good afternoon, everybody! Wow! My name is Kane Baccigalupi. My last name is Italian, which means that I'm supposed to be having a siesta right now, but I really love this subject and wanted to come talk to you about it. The little byline says I'm a fixer, coder, teacher. The reality is that I've done a combination over the last seven years of consulting and being a rescue CTO. I've been doing these trajectory starts and then rescues. Right about now, I'm feeling like a Greenfield project would be really great rather than rescuing another Brownfield project.
00:00:30.279
But I wanted to get across everything that I've been learning over the last seven years so that people could learn from it. So what is this Evergreen thing that I'm talking about? Yes, I made it up, and I made it up so uncreatively that it's probably already out there as something you’ve heard of. In the industry, there's this talk about Greenfield projects and Brownfield projects. You can see from the illustration that Greenfield is new and fresh and everything is possible, while Brownfield is like, 'Holy crap! I cannot do another point because I have sunk myself into the oblivion of tech terribleness.'
00:01:02.160
Evergreen, in my definition, requires a long-term relationship with your project, which I think is pretty rare. I have had the luck, or good fortune, to work on two Evergreen projects: one where I was an architect and one that I revived after it became a terrible Brownfield project. I worked on it long enough to see it go Evergreen again. Generally, one to two years into a project, it's easier to manage than before, because we actually know more about the domain than we did at the beginning.
00:01:30.959
One of the things that goes wrong with projects is that at first, you know nothing. You're building on top of that nothing, but at some point, you know a lot about it, and you want to go back and fix all the mess that you made. However, in an Evergreen project, instead, you know this domain, and therefore you can build abstractions that quickly convert features that happen very often in your product into real functionalities. On a deeper level, things are decoupled enough that when you do massive product or domain reimagining, it's relatively cheap.
00:02:04.520
So why do fields go so Brown? They do, right? It’s because everything we believed at the very beginning of a project is absolutely and totally wrong. Our instincts lead us to stop everything and rebuild, but that instinct is also wrong. What happens is you end up building a Brownfield project a second time around because the reality is that what you don't know about the future is as uncertain as what you know about the past.
00:02:30.959
This leads me to my invention: the law of optimistic rebuild. An unchanged team will build themselves into the same legacy problems, which is kind of like the two images you saw: Brownfield and then Brownfield again. My youngest daughter, who is 11 and really smart, is managing her ADHD well, but she's struggled in middle school because she hasn't been following instructions. Her counselor suggested she underline essential parts of her work, leading to this odd practice where I'm asking her to underline the most important parts of the sentences.
00:02:55.560
This has actually resulted in discovering really interesting things in her studies, even for those who don't have ADHD. The unchanged team part implies that to change the process, you might need to change the team, which is a bit ambiguous. If you do an extraction to rebuild, that counts too; it’s a rebuild, though you haven’t completely rebuilt everything from scratch. Now, we see that unchanged teams rebuild legacy problems. To distill: unchanged teams rebuild legacy problems.
00:03:24.440
I’m inventing more ideas here. It is a waterfall process to rebuild what you already know, meaning even if you're doing Agile, it takes three to ten times longer because it's waterfall. More than likely, your business can’t sustain that kind of approach. Why does Greenfield feel so good? For me, starting a project feels like the beginning of a relationship. You feel like, 'Oh my God, I’m so in love! Look at this! It’s all perfect!'
00:03:46.960
It feels like anything is possible, and if only things don’t change, everything will be good. There’s an incredible velocity at the start where you’re starting something new, and you feel like a hero. I've been a consultant in many situations like this, and that point of high velocity graph is where you exit as a consultant.
00:04:13.880
So where does this velocity come from? It largely comes from borrowing. I want to emphasize right here that this is a phenomenon I have observed growing since I joined the startup industry in 2005. I used to work on long-running projects, but now everything is squashed and accelerated, particularly in the startup industry. There is a pressing need to rapidly jump to something fabulous, and we’re borrowing a lot.
00:04:41.160
We borrow from the standard library, we borrow from gems, and we think we're just getting code. In reality, we're getting much more than that; we're also getting architecture. Every framework comes packaged with architectural decisions. It's not just about Rails or Sinatra; it's about choosing between different service architectures, such as EventMachine versus Celluloid.
00:05:08.559
These choices affect and impact all the code that falls underneath it. It gets even more complicated when examining Rails engines or other libraries that come packaged with a ton of domain knowledge. You're tightly tied to whatever you've borrowed.
00:05:33.990
There was an article about a year ago on Code Climate, which is an excellent resource for software design, that coined the term 'technical drift.' Technical drift occurs when a development team continuously fails to recognize and adapt to change. I believe it only takes a little bit of failure to fall into a Brownfield state. As a result, the concepts in the software domain begin to drift apart from the code, leading to technical debt, which incurs interest and compounds quickly. Suddenly, you're not in a position where you can do anything.
00:06:04.640
If you look at the adjusted velocity, the shaded part reflects borrowed aspects, while the unshaded is what was earned. A more realistic depiction suggests that your velocity doesn’t change over time or ideally should have a linear progression, but the reality is that maintaining the initial velocity you had is incredibly hard. As you scale with developers, the return on velocity tends to diminish, especially in Brownfield projects.
00:06:30.960
The initial amazing velocity might plummet when things start not to go well, and it becomes challenging to deliver anything effectively. The team often feels like heroes during that initial phase, but eventually, they confront the debt incurred from borrowed velocity.
00:07:06.280
There's an important moment when the initial glamor and velocity give way to a more sustainable, enduring trajectory, which is far better than accumulating massive debt, followed by a downward spiral.
00:07:24.280
Now, I'm going to introduce more laws: the Law of Software Stages. This principle states that maintenance is not the same as launching, and we need to apply different rules for each phase. Furthermore, treating maintenance the same as launch leads to diminishing velocity and an increase in technical debt.
00:07:37.360
So, what are the best practices for maintenance? Well, they are well-known yet hard to follow. I have to give a shoutout to Jim Wren, who passed away last February. It was a sad moment for me. I barely knew him; I met him once at RubyConf when I was speaking for the first time, feeling conspicuously odd among few women in attendance. He walked over to our little group of women and introduced himself after giving an incredible presentation on the SOLID principles.
00:08:07.040
The irony of the single responsibility principle is that it has two definitions. Each class should have one responsibility, and also, each should only have one reason to change. Despite that, each bit of code can have one distinct responsibility, but the code might be scattered everywhere.
00:08:32.320
In practice, we often find ourselves caught up in a situation where we have more specificity in the parent class than in the child class, making it hard to keep track. Let's say we are trying to apply this principle to a fake code example. The object or class structure can become complicated with different layers and components, and we need to ensure that responsibilities are appropriately managed.
00:09:02.080
Applying the Open/Closed principle means we should design classes so they can be extended easily without modifying existing code. This can help maintain functionality while introducing new features or functionality, but maintaining single responsibility within these classes is vital.
00:09:27.480
You can drive the design forward with these principles in mind while also remaining flexible, using dependency injection. However, this approach can become complex, as too many dependencies can lead to confusion.
00:09:50.440
The goal of SOLID principles is to help us adapt to changes, but they also risk being overly theoretical. When deploying them in practical situations, they should help guide us in managing real-world changes in projects.
00:10:14.480
Given this context, having team members with strong design expertise is essential but doesn’t mean everyone on the team has to be a solid designer. If not everyone has that expertise, you need at least one strong teacher on your team to guide others.
00:10:40.480
It's crucial to create actionable strategies that all team members can adopt. Has anyone seen this funny bumper sticker: 'What would Sandy Metz do?' My mentor Jeff Dean, when he was in pivotal labs, worked on a project that lasted seven years—quite remarkable in this industry.
00:11:06.799
He had this bumper sticker concept encouraging everyone to think through the maintenance of ongoing projects critically. Approaches envisioned by Sandy can be enlightening. If you want to implement effective processes within your team, consider hiring someone like Sandy Metz; she brings tremendous insights.
00:11:33.640
The takeaway here is after a year of hard work, we saw significant improvement towards an Evergreen state; most of my team, which included junior developers, thrived. However, Sandy returned to assess our progress and pointed out we were missing the essential elements she'd shared.
00:11:58.800
This was illuminated during a dependency injection exercise she conducted. It was evident that while I was doing other things with the team, they were not aligned with Sandy's teachings, which led to misunderstandings in application.
00:12:21.960
To resolve these misunderstandings, you must have solid design principles and an environment that encourages collaboration and communication. More junior engineers can practice these principles under the guidance of someone more experienced than them.
00:12:44.480
My internship program was an effective way for me to teach people who didn't know how to code. Resistance often came from seasoned developers. So, I would say, 'Erase everything and start again with tests.' This approach opened up the conversation about expectations, aligning with the interface principles of SOLID.
00:13:06.120
As a manager, it’s vital to establish a framework for problem-solving that everybody can adhere to, especially when it comes to maintenance and refactoring. You could create concrete rules for your team around basic programming principles related to maintaining the structure of your application.
00:13:30.600
To conclude, while rules can guide developers, the code is ultimately produced by the people, and it's essential to foster a healthy team dynamic. Communication is integral, as shown in my internship program success with pairs coding.
00:14:00.680
In discussions around finding the right team to work on your coding problems, the soft metrics of communication and mutual enjoyment of collaboration play a significant role in achieving successful project outcomes. Here's where you need to look into the possibility of hiring for communication skills.
00:14:29.561
You must seek individuals adept at collaboration while ensuring they are driven by self-education. It's important to gauge a candidate's self-awareness, as it indicates their ability to work effectively within a team.
00:14:59.400
To emphasize, finding the balance between arrogance and impostor syndrome is essential for promoting personal growth within the team. Empathy and self-evaluation are qualities to be nurtured.
00:15:29.600
If your team comprises individuals capable of significant self-reflection, this quality can strongly influence team dynamics and overall success. I find it heartening that our hiring process allowed us to identify and address self-awareness aspects among the team members.
00:15:57.940
In closing, the metrics utilized for evaluating candidates have proven helpful, especially regarding team dynamics. We've continued to see success by retaining principles of self-awareness, adaptability, and a collaborative spirit within our teams.
00:16:27.080
This returns us to the importance of solid foundations for team development, along with relevant feedback and continuous reflection. I hope my journey encourages you to push towards maintaining your projects in an Evergreen state, leading to fruitful outcomes.
00:16:54.000
Thank you for your attention! I'm open for any questions you might have.