If you ask a programmer to list symptoms of low code quality, they could
probably produce a long list: deeply nested conditionals and loops,
long methods, overly terse variable names. Most of these code smells
tend to focus on the implementation of the code. They're about internal code
quality.

External code quality instead asks you to consider the programmer that has
to call your code. When trying to judge how easily somebody else can you
use your code, you might ask yourself:

Do the class and method names describe what the caller wants to accomplish?

How many times must we call into your code to complete a single, discrete task?

Does your code have minimal dependencies on other parts of your codebase and external
libraries?

As an example, consider this snippet of Java to write an XML document to an OutputStream:

While there are probably good reasons for all of those methods, and there are cases where
having a high level of control is valuable, this isn't a good API for our user that just
wants to write out their XML document to an output stream.

Do the class and method names describe what they want to accomplish? We want to write
out our XML document, and instead we're talking about TransformerFactory and
OutputKeys.DOCTYPE_SYSTEM.

How many times must we call into your code to complete a single, discrete task? Writing
out an XML document seems simple, but we have to create an instance of a transformer factory,
then ask it for a transformer, set the output property (whatever that is), wrap up our
document and output stream, before we can finally use the transformer to write out our
document.

Does your code have minimal dependencies on other parts of your codebase and external
libraries? The code above actually does quite well here, since that snippet should
work on a normal installation of Java.

So, why is it valuable to distinguish between internal and external code quality? The effect
of low internal code quality is contained within a small scope (by definition!). I'm certainly not advocating
one letter names for all local variables, but cleaning up that code is
comparatively straightforward compared to improving an API. The effects of
low external code quality tend to pervade your entire system. If you change the signature
of a method, you now have to change every use of that method.

When writing code, we often trade off code quality against speed of execution. Even when writing
good quality code, we're not going to spend weeks refactoring to make it perfect. I'm suggesting
that we should be spending more time worrying about the external quality of our code. Internal
quality is important, but it's not as important.

A good measure of whether a piece of your code has minimal dependencies is to try "libifying" it: turn it
into an independent library. If the code you write frequently depends on large parts of the
entire system, then it probably depends on too much. Once you've split out your code into
a separate library, there's a good chance that external code quality will improve. For starters,
once you've pulled out that code, you're unlikely to accidentally introduce new dependencies that
aren't really required. Beyond that: when you've written a bad API deep within the internals of your large system,
it's easy to ignore. If you've split it out into a library, it's much harder to ignore whether
your library makes it hard or easy to do what it says on the tin.

Decomposing your code into libraries has plenty of advantages, such as code reuse and
being able to test components independently. But I have a hypothesis that aggressively
libifying your code will leave you with a much higher quality of code in the long run.