Adapter - marmot-cn/marmot-framework GitHub Wiki

适配器

我们设计适配器的主要原因是封装不同数据来源的差异. 如: 我们现在数据搜索存储都基于MySQL, 我们为了方便测试需要做一个基于fakermock. 我们只用换掉适配器即可.

设计思路来自于:

  • 领域驱动编程的防腐层
  • 六边形模型

样例代码

Interface

Adapter的抽象层, 所有具体的Adapter都要实现该接口.

<?php
namespace Member\Adapter\Member;

use Member\Model\Member;

interface IMemberAdapter
{
    public function add(Member $member) : bool;

    public function update(Member $member, array $keys = array()) : bool;

    public function fetchOne($id) : Member;

    public function fetchList(array $ids) : array;

    public function filter(
        array $filter = array(),
        array $sort = array(),
        int $offset = 0,
        int $size = 0
    ) : array;
}

DBAdapter

具体的 数据库适配器`, 代表该适配器存储到数据库.

<?php
namespace Member\Adapter\Member;

use Member\Translator\MemberDBTranslator;
use Member\Model\Member;
use Member\Model\NullMember;
use Member\Adapter\Member\Query\MemberRowCacheQuery;
use Common\Adapter\Document\AvatarDocumentAdapter;
use Common\Adapter\Document\ApplyInfoDocumentAdapter;

use Marmot\Core;

class MemberDBAdapter implements IMemberAdapter
{
    private $translator;
    private $rowCacheQuery;

    public function __construct()
    {
        $this->translator = new MemberDBTranslator();
        $this->rowCacheQuery = new MemberRowCacheQuery();
    }

    public function __destruct()
    {
        unset($this->translator);
        unset($this->rowCacheQuery);
    }

    protected function getMemberDBTranslator() : MemberDBTranslator
    {
        return $this->translator;
    }

    protected function getMemberRowCacheQuery() : MemberRowCacheQuery
    {
        return $this->rowCacheQuery;
    }

    public function add(Member $member) : bool
    {
    	...

MockAdapter

具体的 Mock适配器, 用来模拟调用数据.

<?php
namespace Member\Adapter\Member;

use Member\Model\Member;
use Member\Utils\ObjectGenerate;

class MemberMockAdapter implements IMemberAdapter
{
    public function __construct()
    {
    }

    public function __destruct()
    {
    }


    public function add(Member $member) : bool
    {
        unset($member);

        return true;
    }

    public function update(Member $member, array $keys = array()) : bool
    {
        unset($member);
        unset($keys);

        return true;
    }

    public function fetchOne($id) : Member
    {
        return ObjectGenerate::generateMember($id);
    }

    public function fetchList(array $ids) : array
    {
        $memberList = array();

        foreach ($ids as $id) {
            $memberList[] = ObjectGenerate::generateMember($id);
        }

        return $memberList;
    }


    public function filter(
        array $filter = array(),
        array $sort = array(),
        int $offset = 0,
        int $size = 20
    ) :array {

        unset($filter);
        unset($sort);

        $ids = [];

        for ($offset; $offset<$size; $offset++) {
            $ids[] = $offset;
        }

        $count = sizeof($ids);
        return array($this->fetchList($ids), $count);
    }
}