For the last 8 years that I have been giving my architects, tech leads, and developers their yearly performance reviews, I have been using the acronym “SFEMS”.
Arguably you can say I should just be telling my architects and maybe tech leads that they need to design and ensure their team’s implementations follow the SFEMS (Stable, Flexible, Extensible, Maintainable, Scalable) mantra.
Everyone in my group is required to ensure they design and write code that meets this the SFEMS Standards. I don’t care how junior a developer is, we preach it to them from their first day on the job, even if they are just one day out of school.
When I have my town halls and other group meetings, I always remind my developers that the expectation is Quality over Quantity (in terms of how much code they can write in any given day), and that refactoring their code to ensure it meets SFEMS standards is the norm.
It doesn’t matter how small or large of a component a developer or team of developers are writing, it is always important that the code is first of all STABLE – that is the code should be as close to bullet proof as possible; although I make it understood that everyone and anyone can write code that contains a bug or two. Code should be expected to be used in a one off API where the objects containing your code is used once than discarded or the same classes could be used in a Daemon process where the objects may live for hours or even days to weeks without the process being restarted. This is where unstable code usually becomes a problem because it may work by contain a memory leak or a database connection leak, or other resource utilization issue, and it is why the same code may work if it’s only used once in a while in a process and it causes weird behavior or even crashes in long running processes, or short running processes that use the same code in a loop with thousands or even millions of iterations.
Second and Third, their code needs to be Flexible and Extensible. You may say, well what’s the difference? Well to me, code can make an application be flexible if it can be helps the broader application or system which it is part of work under a range of circumstance. Think of it like a person being flexible in their abilities to handle multiple situations or to be able to come up with solutions and work-around automatically to a problem set within the same knowledge domain. In software this is when for example, I am writing a ETL (Extraction, Transformation, Loading) loader and my code should be able to contend with small variances in the data without failing the overall process. More specifically if the loader code encounters one or two records with incorrect Country Codes, the loader should be able to be configured to have a threshold of corrupt records in the source data while still completing the process if that threshold is not met and perhaps report the error records to the development team automatically via email or some other more complex method such as a error queue processing table. We can configure the threshold to be ZERO or ONE and therefore as soon as any error is encountered with fail out the process. But this is where Flexibility comes into the picture, and the threshold can be dictated to us by the business or users.
In terms of Extensibility, I expect all of my programmers to follow good OOP / OOD so that their code can be reused and extended to help us cut down on our time to market. For years I have used the approach of creating an “Internal SDK” (Software Development Kit) at the start of a project when I take over as the manager or architect. We usually create a module in our source code repository called “commons” which contains our groups SDK. It contains all the frameworks, wrappers, and useful utilities that are common across our Middleware, Batch, and Standalone processes. In the case where the User Interface is written in the same language as the rest of the system, the UI is expected to use commons as well. Over the lifetime of the systems I own and develop, we have a process of “Promoting to Commons” as objects and other code become so useful they become “common” within our system, and the code will be refactored and moved from whatever source code repository module it was originally in to the Commons module. We use this same principal for non-object oriented languages or components, such as scripts. Even though common scripting languages we use such as Perl and Python either have the capabilities to create Objects and use OOP concepts or are Object Oriented themselves, most times I find that we treat scripting languages as procedural languages, but this doesn’t mean we can’t have reuse. We enforce the same strategies we do in Java or C#. We always programming forward thinking, so if we feel a subset of functions a script that we write can be useful for future scripts, we create a library of common scripts of functions or objects. So I always tell my team ensure that whenever possible if you even just have a feeling that your code or parts of your code can be useful to someone else, ensure that it written so that it can be reused as much as possible. Or if you notice that you are going to be writing the same thing over again, stop and go back to where you wrote something similar before and refactor the code so that the original becomes reusable two both the original component and the new component, or at least extract the common functions into a base class or utility package.
Fourth, we must ensure that whatever we write is Maintainable, and that means maintainable by other developers. I am very straight forward in telling everyone that we write systems to last 20 years at least, no matter if we or others will replace it sooner, the assumption must be at least 2 decades. And therefore we cannot afford to assume the same people will be on the same project to work on the code they personally wrote or helped to write over that long of a period. Therefore we need to put ego aside for the team’s sake and write code that is clean and clear, and simply for other members of the team to read and make enhancements to. As managers, architect, and leads, we need to watch over our developers to ensure they are not writing code that only a small subset of people or only one person can maintain. If we allow this in our system, we are setting ourselves up for failure in the medium to long term. Maintainability encompasses Extensibility and the next and final word in the SFEMS mantra Scalability. For systems to be Extensible and Scalable, they MUST be easily maintainable. Otherwise, they really can’t be considered build to be forward looking and therefore are not easily extensible and possibly not scalable as well, if we can’t change the code within reasonable cost to handle changes to the business, system load, and user requested enhancements.
The Fifth and final component to the SFEMS mantra is ensuring the code and systems we develop are Scalable. Writing systems to be scalable is not an easy task. We often write code to solve a specific problem. Perhaps we have to write a middleware which will be used by a front-end that will have only 1000 users today. We can do that, because that’s the requirement and we will buy the hardware we need and architect the system to handle this user load. But how will the system perform if we add another couple of hundred users? How about a thousand more? Will it even allow that may users to be online at the same time? How do we build a system within cost that can scale in the future when we don’t even know what the upper limit will be (if there even is one)? It’s definitely not easy, and building scalable systems is an entire topic all to itself worth many volumes of books and articles. However if we followed the first 4 components of SFEMS (Stable, Flexible, Extensible, Maintainable), our systems should be able to scale if we are given the proper resources to enhance it. In my mind we should always build our systems to expect between 1.5 and 2 times the expected user or data load on the system that the original requirements state. If we can do this, we have already bought us enough time to work on ensure the system is Stable, Flexible, and Extensible to scale beyond 2 times the original load. There’s really no way to make a system handle unlimited system loads. Eventually it will come down to a physical limit of the computing platform your code is running on, so we must build systems with Scalability in mind through the first 4 components of the SFEMS mantra so that with the right investment in extending the system to handle the new system loads, we can within reasonable cost models and time to market accomplish the required enhancements.
Each of the five components of SFEMS deserve at least a separate post all to their own. However I hope this article will help everyone from junior developers all the way up to senior technology managers on their journey when building large scale enterprise class systems that are expected to write a multi-decade lifespan.
So just remember “SFEMS”! – Stable, Flexible, Extensible, Maintainable, ScalableJust Another Stream of Random Bits… – Robert C. Ilardi