首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在使用第三方API和在Laravel中创建域时使用适配器模式

在使用第三方API和在Laravel中创建域时使用适配器模式
EN

Stack Overflow用户
提问于 2019-04-26 13:18:10
回答 1查看 5.6K关注 0票数 5

在我的项目中,我主要使用第三方API。为此,我有一个按API(住宿、计划、折扣等)分组的‘服务’文件夹,用于向API发送正确的参数并获取原始数据。

我觉得我需要在这里使用适配器模式,因为这个第三方输出需要格式化。

让我举一个例子。

我有一个EventDao接口(数据访问对象)和一个或多个具体的EventDao类,比如EventbriteDao。

我还为每个具体DAO提供了一个适配器。例如: EvenbriteAdapter

我将有一些业务逻辑,所以我需要一个事件实体类。要将适配器的数据传递给实体,我需要一个EventDTO类(数据传输对象)

最后,我可以调用eventDao (通过接口感谢Laravel的服务提供商)

我将其原始输出传递给适配器,然后将适配器的输出传递给实体。然后,我可以调用实体类的方法之一。(在此之后,我需要将其转换为适当的json数据,但这是很容易的部分。)

我不知道如何放置其他CRUD逻辑,如updateEvent、deleteEvent、getAll等。我应该直接在控制器中调用它们还是创建存储库(存储库模式)?我对此感到困惑。

这是一个好方法还是over-engineering??因为我有5-6个类/接口而不是控制器。

另一个问题是直接在控制器中调用EventbriteAdapter。我应该有一个接口吗?在这种情况下,我需要将服务接口和适配器接口绑定到AppServiceProvider中的实现。

我关心的另一个问题是拥有实体块的集合。如果我调用getAll()方法,我可以循环数据并创建一个对象数组,但我对此并不满意。Laravel的集合将是有用的,但我想将应用层与域分开。什么是解决这个问题的好办法?

下面是我提到的一些文件的示例代码:

代码语言:javascript
运行
复制
interface EventAdapter
{
    public function getId();
    public function getName();
    public function getStartDate();
    public function getLocationName();
}



class EventbriteAdapter implements EventInterface
{
    private $raw;

    public function __construct(array $raw)
    {
        $this->raw = $raw;
    }

    public function getName()
    {
        return $this->raw['name'];
    }

    public function getStartDate()
    {
        return $this->raw['start'];
    }

    public function getLocation()
    {
        return $this->raw['venue']['name'].' '.$this->raw['venue']['address'];
    }
}


// Fetch event from Eventbrite (or other third-party)
$result = fetchEventFromEventbrite();

// Wrap event in adapter
$adapter = new EventbriteAdapter($result);
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-04-30 09:39:36

我不知道如何放置其他CRUD逻辑,如updateEvent、deleteEvent、getAll等。我应该直接在控制器中调用它们还是创建存储库(存储库模式)?我对此感到困惑。

您可以使用网关模式封装与第三方API交互的所有逻辑。网关可以包含获取数据和保存数据的方法。例如:

代码语言:javascript
运行
复制
interface EventGatewayInterface
{
    /**
     * Get an event by id
     * 
     * @param mixed $id unique identifier of an event
     * @return Event the event
     */
    public function getById($id);

    /**
     * Get all events
     *
     * @return Event[] list of events
     */
    public function getAll();

    /** 
     * Add an event
     *
     * @param Event $event the event which will be added
     */
    public function add(Event $event);

    /**
     * Update an event
     *
     * @param Event $event the event which will be updated  
     */
    public function update(Event $event);

    /**
     * Delete an event
     *
     * @param Event $event the event which will be removed
     */
    public function delete();
}

这是一个很好的方法还是过度工程?因为我有5-6个类/接口而不是控制器。

实际上,您可以使用适配器模式将一个表示(原始表示)转换为另一个表示(对象表示)。但是Adapter模式用于将一个程序接口转换为兼容的程序接口。要转换使用Mapper模式的表示形式,请执行以下操作。您可以实现简单的映射器,例如:

代码语言:javascript
运行
复制
class RawEventMapper
{
    /**
     * Map raw data to an event object
     * 
     * @param array $data raw data
     * @return Event the event object
     */
    public function map(array $data)
    {
        $event = new Event();
        $event->name = $data['name'];
        $event->startDate = $data['start'];
        $event->location = $data['venue']['name'].' '.$data['venue']['address'];
        return $event;
    }
}

并在Gateway中使用它将原始数据转换为对象。

代码语言:javascript
运行
复制
class ConcreteEventGateway implement EventGatewayInterface
{
    /** @var RawEventMapper data mapper */
    protected $mapper;

    /**
     * Constructor
     *
     * @param RawEventMapper $mapper data mapper
     */ 
    public function __construct(RawEventMapper $mapper)
    {
        $this->mapper = $mapper;
    }

    /** @inheritdoc */
    public function getById($id)
    {
        // get raw data from 3rd party API
        return $this->mapper->map($raw);
    }
}

Laravel的集合将是有用的,但我想将应用层与域分开。什么是解决这个问题的好办法?

如果您的目标是创建一个独立于框架的域层,则不应该使用Laravel集合。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55868506

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档