Key Takeaways from XConf Thailand 2022
I have been to XConf Thailand 2022 which is a tech conference organized by Thoughtworks in Bangkok. It was packed with insightful sessions…
Key Takeaways from XConf Thailand 2022
I have been to XConf Thailand 2022 which is a tech conference organized by Thoughtworks in Bangkok. It was packed with insightful sessions from thought-leading speakers. I have learnt a lot and here are some of my key takeaways from the conference.

My picture from a photo booth at the conference
Evolutionary Testing in Evolutionary Architecture
It is not uncommon to see a debate around how to correctly write unit tests e.g. should we mock this and that, or shouldn’t we? The speaker pointed out that the fact that we don’t know exactly how to correctly write unit tests is actually an architecture smell that we don’t have a shared understanding of what a unit is.
A unit is a section of an application, whatever that means. Just define whatever is easiest for the team (not just you) to work on an application.
It is not easy to create a shared definition though e.g. we can’t even agree yet on what Agile or Model means. 😂
The speaker argued that architecture is a bunch of definitions and relationships. And frameworks (e.g. MVC) give you definitions and relationships (which is architecture). That’s why it feels easier to write unit tests when using the frameworks.
The first rule of unit testing
The TEAM must create AND maintain a shared definition of unit.
When a question of “how to unit test” arises, it reflects a lack of architecture. Architecture is a shared understanding of how things are supposed to work together. A lack of architecture in this context means a lack of shared understanding of what is a unit.
Analogy: CPU is a unit of a computer. We expect it to comply with CPU specification. It should not just work with a specific mainboard. When we define a unit in software architecture, we expect the same. A unit must work correctly according to its definition, and we could reuse a unit in different places.
The second rule of unit testing (in evolutionary architecture)
As architecture evolved, each unit must be well-tested.
It is not uncommon that when we refactor the code, it forces us to refactor a lot of unit tests. However, the speaker argued that unit testing should enable architecture evolution, rather than blocking it.
Example: Our app may start with a simple logic inside a controller, and we write a controller test as our unit test. As our app becomes more complex, we start to refactor e.g. we may extract data access into a repository. Our old unit tests becomes integration tests and that’s fine. They become an enabler for refactoring to a better architecture.
A common mistake is to define a unit as a class or a method, which cannot evolve. It is a useless definition that will make refactoring become a hassle.

The two rules of unit testing in evolutionary architecture
High Performing Team Essentials
The speakers shared their experience to build a cross-timezone virtual team from scratch. Here are a few of their tips that I like.
Intentional and On-going Team Building
From the beginning, they established a Social Contract to be able to work together effectively. They are simple rules of engagement that everyone agree upon e.g. always turn on your camera, no judgement on clothing, make-ups, or messy room.
Simple games do work e.g. Gartic Phone.
The team building effort should result in a safe environment with fun vibes.
- Open to sharing — You don’t have to be an expert to share.
- Open to try new things — You don’t have to be an expert from Day 1.
- Open to failure — It’s OK when things don’t work out as planned. Let’s understand and try again.
- Non-toxic environment. No blame culture.
- Make it fun!
Hypothesis Driven Development
The speaker shared that their team was working on a performance improvement project which made it hard to come up with a user story since they were not developing a feature, so they decided to use a different approach and gave Hypothesis Driven Development a try.
HDD is a scientific method applied to software development. The team conducts experiments which could succeed or fail. This makes a safe environment even more important.
Step 1 — Observe and come up with hypothesis
- We believe <this capability>
- Will result in <expected outcome>
- We will have confidence to proceed when <we see a measurable signal>
Step 2 — Implement changes according to the hypothesis
Step 3 — Observe for signal that validate the hypothesis
It is important to be able to measure the result, so they put an effort to build performance metrics dashboard to observe improvement result which enabled them to iterate though fast feedback loop.
It is also important to clearly communicate the value the team is delivering because there is no tangible feature that clients can easily see. They maintained a continuous communication with the client with a visualization consisting of 3 columns — Hypothesis / Experiments / What did we learn?
Team Pull Request Review
It is a session that involve all team members and takes precedent over coding. The benefit is so obvious that I won’t bother explaining more here. 😛
Feature Lead
The speaker shared how they fixed the problem that the team depends on TL too much. They tried to build the next generation of leaders by having a Feature Lead. Devs could play this role, with support from BA and TL, so that they can practice their skills to be an enabler in addition to an individual contributor.
4 Pillars of High-Trust Teams
I assumed they refer to this article which said it includes Safety, Dependability, Competence, and Character.

Choose one tip and give it a try
Building the Best Code Doesn’t Build the Best System
This is a really deep topic for me, but the speaker did a wonderful job to deliver such a complex topic in a super engaging and entertaining way. I understand that the concept being discussed is similar to the idea of System Thinking.
A system is never the sum of its parts; it’s the product of their interactions. — Russell L. Ackoff
The performance of a system depends on how all the parts fit together, not how they act separately. Composing a system from the best individual components does not give us the best system.
Example: imagine making a car from the best parts from different manufacturers that are never designed to work together.
Braess’s Paradox
When trying to improve the system, it is extremely important to understand how those improvements will interact with the rest of the system. The speaker introduced an intriguing example, a Braess’s Paradox, in which removing defects does not always improve performance of the whole system.
[embed]Braess’s Paradox
From that point being made, the speaker suggested that when we want to improve something, we should focus on what we want, instead of what we don’t want.
We often fall into a trap to locally optimize the part instead of the system e.g. it’s easy to find ways to improve how Devs, QA, BA, TL work individually, and lost focus on improving how the team is working together.
Efficiency is doing the things right. Effectiveness is doing the right things. — Peter Drucker
Example: Is it the best way to get quality by having the process that only Architect or Senior Devs can approve a PR? What skill do they have? Why other people can’t have it?
Pair programming
The speaker then suggested an alternative solution that could make the whole system better, a Pair Programming. It is always a controversial topic to discuss, especially with management team, as it looks like a team velocity will be cut in half.
There is a paper that actually measured the impact of pair programming. The development time does indeed increase but only by around 15% not 100%. Moreover, other quality dimensions are significantly improved including: increased Design Quality / Satisfaction / Problem Solving / Learning / Communication, and reduced Code Defects, and most interestingly, reduced Staffing Risk.
It was emphasized that better systems come from better teams. Hiring more best people does not give you the best team.
Programming vs Software Engineering
The speaker shared an interesting quote to make a point that software engineering involve many people, so it is important to think about improving the whole system, not just individuals.
Getting a program working. You have a problem to solve, you write some code, you run it, you get your answer, you’re done. That’s programming, and that’s difficult enough by itself.
Software engineering is what happens to programming when you add time and other programmers. — Russ Cox
Why bother?
The speaker invited us to write good enough code with high software engineering practices that supports changes now, not in the future.
In a system, if you are doing nothing, the system is still working, so it is up to us to make it better now, not in the future.
What a wonderful conclusion.

The speaker invited us to “Make tech better, together”
메타데이터
- post_id
- b29909e55873
- slug
- key-takeaways-from-xconf-thailand-2022-b29909e55873
- url
- https://medium.com/@boybundit/key-takeaways-from-xconf-thailand-2022-b29909e55873
- canonical_url
- https://medium.com/@boybundit/key-takeaways-from-xconf-thailand-2022-b29909e55873
- author_url
- https://medium.com/@boybundit
- status
- ok
- fetched_at
- 2026-07-26 17:05:25