The Developer's Path in 2023: Bridging the Gap Between Code and Craft

Modern Software Design: Beyond the Python Hype

When we look at the trajectory of software development in 2023, it is easy to get swept up in the latest library or the newest language version. However, the real work of a developer remains centered on the architecture of logic. Software design is the art of keeping things manageable. While much of my recent work focuses on

, the principles of clean code are largely language-agnostic. Whether you are working in
Rust
,
TypeScript
, or
Java
, the challenge remains the same: how do we structure our systems so they do not collapse under their own weight as they grow?

One of the most frequent requests I receive is for more content on

and
Machine Learning
. While these are undoubtedly the "noisy" sectors of our industry right now, I have intentionally kept my focus on the niche of software design. There is a specific reason for this. In the rush to implement neural networks or data pipelines, many developers abandon the fundamental practices that make software sustainable. A machine learning model wrapped in spaghetti code is a liability, not an asset. My goal is to ensure that as we move into these complex domains, we carry with us the habits of clean functions, decoupled classes, and robust testing.

The Protocol Shift: Inheritance vs. Composition

The Developer's Path in 2023: Bridging the Gap Between Code and Craft
Become A Better Software Developer // ArjanLive Q&A

One of the more nuanced discussions in modern development involves the transition away from heavy inheritance hierarchies. In the past,

(OOP) often forced us into rigid parent-child relationships between classes. Today, I find myself moving toward a more functional approach, favoring protocols and composition over abstract base classes. This is a significant shift in how we think about interfaces.

In

, the use of
Protocols
allows for structural subtyping, or "duck typing." This means we define what an object does rather than what it is. If an object has the required methods, it satisfies the protocol. This leads to much cleaner code because it removes the need for a central inheritance tree that every developer must understand to make a change. When you define a protocol close to the function that uses it, you are documenting the requirements of that function explicitly. This is not just a syntax choice; it is a design philosophy that prioritizes flexibility and reduces the cognitive load on the developer.

We must also be careful about where we place our business logic. A common mistake is overloading constructors with complex operations. Creating an object should be lightweight. If you bury heavy logic in a __init__ method, you lose control over the execution flow. You cannot easily create objects for testing or previewing without triggering those side effects. By keeping constructors thin and moving logic into dedicated methods or factory functions, you gain the ability to manage state more effectively, which is essential for building responsive applications.

Navigating the Ecosystem: Tools, Frameworks, and Risks

Choosing a tech stack is rarely about finding the "best" tool; it is about managing risk. Take the choice between

and newer contenders like
Starlite
.
FastAPI
has become a staple because of its speed and developer experience, but it is largely maintained by one person. This creates a "bus factor" risk. If the primary maintainer disappears, the ecosystem stalls. Conversely, a newer framework might have more maintainers but lacks the massive community support, plugin ecosystem, and battle-tested stability of the market leader.

For production environments, I always lean toward stability. It is fun to experiment with the latest web framework or a new language like

for a hobby project, but when users' data and company revenue are on the line, you want the tool that has the most eyes on its GitHub issues. The same applies to deployment.
Docker
has become non-negotiable for the modern developer because it solves the "it works on my machine" problem. Understanding how your code lives in a container and how that container interacts with a cloud provider like
Amazon Web Services
is no longer a specialty—it is a baseline requirement for being an effective software engineer.

The AI Assistant: GitHub Copilot and the Future of Work

There is a lot of anxiety surrounding

and
GitHub Copilot
. People ask if these tools will replace us. My experience has been the opposite: they make us more powerful, provided we remain the architects.
GitHub Copilot
is excellent at generating boilerplate or suggesting the implementation of a standard algorithm. It saves time on the repetitive parts of coding, allowing the developer to focus on the high-level design and the integration of components.

However, a chat interface is not the future of programming. Coding is about context and overview. You need to see how a change in one module affects the entire system. AI tools struggle with this holistic view. They are optimized for the immediate snippet. As an engineer, your value is not in your ability to type syntax—it is in your ability to define the problem and verify that the solution is correct. We are moving from being "code writers" to "code reviewers" and "system architects." This shift requires even stronger analytical skills and a deeper understanding of design patterns, as you must be able to spot when the AI-generated code is subtly wrong or architecturally unsound.

Balancing the Grind: Career Growth and Learning

One of the hardest parts of being a developer is the constant feeling that you are falling behind. New frameworks emerge every week, and the industry's pace is relentless. My advice is to find a way to incorporate learning into your professional life rather than sacrificing every evening and weekend to the grind. If you are learning new skills, you are becoming a more valuable asset to your employer. It should be a win-win scenario.

For those looking to transition into the field or move into management, remember that credentials matter less than demonstrated skill. While a

degree provides a solid foundation, many successful engineers come from diverse backgrounds like electrical engineering or self-taught paths via coding schools. What matters most is the ability to break down complex problems and communicate solutions. If you want to move into management, start by taking an advisory role in technical decisions. Show that you understand the business impact of code, not just the technical elegance. The most successful lead developers are those who can bridge the gap between a messy business requirement and a clean technical implementation.

Ultimately, software development is a long game. Whether you are dealing with workplace politics, choosing between

and
Kanban
, or debating the merits of
Graph Databases
, the key is to stay curious and methodical. Don't be afraid to step out of your comfort zone—it is the only place where real growth happens. Keep building, keep breaking things, and most importantly, keep designing with the future in mind.

The Developer's Path in 2023: Bridging the Gap Between Code and Craft

Fancy watching it?

Watch the full video and context

7 min read