Feature - Handling Environments

This PR was created for the purpose of handling different environments and building them into classes that can be strictly type checked.

The EnvironmentFactory class can either take in a string, use the current `ENVIRONMENT` variable, or default to a `development` environment.

If the environment isn't recognized as one of the defined (development, staging, production) we create a CustomEnvironment class which will allow for custom configurations in the future.
Hmm, well you could either have an "UnknownEnvironment" (for the null object pattern, like we talked about), you could return null, or you could throw an `UnexpectedValueException`. It depends on the implications throughout the app. I'd suggest against just returning null.