2009-09-23 3 views
0

Ma première question demande essentiellement une révision de code. Est-ce que le code que je suis sur le point de fournir utilise une usine pour promouvoir le polymorphisme? C'est écrit en PHP. Voici les exigences de base:Est-ce que j'utilise une usine pour promouvoir le polymorphisme?

  • Transmettez un URL long à une bibliothèque et renvoyez un URL raccourci. Avec l'URL longue , passez les propriétés de l'utilisateur à pour tenter de localiser le service de raccourcissement et la clé API spécifiques aux utilisateurs.
  • Permet aux utilisateurs de définir des clés API pour des raccourcis d'URL spécifiques. Mon code suppose que ceci est déjà défini dans la base de données et Bitly est le seul service supporté.
  • Si un utilisateur ne dispose pas d'une clé d'API et d'un ensemble de services, utilisez la clé et le service API par défaut. Encore une fois, mon code suppose que la valeur par défaut est Bitly dans la base de données.
  • Si le service de raccourcissement d'URL échoue, notez l'échec, mais ne lancez pas d'exception. La bibliothèque devrait échouer silencieusement. Au lieu d'utiliser l'URL courte, nous utiliserons l'URL longue.

Voici un exemple d'appeler le code:

<?php 
$long_url = 'http://www.news.com/story/1'; 
$account_id = 1; 

$use_this_url = $long_url; 

$meta = array(
    'account_id' => $account_id, 
    // OPTIONS 
    // 'service_id' => $service_id, 
    // 'account_id' => $account_id, 
); 
$shortener = new Shortener_Factory($long_url, $meta); 
if ($shortener->shorten_long_url() AND $shortener->save_short_url()) 
{ 
       $use_this_url = $shortener->short_url;  
} 

echo $use_this_url; 

Voici les classes:

<?php 
interface ShortenerServiceInterface { 
    public function save_short_url(); 
    public function shorten_long_url(); 
} 

abstract class ShortenerServiceAbstract implements ShortenerServiceInterface { 

    // Url to be shortened 
    public $long_url = ''; 

    // Long url unique id 
    public $url_id = 0; 

    // Service unique id 
    public $shorturlservice_id = 0; 

    // Service account unique id 
    public $shorturlserviceaccount_id = 0;  

    // Short url service unique API login 
    public $api_login = ''; 

    // Short url service unique API key 
    public $api_key = ''; 

    // Short url service unique hash which maps to original url value 
    public $hash = ''; 

    // Shortened url string 
    public $short_url = ''; 


    // Attempt to call shortner service three times before failing 
    public $attempts = 3; 

    // Shorten long url with specific service API/logic 
    public function shorten_long_url() 
    { 
     // Can't save a short url when one doesn't exist 
     if (!$this->long_url OR !$this->api_login OR !$this->api_key) { 
      log('error', 'ShortenerServiceAbstract::shorten_long_url - no long url to shorten - '.var_export($this, TRUE)); 
      return FALSE; 
     }   
    } 

    // Save short url and related meta-data to shorturls table 
    public function save_short_url() 
    { 
     // Can't save a short url when one doesn't exist 
     if (!$this->url_id OR !$this->hash OR !$this->shorturlservice_id OR !$this->shorturlserviceaccount_id) { 
      log('error', 'ShortenerServiceAbstract::save_short_url - no short url to save - '.var_export($this, TRUE)); 
      return FALSE; 
     } 

     // Insert a new short url, or update an existing record 
     $saved = Shorturl_Model::insert_on_dup_key_update($this->url_id, $this->hash, $this->shorturlservice_id, $this->shorturlserviceaccount_id); 

     if (!$saved) { 
      log('error', 'ShortenerServiceAbstract::save_short_url - short url record can not be saved - '.var_export($this, TRUE)); 
      return FALSE; 
     } else { 
      return TRUE; 
     }   
    } 

} 

// Bitly, a simple url shortener 
// @link http://code.google.com/p/bitly-api/wiki/ApiDocumentation 
class ShortenerServiceBitly extends ShortenerServiceAbstract { 

    public function shorten_long_url() 
    { 
     // Make sure we have required members set 
     parent::shorten_long_url(); 

     $urlencoded = urlencode($this->long_url); 
     $bitlyurl = 'http://api.bit.ly/shorten?version=2.0.1&longUrl='.$urlencoded.'&login='.$this->api_login.'&apiKey='.$this->api_key.'&history=1'; 

     $attempts = 1; 
     while ($attempts <= 3) { 
      $json_result = file_get_contents($bitlyurl);   
      if ($json_result) {         
       // Return an assoc array 
       $json_decode = json_decode($json_result, TRUE); 
       if (is_array($json_decode) AND isset($json_decode['errorCode']) AND $json_decode['errorCode'] == 0) { 
        // Don't compare sent URL with returned URL 
        // Bitly removes invalid poritions of URLs 
        // The camparison might fail even though the URLs are the "same" 
        $shortened = current($json_decode['results']); 
        break; 
       } else { 
        log('error', 'ShortenerServiceBitly::shorten_long_url - bit.ly json decoded - '.var_export($json_decode, TRUE)); 
       } 
      } else { 
        log('error', 'ShortenerServiceBitly::shorten_long_url - bit.ly http response - '.var_export($json_result, TRUE)); 
      } 
      $attempts++; 
     } 

     if (isset($shortened)) { 
      $this->short_url = $shortened['shortUrl']; 
      $this->hash = $shortened['userHash']; 
      return TRUE; 
     } else { 
      return FALSE; 
     } 
    } 

} 

// Shortener Factory 
class Shortener_Factory { 

    // Shortener service account parameter object 
    // @param object shortener account properties 
    private $_account; 

    // Shortener service object created by factory 
    //@param object shorterner service functions 
    private $_service; 

    // Url to be shortened 
    private $_long_url; 

    // Set url members, service parameter object and finally the service itself 
    public function __construct($long_url, $meta=array()) 
    { 
     $this->_long_url = $long_url; 

     $this->_set_account($meta); 
     $this->_set_service();     
    } 

    // Set shortener service account parameter object 
    // @param $meta array determine parameters for the current service object 
    private function _set_account($meta=array()) 
    {      
     $s = FALSE; 

     // Get shorturl service account 
     if (isset($meta['account_id'])) { 
      $s = Shorturlserviceaccount_Model::get_by_account_id($meta['account_id']); 
     } elseif (isset($meta['service_id'])) { 
      $s = Shorturlserviceaccount_Model::get_by_service_id($meta['service_id']); 
     } 

     // Account not found, lets use default 
     if (!$s) { 
      $s = Shorturlserviceaccount_Model::get_default(); 
     } 

     // Must have a service to use 
     if ($s === FALSE) { 
      log('error', 'Shortener_Core::_set_account - _account not found - '.var_export($this, TRUE)); 
      return FALSE; 
     } else { 
      $this->_account = $s; 
     }   
    } 

    // Use shortener service account parameter object to set shortener service object 
    private function _set_service() 
    { 
     switch ($this->_account->name) { 
      case 'bitly': 
       $this->_service = new ShortenerServiceBitly; 
    break; 
      default: 
       log('error', 'Shortener_Core::_set_service - _account not set - '.var_export($this, TRUE)); 
    return FALSE; 
     } 

     $this->_service->long_url = $this->_long_url;   
     $this->_service->shorturlserviceaccount_id = $this->_account->id;  
     $this->_service->shorturlservice_id = $this->_account->shorturlservice_id; 
     $this->_service->api_login = $this->_account->api_login; 
     $this->_service->api_key = $this->_account->api_key; 
    } 

    // Public API for shortener service object methods 
    public function __call($name, $arguments) 
    { 
     if (!$this->_service) { 
       log('error', 'Shortener_Core::__call - _service not set - '.var_export($this, TRUE)); 
    return FALSE;    
     } 
     return $this->_service->$name(); 
    } 

    // Public API for shortener service object members 
    public function __get($name) 
    { 
     return ($this->_service->$name) ? $this->_service->$name : NULL; 
    } 
} 
+0

Votre conception et code ont l'air bien. Quelle est la fonction ou la partie que vous posez spécifiquement en tant qu'usine? – philfreo

Répondre

0

Le travail du modèle d'usine est à abstraire la création d'objets. La raison pour laquelle cela est utile parce que la façon dont les objets sont créés ne peuvent pas la même chose que simplement:

$instance = new Object(); 

tout moment de sa création. Par exemple, si vous devez d'abord traiter le chargement d'un fichier include ou si vous devez sélectionner l'une des quelques classes dérivées en fonction d'un paramètre inconnu avant l'exécution.

Une usine peut être aussi simple que quelque chose comme:

function getInstance($objectType, $params) 
{ 
    if (!class_exists($objectType)) { 
     throw new Exception('Bad class'); 
    } 
    $instance = new $objectType($params); 
    return $instance; 
} 

Ou peut être aussi complexe que vous le souhaitez, mais ce sont les règles de base à suivre. consultez l'article wikipedia ici pour un PHP exemple

Questions connexes