Today I ran an interesting experiment with Claude and Cursor. I asked both to implement an AIServiceInterface with two concrete implementations—OpenAI and OpenRouter.
The result? Both tools immediately reached for the Singleton pattern.
Now, beyond ensuring client initialization happens once, there's no compelling architectural reason for a singleton here. These AI service implementations don't need shared state—which is the fundamental purpose of the Singleton pattern. When I challenged this decision, both tools acknowledged it was unnecessary—even problematic.
This raises a concerning question: What kind of code are these AI tools learning from?
Think about it:
Developers who don't question the generated patterns get anti-patterns baked into their codebase
The tools seem to favor "familiar" patterns over appropriate ones
We might be creating a feedback loop where bad patterns get reinforced in training data
My take: While AI coding assistants are powerful productivity multipliers, they're not architecture consultants. They excel at implementation details but can stumble on design decisions that require contextual judgment.
The singleton pattern has legitimate uses—shared resource management, logging, configuration. But for service implementations with clear lifecycles? It's often the wrong choice.
Question for the community: Have you noticed AI tools gravitating toward specific patterns—good or bad? How do you balance AI assistance with architectural best practices?
As I explored in my recent post on context engineering for AI agents, the quality of what we put in directly impacts what we get out. Maybe it's time we apply that same scrutiny to the code patterns these tools suggest.
#SoftwareArchitecture #AI #CodeQuality #SoftwareEngineering #TechLeadership
1
6
0