gpt4 book ai didi

PHP。创建对象的最佳实践

转载 作者:可可西里 更新时间:2023-11-01 00:41:06 26 4
gpt4 key购买 nike

假设我有一个实体(一 block 石头),我有一些更具体的实体,它们扩展了基本实体——例如一 block 会说话的石头,它有一些不同的属性和方法。石头的所有属性都存储在同一个表中的数据库中。特定对象的所有特定属性序列化存储在表的“specific_options”字段中。我有“Stone”类和“Talking_Stone”类,它扩展了基本的石头类。我需要根据从数据库中获取的数据创建一个石头对象。

实现此类事情的最佳做法是什么?

到目前为止我得到了什么:

class Stone_Data {
...
public static function get_item( $id ) {
$sql = 'SELECT * FROM `' . self::$table . '` WHERE `id`=' . ( int ) $id;
$item = self::$db->get_row( $sql );
return $item;
}
...
}

class Stone_Factory {
...
public static function create( $id = null ) {
// if the stone's type is set
if ( !is_null( $id ) && !is_null( $data = Stone_Data::get_item( $id ) ) && !empty( $data['type'] ) ) {
// create a stone of this type
$class_name = ucfirst( $data['type'] ) . '_Stone';
return new $class_name( $data );
}
// otherwise create a basic stone
return new Stone;
}
...
}

class Stone {
private $data = array(
...
'specific_options' => '',
...
);
...
public function __construct( $data = array() ) {
$this->set( $data );
}
...
public function __set( $name, $value ) {
if ( array_key_exists( $name, $this->data ) ) {
// serialize if the value is an array or an object
if ( is_array( $value ) || is_object( $value ) ) {
$value = serialize( $value );
}
$this->data[$name] = $value;
}
}
public function set( $data = array() ) {
foreach ( $data as $key => $value ) {
// serialize if the value is an array or an object
if ( is_array( $value ) || is_object( $value ) ) {
$data[$key] = serialize( $value );
}
}
$this->data = array_merge( $this->data, $data );
return $this;
}
...
}
class Talking_Stone extends Stone {
...
public function __construct( $data = array() ) {
parent::__construct( $data );
// $this->type = 'talking'
$this->specific_options->language = 'French';
...
}
...
}

但不知何故,感觉不太对..

最佳答案

你想为此使用一个存储库类:

class StoneRepository
{
private $stoneFactory;

public function __construct(StoneFactory $factory) {
$this->stoneFactory = $factory;
}

/**
* @param integer $id
* @return Stone
*/
public function findStoneById($id) {
// Fetch your data from the database
$row = ...;

// Use the factory to create a new stone from the data
// that has already been fetched
$stone = $this->stoneFactory->create($row);

// Return the new stone
return $stone;
}
}

这里最大的优势是您将数据库逻辑与模型分开。这很棒,因为您可以获得一个不了解数据库的干净模型。您可以随心所欲地进行查询,同时保持它们的整洁和分离。

然后你可以使用它来获取具有给定 id 的石头,例如,你的 Controller :

$factory = new StoneFactory();
$repository = new StoneRepository($factory);

$stone = $repository->findStoneById($id);

获取集合

获取集契约(Contract)样简单:

class StoneRepository
{
...

public function findAllStones() {
// Again, fetch the data
$rows = ...;

// Transform each row into a Stone object
$collection = array_map(function ($row) {
return $this->stoneFactory->create($row);
}, $rows);

return $collection;
}
}

返回具有关系的对象

迟早你可能想要获取一些相关的对象。您可以在此处采用几种方法。最简单的方法是分别获取每种类型的对象并在 Controller 中构建模型。例如,如果您想要一个包含相关 Stone 对象的 Bag 对象:

$bag = $bagRepository->findBagById($bagId);
$stones = $stoneRepository->findStonesByBagId($bagId);

$bag->addStones($stones);

另一种方法是使用join 并在BagRepository 中实际构建BagStones。由于比较复杂,这里就不写了。

增删改查

您也应该使用存储库根据您的模型在数据库中插入/更新/删除数据。同样,它就像添加一个 insertupdatedelete 方法一样简单,它们接受一个 Stone 对象并持久化它是数据库中的数据。

关于PHP。创建对象的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37033926/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com