在确认SOLID原则的同时在模型中引用缓存结果?

时间:2017-04-02 03:07:21

标签: php solid-principles

我有一个优惠类,它扩展了我的基础Model类,我希望返回所有特别优惠,但每个优惠包含与其他模型结果的关系。如何以有条理的方式引用我缓存的记录?

Model.php

abstract class Model {
  protected $db;

  public function __construct() {
       $this->db = new \Db;
  }
  abstract public function getRecords($params);
};

Offers.php

class Offers extends Model {
    public function getRecords($params) {
       $this->db->query('
          SELECT title, 
          GROUP_CONCAT(properties_ids) AS properties, 
          GROUP_CONCAT(cities_ids) AS cities, 
          GROUP_CONCAT(countries_ids) AS countries
       ');

       $results = array();
       while ($temp = $this->db->fetchAssoc()) {
          $results[] = $this->formatResult($temp);
       }
       return $results;
    }

    public function setProperties($properties) {
         $this->properties = $properties;
    }

    public function setCities($cities) {
         $this->cities = $cities;
    }

    public function setCountries($countries) {
         $this->countries = $countries;
    }

    public function formatResult(&$record) {
         if ( $record['properties'] ) {
             // convert a csv string into an array
             \Helper::makeArray($record['properties']);

             $properties = array();
             foreach( $record['properties'] as $id ) {
                 if ( $this->properties[$id] ) {
                     $properties[] = $this->properties[$id];
                 }
             }
             $record['properties'] = $properties;
         }
    }
}

目前我正在这样做:

$properties = (new Properties)->getRecords($filters);
$cities = (new Cities)->getRecords($filters);
$countries = (new Countries)->getRecords($filters);

$offers = new Offers;
$offers->setProperties($properties);
$offers->setCities($cities);
$offers->setCountries($countries);
$offerRecords = $offers->getRecords();

$events = new Events;
$events->setProperties($properties);
$eventRecords = $events->getRecords();

有没有办法可以做到这一点,而不必依赖于不断创建 set 方法?我的模型各自参考了彼此的结果。

我在 set 方法之前的方式是将参数传递给 getRecords ,但由于我创建了一个抽象类和方法,因此参数count必须相同,它不一致所以我放弃了它。

一些理论/想法:

  1. 可以在 Offers :: getRecords 中创建$ properties变量,但我对其他模型使用相同的结果,我想使用该一致结果(在同一页面上)

  2. 将所有模型修改为自缓存,但这会涉及需要缓存覆盖的额外逻辑

  3. 在我的抽象类中创建一个通用的setModelResults方法,所以至少我可以使用一个方法而不是每次都定义一个。

  4. 例如

    public function setModelResults($modelName, array $results) {
       $this->{$modelName} = $results;
    }
    
    $offers->setModelResults('Properties', $properties);
    
    1. 在模型级别实现缓存并重构getRecords以直接调用引用模型,方法是添加静态模型函数以创建实例(清洁imo)或创建实例。
    2. 例如

      class Properties {
      
          public function getRecords($params) {
             $sql = 'SELECT * FROM table';
             if ( $params['id'] ) {
                $sql.= ' WHERE id = '. $id;
             }
      
             $results = Db::cache->get($sql, array(
      
             ));
             if (!$results) {
                 Db::query($sql);
                 Db::cache->set($sql, array(
                     'expires' => (new DateTime)->add(new DateTimeInterval('PT1H'));
                 );
             }
          }
      
          public static function model($className=__CLASS__) { 
              return parent::model($className);
          }
      
      }
      

      优惠中的用法:

          class Offers {
      
          public function getRecords($params) {
             $this->db->query('
                SELECT title, 
                GROUP_CONCAT(properties_ids) AS properties, 
                GROUP_CONCAT(cities_ids) AS cities, 
                GROUP_CONCAT(countries_ids) AS countries
             ');
      
             $this->properties = Properties::model()->getRecords();
             // alternatively
             // $this->properties = new Properties;
      
             $results = array();
             while ($temp = $this->db->fetchAssoc()) {
                $results[] = $this->formatResult($temp);
             }
             return $results;
          }
      
              public function formatResult(&$record) {
                   if ( $record['properties'] ) {
                       // convert a csv string into an array
                       \Helper::makeArray($record['properties']);
      
      
                       $properties = array();
      
      
                       // Method 1
                       foreach( $properties as $id ) {
                           if ( $this->properties[$id] ) {
                               $properties[] = $this->properties[$id];
                           }
                       }
      
                       // Method 2
                       /* alternatively */
                       $this->propertiesResults = $this->properties->getRecords();
                       foreach( $properties as $id ) {
                           if ( $this->propertiesResults[$id] ) {
                               $properties[] = $this->propertiesResults[$id];
                           }
                       }
      
                       $record['properties'] = $properties;
                   }
              }
      
          }
      

0 个答案:

没有答案