Software is the driving force of the world today. How many softwares are there in the world? Gazillions maybe, no one knows. But I think we all agree that all softwares have purposes, and that the best software is a working software.
What is a working software?
Now this is where our paths may split.
For me, it’s a software that solves user’s problems. Emphasis on user.
Those users can be us, product managers, end-users, friends, strangers, anyone.
So,
Software engineering is solving problems through software.
Are we solving the right problems? Are those really user’s problems?
That’s what makes it “engineering.”
Code, the building blocks of software, should be geared toward that purpose.
A software that solves non-existent problems is a product of over-engineering.
Software Engineer often have to be …
Part Engineer
A programmer is not a software engineer.
Conceptually, a programmer is a software contractor. It’s common for programmer to work on just one stage in a project’s life cycle at a time.
A grade-schooler can be a programmer, a financial analyst can be a programmer, an AI could be a 0.1x programmer.
A software engineer is a programmer yes, but they also oversees the entire SDLC (Software Development Life Cycle).
Planning, analysis, design, development, testing, and maintenance are software engineer’s bread and butter.
There are many parallels between software engineering and more traditional engineering roles. Like a conventional engineer, a software engineer is responsible for designing, building, and maintaining systems as solutions to the real-world problems.
Part Psychologist
Anyone who have been involved in a software development project may have noticed that psychology plays an important role in the success of the project. Either managing the team or our own emotion, both need psychological approaches. Psychology also plays an important role during requirements gathering.
Sometimes, we need to listen to users so they will open up about their problems. Sometimes, users do not know what they want, and even if they do, it’s not always what they need. That’s why acting on user feedback alone is questionable. Acting on user feedback and how they do their tasks, either by watching them or by detailed usage analytics, that’s the gold standard.
And of course, Part Farseer
Building software according to functional requirements is a clear road. Building software to be robust and future-proof for our current & future users is a murky path. By definition, future-proofing is the process of anticipating the future and developing methods of minimizing the effects of shocks and stresses of future events. Emphasis on “minimizing”. It doesn’t mean we need to cover all future scenarios as perfectly as possible. Don’t forget YAGNI and KISS principles. Future-proofing is not adding nor removing stuffs. Future-proofing is making sure our system is designed for flexibility, so it can adapt to future events with only minor modifications.
Reliability, scalability, security, maintainability are few things that need to be carefully prepared since the initial phases of software development. We need to mitigate risks more than fixing bugs, implement features securely more than adding on security features, and so on.
For distributed systems, different types need to focus on different things. A financial trading system would need to have a high level of consistency and low latency, while an e-commerce might prioritize high availability and low latency over consistency. Performance optimization is another tricky thing. Optimize early and we may have a premature optimization, optimize later and users may leave when their patience runs out. To avoid the curse of the first, if the gain is not obvious, always back it by benchmarks and profiling.
Finally
Software engineering is a collaboration between domain experts (users) and technical experts. In order to solve a problem, of course, we must first understand the problem. We need to get into our user’s head and understand how they think. They will give you deeper insights into the domain that may be useful later, for example when we’re being asked to implement something and we realize another way that could solve the problem several times quicker or even for free because we have prepared for it beforehand. Conversing with users can also cultivate compassion, we begin to think about what the users really need instead of over-engineering. It will improve how we design and build our software. Listening pays dividends, really.
The oldest form of human communication is maybe listening. Listening actively connects us with the world - with others, it establishes trust with our users. A pity to think that most software engineering courses don’t taught us that most important communication skill. Many students & learners have to learn it the hard way on the job. We’re always taught how to be a better programmer instead of a better software engineer. We’re always taught to communicate with machines, but we leave out the important skill that started it all, to speak with and listen to our users.
Oh, the irony.