ホームページ > バックエンド開発 > PHPチュートリアル > [php]コレクションと永続化ファクトリー

[php]コレクションと永続化ファクトリー

WBOY
リリース: 2016-06-13 12:35:21
オリジナル
777 人が閲覧しました

[php]コレクションおよび永続化ファクトリー

Mapper クラスの FindById($id) は、指定された ID を持つデータをデータベースから取得し、オブジェクトにマッピングして返すことができます。多くの場合、データ コレクション (findAll) を返す必要があるため、このデータを保存し、必要に応じてオブジェクトにマップするためのデータ構造が必要になります。データの一部はオブジェクトにマップされるため、データ コレクションにはオブジェクト コレクションが必要です。データ コレクションとオブジェクト コレクションをクラスに配置すると、データからオブジェクトへのマッピングを簡単に処理できるようになります。このクラスを Collection という名前にしました。コレクション オブジェクトにアクセスしやすくするために、Collection サブクラスは、foreach を使用して簡単にアクセスできる Iterator インターフェイスを実装します。

コレクション クラス構造:


デモマッパーコレクション:

デモドメイン:
namespace demo\mapper;

use demo\base\AppException;
use demo\domain\DomainObject;
use demo\mapper\Mapper;

abstract class Collection {
	// 保存数据库取出的行数据
	protected $raws;
	// 保存已映射的对象
	protected $objects = array();
	// 用于$raws[]到$objects的映射
	protected $mapper;
	// 当前指针
	private $pointer = 0;
	// 对象数组总数
	private $total = 0;
	
	/**
	 * @param array $raws 未处理过的数据库数据
	 * @param Mapper $mapper 用于把$raws映射成对象(createObject)
	 */
	public function __construct(array $raws = null, Mapper $mapper = null) {
		if (!is_null($raws) && !is_null($mapper)) {
			$this->raws = $raws;
			$this->total = count($raws);
		}
		
		$this->mapper = $mapper;
	}
	
	/**
	 * 返回指定$num的数据对象
	 * @param int $num
	 */
	public function getRow($num) {
		if ($num < 0 || $num >= $this->total) {
			return null;
		}
		
		// 延迟加载
		$this->notifyAccess();
		
		if (isset($this->objects[$num])) {
			return $this->objects[$num];
		}
		
		if (isset($this->raws[$num])) {
			$obj = $this->mapper->createObject($this->raws[$num]);
			$this->objects[$num] = $obj;
			return $obj;
		}
		
		return null;
	}
	
	/**
	 * 添加对象
	 * @param DomainObject $obj
	 * @throws AppException
	 */
	public function add(DomainObject $obj) {
		// 类型安全检查
		$targetClass = $this->getTargetClass();
		if (!($obj instanceof $targetClass)) {
			throw new AppException("Object must be {$targetClass}");
		}
		
		// 
		$this->notifyAccess();
		$this->objects[$this->pointer++] = $obj;
	}
	
	public function current() {
		return $this->getRow($this->pointer);
	}
	
	public function next() {
		$obj = $this->getRow($this->pointer);
		if (!is_null($obj)) {
			$this->pointer++;
		}
		
		return $obj;
	}
	
	public function key() {
		return $this->pointer;
	}
	
	public function rewind() {
		$this->pointer = 0;
	}
	
	public function valid() {
		return !is_null($this->current());
	}
	
	/**
	 * 延迟加载
	 */
	protected  function notifyAccess() {
		// 暂时留空
	}
	
	protected abstract function getTargetClass();
}
ログイン後にコピー

デモマッパー:

namespace demo\domain;

use \demo\domain\DomainObject;

interface ClassroomCollection extends \Iterator {
	public function add(DomainObject $obj);
}

interface StudentCollection extends \Iterator {
	public function add(DomainObject $obj);
}

interface ScoreCollection extends \Iterator {
	public function add(DomainObject $obj);
}
ログイン後にコピー
ドメイン パッケージに Collection インターフェイスが必要なのはなぜですか?ドメインパッケージはデータを保存するためにCollectionを使用する必要があるため、ドメインパッケージがマッパーパッケージのCollectionに依存しないようにするためにインターフェースを作成しました。このインターフェースは、demodomainmapperCollection によって実装されます。
namespace demo\mapper;

class ClassroomCollection extends Collection 
		implements \demo\domain\ClassroomCollection {
	
	protected function getTargetClass() {
		return '\demo\domain\Classroom';
	}
}

class StudentCollection extends Collection 
		implements \demo\domain\StudentCollection {
	
	protected function getTargetClass() {
		return '\demo\domain\Student';
	}
}

class ScoreCollection extends Collection 
		implements \demo\domain\ScoreCollection {

	protected function getTargetClass() {
		return '\demo\domain\Score';
	}
}
ログイン後にコピー

ここで、構造が少し複雑になり始めています。Mapper と Collection の特定のサブクラスを管理するために、抽象ファクトリーを使用してオブジェクトの作成を管理できます。クラス図を見てみましょう:

デモマッパーPersistanceFatory
このようなファクトリ パターンを使用すると、指定した Mapper および Collection のサブクラスを簡単に作成できると同時に、将来の新しい機能の追加も容易になります。

コレクション オブジェクトはドメイン パッケージにも必要ですが、マッパーでコレクションから分離する必要があります。ドメイン パッケージ内に HelperFactory クラスを作成し、ドメインからマッパーにアクセスするためのブリッジとして機能させることができます。

namespace demo\mapper;

/**
 * 持久化工厂
 */
abstract class PersistanceFactory {
	
	public static function getFactory($targetClass) {
		switch ($targetClass) {
			case '\demo\domain\Classroom':
				return new ClassroomPersistanceFactory();
				
			case '\demo\domain\Student':
				return new StudentPersistanceFactory();
				
			case '\demo\domain\Score':
				return new ScorePersistanceFactory();
		}
	}
	
	public abstract function getMapper();
	
	public abstract function getCollection(array $raws = null);
}

class ClassroomPersistanceFactory extends PersistanceFactory {
	public function getMapper() {
		return new ClassroomMapper();
	}
	
	public function getCollection(array $raws = null) {
		return new ClassroomCollection($raws, $this->getMapper());
	}
}

class StudentPersistanceFactory extends PersistanceFactory {
	public function getMapper() {
		return new StudentMapper();
	}
	
	public function getCollection(array $raws = null) {
		return new StudentCollection($raws, $this->getMapper());
	}
}

class ScorePersistanceFactory extends PersistanceFactory {
	public function getMapper() {
		return new ScoreMapper();
	}
	
	public function getCollection(array $raws = null) {
		return new ScoreCollection($raws, $this->getMapper());
	}
}
ログイン後にコピー

これにより、ドメイン パッケージとマッパー パッケージが分離されます。

namespace demo\domain;

use demo\mapper\PersistanceFactory;

class HelperFactory {
	
	public static function getCollection($targetClass) {
		$fact = PersistanceFactory::getFactory($targetClass);
		return $fact->getCollection();
	}
	
	public static function getFinder($targetClass) {
		$fact = PersistanceFactory::getFactory($targetClass);
		return $fact->getMapper();	
	}
}
ログイン後にコピー
コレクションを取得したので、Mapper の findAll() を実装しましょう。

例:

Collection は、$raws[] から $objects[] へのマッピングを簡単に管理できます。
namespace demo\mapper;

use demo\base\AppException;
use \demo\base\ApplicationRegistry;

/**
 * Mapper
 */
abstract  class Mapper {
	
	//...
	
	/**
	 * 返回Collection
	 */
	public function findAll() {
		$pStmt = $this->getSelectAllStmt();
		$pStmt->execute(array());
		$raws = $pStmt->fetchAll(\PDO::FETCH_ASSOC);
		$collection = $this->getCollection($raws);
		
		return $collection;
	}
	
	/**
	 * 返回子类Collection
	 * @param array $raw
	 */
	public function getCollection(array $raws) {
		return $this->getFactory()->getCollection($raws);
	}
	
	/**
	 * 返回子类持久化工厂对象
	 */
	public function getFactory() {
		return PersistanceFactory::getFactory($this->getTargetClass());		
	}
	
	//....
}
ログイン後にコピー
PersistanceFactory は、マッパー パッケージ内のクラス オブジェクトの作成を管理できます。

HelperFactory はマッパー パッケージとドメイン パッケージを分離します。

$fact = PersistanceFactory::getFactory('\demo\domain\Classroom');
$mapper = $fact->getMapper();
$classrooms = $mapper->findAll();
foreach ($classrooms as $elem) {
	var_dump($elem);
}
ログイン後にコピー


関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート