In many domains though, the typical customer is:
- Interested in daily operational concerns--short-range tactics ... not strategy;
- Only concerned with the immediate solution;
- Generally one-dimensional, non-abstract thinkers;
- Primarily interested in "getting the job done" as opposed to coming up with a lasting, quality solution.
And to be frank, they usually have good reasons to think like this. First of all, they are running a business, which should generate revenue today and tomorrow, not in some distant future. Secondly, they aren't technical experts - they don't know what's possible and what's not, and what the consequences of specific architectural / design / implementation choices are. This is what we know.
So the answer is - hardly surprising - communication.
You need to communicate a lot, to educate each other, to make each other understand the point of view of the other party at least to a basic level. You need to explain them the short and long term consequences of possible alternatives. And you need to use language they understand.
- If you say "this would be a hack, which makes the code less readable and extensible", they say, "yeah, whatever".
- If you say "this would be a short term fix, which would make longer term development and maintenance more costly, and increase the risk of introducing bugs", they say "a ha, let's consider".
- And if you say "this solution would cost you $100 now, but introduces $500 of technical debt which you are bound to pay back with interest sooner or later; OTOH this other solution costs you $400 now and leaves no technical debt; pick the one you want", they say "now we are talking!".
OTOH they can teach us a thing or two about the business perspective. Business wants usable and good enough - hardly perfect - solutions. And they know probably better than anyone that "perfect is the enemy of good". So you need to keep in mind that our job is to provide solutions to problems of our clients, rather than to produce technically perfect software. Sometimes these two converge to the same, but more often not. This may be seen as sad by many, but it is business reality. For me, if I managed to solve my customer's problem, and I see that it made their life visibly easier, I am as happy as they are. OTOH if I managed to implement the perfect design I had in mind, but the company goes bankrupt the following week, it is hardly a win to anyone is it?
A sensible business owner will understand - if you explain them using their own language - why is it important to keep software clean, to write unit tests, to refactor etc. Even though these do not seem to directly contribute anything in the short term, they are essential for long term maintenance. And sensible customers do care about the long term maintainability of their business, so they surely are willing to invest into it when they see the value their investment generates. However, both their resources and your time are limited, so you need to prioritize and focus on the most important things. But it is important only if it is important to both of you.
You may want to refactor module A because the code in there is just awful, and you have a stupendous idea how to refactor the code to be concise, elegant and clean, using a design pattern you just read about. However, if that module hasn't been touched for years, and it works reliably, you are most likely better off focusing on module B, which is going to be extended next week with a very important new feature, and it contains tons of bugs already.