最近,我已经探索并将我的PHP技能扩展到新领域,并致力于更好地理解各种设计模式。从技术的角度来看,我理解特征以及它们如何有用,但还没有实用的方面。我最近正在处理一段代码,我不确定这是否是实现我想要的最佳方式。
<?php namespace Acme\Traits;
trait TCities{
/**
* @var self
*/
private static $instance;
/**
* @var int
*/
private $cityID;
/**
* @var float
*/
private $latitude;
/**
* @var float
*/
private $longitude;
/**
* @var
*/
private $cityName;
// more fields ----->>>
/**
* @return TCities
*/
public static function getInstance() {
if (!(self::$instance instanceof self)) {
self::$instance = new self;
}
return self::$instance;
}
/**
* @return int
*/
public function getCityID(): int{
return $this->cityID;
}
/**
* @param int $cityID
*/
public function setCityID(int $cityID){
$this->cityID = $cityID;
}
// more methods ....
由于我的城市数据可以来自3个不同的数据库并在整个系统中使用,因此可以轻松访问数据,而无需了解各种数据库中的所有字段。
以下是如何使用特征的示例。
<?php namespace Acme\QueryLibs\MySql;
use Acme\Traits\TCities;
class SqlLocationQueries extends SqlQuery{
use TCities;
/**
* SqlLocationQueries constructor.
*
* @param IDatabaseMySql $db
*/
public function __construct(IDatabaseMySql $db){
parent::__construct($db);
}
/**
* @param int $cityID
*
* @return TCities
*/
public function getCityData(int $cityID): TCities{
$query = ' SELECT *
FROM cities
WHERE id=?
LIMIT 1 ';
$params = [$cityID];
self::setQuery($query);
self::setParams($params);
$result = self::readOne();
if(empty($result)){
LocationErrors::unknownCityByID($cityID);
}
$cityInst = TCities::getInstance();
$cityInst->setCityID($result['cityID']);
$cityInst->setCityName($result['name']);
$cityInst->setLatitude($result['lat']);
$cityInst->setLongitude($result['lon']);
return $cityObj;
}
如您所见,此方法返回&#39; TCities&#39;。它非常方便但不确定这是否是正确/好的方法?
然后在更高级别的方法(这是一个非常简单的用例,但得到了重点)
$locationOrigin = new SqlLocationQueries($this->db);
$cityOriginData = $locationOrigin->getCityData($cityID);
echo 'Welcome to '.$cityOriginData->getCityName().'<br />';
echo 'Where the coordinates are '.$cityOriginData->getLatitude().' '.$cityOriginData->getLatitude().'<br />';
这是滥用特征还是来自他们的好用例?如果它是一个糟糕的用例,那么实现这一目标的更有效和正确的方法是什么?