Refactoring towards Clean Architecture — SymfonyLive Berlin 2026 🇩🇪🏛️

TL;DR: I ran my Refactoring towards Clean Architecture workshop at SymfonyLive Berlin 2026. Smaller room than my previous workshops, but the energy and engagement were top tier. I changed the formula a bit — more theory, more group exercises, more whiteboard work — and I think it landed. Below: what I changed, what the attendees asked, and a big thank you to everyone who made it happen 🙌

Short reflection

This was my third time running Refactoring towards Clean Architecture at a Symfony conference, after SymfonyCon Amsterdam 2025 and SymfonyOnline 2026. And I have to say — every edition feels different.

Berlin gave me a smaller group than the previous two editions. At first, I was slightly worried — fewer people, more pressure on each conversation to carry weight. But it turned out to be a gift 🎁 The group was incredibly active: thoughtful questions, real opinions on architecture trade-offs, and a willingness to push back and discuss. Exactly the kind of room I love teaching in.

What I changed in the format

A smaller group also meant I could afford to slow down and rework the structure. Two main changes:

1. More theory, less rushing into code

In the previous editions, I was always racing to get to the coding part. This time, I gave the theory section more space— not because theory is more important than code, but because without solid mental models, the code refactoring feels like cargo-culting. You move things around, but you don’t know why.

2. A group exercise on primary vs secondary actors

This was the biggest experiment of the day, and I think it paid off.

Hexagonal Architecture talks about primary (driving) and secondary (driven) actors and ports/adapters. On paper, this sounds simple. In practice, people often blur the two and end up with a confused dependency graph.

So we did the following:

  • I drew our application in the centre of the whiteboard.
  • We listed every external thing around it — a user, a controller, a database, a message broker, an external API, a scheduler, a CLI command…
  • For each one, we asked together: Is this primary or secondary?

Then — and this is the part I was most curious about — we flipped the perspective. We treated the database as the centre, and asked the same question about its external collaborators (including our application). Suddenly, things that seemed obviously “secondary” from one angle became “primary” from another. That perspective shift is what makes hexagonal click. From the application’s point of view, the DB is a secondary actor. From the DB’s point of view, the application is a primary actor calling it.

I really wanted that to land for the group, and judging by the discussion that followed, I think it did 😊

3. Coding together on the big screen

The original plan was: theory → live coding → exercise on your own machine. But after the theory and the group whiteboard exercise, the group made an interesting suggestion — let’s code together on the big screen, follow your steps, and we’ll repeat the exercise on our own machines later as homework.

I love this kind of feedback. It gave us more time for discussion during the coding part, and removed the pressure of “did I copy that snippet correctly”. Of course, the trade-off is that the muscle memory comes later, on the homework — but that’s a fair deal.

One thing I keep repeating: architecture is a trade-off

Throughout the day I tried to be very explicit about one thing:

Everything we’re doing today is one possible way. Not the only way, not even necessarily the best way for your context. Architecture is always a trade-off, so always ask whether this approach makes sense for yourproblem.

If there’s one thing I’d like attendees to walk away with, it’s this. Patterns and architectures are tools, not commandments. Use the ones that solve a real problem you have.

What the participants said

I always run a small post-workshop survey. From the responses I got:

  • Everyone said they enjoyed the workshop ✅
  • Ratings were 4 and 5 out of 5 🌟
  • Two pieces of feedback I want to highlight publicly, because they’re fair and useful:
    • Go a bit slower during the coding sessions. Noted — I’ll plan more buffer next time.
    • Give attendees 10–15 minutes to try a task on their own before showing the solution. This is great advice. Even when the group agrees to follow along, having that initial “struggle window” builds way more understanding than watching someone else type.
  • Also — somebody pointed out a typo in the README. Fixed 😅 Thank you for that one.

This kind of feedback is gold to me. If you were in the room and didn’t fill the survey out — it’s never too late, ping me 🙂

Questions & Answers from the workshop

A few questions came up that I think are worth sharing more broadly.

1. Does it make sense to extract an interface for the Use Case?

As we discussed during the workshop — it depends 🙂

If you want to test your primary adapter (e.g., a controller) independently and fast, having an interface for the use case is the way to go. You can mock it, drive your adapter tests with predictable behavior, and skip booting the whole application.

There’s a second, more architectural reason: an interface gives you a clear boundary around your use cases. The interface becomes an abstraction over the use case layer, and abstractions are how you draw lines in your codebase.

If you don’t have either of those needs — testing speed or boundary enforcement — then no, you probably don’t need it.

2. What is the value of using read-models (DTOs) instead of entities?

This is essentially how you start implementing CQRS in a pragmatic way.

In a simple application with anemic models, returning entities directly from your read-side is fine. There’s no domain logic to leak, and the entity is basically a row of data anyway.

But once you have a rich domain model with invariants, behavior, and internal state, the use case layer should (not must) work with read-models / DTOs. Why?

  • You don’t accidentally expose mutable domain state to the outside world.
  • You can shape the read-model exactly for the consumer (UI, API, report).
  • Your reads stop being constrained by your write-side aggregate boundaries.

It’s about giving the read-side and the write-side the freedom to evolve separately.

3. Why create a new directory/namespace for the refactored code?

This is essentially the strangler fig pattern applied at the codebase level.

Three reasons I like it:

  1. A bold line between legacy and new code. No ambiguity about which side a file belongs to.
  2. Motivation. Watching the new namespace grow while the legacy one shrinks is genuinely satisfying. It’s a visible progress bar for your refactoring.
  3. Navigation. When you open the project, you see immediately what’s refactored and what isn’t. No archaeology required.

4. What do we do once everything is refactored out of the legacy folder?

First — celebrate 🎉 Seriously, that’s a milestone worth marking.

I think the real question behind this one was: what about the new namespace? Do we keep it, or rename it back?

It’s up to you. You can leave it as is, or you can do one big rename to fold the new namespace into the original one. Just be aware: that final rename will be a massive pull request with a lot of moved files. Coordinate with your team, do it on a quiet day, and prepare for some merge-conflict gymnastics 🤹

Thank you 🙌

To the SymfonyLive Berlin organisers

Every time I attend a Symfony conference — Amsterdam, Online, and now Berlin — I’m struck by the same thing: the openness, friendliness, and genuine welcome that runs through the whole event. It’s not marketing copy, it’s real. Speakers, attendees, organisers — everyone treats each other like part of the same community. Thank you for keeping that culture alive.

To the other speakers and trainers

Spending time with you between sessions, at speaker dinners, in hallway conversations — that’s where I learn the most. Thank you for being generous with your time and ideas.

A note on “paying back”

I use open source every single day at work, and Symfony is a huge part of that. I’m not a core contributor — I don’t have the bandwidth for that right now — but running these workshops at Symfony conferences feels like my way of giving something back to a community that gives me so much. If a few engineers leave the room with a cleaner mental model of architecture, that’s a small thank-you to the people who make the framework possible 💜

To the attendees

You showed up on a workshop day, asked sharp questions, pushed back where you disagreed, and committed to doing the coding as homework. That’s exactly the kind of group that makes a workshop worth running. Thank you 🙏

A few words about Berlin

This was my first time in Berlin, and I really liked the city. The thing that surprised me most was the bike culture — it’s not Dutch level (Amsterdam still wins this contest 🚲🇳🇱), but it’s seriously high. Wide bike lanes, drivers who actually respect them, lots of people commuting on two wheels. As someone who appreciates well-designed urban infrastructure, this made me very happy.

I’ll definitely come back.

Final thoughts

Three editions of this workshop now, three very different rooms, three different formats. Each time I learn something I want to bring into the next one. From Berlin I’m taking:

  • The two-perspective whiteboard exercise for primary/secondary actors — this stays.
  • More time buffers in the coding section — fix this.
  • “try it yourself first” window before live-coding — try this next time.

If you were at the workshop, thank you 🙏 If you weren’t but you’d like to be at the next one, I’ll keep posting updates on my talks page and on LinkedIn.

See you at the next conference 👋

My First Talk at Boiling Frogs 2026 🐸

TL;DR: I spoke at Boiling Frogs — the conference I consider the best in Poland. I was afraid my topic wouldn’t be good enough for that room. It was. But the most valuable part of the day had nothing to do with my talk.

Boiling Frogs is the conference I registered for without checking the agenda first.

One day. Three tracks. No filler. The selection is tough by design — hundreds of submissions, a handful of slots. The result is a room full of people who actually care. Engineers, architects, CTOs, QA specialists, product people — all choosing your talk over two others running in parallel.

I’ve been attending every year. Getting accepted to speak there meant something to me ☺️

Continue reading My First Talk at Boiling Frogs 2026 🐸

My First Remote Workshop at SymfonyOnline 2026

Short reflection

On 20th January I had the chance to run a workshop during SymfonyOnline 2026, titled refactoring towards Clean Architecture.
What made this session special for me was the fact that it was my very first remote workshop ever.

Going into it, I honestly expected around 10–15 participants. Instead, almost 25 people showed up, which was both surprising and incredibly motivating. Even more important than the number was the level of engagement — lots of thoughtful questions, real-life problems, and open discussions around legacy code, boundaries, and architectural trade-offs.

Running a remote workshop is very different from speaking on stage. You don’t see the whole room, you don’t feel the same energy — or at least that’s what I was afraid of. In reality, the interaction, questions, and feedback made it feel very alive and dynamic.

Of course, it wasn’t perfect. There are a few things I already know I want to improve next time — pacing, timing of exercises, and some technical details. But overall, for a first remote workshop, it went surprisingly well, and I’m genuinely proud of how it turned out.

Continue reading My First Remote Workshop at SymfonyOnline 2026

SymfonyCon 2025: My First International Workshop Experience

Intro

Oh wow — it’s already over, but I’m still riding the emotions from this conference. That’s why I’m here, writing this article for you. I hope you can learn something from my experience and maybe you’ll soon find yourself as speaker/trainer at your very first conference — either in your country or abroad 🙂

I’ve been a public speaker since 2023, and ever since then I’ve been applying to multiple conferences. I’ve spoken at events across Poland, sharing my experience and ideas, but for a long time I couldn’t quite make it happen abroad… until SymfonyCon 2025! I’m truly happy it finally worked out 🔥

My speaker badge

In this article, I want to cover everything related to this trip, so treat it as a practical guide on how to apply, prepare, and perform on an international stage — especially if you’re thinking about submitting your own talk or workshop.

SymfonyCon is the flagship annual conference for the Symfony community — the main event for anyone building with Symfony in PHP. There’s only one SymfonyCon each year, but the ecosystem also includes local SymfonyDay and SymfonyLive conferences/meetups, as well as SymfonyOnline, the online-only conference.

I’ve decided to apply with multiple talks and one workshop, but only the workshop got selected – Refactoring towards Clean Architecture. In this workshop I teach how to refactor the application written in a framework way into Clean Architecture. You can find more (what it is about, outcomes, agenda, etc.) on the dedicated page.

Continue reading SymfonyCon 2025: My First International Workshop Experience

From Monolith to Modularity – My Talk at the Fyul Tech Day

This summer I had the chance to speak at our internal engineering conference, and wow, what an experience! The room was completely packed (even our CTO joined 😱), and we actually ran out of time due to the number of questions and discussions. That’s probably the best kind of problem to have.

My talk was titled From Monolith to Modularity: How Deptrac Helped Us Break the Monolith”, and it told the story of how our team took a growing, hard-to-maintain PHP codebase and started turning it into a well-structured modular monolith, by using bounded contextsclean architecture, and most importantly, Deptrac.

Continue reading From Monolith to Modularity – My Talk at the Fyul Tech Day

🚀 A big step – my workshop at SymfonyCon 2025 in Amsterdam!

I’m truly excited to announce that my workshop Refactoring Towards Clean Architecture has been selected for this year’s SymfonyCon 2025 in Amsterdam!

This is a huge milestone for me because:

  • I’ve never spoken at an international conference before,
  • I’ve never been part of an event of this scale,
  • and this will be the very first time presenting this workshop at a conference – so far, I’ve only delivered it once, at Masterlease.

Funny coincidence: I actually received the confirmation email that I got accepted to SymfonyCon while I was giving a talk at our internal company conference 😆 On the one hand, I was over the moon with happiness; on the other hand, my imposter syndrome immediately kicked in 😂

I’ve worked hard to build my credibility as a speaker – you can find all my talks here.

I can’t wait to meet the Symfony community in Amsterdam and share my knowledge 🎉

ZSA Voyager – buying & waiting

Hello there 👋🏻. Welcome to the second part of my article series about the keyboard. This time I would like to describe the buying, awaiting till to unboxing the product. So, as you know from the first article in this series, I decided to buy a split columnar keyboard, which is ZSA Voyager.

All articles in this series:

  1. Why I switched to the split columnar keyboard
  2. ZSA Voyager – buying & waiting
  3. ZSA Voygare – unboxing and the first impressions
Read more: ZSA Voyager – buying & waiting

Why ZSA? It is one of the most known companies that produce ergonomic keyboards. They are quite an established company, which sells plenty of keyboards. They started in 2015. Besides the Voyager, they also have different split keyboards like Moonlander Mark 1 and Ergodox EZ 🧑‍💻

ZSA Ergodox EZ

When you visit the ZSA website, you will find a beautiful, intuitive website that clearly shows what you can expect when you buy their product. There is a comparison tool that will help you to choose a proper keyboard. Lastly, I would like to mention the printables. Ah, they are amazing – just print the keyboard on paper and try it on your own to see whether it will fit your hands 🙌.

Although I could end up here, I would like to emphasize the rest of their webpage, which is packed with information, about the switches, keycaps, layouts (like Dvorak, Colemak), ergonomics etc. Finally, it is worth mentioning their blog where you can find a lot of interviews with people who bought their keyboards. I found such information very valuable and they made me confident before buying 🎯.

Before finishing this short article, I move on to focus on the purchase experience. In the checkout process, there is a field that allows you to add any notes/questions to your order. I wrote that I am concerned about the usage of the laptop keyboard vs the Voyager. I had doubts that I wouldn’t be able to use the regular old-fashioned keyboard. To my surprise I’ve received a response from the company CEO, here it is:

As you have to wait for the keyboard quite long (the delivery took around 20 days), the company sends multiple emails with an introduction to their software and the customization. They even encourage us to make the first changes in the keyboard layout, as it is doable without the keyboard itself via Oryx software.

Stay tuned for the next part where I will cover the unboxing and the first impressions!

Senior Software Engineer – what next?

Hello there! I am a Software Engineer with 13 years of experience. Last year I felt the need to do something with my career to not die as a Senior Software Engineer. Although staying in such a position is fine for most people. So I started doing presentations and sharing the knowledge, but without any concrete plan. This year I want to approach the problem differently.

The main image by Arek Socha from Pixabay.

So, what to do next?

Continue reading Senior Software Engineer – what next?

Why I switched to the split columnar keyboard

All articles in this series:

  1. Why I switched to the split columnar keyboard
  2. ZSA Voyager – buying & waiting
  3. ZSA Voygare – unboxing and the first impressions

A bit of history

Have you ever wondered why every row with letters on a keyboard is moved a bit to the side, but no such thing is happening on the numpad? Do you know how this impacts your ergonomics?

The typical full computer keyboard
Keychron C2

Let me introduce you to the staggered keyboard layout. The staggered layout means that each row of letters is moved a bit to the side. I would bet that 99% of keyboards currently sold or built-in into the devices are staggered keyboards.

By GodeNehler – Own work, CC BY-SA 4.0, https://commons.wikimedia.org/w/index.php?curid=75088136

Such a layout was introduced with the first typewriters. So the layout that you are currently using has not changed since the 1870s! The idea was simple – there was a mechanical device, and on each key press the ribbon was moved to type a character. To prevent jamming the ribbons the staggered QWERTY layout was introduced. As you might guess, the more the machines become popular, the layout becomes a standard.

Later computers were invented, and they also got a keyboard, yes, with the same QWERTY staggered layout. But you might be wondering – there are no ribbons on the keyboard, so why did we still use the same layout? The answer is pretty simple – the people were already used to the layout from the typewriters, consequently, it was easier to switch to the computer if it had the same layout. OK, now that the history lesson is done, let’s jump to another part of this article.

What is wrong with the staggered layout?

Let’s think about how we usually write on the staggered keyboard.

The device is in front of you, and it is narrower than your arms, hence you have to angle your wrist to type properly. This position is not ergonomic at all. Let’s list all the problems.

Problem one – the keys are not aligned with your fingers. For example, if you want to press key D and then E, you have to move the finger up and a bit left. Yes, you might be already used to that, but would it be better to just move up?

Problem two – angling your wrists. If you do so for many hours, many days per year, this can lead to repetitive strain injuries.

Problem three – closing the chest by angling your arms to the inside. By sitting in such a position for a long time, you will have weaker back muscles. It can also lead to pain in the back/shoulders.

Problem four – many of the keys are out of reach so you have to move your whole hand to reach them. That usually means angling your wrist even more…

My issues

I have been working with keyboards for around 15 years. I’ve tried to improve the comfort and ergonomics of my work.

For a few years, I didn’t bother until my first child was born. After a quick parental leave, I went back to work and I discovered the back pain. That is how my ergo journey began. I’ve tried four office chairs and bought a sit-stand desk.

With the keyboards, I started by buying a 100% mechanical keyboard. I quickly realized how ineffective that keyboard was because of how much I had to move my hands.

Keychron C2 vs Keychron K12

Consequently, I bought a 60% keyboard, it was way better. But, there was still one problem that started to become a serious issue.

My left shoulder hurt me just after four hours of working. Some of you might say „Hey you need to exercise and all the problems will be gone”. The problem is that I am already an active person, I am working out.

My physiotherapist said that I have a closed chest and I need to open it, so my shoulders will be inlined, which should fix my pain.

At that moment I decided to try something new – the split columnar keyboard.

ZSA Voyager

The switch

After buying the new keyboard, the switch was fairly easy. The worst was the first week. Then all went smoothly.

The biggest benefit of the new keyboard is that it fixed my pain, literally. I can now sit comfortably for hours, my chest is open and my shoulders are aligned.

I thought that after switching I would have problems with typing on a regular keyboard, which I still have, on my laptop. Happily, that is not true. By learning to type on such a keyboard you are doing it from scratch. That means that you still remember how to type on the staggered keyboard. Your brain will contain two distinct muscle memories. For me, it is not an issue to take a laptop, sit on a couch and type on a built-in keyboard. The only problem is that it is much less comfortable…

Should you also switch?

If you have the same feeling as me – why I am using a staggered keyboard that was invented with the typewriters – do not be shy and go for it.

If you have an RSI – then the split columnar keyboards are the way to go.

If you are curious – you will not regret it.

I have to warn you – it is not an easy switch. You have to learn to type again. So you will have to get out of your comfort zone. You have to slow down to get better.

Next articles about the keyboards

As the next article, I am planning to do a review of my split columnar keyboard – the ZSA Voyager. I will show you the process from ordering, first thoughts, and learning up to my current setup.

Stay tuned.

Crash early

A dead program normally does a lot less damage than a crippled one.

The Pragmatic Programmer, Tip #38, page 113

Have you ever thought about what can go wrong when the application’s logic is broken, but it continues to work? That might happen when the values are not the ones that you expect. For example, a method/function returns an integer, but a negative one, but you expect it to be positive. Another example is trying to access an unknown array key. The database returns an invalid value. You name it.

What if you won’t allow it and crash early? Yes, the client will see “an error occurred, our engineers are working on it”. The actual benefit is that the program will exit and not cause any harm. No corrupted data in the database nor missing files.

How to crash early in the PHP? There are two ways. Throwing a \LogicExpcetion or enabling assertions on production and using them.

Continue reading Crash early