-
Notifications
You must be signed in to change notification settings - Fork 135
SE 01 Introduction to Software Engineering
Part of the Software Engineering Principles series
Software engineering is the disciplined application of engineering principles to the design, development, testing, deployment, and maintenance of software systems. It is not simply "writing code" — it is a systematic process that treats software as a product that must be reliable, maintainable, and fit for purpose.
The term was deliberately chosen to signal that building software deserves the same rigour applied to bridges, aircraft, and medical devices. A bridge that collapses or a medical device that misbehaves has real-world consequences; so does software that loses patient records, produces incorrect billing, or crashes during a critical clinical event.
| Era | Milestone |
|---|---|
| 1940s–50s | Software written in machine code; no methodology |
| 1960s | "Software crisis" — projects late, over budget, unreliable |
| 1968 | NATO conference coins the term software engineering |
| 1970s | Structured programming, first formal methodologies (Waterfall) |
| 1980s | Object-oriented languages (Smalltalk, C++) gain traction |
| 1990s | UML, design patterns (Gang of Four book, 1994), Java |
| 2001 | Agile Manifesto published |
| 2010s | DevOps, continuous delivery, cloud-native architecture |
| 2020s | AI-assisted development, microservices at scale |
Without discipline, software projects exhibit predictable failure modes:
- Scope creep — requirements grow uncontrolled until delivery becomes impossible
- Technical debt — quick fixes compound into systems nobody dares touch
- Integration failures — modules built in isolation that cannot talk to each other
- Maintenance traps — original authors leave; no documentation; nobody knows how it works
- Security vulnerabilities — code written without security awareness exposes users and data
Software engineering provides tools to prevent or manage each of these.
The software must do what it is specified to do — no more, no less. A billing system that rounds incorrectly, even by a fraction, produces incorrect financial records.
The system must perform its function consistently over time and under varying conditions. Failures should be rare, predictable, and recoverable.
Code will be read far more often than it is written. It must be understandable and modifiable by someone who was not involved in writing it.
Resources (CPU, memory, database connections, network) are finite. Software must use them proportionally to the value it delivers.
Software that handles personal, financial, or clinical data carries a duty of protection. Security is not a feature added at the end — it is a property designed in from the beginning.
Software that cannot be used correctly by its intended users has failed regardless of how elegant its internals are.
Good software engineers share certain habits of thought:
Decompose problems. Break large, vague problems into smaller, concrete ones that can be solved independently and composed back together.
Make trade-offs explicit. Every design decision has costs and benefits. Name them. Document them. Revisit them when context changes.
Prefer simplicity. The simplest solution that correctly solves the problem is almost always the best. Complexity is a liability, not an asset.
Design for change. Requirements change. Technology changes. Teams change. Code that assumes everything will stay fixed becomes a burden quickly.
Automate repetition. If you do something more than twice manually, consider whether it should be automated. This applies to builds, tests, deployments, and data migrations.
Verify assumptions. "I think it works" is not the same as "I know it works." Write tests. Monitor systems. Read logs.
Software engineering differs from civil or mechanical engineering in important ways:
| Property | Civil Engineering | Software Engineering |
|---|---|---|
| Material | Concrete, steel | Logic, abstraction |
| Failure mode | Usually visible | Often silent |
| Cost to change | Very high after construction | Varies enormously by design |
| Copy cost | Very high | Near zero |
| Wear and tear | Physical degradation | Does not degrade (but becomes obsolete) |
The near-zero cost of copying software creates a unique opportunity: reuse. A well-designed component can be used in thousands of places without being rebuilt. This amplifies both the benefits of good design and the costs of bad design.
This series walks through the foundational principles that professional software engineers apply daily:
| Article | Topic |
|---|---|
| SE-02: SDLC | How software projects are structured from idea to retirement |
| SE-03: OOP | Object-oriented thinking and its four pillars |
| SE-04: SOLID | Five principles for maintainable OO design |
| SE-05: Design Patterns | Proven solutions to recurring design problems |
| SE-06: Clean Code | Writing code that humans can read and maintain |
| SE-07: Architecture | Structural decisions that shape entire systems |
| SE-08: Refactoring | Improving existing code without changing its behaviour |
| SE-09: Testing | How to verify that software does what it should |
| SE-10: Version Control | Managing change over time |
| SE-11: API Design | Building interfaces that others can depend on |
| SE-12: Security | Writing software that protects its users |
| SE-13: Database Design | Structuring data for correctness and performance |
| SE-14: Agile & Scrum | Iterative, collaborative delivery |
| SE-15: Foundational Coding Principles | KISS, YAGNI, DRY, Cohesion/Coupling, Boy Scout Rule, Fail Fast, Observability, and more |