<?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: James Thompson</title>
    <description>The latest articles on Forem by James Thompson (@plainprogrammer).</description>
    <link>https://forem.com/plainprogrammer</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%2F163280%2F7862d9f1-c1ac-45b5-831d-19199942a18c.jpg</url>
      <title>Forem: James Thompson</title>
      <link>https://forem.com/plainprogrammer</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/plainprogrammer"/>
    <language>en</language>
    <item>
      <title>Considering Mob Programming</title>
      <dc:creator>James Thompson</dc:creator>
      <pubDate>Thu, 19 Sep 2019 22:24:53 +0000</pubDate>
      <link>https://forem.com/plainprogrammer/considering-mob-programming-pmg</link>
      <guid>https://forem.com/plainprogrammer/considering-mob-programming-pmg</guid>
      <description>&lt;p&gt;Recently I enjoyed working with some of my San Francisco colleagues on-site. During this visit we wanted to take time to do something a little different. So, we devoted two days to experimenting with &lt;a href="https://www.agilealliance.org/glossary/mob-programming/"&gt;Mob Programming&lt;/a&gt; on some exploratory work. Over those two days we discovered a number of things about Mob Programming as well as the work we were exploring. While we didn’t all walk away with the same insights, we all agreed that Mob Programming was a technique we were interested in trying out some more.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exploring a Problem
&lt;/h2&gt;

&lt;p&gt;The team I currently work on is responsible for our Master Planning solution for resource managers within professional service organizations. This system provides a way to identify what kinds of personnel are necessary for various projects, including the required skills, availability, and other factors. This tool also enables the assignment of specific personnel to these defined areas of need. In order to do their work effectively, resource managers need to be able to adequately filter and organize their view of projects and personnel.&lt;/p&gt;

&lt;p&gt;We needed to explore the relative complexity of the filters we provide in our Master Planning solution. Specifically, we needed to explore three different approaches to how we might want make changes to these filters. Currently these filters rely on the Backbone Javascript framework, but all new development is targeting React. So, the three approaches we wanted to explore were; (1) how complex would it be to make a functional change to one of the existing filters, (2) how complex would it be to reimplement the filters using React, and (3) how complex would it be to reimplement the filters using a newer UI paradigm that relied on both React and a light-box presentation. In both of the latter cases we also had the secondary interest to get a sense of how complex it might be to have React-based filters work seamlessly alongside Backbone-based filters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ground Rules
&lt;/h2&gt;

&lt;p&gt;I was tapped to help facilitate the Mob Programming and worked with our team lead to get a suitable setup. One complication that we did encounter was a need to include a single remote participant, and I will return to this complication later. In bringing the team together, we set four basic rules to help maintain a good working environment for this new technique. Since we Pair Program regularly, none of these rules were new, but we felt they were worth being explicit about.&lt;/p&gt;

&lt;p&gt;First, we committed to step away if we felt distracted, or otherwise not engaged in the work being done. This was our way of giving everyone permission to keep up with other commitments and not feeling like they simply had to be in the room.&lt;/p&gt;

&lt;p&gt;Second, we committed to suggest, instead of demanding. In our environment we already value mutual respect and would not expect anyone to make demands of their colleagues in a collaborative setting. But, because this was a new context and way of working, we felt it was valuable to identify this specific means of maintaining respect during the exercise.&lt;/p&gt;

&lt;p&gt;Third, we committed to stop the session and have any design discussions as a whole. We recognized that as we are going along there may be times we need to have a conversation that involves the whole team. We wanted to give permission for the typist to step back from their role and engage fully in those conversations.&lt;/p&gt;

&lt;p&gt;Finally, we committed to focussing on just one task at a time. We had the disadvantage of not being engaged with our typical user stories, so we felt there would be a temptation to try and do too many things at once. This commitment encouraged us to keep ourselves, and each other focussed on the small steps we needed to take to achieve the learning we wanted. This commitment also gave us regular opportunities to ask ourselves if we had completed the desired learning as we went.&lt;/p&gt;

&lt;h2&gt;
  
  
  Our Schedule
&lt;/h2&gt;

&lt;p&gt;We decided that since we were going to work over two days we would build some breaks into our sessions. We knew, because of our first ground rule, that individuals could and would step away as they needed. But, we also wanted to provide some specific times for decompression and review throughout the process. We divided our days into, as best we could, a series of two-hour sessions. We committed the latter 15 minutes or so of many of those sessions to doing retrospectives on the time we had just spent working. This led us to make a few helpful adjustments as we were Mob Programming that helped keep us learning smoothly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Some Practice
&lt;/h2&gt;

&lt;p&gt;Since none of us had ever done Mob Programming before, we decided to use a shorter session on the first day to get a little practice. This proved to be an incredibly valuable decision since it allowed us to quickly identify two problems in our approach that we changed before jumping into our main work.&lt;/p&gt;

&lt;p&gt;We chose to do some code review on an open pull request we had on our team. In the process of doing this code review we used a timer to rotate who the typist was every eight minutes. This proved to be way too little time for a rotation, which led us to move to, and stick with, 15 minutes per person through the rest of our Mob Programming time. We also discovered that our use of Zoom and Apple Airplay introduced an unacceptable amount of latency for both our remote participant and even for our co-located team members. This led us to switch to using Tuple for our remote participant, which had its own complications, and connecting our workstation directly to our conference room television.&lt;/p&gt;

&lt;p&gt;The practice was invaluable in helping us quickly refine those areas of our process that were causing friction. And, even in that brief practice session we gained a handful of insights about the process of Mob Programming, and how it could impact our work, both in good and bad ways.&lt;/p&gt;

&lt;h2&gt;
  
  
  What We Learned
&lt;/h2&gt;

&lt;p&gt;Over the two days of Mob Programming we learned a lot. Most valuably we were able to provide feedback to our Product Manager on the work he was considering for the team. The overall tenor of that feedback was that none of the options were discouragingly complex. We walked away feeling more confident that we could tackle any of the approaches to our filters without introducing delays that would necessarily compromise our ability to deliver value to customers quickly. We did not all come to the same conclusions about the value of Mob Programming, but we all saw its benefits. I will save the epiphany I came to in observing and facilitating our Mob Programming experiment for a different post.&lt;/p&gt;

&lt;h3&gt;
  
  
  About Mob Programming
&lt;/h3&gt;

&lt;p&gt;One of the things I noticed as we began Mob Programming was that the same skills that are important for Pair Programming come into play. The fact that our team has a good base in Pair Programming meant that discussing and resolving small differences in preference are quick. When we needed to stop and brainstorm on approaches the conversations also flowed very naturally and it did not feel like we were breaking context much at all. The one downside was that the same social dynamics that helped with driving towards solutions also led to chasing the occasional rabbit together. But, agreeing on when we were done was very easy to do as a group.&lt;/p&gt;

&lt;p&gt;We attempted to impose an eight minute rotation at first, and that proved too short. We followed up with a fifteen minute rotation and while that was a lot better, I think the aim should be to move between typists in Mob Programming with the same fluidity we see in Pair Programming. Along this same line, identifying a cadence for group breaks was difficult and occasionally felt artificial.&lt;/p&gt;

&lt;p&gt;We found that Mob Programming was a good way to introduce newer team members to code organization and concepts at least as well as Pair Programming. Any specific benefits to Mob Programming in this respect were likely diminished by the type of work we were engaged with. We also found that identifying one member of the mob as a researcher and encouraging everyone else to focus on the main coding work was very beneficial.&lt;/p&gt;

&lt;p&gt;We observed that having product and design team members present was very helpful for decision-making, but it was unclear if their presence throughout the mobbing session would have been better. Deficiencies in workflow were more acutely painful to the mob than they would have been to a pair. And, we recognized that there were technical challenges to adequately incorporating a remote participant that we have overcome well for Pair Programming.&lt;/p&gt;

&lt;h3&gt;
  
  
  About Ourselves
&lt;/h3&gt;

&lt;p&gt;The process of Mob Programming surfaced some interesting details about our workflow and product. We noticed that the pain of prepping our data set so we can adequately perform basic QA tasks as a mob was an issue. One suggestion that was made was to have a pair do the setup instead of conducting it as the mob. My concern with this approach would be that it would not necessarily seek a solution to the pain that is being felt, merely bandage over it. I think I favor empowering mobs to address pain points like this whenever they come up, which is something our Pair Programming sets should already feel empowered to do. It is possible that this pain point is exposing a team dynamic worth correcting even without the adoption of Mob Programming.&lt;/p&gt;

&lt;p&gt;I noticed that the way we were addressing our work as a &lt;em&gt;spike&lt;/em&gt; and setting aside some of our regular practices created uncomfortable friction. I was encouraged to see the discomfort, but it raised some interesting questions I want to revisit in another post on the concept of &lt;em&gt;spikes&lt;/em&gt;. I think maintaining our normal practices, particularly the practices of TDD and starting with clear users stories, would have made the overall Mob Programming experience more informative.&lt;/p&gt;

&lt;h3&gt;
  
  
  About Our Work
&lt;/h3&gt;

&lt;p&gt;As we worked together we learned several things about our work and the impact Mob Programming could have on our process. One thing I noticed was that frustration rose much higher when encountering constraints or friction in our process. This encouraged me that when doing regular work, a mob might be more strongly inclined to address those issues immediately, rather than deferring them.&lt;/p&gt;

&lt;p&gt;I observed that Mob Programming seemed to more quickly surface small solutions than I’ve observed in some pairing session. I believe this was because the group exhibited a stronger social reinforcement dynamic when it came to pushing towards a working solution quickly and then iterating. I believe the rotation of the driver also provided encouragement to keep the active work focussed on keeping things working, rather than accepting the risk of attempting big bang style changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where We Go From Here
&lt;/h2&gt;

&lt;p&gt;Our environment was not a great one for Mob Programming. Because we were using a conference room, there was some awkwardness involved in changing the driver because of how people wanted and needed to move around the space. I think this issue could be well addressed with a more tailored space for Mob Programming, rather than simply repurposing a room designed for round-table meetings.&lt;/p&gt;

&lt;p&gt;I observed that decision-making was very effective when we had our Product Design and Product Manager in the room. I think our experience with Mob Programming would be even better with a “Whole Team.” And, I think this would be a necessary feature to incorporate the next time we engage in this practice.&lt;/p&gt;

&lt;p&gt;All of us agreed that Mob Programming was a valuable tool and would be worth employing again for exploratory work. We did discuss the value of having user stories to better inform our work. I am definitely a proponent of looking for more opportunities to apply Mob Programming, but there are some technical and organizational hurdles we will have to address to make that feasible. For now, I’m not confident that support for remote participants is strong enough to make that a good approach, but for fully co-located teams I think Mob Programming is a practice that should likely be tried out, and eventually adopted.&lt;/p&gt;

</description>
      <category>softwaredevelopment</category>
      <category>practices</category>
      <category>techniques</category>
    </item>
    <item>
      <title>Software Architect as Guide</title>
      <dc:creator>James Thompson</dc:creator>
      <pubDate>Mon, 15 Jul 2019 04:00:54 +0000</pubDate>
      <link>https://forem.com/plainprogrammer/software-architect-as-guide-3562</link>
      <guid>https://forem.com/plainprogrammer/software-architect-as-guide-3562</guid>
      <description>&lt;p&gt;The work of software architecture belongs to &lt;a href="https://james.thomps.onl/2019/07/05/who-does-software-architecture/" rel="noopener noreferrer"&gt;every developer on a software team&lt;/a&gt;. So, what is the role of those given the title  Software Architect? At its most basic, I believe it is to be a leader in mentorship of their teams. They should be excellent developers in their own right, promoting their team’s principles, refining their team’s practices, and guiding their fellow developers toward the same.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other Responsibilities
&lt;/h2&gt;

&lt;p&gt;Many understandings of the role of software architect incorporate a variety of seemingly non-technical responsibilities. And, I believe those other concerns are valuable; but I’m not sure of their primacy. I think &lt;a href="https://martinfowler.com/articles/architect-elevator.html" rel="noopener noreferrer"&gt;Gregor Hohpe’s perspective&lt;/a&gt; is a helpful one, although it is connected to ideas tied up in traditional IT structures in many respects, as well as the particular concerns of certain larger organizations. However, I think one of his initial observations is fundamentally correct:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Traditionally, architects were considered to be those folks who make major design decisions on a project, draw architecture diagrams, and direct developers. Those tasks are in fact better handled by the development team and modern tooling than by a single person.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And, I think that initial observation is wrapped up nicely by one of his closing points as well:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It’s the combination of technical acumen and organizational skill that makes modern architects valuable&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And, it is on that last bit that I think the role of software architect can be distinguished from that of a developer, even an architecturally interested one. The fusion of technical capability with a team-orientation and priority is at the heart of what I think the software architect role should be.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architect Is Loaded
&lt;/h2&gt;

&lt;p&gt;I have come to dislike the title of Software Architect. A big part of this is due to my observation that it is ill-defined in many organizations and comes with too much baggage, both from within and outside our industry. I am far from the first person to make such an observation. I was reminded recently that Martin Fowler and some of his ThoughtWorks colleagues were struggling with much the same concerns back in 2003.&lt;/p&gt;

&lt;p&gt;Part of the problem is that the title &lt;em&gt;architect&lt;/em&gt; is borrowed. The title can be conceived as having a more generic meaning, but its roots are in the field of building and construction. While I think there are some good things to learn from this analogy, I believe it also unduly constrains our thinking in many regards.&lt;/p&gt;

&lt;p&gt;I have been searching for a better title to encapsulate and reveal what I believe software “architects” should be, but I have yet to find anything fully appropriate. And, perhaps I never will. But, I think there is an alternative metaphor that can help clarify understanding about how what we call “architects” can and should be functioning within software development teams.&lt;/p&gt;

&lt;h2&gt;
  
  
  Towards A Better Metaphor
&lt;/h2&gt;

&lt;p&gt;The two terms I keep coming back to as I consider the ideal of the role we call “architect” are that of &lt;em&gt;shepherd&lt;/em&gt; and &lt;em&gt;guide&lt;/em&gt;. Given my educational background in Biblical Studies and Christian History, I suspect my affinity for the term &lt;em&gt;shepherd&lt;/em&gt; is rooted in a strong &lt;a href="https://yourbias.is/the-curse-of-knowledge" rel="noopener noreferrer"&gt;knowledge bias&lt;/a&gt;. So, while I want to favor that metaphor, I think the metaphor of being a &lt;em&gt;guide&lt;/em&gt; is actually more familiar to most people.&lt;/p&gt;

&lt;p&gt;Both metaphors include in their scope the notion of being a caretaker or steward. And, both lend themselves to recognizing that the stewardship being exercised is over a group, not a thing. And, I think this is the first thing we ought to recognize:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Being a software &lt;del&gt;architect&lt;/del&gt; guide makes you responsible for a team, before your technology.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  The Dive Master
&lt;/h3&gt;

&lt;p&gt;While growing up in Florida, my father and I became certified scuba divers. The process of learning to be a scuba diver is where I want to ground this metaphor of the &lt;em&gt;software guide&lt;/em&gt;. The reason is that everyone who teaches or learns to dive is a fully engaged participant.&lt;/p&gt;

&lt;p&gt;A well-qualified scuba instructor has to be capable of doing all the things they are teaching others to do. They must have mastery of various hardware and dive scenarios and be a competent practitioner. Within the field of scuba diving there are even sub-specialties for scenarios like wreck and cave diving; as well as for such things as the use of specialized equipment. We see comparable areas of technical competency in the field of software development.&lt;/p&gt;

&lt;p&gt;But having mastery of the equipment, techniques and scenarios are not sufficient to qualify a diver for the role of dive master, or instructor. Both require additional training and certification. And, I think we could easily apply such a framework, minus the formal certification, to the role of a software guide. The blending of technical capability with training, instruction, and leadership skills are very similar. A good software guide should be competent in the field of software development. They also need to demonstrate a concern for the other members of their team, and a mentorship mindset. And I think this is distinct from what we tend to assume about the notions of education and training.&lt;/p&gt;

&lt;p&gt;When a dive instructor is preparing a class for certification, only a portion is about instructing in mere knowledge. There are examinations necessary for dive training, but the more critical elements come through experience. It is not enough to hand a trainee the manual, or describe the function of a buoyancy control device, or regulator. They must actually put it on and know how to operate it in real environments. This normally begins on land, then in a pool, and finally in open water. And so it should be with a software guide, they should be engaged in the work with their team.&lt;/p&gt;

&lt;p&gt;The best software guides don’t merely instruct, they demonstrate. And this is what makes the metaphor of the guide so compelling to me. The software guide goes with their team through the process of developing software. Instructing at times, but demonstrating far more often. They work with their teams to distribute the knowledge of how to craft software well. They encourage everyone to become more competent in their shared craft. They communicate the requirements that they hear, and help their teams recognize when certain things are being implied by other stakeholders. They encourage and engage their team in actively refining their processes and techniques in light of their common principles. They help others grow to think and work like themselves.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The best software guides don’t merely instruct, they demonstrate.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Being a guide prevents one from becoming aloof or in any way separated from the team. The software guide is an integral part of how the team functions. And, they are both positioned and able to train practitioners to become better, and to train up new guides. A guide is not just a higher-level practitioner, they are also a trainer of the next cohort of excellent practitioners and guides. In contrast, and “architect” unable or ill-positioned to raise up other “architects” is a constraint, rather than an asset.&lt;/p&gt;

&lt;p&gt;This same pattern of guide can be found beyond just the setting of scuba diving. It is also common in mountaineering, spelunking, and even sports. At the youth level most coaches are guides to their athletes, demonstrating the appropriate techniques, not merely describing them. And, we can see a not dissimilar model in any discipline that involves formal apprenticeship.&lt;/p&gt;

&lt;h2&gt;
  
  
  Software Guides versus Software Architects
&lt;/h2&gt;

&lt;p&gt;Some might object to eschewing the role or title of architect for any number of reasons. Some might argue that a guide being embedded in the team prevents them from having the broader view that being an “architect” might afford due to its autonomy. But, I doubt that many of the guides leading treks up Mount Everest are unaware of the big picture of what they are doing and where they are going. Nor can a dive master lose site of the dive plan discussed with their group before they entered the water and lost the ability to communicate apart from much beyond hand signals. It is entirely possible to maintain a broad vision while also working in the code with one’s team.&lt;/p&gt;

&lt;p&gt;The assumed benefits of the “architect” who is separated from the team are illusions. They are pretenses for behaviors and activities that often deliver far less value and sometimes are actively harmful to their organizations and their teams.&lt;/p&gt;

&lt;p&gt;Consider the “architect” who consults with a product manager, designer and even a customer before contemplating, designing, and eventually advising their team on how to build a new feature. They are, in fact, an active impediment to responsive development and are undermining everything from their team’s ability to react to changes in requirements, to their relationship to the customer, to the very idea of delivering iterative value. For those in shops that don’t care for the principles of agile software development, this may not seem like a problem. But, for those, like myself, who find those principles and the practices that flow from them invaluable, this conception should be more than a little concerning, if not repugnant.&lt;/p&gt;

&lt;p&gt;How would such a process be different with a software guide? First the guide would not seek to insert themselves between the team and the other stakeholders. They would look for ways to knit the whole team closer together. Further, they would involve the team in any requirements investigation and would actively solicit and discuss any possible approaches with the team. But, most importantly, the guide would not stop at giving direction or advice to the team. A guide would engage with the team in the act of building the solution they had arrived at together. They would help lead the team to react to changes that come up. They would reinforce and help refine sound practices. And, whatever the outcome, the software guide would be a part of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practices of the Software Guide
&lt;/h2&gt;

&lt;p&gt;The key theme should be evident: guides are part of the team, in a way that many “architects” seek to avoid.&lt;/p&gt;

&lt;h3&gt;
  
  
  Guides Design (With Their Team)
&lt;/h3&gt;

&lt;p&gt;Guides will involve their teams in the design phase of software development. They will actively seek the input of the others who will be working to build the software. They will not just seek to inform them. They will solicit their input, so that the design can be refined. The guide will help the team work through both the functional and quality attributes of what is being built. The guide will help the team learn about the process of research and ideation that happens between a customer stating their problem and beginning to write code. &lt;strong&gt;The guide must demonstrate how to do design, not merely do it for the team.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Guides Write Code (With Their Team)
&lt;/h3&gt;

&lt;p&gt;Guides will write code with their team. Not for their team; nor while their team watches. The guide will work with the team to write the code necessary to deliver value to their customer. This means, even if pair programming is not a regular practice for your team, that your guides should do it and be good at it. This is one of the key ways the guide can transfer knowledge to the team, but also how the guide can refine their own ideas about the software being built. Some might try to substitute code reviews, but they are not enough to pass on skills and knowledge since they provide less context than one gets when pair programming. And, when guides code with their teams, any upfront design will have to stand-up to actually being coded, and the guide will have a front-row seat to that activity. This is where the guide gets to live with their decisions, and be in a much better position to fix their own mistakes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Guides Suffer &amp;amp; Celebrate (With Their Team)
&lt;/h3&gt;

&lt;p&gt;Whether a project goes well, or not, the guide should go through it with their team. This is an extension of the notion of the guide living with the consequences of their decisions. If their design works out poorly, they should be around to help clean it up; and to help their team learn from the mistakes. And, if it goes well, they should encourage the team to celebrate their success. The guide should be a part of the team’s full experience of the software development lifecycle.&lt;/p&gt;

&lt;h3&gt;
  
  
  Guides Help Improve Their Team
&lt;/h3&gt;

&lt;p&gt;The guide is not only concerned with the technical design and development of the team. They should also be able to help the team spot and resolve inefficiencies. They can not do that effectively if they are not engaged in the team’s regular work. They should be able to identify opportunities to refine the teams practices, whether that means helping them break down requirements, effectively assigning work, or guiding another developer to take on new leadership responsibilities within a team. They should also help negotiate the concerns of the various stakeholders, whether they be customers, product designers, developers, or other parts of the business.&lt;/p&gt;

&lt;h2&gt;
  
  
  Considering Some Objections
&lt;/h2&gt;

&lt;p&gt;For smaller teams and organizations the practices and the pattern of the software guide should not be too onerous or give much room for objection. It is possible such organizations may not like the metaphor, or more likely those who fancy themselves “architects” don’t like the responsibilities and competencies such a model entails. But, I think those objections are more emblematic of a culture or personalities obsessed with the notion of the lone genius, which I am more than comfortable dismissing outright as such a rare occurrence that no one should plan around it.&lt;/p&gt;

&lt;p&gt;Larger organizations with architects overseeing teams in the hundreds, or thousands may have a difficult time with this model. I am sympathetic to such scenarios. However, I think there is room to strive for the better model that is represented by the software guide, instead of our traditional notions of the software architect. Whether it comes from investing in and promoting more developers to be guides; or dismantling elements of the hierarchical nature of large organizations. I think it is worth finding ways to encourage more collaborative, learning, and growth-oriented cultures. So, I don’t think architects in large organizations are off the hook when it comes to considering this model. I think the steps necessary to implement it will take longer, and may entail broader organizational changes; but I think the cost is worth the effort.&lt;/p&gt;

&lt;h2&gt;
  
  
  Put The Team First
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Being a guide makes you responsible for a team, before your technology.&lt;/em&gt; I think that is the underlying element of what it means to embrace the &lt;em&gt;architect as guide&lt;/em&gt; metaphor. And, I think it is the key to why the title of &lt;em&gt;architect&lt;/em&gt; may be worth abandoning in the long run. We ought to put our teams ahead of the technology. We ought to value our teams more than our own ideas and ambitions. And, we ought to prioritize our teams ahead of our deadlines. We need to figure out how to better prioritize what really matters in relation to those deadlines. In the end, I think good software development leader must always be focused on their team and their needs, &lt;strong&gt;because it is that team that does the bulk of the work anyways&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>teams</category>
    </item>
    <item>
      <title>Who Does Software Architecture?</title>
      <dc:creator>James Thompson</dc:creator>
      <pubDate>Fri, 05 Jul 2019 18:52:04 +0000</pubDate>
      <link>https://forem.com/plainprogrammer/who-does-software-architecture-51a5</link>
      <guid>https://forem.com/plainprogrammer/who-does-software-architecture-51a5</guid>
      <description>&lt;p&gt;The discipline of software architecture, and the role of the software architect, remains somewhat nebulous after nearly 30 years of prominence. Its origins go back even further, and it derives from an straightforward analogy. That analogy is to the field of civil architecture. But, the closer we examine this analogy, the less it seems to hold up.&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%2Fjames.thomps.onl%2Fwp-content%2Fuploads%2F2019%2F07%2FAdobeStock_114654788.jpeg" 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%2Fjames.thomps.onl%2Fwp-content%2Fuploads%2F2019%2F07%2FAdobeStock_114654788.jpeg" alt="Two modeling figures carrying a keyboard together" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Considering Civil Architecture
&lt;/h2&gt;

&lt;p&gt;Civil architecture is often conceived as a planning and design endeavor. However, it is easy to miss that the planning and design is not merely abstract. Varying levels of detail tend to be included in a set of architectural drawings. It is also not unusual for the architect to collaborate closely with civil engineers and others involved in construction. This leads to the work of the civil architect being nearly equal parts prescriptive and descriptive. I believe it is the assumed separation between the work of the civil architect and those doing the construction that leads our misunderstanding of this analogy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building Software
&lt;/h2&gt;

&lt;p&gt;It can be easy to think that the construciton phase of software development is found in the writing of source code. But, that assumption is mistaken. In the essay “Programming Is an Act of Design” from &lt;a href="https://amzn.to/2JegKkU" rel="noopener noreferrer"&gt;&lt;em&gt;97 Things Every Software Architect Should Know&lt;/em&gt;&lt;/a&gt;, Einar Landre helpfully observes that “software development is a processes of discovery and learning, not a process of engineering and construction.”&lt;/p&gt;

&lt;p&gt;I believe Landre goes on to correctly identify that the process of compiling and running the software is the most analogous to the construction phase of civil architecture. This means that the source code of software is not the output of construction, but is the design of the system; its blueprint. The source code is the architecture of the software system. The source code specifies the meaningful details, and the rest of the build process that is handled by the computer and other software does the construction. This means that what we tend to observe as the abstract work of the software architect is mere ideation, since it lacks any meaningful or useful specificity. Only the source code actually provides actionable and useful design detail.&lt;/p&gt;

&lt;p&gt;Even in the architecting of interconnected systems, the high-level drawings of how we think things fit together are speculative. The actual configuration, customization, and programming of the details is the meaningful expression of design and architecture. Because, from those elements, the construction is then automated and any mistakes in the design laid down in configuration or code become effective.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tendencies in Software Architecture
&lt;/h3&gt;

&lt;p&gt;Many conceive of software architecture as being those processes of abstract design. While such ideation can be helpful and even necessary, they can not deliver value themselves. This misunderstanding of architecture strains both the anology to civil architecture, but also reduces the value of what such architects produce. Still others press for very fine minutia to be considered the concern of the software architect. While they are arguably doing better than the abstract architect, they may well err in wanting to dictate from afar in a way that undermines their credibility and even their ability to do well in their role.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://martinfowler.com/ieeeSoftware/whoNeedsArchitect.pdf" rel="noopener noreferrer"&gt;Martin Fowler’s definition from “Who Needs an Architect?”&lt;/a&gt; is fairly well know:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Architecture is about the important stuff. Whatever that is.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And, while I love that defintion, I observe that many will quibble over its extent. We like to argue about what is or is not important. We seem to relish expanding the scope of what should be considered architecturally significant. But few will seriously consider the more practical advice Fowler gives later in the very same article:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I think that one of an architects most important tasks is to remove architecture by finding ways to eliminate irreversibility in software designs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This advice is perhaps the most meaningful part of the article, with the possible exception of one other observation that Fowler makes and that I will come back to. How many of us believe that &lt;strong&gt;removing architecture&lt;/strong&gt; is one of the most important things that an architect can do? I’ve seen too many aspiring architects, or folks in the role, that seem to think their most imporant task is to insert themselves into decision-making processes, and to concern themselves with the minutia of their team’s decisions. These sorts of tendencies to either be too abstract, or too expansionist are both serious errors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Developers Are Architects
&lt;/h2&gt;

&lt;p&gt;If we go back to Landre’s insights, we should easily recognize that with the source code as the real design document for a software system, &lt;em&gt;every developer is an architect&lt;/em&gt;. That means an architect is only effective in their role to the extent that they are still an active developer working with their team. Writing source code is the valuable design work, so architects ought to be engaged in it. And, they ought to recognize that the other developers on their team are doing architectural work too. So, how can the architect do their work well? What should they be doing more of?&lt;/p&gt;

&lt;h3&gt;
  
  
  Architect Archetypes
&lt;/h3&gt;

&lt;p&gt;It is at this point I want to consider the other observation that Martin Fowler makes in his article, “Who Needs an Architect.” He identifies two different archetypes for the role of software architect. The first is like the two errant approaches that I noted earlier, and Martin calls this archetype the &lt;em&gt;Architectus Reloadus&lt;/em&gt;. He draws on the presentation of &lt;a href="https://en.wikipedia.org/wiki/Architect_%28The_Matrix%29" rel="noopener noreferrer"&gt;the character of The Architect&lt;/a&gt; from &lt;a href="https://amzn.to/30ojBOb" rel="noopener noreferrer"&gt;&lt;em&gt;The Matrix Reloaded&lt;/em&gt; movie&lt;/a&gt;. This archetype is typified by two characteristics. First, they seek to be the person “who makes all the important decisions.” And, second, they often seek that end because they do not ”think that the team members are sufficiently skilled to make those decisions.”&lt;/p&gt;

&lt;p&gt;In many cases this type of architect seeks to impose their will and sense of wisdom on their team by various means. Instead of being a partner and collaborator, they are, at best, a benevolent dictator. This archetype is both common and an anti-pattern, if we recognize that software architecture is about the code we write, not the decisions we make. This negative archetype is expressed when we see architects insisting on being involved with all technical planning decisions, heavy-handed code review, or dictating rather than collaborating with teams. The expression of our software in code can rarely be dictated effectively, and even less so when the ones dictating are not in the thick of the problems being solved.&lt;/p&gt;

&lt;p&gt;This is where the other archetype that Fowler mentions comes in, the &lt;em&gt;Architectus Oryzus&lt;/em&gt;. Fowler identifies the leading characteristic for this type of architect is that of “intense collaboration.” He gives the example for this type of architect pairing with a developer on their team, and calls out that their most important activity is mentoring so that the team can tackle complex issues themselves. the observation of the collaborative, mentoring, and guiding role of this type of architect then led to this perspective:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This leads to the satisfying rule of thumb that an architects value is inversely proportional to the number of decisions he or she makes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Fowler even notes that the prevalence of the &lt;em&gt;Architectus Reloadus&lt;/em&gt; type in the industry, circa 2003, was so common that he and other coworkers were uncomfortable with the very title &lt;em&gt;architect&lt;/em&gt;. They searched for other and better descriptive titles. Even sixteen years later, I find that the title of &lt;em&gt;architect&lt;/em&gt; does not sit well with me, much like it did not sit well with Fowler, et al. I’ve observed it being used in too many inconsistent and unhelpful ways, just like they had. But, I’m no closer to a wholly suitable replacement for the title, although I am actively searching for one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architect as Guide
&lt;/h2&gt;

&lt;p&gt;I have consistently viewed the software architect role as one that involves teaching and advising. But, it was only recently that I fully appreciated the notion of the &lt;em&gt;architect as guide&lt;/em&gt;. In re-reading Fowler’s article I was pleased to see him describe how he and his colleagues arrived at the same place I had. I have come to realize that the best way to teach is to work alongside those who want to learn. The best way to share advice is to also experience the conditions that are giving rise to the need for advice. And, the best way to shape software architecture is to enable more developers to think about the issues involved well.&lt;/p&gt;

&lt;p&gt;Being an architect is not about making the important decisions. At best, that kind of architect is going to end up as a benevolent dictator. The best thing an architect can do is enable their team to make the important decisions themselves. Without that approach architects aren’t going to grow their team appropriately. The problems of &lt;a href="https://james.thomps.onl/2017/06/20/what-is-accidental-software-architecture/" rel="noopener noreferrer"&gt;accidental architecture&lt;/a&gt; and &lt;a href="https://en.wikipedia.org/wiki/Software_architecture#Software_architecture_erosion" rel="noopener noreferrer"&gt;architectural erosion&lt;/a&gt; will persist under such a lackluster approach to architectural oversight.&lt;/p&gt;

&lt;p&gt;But, if an architect is a true collaborator. Guiding their teams to know, understand, and make better decisions themselves. If that is the kind of architect we can strive for then our teams will thrive and grow. The architect is then an engineer of engineers, a developer of developers. The architect as a guide emphasizes trust, cooperation, shared experience, mutual growth, and respect. This is the model we ought to strive for.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who Does Software Architecture?
&lt;/h2&gt;

&lt;p&gt;Returning to the titular question of this post, I think the answer is straightforward: &lt;em&gt;every developer does software architecture&lt;/em&gt;. So, what is the role of those given the title or responsibility of being the architect? They are a guide, a shepherd, a fellow developer helping other developers to make the best decisison they can, whether the architect is available or not. The software architect is another developer who recognizes the value in investing their energy into making every other developer they can better.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>development</category>
      <category>teams</category>
    </item>
    <item>
      <title>Overtime Hurts Your Software &amp; Your Team</title>
      <dc:creator>James Thompson</dc:creator>
      <pubDate>Fri, 28 Sep 2018 15:00:32 +0000</pubDate>
      <link>https://forem.com/plainprogrammer/overtime-hurts-your-software-your-team-1324</link>
      <guid>https://forem.com/plainprogrammer/overtime-hurts-your-software-your-team-1324</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UyZy6nqQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://james.thomps.onl/wp-content/uploads/2019/07/fc58b-1i2mzebkb5jmjwnjythudrw.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UyZy6nqQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://james.thomps.onl/wp-content/uploads/2019/07/fc58b-1i2mzebkb5jmjwnjythudrw.jpeg" alt=""&gt;&lt;/a&gt;Photo by energepic.com from Pexels&lt;/p&gt;

&lt;p&gt;At almost every company there is some level of pressure to work overtime. It gets couched in language about mission, impact, hustle, and other euphemisms. Positive employee recognition usually comes to people willing to work the extra hours.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Joe really went that extra mile to help us meet our goal. Staying late, coming in on weekends. He really sacrificed for our mission.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Thankfully, I’ve never worked anywhere where my aversion to overtime was denigrated. But, praising overtime is ridiculous. Overtime is a sign of problems that should never receive praise. Ever.&lt;/p&gt;

&lt;p&gt;At its most basic the need for overtime reflects a breakdown in professionalism, priorities, and agility. I’m primarily concerned with overtime for software development organizations. But, the negative effects it has on productivity and quality can be observed in any context.&lt;/p&gt;

&lt;h4&gt;
  
  
  Professionalism
&lt;/h4&gt;

&lt;p&gt;Professionalism comes down to discipline. Competence and skill are obtained through discipline, no matter the endeavor. Overtime represents a lack of discipline with relation to scheduling. It represents a lack of discipline in other areas too. But, fundamentally, it is a failure to confine our work in a way that prevents it from pushing out other things.&lt;/p&gt;

&lt;p&gt;The phrase “work hard, play hard” is often associated with the mindset that leads to overtime. The idea being that if we push ourselves to work hard towards a goal, when we achieve it we gain license to let loose. But, what about when you miss the mark? What about when you never get the break because another goal arises? When overtime is acceptable it breeds more overtime to the exclusion of ever being able to &lt;em&gt;play&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;A better approach is embodied in the phrase “work hard, then go home.” This captures an assumption of balance between work and the rest of life. Each day we endeavor to do the work we need to and when that day is over we &lt;em&gt;go home&lt;/em&gt;. What we do when we are done with a day’s work is our concern. We have permission to leave work at work and take ownership of our time.&lt;/p&gt;

&lt;p&gt;This approach puts the power back in the hands of the individual to determine what is important to them. Some may say they want to prioritize their work, but we will get to other reasons that is often an unwise trade. Professionalism means respecting boundaries and exercising discipline. We should not expect people to choose between career and family, or job and friends, or work and fun. Professionals, and the organizations that want the best of them, should be disciplined about this balance.&lt;/p&gt;

&lt;h4&gt;
  
  
  Priorities
&lt;/h4&gt;

&lt;p&gt;Another area that is closely related to professionalism is that of priorities. In almost every case where I’ve observed, or been asked, to accept overtime has come when someone messed up what the most important thing was. Somewhere, somehow, prioritization had failed. The most important and urgent work was not done at the most appropriate time. Sometimes mistakes happen or circumstances change. But, more often than not, someone got the priorities wrong.&lt;/p&gt;

&lt;p&gt;This comes back to the need for communication. We need to be seeking consistent and clear feedback as we work. Anytime that breaks down we increase the risk we will not be working on the most important things when we need to. The reality is that we should not work on things whose value is suspect. Work to clarify our lack of understanding can help us keep the most valuable thing at the fore. But, if we can’t validate something’s value then it is not likely something worth working on. Failure to prioritize appropriately risks the product’s success since we can’t be sure we’re building what matters.&lt;/p&gt;

&lt;p&gt;When priorities are properly understood, along with their value it becomes easier to adjust plans. Understanding the value of our work provides opportunities to manage scope and timelines.We can move valuable work to the front and either delay or drop less valuable work. Emphasizing the important of priorities allows us to get at one of the root causes of needing overtime and avoid it.&lt;/p&gt;

&lt;h4&gt;
  
  
  After-Hours
&lt;/h4&gt;

&lt;p&gt;I’ve worked as a software engineer for the vast majority of the last fifteen years. But, interspersed in that time, I have also done a lot of work maintaining business computer systems. Sometimes those systems go down and require after-hours attention. Re-aligning our schedules can be part of the job we have sometimes. But, to connect back to professionalism, that should not translate into working a full day plus giving up our personal time.&lt;/p&gt;

&lt;p&gt;I’ve been fortunate to have roles at companies that permitted me to flex my schedule to accommodate the unexpected. If I’m fixing a server at 2:00am, I was not expected to be back in office for a normal day the following morning. Routine duties would have to be rescheduled to compensate for my need to rest and avoid burn-out. It’s important to recognize that adjusting one’s schedule or accommodating after-hours work is not the same as being pushed into, or even voluntarily accepting overtime.&lt;/p&gt;

&lt;h4&gt;
  
  
  Agility
&lt;/h4&gt;

&lt;p&gt;The first value statement of &lt;a href="http://agilemanifesto.org/"&gt;the Manifesto for Agile Software Development&lt;/a&gt; is “Individuals and interactions over processes and tools.” People come first in any agile organization. You can not take care of the work you want to get done unless you first take care of the people you expect to do that work. And, among &lt;a href="http://agilemanifesto.org/principles.html"&gt;the principles underlying that same manifesto&lt;/a&gt; is that of Sustainable Pace.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Agile processes promote sustainable development. The sponsors, developers, and users should be able to maintain a constant pace indefinitely.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Overtime is an adversary to Sustainable Pace. If we need overtime then something about our processes is misaligned, or not working. In an agile organization overtime is a symptom of more systemic failings. Address the problems in prioritization, scoping, quality or other areas. Whatever the root cause is, address that. Don’t accept overtime as unavoidable, or necessary.&lt;/p&gt;

&lt;p&gt;Agility requires keeping the lives of the people involved balanced. This means they need time to decompress. We can not work effectively if we are always working. Eventually our ability to deliver will suffer, quality will suffer, and we will be called upon to invest more overtime to fix what we failed to do well the first time. So, if we can focus on fixing the systemic issues that make overtime seem necessary, then we can avoid overtime and be more consistently at our best.&lt;/p&gt;

&lt;h4&gt;
  
  
  Productivity
&lt;/h4&gt;

&lt;p&gt;Research also indicates that &lt;a href="https://www.entrepreneur.com/article/288359"&gt;overtime is a waste of time&lt;/a&gt;. Productivity drops as sustained overtime continues. And, it appears that the drop can entirely negate the extra time. The emerging wisdom indicates that when we stay late we don’t get more done, we get the same done more slowly. Overtime work is, as my title points out unproductive time.&lt;/p&gt;

&lt;p&gt;Overtime has a negative effect on productivity for numerous reasons. That makes it better to avoid altogether. Why spend more unproductive time working if we could simply rest and return to full productivity after some time away? There is no good justification. We have conditioned ourselves to think overtime is somehow normal. We have engaged in self-deception in spite of what research and even intuition can tell us.&lt;/p&gt;

&lt;h4&gt;
  
  
  Quality
&lt;/h4&gt;

&lt;p&gt;Finally, there is the matter of quality. Overtime does not encourage continued discipline around good practices for maintaining consistent quality. Overtime is, itself, a way to cut corners, and it encourages more of the same in the work done during that time. If we are working overtime then we have already been stripped of the ability to take our time and to be thoughtful with regards to the things we build.&lt;/p&gt;

&lt;p&gt;When we lose encouragement to be thoughtful and disciplined in our development practices our quality slips. We skip a test here and there because that part of the solution is simple enough. We become arrogant in our ability to build software without the practices that sustain quality over time. And, our arrogance is always misplaced. None of us is as smart as we think we are. The practices and discipline that help us maintain quality software are our best safeguards against that arrogance run amok. But overtime does not afford us the one thing we need to maintain those practices and discipline: time.&lt;/p&gt;

&lt;p&gt;Quality will always suffer in the face of overtime. Maybe not immediately. But, as it continues to be accepted or encouraged, it will erode sound practices and stifle even the best developer’s discipline. If we want to maintain high quality software and high quality teams we can not accept overtime as normal. It never pays off in the way it promises and we often can’t know that until the costs have gotten much higher.&lt;/p&gt;




&lt;p&gt;So, how do we address the problem? Personally, I don’t work overtime. I get annoyed when I see folks praised for working overtime. I also speak up for others, whether they want me to or not, who often don’t know any better. So, we have to start by recognizing and calling out overtime as a problem. That is the first step.&lt;/p&gt;

&lt;p&gt;Overtime is a sign of dysfunction. It means something, somewhere, has gone wrong. If someone works overtime we should identify how to make sure that never happens again. We never want overtime to turn into burn-out. But, when we praise overtime we are inviting burn-out to come along too. This needs to be something an organizations draws a line in the cement over.&lt;/p&gt;

&lt;p&gt;How have you tried to combat the impulse or calls for overtime? Have you found other ways to achieve what is needed without sacrificing personal time? How can we all do better at ensuring work does not get to take over our lives?&lt;/p&gt;

</description>
      <category>overtime</category>
      <category>productivity</category>
      <category>softwarequality</category>
    </item>
    <item>
      <title>The Problem with Free &amp; Open Source Software</title>
      <dc:creator>James Thompson</dc:creator>
      <pubDate>Thu, 30 Aug 2018 00:03:34 +0000</pubDate>
      <link>https://forem.com/plainprogrammer/the-problem-with-free-open-source-software-fo4</link>
      <guid>https://forem.com/plainprogrammer/the-problem-with-free-open-source-software-fo4</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--C3WPvJiw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://james.thomps.onl/wp-content/uploads/2019/07/d19d1-1bj9y1hbx1wpa84rr5uhtcg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--C3WPvJiw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://james.thomps.onl/wp-content/uploads/2019/07/d19d1-1bj9y1hbx1wpa84rr5uhtcg.jpeg" alt=""&gt;&lt;/a&gt;&lt;a href="https://www.flickr.com/photos/nolanus/6812409085/in/photolist-bnZnT4-7NGTnv-5Vo6MT-73uXv-33GuaA-aWMPDp-9zxhTP-qwRFHX-4n5Lux-D5m1-geAjvM-2tHd8Z-aptaHZ-4nGMEH-7mhj7t-d7ArX3-7xXuE6-92zW2-eqcQt-8fVCnt-axoGj5-r17PuT-9Gp4WH-9gGeF8-5fUmnN-78Hr8W-9BX9Gq-o5ntva-8F7XDx-8fCPTt-2qc2UL-8F7YX4-5882mE-9RjiJk-aFMghP-auXmba-e5JnF6-p1yraV-ciWbyN-ai3x3Q-6H2hE-61gTgE-gAAfTi-e5qbYs-nN2qtS-qUY83b-ooAVA8-JxKyuk-5ex3uR-auXmqD" rel="noopener noreferrer"&gt;“Freedom”&lt;/a&gt; by &lt;a href="https://www.flickr.com/photos/nolanus/" title="Go to Sebastian Fuss's photostream" rel="noopener noreferrer"&gt;Sebastian Fuss&lt;/a&gt; — &lt;a href="https://creativecommons.org/licenses/by-sa/2.0/" rel="noopener noreferrer"&gt;Some Rights Reserved&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Back in the early 2000’s I got into a discussion about the relative merits and problems with &lt;a href="https://en.wikipedia.org/wiki/Free_and_open-source_software"&gt;Free and Open Source software&lt;/a&gt;. One of the points of discussion was the first freedom identified by Free Software:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The freedom to run the program as you wish, for any purpose&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This same freedom is identified in article five of the &lt;a href="https://opensource.org/osd"&gt;Open Source Definition&lt;/a&gt;. The point of that discussion was about the moral position of free and open source software as it related to proprietary software. My counterpart proposed that any software that was not free or open source was morally evil, while I defended the rights of creators to determine the bounds of their software’s use. I still stand by my position and will not retread it here. Any software developer has the right to define how and by whom their software can be used. But, I also believe that free and open source software is superior to proprietary software for many reasons and in many circumstances. &lt;strong&gt;&lt;em&gt;The most important of those reasons is freedom.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Freedom Is Not Free
&lt;/h4&gt;

&lt;p&gt;Freedom has consequences. Taking action necessitates accepting the consequences of such action. Sometimes those consequences are not to our liking, and still other times we have no control over the consequences. The trouble arises when the consequences become so objectionable that we think the problem is with freedom itself. That’s the trap that is always lurking just beyond our view, tempting us to restrict freedom for the sake of our comfort. But, the truth is that to gain our comfort we have to give up our freedom entirely.&lt;/p&gt;

&lt;h4&gt;
  
  
  Denying Freedom
&lt;/h4&gt;

&lt;p&gt;Today I ran across this tweet about a project I had never heard about doing something they have every right to do, but about which they were thoroughly ignorant of the full consequences:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Lerna, a popular tool for managing JavaScript projects with multiple packages, has added a clause to its MIT license blocking a variety of companies from using future versions: &lt;a href="https://t.co/ikypwrT84G"&gt;https://t.co/ikypwrT84G&lt;/a&gt; – what do you think about this well-meaning moral stance? &lt;a href="https://t.co/GF1PGBpEcP"&gt;pic.twitter.com/GF1PGBpEcP&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;— JavaScript Daily (@JavaScriptDaily) &lt;a href="https://twitter.com/JavaScriptDaily/status/1034842426861645824?ref_src=twsrc%5Etfw"&gt;August 29, 2018&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The &lt;a href="https://github.com/lerna/lerna"&gt;Lerna project&lt;/a&gt; was originally licensed under one of the most permissive open source licenses there is: &lt;a href="https://opensource.org/licenses/MIT"&gt;the MIT license&lt;/a&gt;. But, they decided to add an additional clause:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The following license shall not be granted to the following entities or any subsidiary thereof due to their collaboration with US Immigration and Customs Enforcement (“ICE”):&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The specific list of companies is immaterial, as are any political opinions concerning US Immigration and Customs Enforcement policies. The consequence of this change was that Lerna has made their project untouchable to the rest of the Free and Open Source software community. By denying the freedom for any person or group to use their project they have made their project incompatible with any project that upholds either the Free Software or the Open Source definitions.&lt;/p&gt;

&lt;p&gt;This is not the first time Free or Open Source software has dealt with the moral questions. Back in 2012 &lt;a href="https://dzone.com/articles/jsonorg-license-literally-says"&gt;it was called out&lt;/a&gt; the license used on JSON.org contained an explicit morality clause. In fact, the ambiguous clause is still included in &lt;a href="https://www.json.org/license.html"&gt;the license&lt;/a&gt;. The Debian project &lt;a href="https://wiki.debian.org/qa.debian.org/jsonevil"&gt;has labelled this license as non-free&lt;/a&gt; because it imposes this additional clause.&lt;/p&gt;

&lt;p&gt;The Open Source Initiative is clear in their FAQ that restricting a person or group is not permissible when they answer the question “Can I stop “evil people” from using my program?”&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;No. The Open Source Definition specifies that Open Source licenses may not discriminate against persons or groups. Giving everyone freedom means giving evil people freedom, too.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Unintended Consequences
&lt;/h4&gt;

&lt;p&gt;The reason both the Debian project and the Open Source Initiative are so unequivocal is that such restrictions cannot be reliably bounded. Debian recognized that the additional clause in the JSON license would pollute their project and require all its users to abide by the terms, which is something they could not reliably even enforce. Adopting restrictions on freedom always ripple out and effect others.&lt;/p&gt;

&lt;p&gt;Moral and ethical decisions exist within cultural contexts, and that makes them practically impossible to reliably define ahead of time. Since neither the Free Software or Open Source movements were omniscient they erred on the side of freedom. But, the maintainers of the Lerna project, the original JSON implementors, and others will continue to repeat the hubris of thinking they can adequately respond to evil by denying freedom not only to their perceived enemies, but also to everyone else who wants to use or produce Free and Open Source software that preserves freedom.&lt;/p&gt;

&lt;h4&gt;
  
  
  Freedom is the Problem (and the solution)
&lt;/h4&gt;

&lt;p&gt;At the end of the day freedom is the problem. It has costs, and consequences. But, freedom is worth having, even in the realm of software. Freedom means that with the same tools some would employ for evil we have all the rights to employ those same tools for good. But, we can’t maintain the freedom to do good effectively without risking freedom for others to do evil. That is the risk, but, in this case, I think it is a risk worth taking.&lt;/p&gt;

</description>
      <category>freesoftware</category>
      <category>freedom</category>
      <category>opensource</category>
      <category>foss</category>
    </item>
    <item>
      <title>Programmers Don’t Understand Value</title>
      <dc:creator>James Thompson</dc:creator>
      <pubDate>Wed, 18 Apr 2018 22:35:37 +0000</pubDate>
      <link>https://forem.com/plainprogrammer/programmers-don-t-understand-value-1epe</link>
      <guid>https://forem.com/plainprogrammer/programmers-don-t-understand-value-1epe</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fjames.thomps.onl%2Fwp-content%2Fuploads%2F2019%2F07%2Fd8fc6-1vvlz0g26brp0ki1dh06vrw.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fjames.thomps.onl%2Fwp-content%2Fuploads%2F2019%2F07%2Fd8fc6-1vvlz0g26brp0ki1dh06vrw.jpeg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How should we decide what to work on? Answering that question is the key to all software development processes. In my experience a lot of programmers, developers, and engineers are bad at answering it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Technical Debt
&lt;/h3&gt;

&lt;p&gt;This is the elephant in every room; at least in every room containing software developers. If there is software running somewhere, there is technical debt somewhere. At least, something some developer would identify as technical debt. And, developers love to address technical debt. Or, rather, they love to talk about addressing technical debt.&lt;/p&gt;

&lt;p&gt;I like talking about technical debt. I like addressing technical debt. But, I and many others enjoy discussing the problem most of all. It’s the easiest way to feel high minded and like we are experts at something. We all want to be pundits. And, nothing inspires punditry like the subject of technical debt among software developers.&lt;/p&gt;

&lt;p&gt;This is because it’s easy to talk about. It’s also easy to theorize about. But, it’s hard to fix while also delivering value. &lt;strong&gt;&lt;em&gt;Take a moment to run down the implications of that last statement.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Fixing Technical Debt Rarely Delivers Value On Its Own&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Technical debt implies the existence of something that already works. And, something that already works has already delivered value. So, how do we change something’s implementation in a way that delivers new value?&lt;/p&gt;

&lt;p&gt;Sure, the new implementation may be more performant. But, was that needed by customers right now? Sure, it may be easier to maintain or extend. But, do you need to extend it right now? Sure, it may let you use some shiny new tech. But, will the customer even know or care?&lt;/p&gt;

&lt;p&gt;The answers to those questions are too often a definitive “no.” So, why do we need to fix that technical debt right now? The answer is we often do not need to do any of the work we imagine. That is because we both misunderstand &lt;em&gt;technical debt&lt;/em&gt; and &lt;em&gt;value&lt;/em&gt;. Technical debt is only real if it costs us something. If there is no cost, then who do we owe something to again?&lt;/p&gt;

&lt;p&gt;Debt is something owed; and owing something to our egos does not count. Technical debt arises at the intersection of two conditions. First, our code must need active development. Second, changes must have become more difficult to make. Without both those conditions met the debt is not real. This can arise because of pure technical necessity, such as a need to update dependencies. But, unless those updates are necessary they do not qualify as technical debt either. The key is the presence of a necessary cost to pay to continue work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Refactoring, Refactoring, Refactoring
&lt;/h3&gt;

&lt;p&gt;I love Test-Driven Development. The Red-Green-Refactor cycle brings me great joy. And, refactoring is about keeping things working. Refactoring never involves changing behavior of code, only implementation. It’s about keeping the &lt;em&gt;what&lt;/em&gt; and &lt;em&gt;why&lt;/em&gt; of a unit of code intact while changing the &lt;em&gt;how&lt;/em&gt;. Refactoring is where we discover better abstractions, or unpack ones that have lost their value.&lt;/p&gt;

&lt;p&gt;So, if you are working in proximity to code that needs to change to make your work easier: refactor it. That is part of what refactoring is for. It’s called &lt;a href="https://martinfowler.com/articles/preparatory-refactoring-example.html" rel="noopener noreferrer"&gt;Preparatory Refactoring&lt;/a&gt; and is the heart of one of my favorite Kent Beck quotes:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;for each desired change, make the change easy (warning: this may be hard), then make the easy change&lt;/p&gt;

&lt;p&gt;— Kent Beck (@KentBeck) &lt;a href="https://twitter.com/KentBeck/status/250733358307500032?ref_src=twsrc%5Etfw" rel="noopener noreferrer"&gt;September 25, 2012&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Too often developers forget to refactor as they go in favor of imagining one day they’ll get to &lt;em&gt;do it right&lt;/em&gt;. And, too often, doing it right means doing it over. That’s not working smart, that’s working hard. And, it is straight up duplication of labor. That kind of approach has negative value.&lt;/p&gt;

&lt;p&gt;Instead, we should make improvements in the course of doing things that we know deliver value. But, that begs the question: what do we mean by the term &lt;em&gt;value&lt;/em&gt;?&lt;/p&gt;

&lt;h3&gt;
  
  
  So, What Has Value?
&lt;/h3&gt;

&lt;p&gt;In the realm of software the only thing that has value is what the customer finds valuable. Technical choices only have value to the extent that they produce value for the customer. That means value is subjective.&lt;/p&gt;

&lt;p&gt;That is one of the factors that can tend to trip up programmers. We like to believe we are rational. That is not true. We give in to our preferences, biases, and emotions readily because we are human beings. We bring those biases, preferences, and emotional attachments into how we assess value. But, our assessment is nowhere near as important as the people who actually use our software. Our opinions, preferences, and the like are mostly irrelevant. But, we tend to inject them anyways. And, when we do this we lead ourselves away from understanding what has value.&lt;/p&gt;

&lt;p&gt;Our subjective assessments lead us to rank our wants ahead of the customers needs. This can happen when we dismiss a user experience by saying things like: “I wouldn’t want to do it that way.” That sounds like we’re putting ourselves in the customer’s position. In reality we are disguising our biases, and preferences as if it were user feedback.&lt;/p&gt;

&lt;p&gt;Unless a customer deems something to have value, it has none. If the customer needs something faster, than the value is clear. If the customer needs a revised interface, then the value is clear. If the customer needs anything, then the value is clear. But, too often we assume that because we want something it has value. We should treat anything not in service of the customer as suspect.&lt;/p&gt;

&lt;p&gt;Find ways to address technical debt and technical wants in the flow of normal feature work. Deliver value to yourself and the customer in tandem. That can produce a virtuous cycle and keep you from doing unnecessary work. But, that’s how I like to approach things. What do you think?&lt;/p&gt;

</description>
      <category>programming</category>
      <category>softwaredevelopment</category>
      <category>technicaldebt</category>
    </item>
    <item>
      <title>In Honor of Legacy Code</title>
      <dc:creator>James Thompson</dc:creator>
      <pubDate>Mon, 09 Apr 2018 18:01:04 +0000</pubDate>
      <link>https://forem.com/plainprogrammer/in-honor-of-legacy-code-241</link>
      <guid>https://forem.com/plainprogrammer/in-honor-of-legacy-code-241</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bt7uNEEg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://james.thomps.onl/wp-content/uploads/2019/07/515bd-1pxqnjlgqlqw-rxnay3ei-a.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bt7uNEEg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://james.thomps.onl/wp-content/uploads/2019/07/515bd-1pxqnjlgqlqw-rxnay3ei-a.jpeg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Every company I have ever worked for had some. Few seemed to want to deal with it, and even fewer were confident they could. &lt;em&gt;Legacy Code&lt;/em&gt; is a fairly consistent, and strongly pejorative term within software development. But, is that a good thing? Over the last several years I have come to think that it is not. And, after hearing &lt;a href="http://confreaks.tv/videos/rubyconf2017-keynote-growing-old"&gt;Chad Fowler present his keynote at RubyConf 2017 titled “Growing Old,”&lt;/a&gt; I have been reinforced in that opinion.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Defining a Legacy&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;One of the big themes that I took away from Chad Fowler’s talk was the reminder that in every other field of endeavor the idea of &lt;em&gt;Legacy&lt;/em&gt; is a good thing. A legacy is typically thought of as a gift left by prior generations. Sometimes that gift is knowledge, or money — Yet, in the realm of software development the notion of what is left from one generation of programmers to another is very rarely viewed in a positive way.&lt;/p&gt;

&lt;p&gt;In one sense, this can be understandable given the rapid pace of technological advancement and the way certain tools and techniques can become antiquated. But, in many businesses the legacy systems are still delivering value, and often in a predictable way. But, our perspective as programmers, developers, or engineers is rarely centered on value.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Selfishness &amp;amp; Novelty&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Instead of looking at the value that is delivered by these existing systems we tend to focus on how hard they are for us to work in. Sometimes we grip about the frameworks they rely on, or the patterns an approaches taken by former caretakers. Sometimes we complain about the tangle of code that is hard to decipher. And, sometimes our criticisms have merit. But, as I reflect on my own career, more often than not, I was usually just being whiny.&lt;/p&gt;

&lt;p&gt;Two contrasting examples spring to my mind, one from the mid-point of my career where I feel like I helped my employer make a good change, and another from a little earlier in my career where I’m less confident I made the best long-term choice for my employer. I’ll start with the case where I think I did well.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;A Success Story&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Several years ago I was working for &lt;a href="https://www.readyproject.com/"&gt;The Ready Project&lt;/a&gt;. I had the opportunity to run into my former boss a couple days ago. I was glad to hear that, after a couple years of contraction across their whole industry, things are starting to stabilize. When I started working for them they were running an e-commerce site on Magento that was costing a substantial amount of money to maintain performance and availability. After getting a good understanding of how they were maintaining inventory synchronization with some third-party fulfillment partners, and their own warehouse; I encouraged them to make a switch to Shopify.&lt;/p&gt;

&lt;p&gt;The monthly costs were about the same at that time. Switching to Shopify offered an opportunity to freeze the operational costs at a predictable level that we could not do with Magento. So, we contracted another firm to do a coordinated redesign while I built the inventory integrations with Shopify. After a few months we were able to launch and they are still running on Shopify. I ended up having to leave as a part of the industry contraction that effected the business, but I’m proud of a lot of the work I did for The Ready Project. It put them in a position where my role was not essential and even without my technical abilities they were still able to go on with their business.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;A Lack of Forethought&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;The other example is from a couple years prior to my time at The Ready Project. I was working with a marketing and design consultancy doing implementation work for web sites they designed. Like many companies in that space they delivered sites with Content Management Systems (CMS) to allow clients to manage as much of their own sites as they felt comfortable with.&lt;/p&gt;

&lt;p&gt;The year prior to me starting with them I had begun doing a lot of work with Ruby, and was starting to learn about Ruby on Rails. In that process I came across a CMS built on Rails that was absolutely great for me to work in and build extensions for. I built a lot of fun to work on custom extensions. But, that was not the work I should have been doing. I delivered my work on time, but not always in a sustainable way. That made the job really stressful for me. The problem was that I had chosen to do work that was fun for me, but wasn’t necessarily good for the business.&lt;/p&gt;

&lt;p&gt;I should have chosen tools like Drupal, or WordPress, and focussed effort on minor customizations, rather than creating thoroughly custom solutions. There would have still been products that made sense to use my Rails-based CMS, because it was much easier to work with than Drupal or WordPress at the time. The problem was I was not thinking about the long-term ramifications of my work. I was not thinking about what would come after I eventually left. I don’t know if anything I built while in that role is still running today.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Check Your Motivations&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;The problem in the latter case was that I was focussed on myself and what I wanted to do. I cared about my employer and their success, but I wasn’t taking the long-term view. That was a pretty good time ago now, and I’ve learned a lot since then. But, there were decisions I could have made that would allow me to feel better about the legacy I left there. In the time since, including my time at The Ready Project, I have gotten much better at thinking holistically about my employer and less about myself. So, my motivations have shifted subtly. I now am less worried about padding my resume and instead want to do what I can to make sure I am doing what my employer needs to be successful. I am applying my experience in different ways, and not all of them are technical. That is a big reason why I don’t care as much for chasing the newest tech. I want to understand it, but using it is not my priority. That decrease in selfish motivations makes me a better employee, at least in my estimation.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Back to Legacy Code&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;So, what does any of this have to do with Legacy Code? Well, first, Legacy should not be a pejorative. In many instances the code is working and producing business value. Can the same be said for whatever else is being actively developed; all of it? I doubt that answer in many businesses is a overwhelming and defensible affirmative.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Working code is better than code that does not yet exist, work, or produce value.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Legacy code was produced by people who we should assume were doing the best they could with the resources and information they had available. We may not like the output, but we should appreciate the effort. We should respect the work that went into the projects. And, we should look for ways to improve it when possible, retire it graciously, and speak well of those who managed to deliver business value that we are today working to build on top of.&lt;/p&gt;

</description>
      <category>experience</category>
      <category>legacycode</category>
    </item>
    <item>
      <title>Tests Should Not Be Optional</title>
      <dc:creator>James Thompson</dc:creator>
      <pubDate>Mon, 02 Apr 2018 17:14:06 +0000</pubDate>
      <link>https://forem.com/plainprogrammer/tests-should-not-be-optional-1ak</link>
      <guid>https://forem.com/plainprogrammer/tests-should-not-be-optional-1ak</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fjames.thomps.onl%2Fwp-content%2Fuploads%2F2019%2F07%2F006d5-10mgkhw1_ulkzlbps07mq3q.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fjames.thomps.onl%2Fwp-content%2Fuploads%2F2019%2F07%2F006d5-10mgkhw1_ulkzlbps07mq3q.jpeg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I am of the opinion that any code that does not have accompanying automated tests should be considered inherently defective. When we write code we have certain notions of suitableness in mind. Tests are a way to express those notions in a way that others can run, and examine, independent of having to delve into our actual implementation. Tests provide a way to communicate about the code we write in regards to what it does, not simply how it does some thing. While those two notions of “what code does,” and “how code does something” seem almost like the same thing, I believe there is value in distinguishing them, and that distinction is why I think code without tests should be considered inherently defective.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;What versus How&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;When we write code we are being prescriptive, we are stating with as much precision as our chosen language allows, or implies, the steps we want the computer to take in completing some work. Our implementation is a judgement about the best way, at a given point in time to accomplish something. This judgement has assumptions baked in that are derived from the context within which the code was written. When we commit to a particular implementation we are making the assertion that the code we are writing ought to work. But, the code we write makes only the most minimal of guarantees, and those guarantees it does make strongly are highly contextual.&lt;/p&gt;

&lt;p&gt;However, when we write tests we are stepping out of the prescriptive and, hopefully, engaging with something more descriptive. This is a hopeful outlook because writing tests can simply reinforce the prescriptions inherent to the implementation and, in many cases, those represent poor tests. When I write tests I want to describe the behavior of my software, not how it accomplishes that behavior. The difference is subtle, but important. As an example let us take this snippet of implementation code a starting point:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gist.github.com/plainprogrammer/3faeab94b0dd5b09eb8a2ef48af2ba45" rel="noopener noreferrer"&gt;https://gist.github.com/plainprogrammer/3faeab94b0dd5b09eb8a2ef48af2ba45&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are a few ways this code could be tested, but I only want to compare two approaches. This first example, I would assert, is a poor test because of its reliance on internal implementation details:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gist.github.com/plainprogrammer/7fce0abdf4f0027155a314c964900868" rel="noopener noreferrer"&gt;https://gist.github.com/plainprogrammer/7fce0abdf4f0027155a314c964900868&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This set of tests, while providing complete coverage, is inextricably tied to how this method accomplishes its work. If at any point the specific internals of this method changes, then the tests will also need to change. In contrast, the following example tests are much better, in my opinion:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gist.github.com/plainprogrammer/0cf56d3b3fe02e6c96d0e09b95fedb01" rel="noopener noreferrer"&gt;https://gist.github.com/plainprogrammer/0cf56d3b3fe02e6c96d0e09b95fedb01&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These tests, specifically the last two, focus on the behavior that this method encapsulates and could even be refactored away from this model should a service object, or some other pattern be desired with most of the changes being isolated to the context of the tests, not the tests themselves. By focussing on behavior, the internal implementation can change more substantially without needing the test code to change. Only when the overall behavior of the code changes will the test case need to change significantly. This emphasis on describing what the code does, versus how it does it, is where the value of tests come from. If tests only reinforce what is already prescribed in the implementation, then they are just another layer of coupling and fragility that will need to be contended with in the future. The emphasis of good, descriptive tests should be on the effects that some code causes. Tests should answer the question, what does this code cause to change, not how does this code accomplish that change.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Prescription Alone is a Defect&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;To return to my original assertion that code without accompanying tests should be considered inherently defective: without some aspect of description around a piece of software that can be run repeatedly and automatically, certainty about the behavior of the system, at any layer, will always be rooted in assumptions. While manual QA can provide a level of certainty that the software behaves as expected, that level of certainty relies entirely on how certain we are on the infallibility of humans.&lt;/p&gt;

&lt;p&gt;Test code is full of assumptions as well, but those assumptions are part of the code and thus subject to inspection, adjustment, or removal. Tests allow for the controlling of what assumptions are in place at any given point in time in a way that manual QA does not facilitate well. Good manual QA requires meticulous documentation to achieve repeatability, and its scale is always limited by staffing. But, if manual QA discoveries can be codified with automated tests then the entire process can be made more efficient, reliable, and repeatable.&lt;/p&gt;

&lt;p&gt;So, while automated tests can not replace all forms of manual QA, they can increase the reliability of the testing process and often can increase speed as well. But, the descriptiveness of manual QA and system-level testing is only one facet of the issue. Lower level tests, such as unit and other functional tests, as illustrated above, also reap benefits from automated testing. While it can be possible to test an entire system through only its public interface, testing the units that compose that system can often be far faster, and can lead to a much faster feedback cycle during development. That speed in both execution time and feedback is what allows lower level tests to help drive design decisions, guide refactoring, and prevent some bugs from making it to production in the first place.&lt;/p&gt;

&lt;p&gt;If the only certainty that we have about a piece of software comes from the prescriptions of its implementation, then our certainty is incredibly shaky. The prescriptions are founded on assumptions that are at best implicit, and suitability for any present or future purpose is also entirely assumed. The compounding nature of the assumptions tied in to only working with software in its prescriptive form is not a feature, it is a serious defect, and the remedy is not terribly difficult or costly.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Even a Little Description Instills Confidence&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;I have walked into a few untested, or poorly tested code bases, and my initial impulse has become incredibly consistent: I try to figure out how to add tests. If a system is running then it meets some level of suitability, but sometimes it is tentative. In such code bases I prefer to write as high a level tests as possible. This trades off test runtime speed for coverage and anti-fragility. Higher level integration or acceptance tests always run slower, and cover more than unit tests. But, they also tend to be easier to write in a way that captures effects rather than methods. For this reason they can help us more rapidly build confidence around a system.&lt;/p&gt;

&lt;p&gt;The trick with adding this kind of descriptive clarity and confidence to a system is knowing where to begin. This is best answered by non-technical stakeholders. Ask them to identify what the system does that is either the most valuable to the business, or would represent the greatest risk if it were incorrect. Then ask them to define its expected behavior at the present time. Then write the tests around that system to match the description provided.&lt;/p&gt;

&lt;p&gt;This approach will often surface bugs in the existing implementation. Whenever this happens make note of them and encapsulate the proof in pending test cases, but focus on capture what the system currently does. Once the existing effects of the system are captured then bring your finding regarding buggy behavior to stakeholders and discuss their relative importance to establish when, or if, they need to be addressed. The good this is you will have some level of testing around those issues which will allow you to know when you have fixed them, if that time comes.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Putting Code Coverage in its Place&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Repeatedly I’ve referred to code coverage. I value code coverage a lot. On all the projects I actively maintain I aim for 100% C0 coverage. There are two reasons for this: confidence and testability. Having 100% code coverage does not guarantee my code is defect free, or even correct; but it does mean I have tests that exercise every line of my code in some way. This means all my code can run. It also means that all my code is testable by way of being reachable via tests.&lt;/p&gt;

&lt;p&gt;But, code coverage is not the goal. Poorly written tests can also achieve high levels of coverage, so test coverage proves very little. But, it can be a helpful metric when rightly understood. I highly recommend Martin Fowler’s &lt;a href="https://martinfowler.com/bliki/TestCoverage.html" rel="noopener noreferrer"&gt;brief commentary on the topic&lt;/a&gt; for getting a healthy perspective.&lt;/p&gt;

&lt;h3&gt;
  
  
  Confidence &amp;amp; Clarity
&lt;/h3&gt;

&lt;p&gt;The goal with writing tests around code is to provide confidence that the desired behaviors, the effects of the system, are in place. That is the first goal of testing. The second goal is to communicate that desired behavior to other in a way that is clear. Good code is clear code, and the same goes for tests. Tests are another form of code, and so they ought to be clear too. But, it is important to remember the different types of clarity involved: your implementation code should clearly communicate how your software does something, while the test code should clearly communicate what your software does. In this way tests provide another helpful angle for understanding a software system and why it has value.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>softwaredevelopment</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Software Testing &amp; Confidence</title>
      <dc:creator>James Thompson</dc:creator>
      <pubDate>Wed, 24 Jan 2018 23:28:52 +0000</pubDate>
      <link>https://forem.com/plainprogrammer/software-testing-confidence-51ap</link>
      <guid>https://forem.com/plainprogrammer/software-testing-confidence-51ap</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%2Fjames.thomps.onl%2Fwp-content%2Fuploads%2F2019%2F07%2F044ce-13kvy25v-po1yotwulzzfyg.jpeg" 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%2Fjames.thomps.onl%2Fwp-content%2Fuploads%2F2019%2F07%2F044ce-13kvy25v-po1yotwulzzfyg.jpeg" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When we build software it can sometimes feel like a precarious balancing act. Will this next bit of code do what we expect? Will something we did not change begin behaving strangely? Certainty and confidence are not always feelings close at hand for many software developers.&lt;/p&gt;

&lt;p&gt;Being able to answer these concerns with greater confidence is why software tests are so important. For over a decade now I have been a consistent practitioner of Test-Driven Development. It has made me a better software craftsman and helped me move from programmer, to developer, and now to the point where I consider myself a software engineer. And, as new paradigms of software architecture continue to emerge and evolve the confidence I gain from good tests will remain important to my work.&lt;/p&gt;




&lt;h3&gt;
  
  
  Layers of Testing
&lt;/h3&gt;

&lt;p&gt;Over the last several months I’ve been working on a new microservice at &lt;a href="https://www.nav.com/" rel="noopener noreferrer"&gt;Nav&lt;/a&gt;. It is intended to supplant an existing service and so it has multiple criteria it has to meet. It needs to provide a certain degree of parity with the existing service. It needs to add additional value based on its own functionality. And, it must support a migration path for both data in the existing service, as well as for other services within our ecosystem.&lt;/p&gt;

&lt;p&gt;The first two of those criteria are easily handled by service-level unit tests. I have long made a habit of starting with 100% &lt;a href="https://grosser.it/2008/04/04/whats-my-coverage-c0-c1-c2-c3-path-coverage/" rel="noopener noreferrer"&gt;C0 code coverage&lt;/a&gt; and not allowing that to slip. But, that only gives me confidence that my code works as intended, and specifically as I have described that intent in my tests. And, were this a new service, not meant to replace anything else, then those tests would give me sufficient confidence to release the service within our ecosystem. But, the third criteria I described above is the concerning one. Because that criteria relates to interacting with other systems, another layer of testing is necessary.&lt;/p&gt;

&lt;p&gt;Unfortunately this layer of inter-service testing is the more challenging, but necessary. I need to gain confidence for the communication between the new and old service for current activity. There will be an ETL stage to bring over old data, which will need to be manually confirmed. And, finally there will be a need to confirm that services relying on the old service can interact with the new service instead.&lt;/p&gt;

&lt;h3&gt;
  
  
  Externalities Add Difficulty
&lt;/h3&gt;

&lt;p&gt;For my work, we have a messaging system to enable asynchronous communications between the new and old services. I have tests that mock the messaging system and ensure we are attempting to do the right thing. But, for both services I need to increase my confidence that messages are actually being sent properly. This means that I need to test the messages that are sent and the action of the service receiving those messages.&lt;/p&gt;

&lt;p&gt;The first step was to add tests to confirm the right messages are passed to the messaging system. These tests took some careful work because adding a dependency on the messaging system meant latency was introduced. I had to build wait time into the tests which made them slower, but only marginally so. Thankfully we use Docker on our development machines so setting up the messaging system for local testing was incredibly easy.&lt;/p&gt;

&lt;p&gt;After I established tests to confirm the right messages were getting to the messaging system, I moved on to ensuring that the right actions occurred on the services. This introduced another dependency that required more careful testing. But, I could assert that with both services running, when an event happened on one it triggered the appropriate action on the other. I wrote tests to confirm this in both directions.&lt;/p&gt;

&lt;p&gt;With these tests I have confidence that these services interact correctly. And, that was the goal. There are other details that needed to be managed. Ensuring proper expectations in regard to the messaging system was important. Knowing how the system would behave if there was a temporary inability for one service to process inbound messages. And, each of those were about improving confidence. And, whenever possible, that confidence is backed up with automated tests.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Unacceptable Alternative
&lt;/h3&gt;

&lt;p&gt;Now, this may all sound like a lot of work, and it is. But it is absolutely essential. Code without tests is defective. And, in a microservice ecosystem this leads to the assertion that collaborating services without tests are defective. If two services have explicit dependency on one another, but their actual interactions are never tested, then there is no reproducible proof that they work together.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Code without tests is defective, and so are collaborating services without tests.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The alternative is a lack of confidence that the system behaves as expected. The alternative is uncertainty. And, the reality is that &lt;strong&gt;&lt;em&gt;hope is not a good plan&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;Testing is an incredible practice for software development and will make the developer and their software better. Noel Rappin has a great talk available from RubyConf 2017 on &lt;a href="https://youtu.be/IS_9cRP9OZM" rel="noopener noreferrer"&gt;&lt;em&gt;High Cost Tests and High Value Tests&lt;/em&gt;&lt;/a&gt;. For those interested in more details on testing microservices, I recommend this talk from the 2017 O’Reilly Software Architecture Conference in London called &lt;em&gt;Reality is Overrated: API simulation for microservice testing&lt;/em&gt;, &lt;a href="https://www.safaribooksonline.com/library/view/oreilly-software-architecture/9781491985274/video315474.html?utm_medium=affiliate&amp;amp;utm_source=cj&amp;amp;utm_campaign=paid&amp;amp;utm_content_cj_12989168_1" rel="noopener noreferrer"&gt;part one&lt;/a&gt; and &lt;a href="https://www.safaribooksonline.com/library/view/oreilly-software-architecture/9781491985274/video316851.html?utm_medium=affiliate&amp;amp;utm_source=cj&amp;amp;utm_campaign=paid&amp;amp;utm_content_cj_12989168_1" rel="noopener noreferrer"&gt;part two&lt;/a&gt;, which is available via &lt;a href="http://www.jdoqocy.com/click-8483885-12989168" rel="noopener noreferrer"&gt;Safari Books Online&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>agile</category>
      <category>confidence</category>
      <category>programming</category>
    </item>
    <item>
      <title>Microservices Will Mess Your Team Up</title>
      <dc:creator>James Thompson</dc:creator>
      <pubDate>Tue, 09 Jan 2018 21:41:35 +0000</pubDate>
      <link>https://forem.com/plainprogrammer/microservices-will-mess-your-team-up-55ie</link>
      <guid>https://forem.com/plainprogrammer/microservices-will-mess-your-team-up-55ie</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%2Fjames.thomps.onl%2Fwp-content%2Fuploads%2F2019%2F07%2Fed641-1ufpfetekvft74xsmxnka9w.jpeg" 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%2Fjames.thomps.onl%2Fwp-content%2Fuploads%2F2019%2F07%2Fed641-1ufpfetekvft74xsmxnka9w.jpeg" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://martinfowler.com/articles/microservices.html" rel="noopener noreferrer"&gt;Microservices&lt;/a&gt; are popular with many teams. But, software development patterns are still in flux around this architectural pattern. In the last several years the space has matured a lot. Still, too many teams produce poor implementations.&lt;/p&gt;

&lt;p&gt;Microservices are often placed in contrast to Monolithic applications. That comparison is instructive, but it is also naive. Microservices is an extension of modular, or component-based, software design. It applies the idea of boundary definitions and extends it towards clearer vertical segmentation.&lt;/p&gt;

&lt;p&gt;The problem I’ve observed is that very few teams invest the requisite time to define proper boundaries. That failure produces difficult to maintain applications when it comes to Monolithic applications. Microservice systems that lack such defined boundaries are an order of magnitude worse. Without defined boundaries in a Microservice ecosystem, all you end up with is a distributed Monolith. This reality is one only experienced teams seem to appreciate.&lt;/p&gt;

&lt;h4&gt;
  
  
  Counting the Cost
&lt;/h4&gt;

&lt;p&gt;Independent and granular deployability is the biggest benefit that many teams do not need. This benefit comes at the cost of operational complexity for a distributed system. From messaging protocols, to event and message channels, to coordination and discovery. Even small ecosystems need more complex tooling requiring specialized operations-oriented knowledge and skills.&lt;/p&gt;

&lt;p&gt;Another big benefit of Microservices is stronger module boundaries. But, too many teams have difficulty defining boundaries in a Monolithic applications. That difficulty is not reduced with an architectural approach as complex as Microservices. Teams that adopt Microservices need architectural skill in identifying and defining boundaries. That skill is easier to hone in a Monolithic application first, but few teams invest in that approach.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Without defined boundaries in a Microservice ecosystem, all you end up with is a distributed Monolith.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Technological diversity is something that can keep a team excited about their work. Microservices make it easier to adopt diverse technologies. Like independent deployability this benefit comes at the expense of operational complexity. And, teams can adopt more technologies than they can manage if guidance is lacking.&lt;/p&gt;

&lt;h4&gt;
  
  
  Solve Your Problems
&lt;/h4&gt;

&lt;p&gt;Microservices, like any architectural approach solve certain problems and opens doors to others. Before adopting any approach it is important to identify the needs of a project and team. In more cases than not, Microservices are the wrong place to start. Until a team needs independent deployability and has the skill to identify and sustain clear service boundaries a Monolith is best. Too many teams pursue Microservices for the wrong reasons and fail to identify the problems they want to solve.&lt;/p&gt;

&lt;h4&gt;
  
  
  Make a Map
&lt;/h4&gt;

&lt;p&gt;One approach that any team can borrow from Domain-Driven Design is to work on a &lt;a href="https://www.google.com/url?sa=t&amp;amp;rct=j&amp;amp;q=&amp;amp;esrc=s&amp;amp;source=web&amp;amp;cd=7&amp;amp;cad=rja&amp;amp;uact=8&amp;amp;ved=0ahUKEwjErLj35cvYAhVG12MKHW7AAm4QtwIIQDAG&amp;amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3Dvwr2wAclIwg&amp;amp;usg=AOvVaw2rLoYY-puJq1MXdv8yHLYX" rel="noopener noreferrer"&gt;Context Map&lt;/a&gt;. A Context Map defines the various &lt;a href="https://martinfowler.com/bliki/BoundedContext.html" rel="noopener noreferrer"&gt;Bounded Contexts&lt;/a&gt; that exist within a system. It is technology and implementation independent. This practice can help a team gain insight on where boundaries should exist in their system. It can also help them explore how those boundaries may overlap or need to interact. This kind of team and business discovery will help identify where Microservices may present real value.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Conway%27s_law" rel="noopener noreferrer"&gt;Conway’s Law&lt;/a&gt; is often cited in relation to Software Architecture and it is a valuable concept to keep in mind. But, the influence of an organization on the systems it produces is not one-way. The systems a team works on will also influence the organization. Teams that work on distributed systems can also tend towards separation and lower cohesion. Without specific practices to manage these tendencies teams can become insular and territorial. So, adopting Microservices is as much about culture as it is about technology. And, if that is not taken into account the choice of Microservices may harm, rather than help, your team.&lt;/p&gt;

</description>
      <category>microservices</category>
      <category>architecture</category>
    </item>
    <item>
      <title>JavaScript Can Not Win</title>
      <dc:creator>James Thompson</dc:creator>
      <pubDate>Thu, 04 Jan 2018 16:01:01 +0000</pubDate>
      <link>https://forem.com/plainprogrammer/javascript-can-not-win-25ed</link>
      <guid>https://forem.com/plainprogrammer/javascript-can-not-win-25ed</guid>
      <description>&lt;p&gt;I read a story over on &lt;a href="https://medium.com/u/4a8a924edf41" rel="noopener noreferrer"&gt;Hackernoon&lt;/a&gt; by &lt;a href="https://medium.com/u/7e0f0c4bba2b" rel="noopener noreferrer"&gt;Jonny Asmar&lt;/a&gt; — &lt;a href="https://hackernoon.com/javascript-has-already-won-235b29ed126b" rel="noopener noreferrer"&gt;&lt;em&gt;Javascript Has Already Won&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt; The premise is that Node.js and JavaScript have become so far reaching that it has won out over other programming languages.&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%2Fjames.thomps.onl%2Fwp-content%2Fuploads%2F2019%2F07%2Ff080f-1dmfnkrwdue3lm3ki7qvvqg.jpeg" 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%2Fjames.thomps.onl%2Fwp-content%2Fuploads%2F2019%2F07%2Ff080f-1dmfnkrwdue3lm3ki7qvvqg.jpeg" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Unfortunately, this entire line of thinking is nonsense. Not because JavaScript can’t do all the things claimed, but because there is nothing to win. JavaScript can not win, because there is no contest. JavaScript can not win, because there is nothing to win.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;JavaScript can not win, because there is nothing to win.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;JavaScript has been around since 1995. Other notable programming languages of the 90’s include Haskell (1990), Python &amp;amp; Visual Basic (1991), Ruby (1993), and both Java &amp;amp; PHP (1995). According to the &lt;a href="https://www.tiobe.com/tiobe-index/" rel="noopener noreferrer"&gt;TIOBE Index&lt;/a&gt;, both Java and Python exceed JavaScript in this survey’s index of popularity. And, even venerable old C, released way back in 1972, is experiencing more rapid growth than JavaScript.&lt;/p&gt;

&lt;p&gt;But, so what? So, nothing. That’s the point. If we keep looking at the TIOBE Index, such languages as COBOL (#24), Fortran (#33), and Prolog (#41) still make the rankings — and, those former two are from the later 1950s. So, what exactly has JavaScript won? Nothing. Because there is nothing to win.&lt;/p&gt;

&lt;p&gt;There’s no prize for ubiquity when it comes to programming languages, because there is no ubiquity to be had. Any programming language able to reach a certain level of popularity is very unlikely to ever &lt;strong&gt;&lt;em&gt;die&lt;/em&gt;&lt;/strong&gt;. COBOL has been around since 1959 and it has been cited that &lt;a href="https://blog.hackerrank.com/the-inevitable-return-of-cobol/" rel="noopener noreferrer"&gt;70 to 80 percent of business transactions&lt;/a&gt; run on it. So, if anyone has won anything it is COBOL, not JavaScript.&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%2Fjames.thomps.onl%2Fwp-content%2Fuploads%2F2019%2F07%2F02227-1liiglwrpjzse8don8_roag.jpeg" 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%2Fjames.thomps.onl%2Fwp-content%2Fuploads%2F2019%2F07%2F02227-1liiglwrpjzse8don8_roag.jpeg" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No matter how popular a language gets, there is no prize to claim. Not only because popularity comes and goes, but because the competition is worse than vanity: it’s imaginary. If every line of COBOL were rewritten in JavaScript, there is nothing preventing the same disruption from coming to JavaScript. And that’s because there is no perfect programming language, paradigm, or ecosystem. That is the great vanity of too many software developers.&lt;/p&gt;

&lt;p&gt;I have developed software for the web since 2003. And I know that my years of experience are minuscule compared to those in this industry since before I was born. I’m not old enough to have seen any technologies take-off and then vanish into obscurity, but I know it has happened. I’ve not had the misfortune of working with a thriving technology and to see it stagnate and dwindle to nothing. But, I’ve heard the tales of those who have been around and worked long enough to have experienced that. And, even for those folks, their loss was only temporary. They lost one tool and found another. In the end, they lost nothing because there was nothing for them to lose.&lt;/p&gt;

&lt;p&gt;Programming languages are tools. The ones that are suitable and flexible can become popular. Even ones that are unpleasant can find their own degree of popularity. But, to ever say that one programming language has &lt;strong&gt;&lt;em&gt;won&lt;/em&gt;&lt;/strong&gt; seems like nonsense to me. That is, unless you are talking about COBOL. Because, if the stats are true, COBOL is the winner of whatever the contest of programming languages is.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>programming</category>
    </item>
    <item>
      <title>Defining Principles for Software Engineering</title>
      <dc:creator>James Thompson</dc:creator>
      <pubDate>Wed, 27 Dec 2017 17:01:03 +0000</pubDate>
      <link>https://forem.com/plainprogrammer/defining-principles-for-software-engineering-4gob</link>
      <guid>https://forem.com/plainprogrammer/defining-principles-for-software-engineering-4gob</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UOsL2x85--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2560/0%2AL1RUhuhsIawMmZ6e." class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UOsL2x85--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2560/0%2AL1RUhuhsIawMmZ6e." alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Several months ago I wrote about my personal &lt;a href="https://theplainprogrammer.com/principles-of-software-engineering-ab75f74e91d4"&gt;principles of software engineering&lt;/a&gt;. That post was informed by a talk a watched by Peter Campbell. Since then, I have been reflecting how to align various ideas I have been addressing independently up to this point. To help bring these various ideas together I want to start at what I think is the most fundamental and address how to define the principles that drive software engineering efforts.&lt;/p&gt;

&lt;h3&gt;
  
  
  What are Principles?
&lt;/h3&gt;

&lt;p&gt;A principle is the most fundamental source or basis for something. Principles are the roots of ideas and practices. They are the most basic elements that give shape, structure, and direction.&lt;/p&gt;

&lt;p&gt;Religions, governments, fields of study, businesses, and even software systems have their form guided by certain principles. When principles are recognized, accepted, and reinforced a degree of sustainability and stability tends to emerge. When principles go unspoken, neglected, and thus degrade instability and uncertainty emerge until failure, disintegration, or reorganization around new principles occurs.&lt;/p&gt;

&lt;h4&gt;
  
  
  Characteristics of Principles
&lt;/h4&gt;

&lt;p&gt;One of the key characteristics of principles is that they inform other beliefs or practices. This gets to the notion of being foundational, or basic. Without a given principle it is difficult to sustain other ideas or activities. An example of this building-block tendency that I will draw from my background as a student of Biblical Studies and Christian History is a basic principle that undergirds the &lt;a href="https://en.wikipedia.org/wiki/Reformation"&gt;Protestant Reformation&lt;/a&gt; idea of &lt;a href="https://en.wikipedia.org/wiki/Sola_scriptura"&gt;&lt;em&gt;sola scriptura&lt;/em&gt;&lt;/a&gt;: the clarity of Scripture.&lt;/p&gt;

&lt;p&gt;The principle of Scripture’s clarity is derived from certain other beliefs and certain readings of the Bible; but without it, the belief in Scripture as the final and sole authority for all matters of Christian faith and practice would be unsustainable. The principle of Scripture’s clarity is the affirmation that the meaning of a biblical text can be clear to the ordinary reader. The implications of this principle gave rise to the efforts that continue today to make the Bible available in every language, the democratization of church life, and much more.&lt;/p&gt;

&lt;p&gt;In addition to promoting derivation of other ideas and actions, another characteristic of principles is that they tend to be exclusionary in some fashion. A principle tends to include certain ideas or actions as acceptable, and others as unacceptable. This is best revealed in the way principles of logic work, such as the &lt;a href="https://en.wikipedia.org/wiki/Law_of_noncontradiction"&gt;principle of non-contradiction&lt;/a&gt; which holds that a thing cannot be both the same and different from another thing at the same time and in the same sense. So, the principle of noncontradiction excludes the possibility that its opposite can be the case if it is accepted. And, this logical principle informs work down to the present in such seemingly disparate fields as physics and theology.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Principles both promote the derivation of other ideas and actions; and they tend to exclude other ideas and actions as well.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In fields other than software engineering there are other characteristics that principles within that field may possess. But, for the purpose of exploring the idea of principles in software engineering, these two characteristics suffice.&lt;/p&gt;

&lt;h3&gt;
  
  
  Principles in Software Engineering
&lt;/h3&gt;

&lt;p&gt;In software engineering, there are some specific implications of these two characteristics that bear addressing. Some principles within the field of software engineering can be contrary to each other.&lt;/p&gt;

&lt;p&gt;As an example, both &lt;em&gt;brevity&lt;/em&gt; and &lt;em&gt;clarity&lt;/em&gt; may be reasonable principles to adopt for the production of a software system. But, these two principles exclude the other.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gist.github.com/plainprogrammer/bd8d6fd042081442ffe75c5d79f269bf"&gt;https://gist.github.com/plainprogrammer/bd8d6fd042081442ffe75c5d79f269bf&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Only when external domain knowledge is available is the more brief code on top equally clear in comparison to the example on the bottom. Code that is brief also tends to require more knowledge of alternative language features, such as the parallel assignment behavior of line three in the top example. Whereas, clear code allows for the expression of what the algorithm is doing, and thus communicates more to the individual coming along later.&lt;/p&gt;

&lt;p&gt;In addition to some principles being contrary to each other, in software engineering, some principles can overlap in many respects but be contrary to only a subset of their implications. An example of this, which is very semantic and may seem pedantic, is the distinction between &lt;em&gt;evolvability&lt;/em&gt; and &lt;em&gt;changeability&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Both evolvability and changeability involve the notion that a system should be able to change, but that is all changeability necessarily entails. And, so to assert that a changeable system should be able to change in any particular way is not encapsulated within the principle. Evolvability, on the other hand, implies that changes ought to improve suitability for a particular purpose and that those changes ought to be incremental. For this reason, it would be odd to seek to embrace both evolvability and changeability since the former necessitates purpose and practice, while the latter emphasizes mere ability to change. The only thing that undermines this kind of distinction, which can be incredibly subtle, is the matter of presupposed principles.&lt;/p&gt;

&lt;h4&gt;
  
  
  Presupposed Principles
&lt;/h4&gt;

&lt;p&gt;Some principles can seem so fundamental that they don’t need to be stated explicitly. Such principles can include ideas of &lt;em&gt;suitability&lt;/em&gt; and &lt;em&gt;operability&lt;/em&gt;. If suitability is presupposed to be a necessary principle then the distinction between changeability and evolvability noted above nearly evaporates. But, there is a &lt;a href="https://www.explainxkcd.com/wiki/index.php/1339:_When_You_Assume"&gt;cliche about what happens when you assume&lt;/a&gt; that bears remembering. So, I don’t believe we should presuppose principles in relation to software engineering.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I think it is a mistake (especially in a team context) to leave principles, no matter how seemingly basic and fundamental, as assumptions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Contextual Principles
&lt;/h4&gt;

&lt;p&gt;Another facet of principles with relation to software engineering is the notion of context. Sometimes certain principles are difficult or impossible to sustain in a given context. This relates to the notion of &lt;a href="https://en.wikipedia.org/wiki/Situational_ethics"&gt;situational ethics&lt;/a&gt;, which insists on judging a decision based on the context in which it occurred rather than exclusively on the basis of some objective standard.&lt;/p&gt;

&lt;p&gt;Going back to my background in Biblical studies, there is an example of the importance of context that is embedded in the Ten Commandments. The King James Version of the Bible renders the sixth commandment this way.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Thou shalt not kill.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In contrast, the New International Version of the Bible renders the same text this way:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You shall not murder.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Murder and killing are not the same, the latter involves the bringing about of death in any context while the former assumes the context of killing a person who did not otherwise deserve to die. Some principles in software engineering exhibit a similar need for context to make the principle appropriately actionable.&lt;/p&gt;

&lt;p&gt;One example of such a contextually bound principle is that of performance. Without context, what level of performance is reasonable and acceptable? Without additional context building software with the principle of caring about performance is not actionable. So, it is important to not merely state the principles one’s self or a team believes are important but to also supply any necessary context to make the principles actionable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Individual and Collective Principles
&lt;/h3&gt;

&lt;p&gt;The final detail of principles I believe is essential is to distinguish between individual and collective principles. When these two are aligned conflict can be better managed and the process of decision-making becomes clearer. But, perfect alignment is not a necessity, so long as differing principles can be helpfully prioritized and do not come into strong, direct, conflict. However, sometimes a mismatch between personal and team principles reveals a mismatch that is best resolved by changes in staff, as uncomfortable as that might be.&lt;/p&gt;

&lt;h4&gt;
  
  
  Developing Personal Principles
&lt;/h4&gt;

&lt;p&gt;Thinking through our own software engineering principles is at its most basic about what kind of code we like to work with. Personal aesthetics and preferences weigh heavily in this exercise. I recommend thinking about a project you have worked on that was pleasant to modify or add on to. Those two tasks comprise what many software engineers spend a majority of their time doing. Because of that, it is important to think about what principles you believe will have the greatest impact on those tasks.&lt;/p&gt;

&lt;p&gt;I intentionally use the term &lt;em&gt;believe&lt;/em&gt;, because developing principles in relation to software engineering has a lot to do with what we think is best. I prefer code that is clear with regards to its intentions, which leads me to choose names for classes, methods, and variables that I feel convey lots of detail. I also enjoy working with code that is well-tested, so I emphasize making my own code easy to test. These are the kinds of factors that should be considered when thinking about your personal principles of software engineering.&lt;/p&gt;

&lt;p&gt;I suggest starting with no more than two or three such principles. If you can’t recall any projects that prompt you to think positively about them, then you’ll have to start from something more abstract. This is a much more daunting task because you do not have the benefit of practical examples. One good resource for developing principles from nothing is the list of &lt;a href="https://en.wikipedia.org/wiki/List_of_system_quality_attributes"&gt;system quality attributes&lt;/a&gt; available on Wikipedia.&lt;/p&gt;

&lt;h4&gt;
  
  
  Developing Team Principles
&lt;/h4&gt;

&lt;p&gt;Software engineering is not often a single-player activity. Large projects often necessitate an entire team of talented individuals, who likely each have their own ideas about what is best. Investing the time to identify the principles that are most meaningful to the teams you work on can pay extraordinary dividends. Teams that are able to, for example, agree on what such principles as testability, modularity, or deployability mean for their shared context will be less likely to invest effort in activities that are not seen as beneficial by the whole.&lt;/p&gt;

&lt;p&gt;Again, I recommend identifying no more than three principles at the beginning. This will keep initial discussions shorter and less intense. Agreeing on the highest priority principles up front should also provide an opportunity to consider the broader priorities of the business or organizational context of the team. Hopefully, this discussion can be had on projects that already exist, or their components, which are pleasant to work on. Even in large, monolithic, projects that a difficult to work in; there are typically areas that exhibit qualities that will be preferable to the team as a whole.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Value of Principles
&lt;/h3&gt;

&lt;p&gt;Working on software from a set of principles helps guide decision-making by reducing the broad range of choices we are confronted with. Some principles also encourage us to take into account things beyond the purely technical and thus produce code that is more accessible to the others we work with. And, sometimes the principles we embrace are just about meeting our own aesthetic sensibilities. Whatever reasoning exists for the principles we embrace and act on, it is important to hold on to them loosely since the discipline of software engineering is not ruled by immutable rules beyond the need for reconsideration from time to time.&lt;/p&gt;




&lt;p&gt;If you want to explore these ideas more I recommend starting with &lt;a href="https://medium.com/u/a2a774fe7d7d"&gt;Peter Campbell&lt;/a&gt;’s presentation from the &lt;a href="https://www.safaribooksonline.com/library/view/oreilly-software-architecture/9781491958490/?utm_medium=affiliate&amp;amp;utm_source=cj&amp;amp;utm_campaign=paid&amp;amp;utm_content_cj_12989168_8483885"&gt;O’Reilly 2016 Software Architecture Conference in London&lt;/a&gt;: &lt;a href="https://www.safaribooksonline.com/library/view/oreilly-software-architecture/9781491958490/video284872.html?utm_medium=affiliate&amp;amp;utm_source=cj&amp;amp;utm_campaign=paid&amp;amp;utm_content_cj_12989168_8483885"&gt;Architecture As Belief&lt;/a&gt;. And, to get convenient access to this content, and much more to help you stay up to date with the latest technology consider subscribing to &lt;a href="https://www.safaribooksonline.com/subscribe/?utm_medium=affiliate&amp;amp;utm_source=cj&amp;amp;utm_campaign=paid&amp;amp;utm_content_cj_12989168_8483885"&gt;Safari Books Online&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>architecture</category>
      <category>softwaredevelopment</category>
    </item>
  </channel>
</rss>
