Lately I’ve been spending a lot of time thinking about my career and where it’s going. I don’t want to give the impression that I have never thought about my career before, but now the thoughts are becoming constant.
Our lives are intertwined with each other whether it's directly or indirectly. Processes must work together to bring about solutions and engineers must understand how pieces fit together like a puzzle. When writing code line by line, or executing a business process step by step, success depends on the execution of the previous line of code (step) and passes on those results to the next. This is an inescapable truth about our existence, the truth about how time works; the nature of cause and effect.
The famous quote of King Solomon, "So there is nothing new under the sun" (Ecclesiastes 1:9) says it all. Now whether you're religious or not, there is truth to this statement, especially when it comes to more abstract ideas, methodologies, and best practices.
In my last post, Young and Stupid: The Software Industry Story, I talk about understanding foundations of your craft. To expand on the point a bit more, understanding foundational concepts provide us the ability to connect and innovate, irregardless of the field of study we're in. I propose that many (if not all) idea(s) in software development applies to all other fields of science/technology and business.
I'm not referring to the idea that a for-loop somehow directly relates to business processes, but instead, I am stating that best practices in software can correlate to best practices in other fields. Let's talk about one example of this in action.
Let's look at the following diagram pertaining to the .NET Core Architecture:
Here you can see the architecture is broken down into different components: Build Tools, Languages, Runtime Components. Then another component layer, the .NET Standard Library, is built up. This is a solid arhitecture to allow for flexibility and clear separation of concerns. In software, we should be focusing on componentization and reusability. A good developer will understand the importance of this concept and be continually improving code to achieve this goal. But could they use this knowledge somewhere else?
Now let's talk about a business process producing software from Sales to Release of the software. This process is different from company to company and often times is separated by division or program in larger corporations. Many times, communication suffers and information is lost along the way. The process is less than flexible and struggles because of the rigidity.
In some companies, the SDLC (Software Development Life Cycle) process is a large monolithic process designed at the top of the hierarchy and enforced as a whole, making all departments dependent on this singular process. However, this doesn't really seem like the best use of the "componentization" concept.
In order for modularity to work well in software, there is a concept of interfaces, contracts between different modules. They only define how communication occurs between components, but not necessarily "how" the component does its job. If we apply this to the SDLC process as a whole, the executives only define the "interface" between the departments.
For example, when a customer calls in to the help center and a bug is detected, a change request (or escalation) must be written up. This is then taken by a project manager or development lead and assigned to a developer for work. From there, testing, builds, and a release schedule are produced. Once it goes live, the help center is notified, who in turn, notifies the customer of the fix. The customer validates the fix and we close the change request (or ticket).
This is a contrived example, to say the least. But if the executives designed this process from start to finish, how can efficiency be improved in the life cycle? Does the development group have unilateral control to change their documentation and process to speed up their portion of the process? Most likely not without significant debating with upper management, bringing in the call center stakeholders, and QA specialists.
Instead, we should modularize and have queues of work between departments so we have a separation of concerns. Each department has inputs/outputs, but how they execute is completely up to the groups. As long as the interface isn't broken between departments, we should be able to adjust our process without affecting other departments significantly.
Let's define these interfaces at the business level from a software perspective. First let's define a couple interfaces that can be used between departments.
// Help Center public interface IHelpCenter { Ticket ReceiveCall(Customer customer, ProblemInformation problem); ApprovedTicket SubmitTicket(Ticket ticket, IManagement management); void ReceiveCompletedTicket(CompletedTicket ticket); void UpdateCustomer(CompletedTicket ticket, Customer customer); } // Management public interface IManagement { ApprovedTicket ApproveTicket(Ticket ticket); AcceptedTicket SubmitTicket(ApprovedTicket ticket, IDevelopment development); } // Development public interface IDevelopment { AcceptedTicket AcceptTicket(ApprovedTicket ticket); AcceptedTicket AcceptTicket(QATicket ticket); ReleaseTicket Develop(AcceptedTicket ticket, Developer developer); QATicket SubmitTicket(ReleaseTicket ticket, IQuality quality); } // Quality Assurance public interface IQuality { QATicket AcceptTicket(ReleaseTicket ticket); CompletedTicket Pass(QATicket ticket, IHelpCenter); QATicket Fail(QATicket ticket, IDevelopment); } // Process in charge of marshalling all these departments together public interface ISDLC { void StartProcess(); }
These interfaces in C# define the contracts that must be implemented in each department for the process to work. All departments MUST maintain this interface in order for the process to work appropriately and be coherent.
You will notice that the outputs from each action corresponds to a different ticket type. This ensures separation and uniformity within each department. Imagine if we had something like this below:
// Help Center public interface IHelpCenter { Ticket ReceiveCall(Customer customer, ProblemInformation problem); Ticket SubmitTicket(Ticket ticket, IManagement management); void ReceiveCompletedTicket(Ticket ticket); void UpdateCustomer(Ticket ticket, Customer customer); } // Management public interface IManagement { Ticket ApproveTicket(Ticket ticket); Ticket SubmitTicket(Ticket ticket, IDevelopment development); } // Development public interface IDevelopment { Ticket AcceptTicket(Ticket ticket); Ticket AcceptTicket(Ticket ticket); Ticket Develop(Ticket ticket, Developer developer); Ticket SubmitTicket(Ticket ticket, IQuality quality); } // Quality Assurance public interface IQuality { Ticket AcceptTicket(Ticket ticket); Ticket Pass(Ticket ticket, IHelpCenter); Ticket Fail(Ticket ticket, IDevelopment); } // Process in charge of marshalling all these departments together public interface ISDLC { void StartProcess(); }
Every output of each piece of the process is the same format of Ticket. This is a serious issue, yet in many companies, this is exactly how it works. Why is this an issue? Because, now every field needed for all departments is in a single type. Whenever, Quality needs new fields, it will inevitably affect all departments. Everyone has to learn about the new field and this will be a nightmare to maintain. Instead, separating it out like the first design, allows QA to add/change fields to better their process while only affecting them and development (which makes sense logically).
As you may notice, nothing about Building/Releasing code is included in the IDevelopment interface. This is intentional. Other departments have no need to understand how this works. This is all wrapped up in the Develop method. So development can change this process as much as needed until they are efficient without disturbing other departments, as long as they output an appropriate ReleaseTicket to be submitted to QA.
The first design would be considered a decent software design by some architects. However, it may not be the best. If it isn't, let's refine it until we find the best architecture. Then, once found, we should have a very modular company that can pivot as needed to improve efficiency.
I say all that to say this: The best innovations come from ideas in other industries. In the above example (one of many), we used software architecture to design a business process. For developers, or techie people, will find working this way more intuitive than trying to help with this process at the executive level where personel and higher level thinking take precedence.
Innovation comes by taking these ideas and finding their applicability everywhere. Interfaces and modularity is only one idea. But we could do the same with the "Single Responsibility Principal", "Interface Segregation", and "Dependency Inversion" principals. Although the SOLID principals were meant for software, they apply everywhere.
The reason this is true is going back to the Solomon quote, "There is nothing new under the sun." In reality, componentization is what sparked the Industrial Revolution. It's what allowed the Egyptians to build the great pyramid. The fact that in our new field of software, we have to re-learn this, is beyond me. We like to think of ourselves advancing, but we really just forget what our forefathers already figured out. We decide that "those principles don't apply to us," when in fact they can and do.
Whatever principal, methodology, or best practice you have learned, or learn in the future, take a minute and decide if it can be applied to another industry. Would it improve flexibility or efficiency? Be innovative! Even programmers can be good at business process design if you can simply learn to translate their knowledge.
Check out our thoughts here.
Lately I’ve been spending a lot of time thinking about my career and where it’s going. I don’t want to give the impression that I have never thought about my career before, but now the thoughts are becoming constant.
There is always strong debate around databases and their role in development. Sometimes they are considered components, while others will consider them infrastructure. Is there a right answer? Let's discuss!
There is one, and only one, primary focus that any software developer acknowledge: the ability for software to be maintainable. Of course, correctness, functionality, and performance are all important, these will always be easier to address with maintainable software.