A good question to ask when you wonder why certain things are a certain way, is: What if it wasn’t that way? What would be the drawback?
So we basically have three of those questions here:
What if this wasn’t in a class / function?
Let’s suppose that instead of having this in a class we would have this in a single file (aka transaction script).
It might look a little something like this.
Code:
$db = mysqli_connect(...);
ob_start();
extract($args);
include BP . "app/view/$name.phtml";
$content = ob_get_clean();
One clear drawback here is that the template is able to use everything that is in the scope of this file, including the database connection! But the whole point of MVC is that the view should be as dumb as possible, and should contain as little logic as possible. So giving it access to a database connection is not done, because that gives it way too much power.
Instead if you extract this code to a function or a method, the template only has access to variables that are defined within that function (and of course any (super)globals), and that fits better with the philosophy that the view should be as dumb as possible.
Note that within a method the template still has access to $this
, which is a reference to the Renderer
instance it’s being called from. There is a way around that. Brownie points to anyone who can tell me how 
What if we didn’t use ob_start / ob_get_clean?
Suppose we have the following template:
<h1>Hello <?= $username; ?></h1>
And the render
method doesn’t have ob_start()
and ob_get_clean()
but just echoes the template directly.
And we call our render method without any data:
Then as @ahundiak already said you would have to render all sub templates in the exact correct order, which can be hard or even impossible at times. So it’s better if you can just render anything you like and then stitch all the partials back together at the end.
What if we didn’t use extract?
Using extract
means that all keys in $args
will become variables in the current scope, so if you have an array like ['username' => 'rpkamp']
and you extract it, a variable $username
is available in the render
method, and thus also in your template. Without extract
your template would look like this:
<h1>Hello <?= $args['username']; ?></h1>
Which works just as fine, except you’d need to type $args['']
for each and every variable, which would become annoying after a while. So the extract
is just for convenience.