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.
So I bought myself a pinball machine this Christmas, Space Station (1987 Williams). It is fully functional and plays awesome. However, owning a pinball machine brings its own challenges. Keeping it running in tip-top shape isn't as simple as you'd initially think. It's almost an artform.
All of a sudden, the switch doesn't work anymore. Oh No! I locked the ball but another ball doesn't spit out into the trough. Or wait! The ball is stuck in an alley.
This can be frustrating. It can also be fun. Opening up a pinball machine is kind of cool. A lot of wires, electronics, switches, solenoids. It's also complicated, depending on your perspective. But there is a beauty in its complication. Each piece and part can be swapped out for another part or style. In fact, if you wanted to you could completely change the playfield around into something new, keep the controller, and the game would still play. This is beautiful.
Software is woefully behind in the world of engineering. There is no finesse in its creation. Hardware forces you think. It requires full design because of the severe cost of creating prototypes. It requires componentization. If you don't, you corner yourself when things go wrong and parts go bad, or the process needs to change. In reality, with the exception of software engineering, componentization is a requirement in all forms of engineering. Why is this?
Software is "easy." It can change on a dime (probably why it's called "soft"ware). But imagine for a minute if we built software like we built hardware? What if each piece of software really was a piece of a whole, reusable in 100s of applications? This IS the goal right?
I think this is what most developers strive for but the problem is, we live in a world of hackers. I know the tone is negative here, but there is purpose for hackers. Hackers have created great open-source projects that have changed the world. Hackers, however, did not create the Microsoft Office products or the Adobe products or even the Apple products. These are disciplined, mature developers that have been battle-tested.
But enough rambling about this. Let's talk about why hardware is naturally modular and software is not.
Let's think about a computer for a second. At its most basic level, computers are made of transistors, resistors, capacitors, inductors, and power sources. That's about it. Sure there are transformers in here and other such components but you could create a computer with just these things. But how impractical would this be?
But I would argue that some developers program at this level. The level of resistors and capacitors and transistors. The level where they throw pieces together as needed and hack through it. Once it works, they move on to the next set of problems to solve. This is very procedural and many routines would be 100s if not 1000s of lines of code.
The equivalent at the software level is writing single-use routines and "modules" with basic language-only code. This has its place but trying to develop a whole computer this way would take forever and be extremely large.
The next level is creating circuits and modules that contain a higher level of usefulness. In computer hardware terms, this would be things like Timer ICs, NAND ICs, Memory ICs, or anything else that works on the gate-level (XOR, NAND, NOR, etc). A NAND gate can be created with 2 transistors and three resistors. It can be simplified even more to only need transistors. Either way, by manufacturing these ICs, the hardware engineer can focus on bigger problems.
This is an important concept for developers. We already have this in our frameworks. Anytime you have used C#'s Serialization Namespace or Web namespaces, you're utilizing "Integrated Circuits" in software. The designers of the the frameworks were wise enough to provide this to you. We, as developers, don't have to worry about it.
However, imagine putting a computer together with only NAND gate ICs? Although better than using transistors directly, it would still be cumbersome and difficult. To be effective, we need to at least go up one more level.
Remember, if you are creating a framework from raw language code, you're a level 2 developer.
After Gate-Level ICs, we have fully integrated circuits. This comes in the form of memory modules, with their flip-flops already implemented. This comes in the form of microcontrollers and power regulators. This comes in the form of any IC that has implemented useful functionality past the basics.
In software, this would be the equivalent of any code created by you. This could be functions, or classes, you have created to be used in a piece of software. However, this code is utilizing framework code; not raw language code. If you're a framework author, you are creating software to be used by Level 3 developers. However, you are yourself working at Level 3, if you are utilizing frameworks.
Most developers work at this level. They utilize the Java Frameworks or the .NET Framework and whatever is provided to create software applications.
Circuit assemblies are groups of ICs and basic components that create a fully functional module. In hardware, this is the motherboard, the memory sticks, the graphics cards, the harddrives, the bigger components. At this level of hardware, these pieces can no longer be interchanged and used for just anything. Instead, they have very specific purposes for specific applications.
You may look at Memory cards as general, but the connectors and layouts are for a specific type of application. An SD card can be used in phones and cameras as primary memory, but in a laptop, they act like an extra disk. A DDR RAM stick is for computers, not cameras (typically).
In software these components are things like SQL Server vs SQL Lite. They are things that are created to work across an organization but not really intended to be used outside it. But like DDR Memory, more uses of the component are discovered over time, and once accepted, could be used for other purposes if it is unique enough.
At this level, a developer is creating another framework, but at a service level. These are windows services, web services, data stores, and applications. These are things that are useful for one real purpose. The interfaces within this "framework" are specific to a business or unit of business; like logging.
But don't confuse this with a framework that is used from the outside (Level 2 or 3). This type of framework was written by your developers. It's a framework for making business more effective and is owned locally. Not many developers think at this level. This is the architects level of thinking.
At this level, building a computer becomes a lot simpler. The components are bigger and anybody that has tried to build their own PC, knows you work at this level.
This is the final product. The most reliable computers are built from Level 4 components, not Level 1 or Level 2. You could probably make simple computers at Level 3, but it definitely would be difficult. But Level 4? We can do that, even with little engineering understanding. This is possible because of the level or abstraction we're working with. We can build a computer with the following components:
This has 9 required components to make a computer work. Of course, more complicated computers can use more components, but at its simplest, this would work. And honestly, you could buy all the parts needed to build this computer in a few hours of research. The actual building may take another couple hours. What if software was like this? Man! Wouldn't that be awesome!
I don't believe I've met a developer (myself included) that could build an app in a few hours. Why are we so far behind? Are we lazy? Incompetent?
Nah. I don't think its any of the above. But we need to move in this direction. And honestly, there are some frameworks and tools that get very close. I've seen different software where you can generate very general software with only a few hours of work. It might not look the way you want, but the functionality is there. How often do we really think like this though? Not often enough...
I have always loved hardware. My pinball machine made me love it even more. It also made me think about how I write software. I need to try and create deeper abstractions that can be utilized better to create software applications. When a new client comes on board, I need to be able to take these components and just drop them in, spend a couple hours putting the parts together at a system level, and release it to the customer, WordPress-Style! As of now this isn't possible for me, but maybe one day.
So, my rant is over. Good luck with this, however you use it! 'Til next time!So I bought myself a pinball machine this Christmas, Space Station (1987 Williams). It is fully functional and plays awesome. However, owning a pinball machine brings its own challenges. Keeping it running in tip-top shape isn't as simple as you'd initially think. It's almost an artform.
Check out our thoughts here.
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.