Every Programming Problem is a Domain Problem
Why Understanding the Business Domain Matters More Than Writing Code
Developers often overlook the importance of domain knowledge, especially after writing thousands of lines of code. Everything starts to feel repetitive—if-else statements, loops, functions, modules, data fetching, error handling, signal processing, feature toggles. It’s easy to focus solely on syntax and patterns while missing the real differentiator: the language of the domain.
Understanding Code Beyond Syntax
Programming is not just about writing code—it’s about understanding and expressing the domain. The most critical skill a developer can develop is learning how to speak the domain language in code.
Consider the following test case:
describe("Menu", () => {
it("should show menu item", () => {
render(<Navigation {...menus} />);
const linkElement = screen.queryByRole("link", { name: "About" });
expect(linkElement).toBeVisible();
expect(linkElement).toHaveAttribute("href", "/about");
});
});
The terms describe
, it
, expect
, and toBeVisible
make perfect sense within the context of testing, particularly in behavior-driven development (BDD). Without understanding that context, the code feels cryptic.
Now, let’s look at a data-fetching example:
const Profile = ({ id }: { id: string }) => {
const [user, setUser] = useState<User | undefined>();
useEffect(() => {
const fetchUser = async () => {
const response = await fetch(`/api/users/${id}`);
const jsonData = await response.json();
setUser(jsonData);
};
fetchUser();
}, [id]);
return <UserBrief user={user} />;
};
Understanding this code requires knowing that useEffect
is a React hook for handling side effects. This stems from a fundamental concept in React: rendering is pure, and anything outside that cycle—like fetching data—is a side effect.
Domain-Specific Formatting Challenges
Once you recognize that different domains require different abstractions, you start to see that even something as simple as formatting a list can vary significantly based on the context.
A few days ago, I was working on an internationalization (i18n) issue in a React project. The task seemed simple: display a list of values in a readable format. But as soon as I saw the requirements, I realized it wasn’t that straightforward.
In English, when listing three items—let’s say "Apple, Banana, and Cherry"—we use a conjunction ("and") before the last item. However, not all languages work this way. In French, for example, there is no comma before "et" ("and"). In Spanish, "and" ("y") changes to "e" if the next word starts with "i." Japanese, on the other hand, doesn’t use a conjunction at all—it separates items with a special symbol ("・").
To handle these differences, I used formatList
from react-intl
, but I also needed more customization. Specifically, I wanted to wrap each item in <strong>
tags while ensuring the conjunction words (like "and") remained outside the formatting. Luckily, react-intl
provides a way to achieve this:
import { useIntl, FormattedMessage } from "react-intl";
function EnumListFormatter({ values }) {
const intl = useIntl();
const formattedList = intl.formatList(values, {
type: "conjunction",
style: "long",
}, (chunk, index) => <strong key={index}>{chunk}</strong>);
return (
<FormattedMessage
id="enum.possibleValues"
defaultMessage="The possible values are {values}."
values={{ values: formattedList }}
/>
);
}
By leveraging the third argument of formatList
, I was able to format each individual item differently while keeping the conjunctions untouched. This kind of abstraction helps developers handle localization without manually constructing formatted strings.
Domain Language Over Programming Language
Once you’ve mastered basic programming concepts, the real challenge is learning the language of the domain—its processes, nouns, and verbs. The core of software development is translating domain knowledge into executable code.
The domain language is more important than the programming language. While you might need to use abstractions like useEffect
, ActiveRecord
, or Mapper
, they should always serve the purpose of expressing the domain’s concepts clearly.
Next time you write code, ask yourself: Am I just programming, or am I speaking the domain’s language?
This is a great breakdown of a deceptively tricky topic. List formatting often flies under the radar in internationalization, but as you’ve clearly shown, it’s full of linguistic edge cases that vary by language and context.