Why do so few code examples use the ::load($id) method for loading entities? Over at How to get term name from a tid? the accepted answer for "how do I get the name for a Term" is this:

use Drupal\taxonomy\Entity\Term;
...
$term = Term::load($tid);
...


That's really nice, easy to read code (and very easy to remember). It's also, as it turns out, applicable to all entity types in Drupal (just substitute the Term class for the type of entity you want).

Why then, do the overwhelming majority of the code examples and tutorials published around the place seem to advocate this monstrosity? ...

$term = \Drupal::entityTypeManager()-&gt;getStorage('taxonomy_term')-&gt;load($tid);


That approach bakes in one of my [many] grievances with PHP in general - it's full of magic strings! How the hell am I supposed to know at "compile time" whether 'taxonomy_term' is the right argument to getStorage()?? There's not a PHP IDE in the land that'll catch me sticking 'taxonomy' in there instead.

Looking at the contents of that ::load method (which is defined in \Drupal\Core\Entity\Entity and shared by all Drupal entities), it's got all the dependency-injection cleverness of that second-approach - plus it fills in the right argument to getStorage() for you automatically!

So why does more of the Drupal community not use it? Is there something I'm missing? Or is it just to teach us "first principles" so that we can write shared code that works with any entity type? (you'd need the long-hand way in a hook that was intended to work across all entity types).
There is actually an issue about adding this info to the docs. 

In short, the long winded version is unit test friendly. 

A comment by one of the Core's contributors fully detailed explains why. Just to highlight the main point:


  If we call Node::load() in OO code we are breaking this principle (dependency inversion),
  because we are hardcoding the specific implementation
  (\Drupal\node\Entity\Node::load() to be exact). This code path is hard
  coupled to \Drupal::entityManager() which is hard coupled to
  \Drupal::$container. So now our code becomes impossible to run outside
  of Drupal.
  
  Furthermore, since code that uses the dependency inversion principle
  is fully standalone it is very easy to unit test it by mocking the
  dependencies according to the requested interfaces. If we introduce
  Node::load() then it becomes really hard to "properly" unit test the
  class, since it will start polluting the test environment with
  external code, and the dependency injection container is not available
  in unit tests.


Now if you wonder then why does Entity::load exists


  There were many loud voices at the time that D8 was going to be a DX
  disaster, that the OO approach was too difficult to understand and
  write, that it would never get adopted by the wider community. There
  was a huge push going on to make D8 more DX friendly, mainly driven by
  the Backdrop fork that was announced a few months earlier.
  
  So we created these static methods that wrap the loading of the entity
  manager from the container, and can be called directly from the
  procedural side. It was great, since it offers a drop-in replacement
  that works and looks very much like the original code. This made
  porting of procedural D7 code vastly easier:

// Original D7 procedural code. 
$node = node_load($nid);

// New D8 procedural code. 
$node = Node::load($nid);