Created
December 2, 2012 16:57
-
-
Save AmyStephen/4189804 to your computer and use it in GitHub Desktop.
Services Mock up
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* @package Molajo | |
* @copyright 2012 Amy Stephen. All rights reserved. | |
* @license GNU GPL v 2, or later and MIT, see License folder | |
*/ | |
namespace Molajo\Service; | |
use Molajo\Application; | |
use Molajo\Service\Services\Configuration\ConfigurationService; | |
defined('MOLAJO') or die; | |
/** | |
* Service | |
* | |
* The Services Class serves as a facade and can be useful over time for these goals: | |
* | |
* 1) Simplify application interface for developers | |
* | |
* 2) Provide a cushioning layer for change where backwards compatibility can be better insured | |
* | |
* 3) Serves as an abstraction layer for the API, making changes in the framework easier to implement | |
* while ensuring base services continue to produce expected results | |
* | |
* @return boolean | |
* @since 1.0 | |
*/ | |
Class Services | |
{ | |
/** | |
* Used to connect to service either dynamically or reuse of an existing connection | |
* | |
* @static | |
* @param string $name | |
* @param array $arguments | |
* | |
* @return object | |
* @since 1.0 | |
*/ | |
public static function __callStatic($name, $arguments) | |
{ | |
return Application::Services()->get($name . 'Service'); | |
} | |
/** | |
* Connect Service | |
* | |
* @param string $key | |
* | |
* @return mixed | |
* @since 1.0 | |
* | |
* @throws \BadMethodCallException | |
*/ | |
protected function get($key) | |
{ | |
try { | |
$serviceClass = 'Molajo\\Service\\Services\\' | |
. substr($key, 0, strlen($key) - strlen('service')) | |
. '\\' | |
. $key; | |
return $this->getClassInstance($serviceClass); | |
} catch (\Exception $e) { | |
$trace = debug_backtrace(); | |
$caller = array_shift($trace); | |
$error_message = "Called by {$caller['function']}"; | |
if (isset($caller['class'])) { | |
$error_message .= " in {$caller['class']}"; | |
} | |
throw new \Exception($error_message); | |
} | |
} | |
/** | |
* Get Class Instance | |
* | |
* @param string $entry | |
* @param $folder $entry | |
* | |
* @return mixed | |
* @since 1.0 | |
*/ | |
private function getClassInstance($serviceClass) | |
{ | |
if (class_exists($serviceClass)) { | |
} else { | |
throw new \Exception('Service Class ' . $serviceClass . ' does not exist.'); | |
} | |
return new $serviceClass(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
In the Front Controller: ( http://en.wikipedia.org/wiki/Front_Controller_pattern )
declare the namespace:
use Molajo\Service\Services;
define a static property:
/**
*
*/
protected static $services = null;
Include a connectivity method for the Services Class:
/**
Application::Services
*
@static
@return Services
@throws \RuntimeException
@SInCE 1.0
*/
public static function Services()
{
if (self::$services) {
} else {
try {
self::$services = new Services();
} catch (\RuntimeException $e) {
echo 'Instantiate Service Exception : ', $e->getMessage(), "\n";
die;
}
}
return self::$services;
}
Within the application, calls to the Services connections can look like:
$results = Services::Registry()->set($key, $value);
$connection = Services::Database()->connect($configuration);
$user = Services::User()->get($id);
All of these calls use a dynamic, not static, instance of the underlying class which is handled by the Services Class.
The benefit is an abstracted layer between the application and the platform where "logic can occur." This can be useful in ushering in change without impacting the application.
Over time, it can also help to drive focus on simplifying the API and moving towards providing a level of service (for example, send email, save row, schedule event), without tying those services so closely to class and method names. In that sense, if phpmailer was swapped out for another email option, the change could be made without the application even being aware.
Given the foundation separation effort, a facade is also a useful approach to various groupings of underlying services.