Here’s a thought:

When your theory does not fit reality, drop reality.

That sounds insane, right? But what about this:

When your user does not understand your software, they are just too stupid.

This is an attitude you probably encounter quite frequently. Or this:

When your beautiful program does not solve the problem, convince yourself that you do not actually need to solve the problem.

Maybe this is not something you actually, actively tell yourself, but people still do it. Note the similarity to the first statement that is so utterly insane.

Of course it is not always that simple. Sometimes a user is not in your target audience and sometimes your theory is not meant to describe all of reality. You have my full sympathy for developing a nice theory, a beautiful program, or an idiosyncratic user interface. It just comes down to what you are trying to achieve – and often you are trying to actually solve a problem and not produce nice code. Which is not to say that you should not ever care about code quality, of course you should! But it’s usually not the main point (and what many people call code quality is often measured by an absolutely arbitrary theory or modeling approach in this sense).

As a related thought, I often think the a key difference between two of my interests, software engineering and (abstract) mathematics, is that in mathematics you are usually looking for the best, most extreme entity; it’s about universal properties and adjunctions. When writing software you often have to accept that mostly there is no best solution, no universal property,1 but just different trade-offs that you can make. If you are lucky enough to find some solution that can be considered the best, changing requirements will ensure that it looses that status at some point.

  1. I’m not talking about type-theory here; I mostly have actually building software for a business in mind.