如何在不将我的存储库与我的API服务混合的情况下实现层分离?

时间:2016-04-25 22:43:08

标签: php model-view-controller service repository separation-of-concerns

(有一个TL; DR:在底部)

我有通过MVC模式制作的PDF。我正在使用现有的代码,这有点乱,但现在我看到了一个模式出现。

目前,我有一个Controller类,在里面我有很多单独的函数,每页大约有一个函数。每个函数都是这样的:

function showPage()
{ 
    //get some data from repository
    $data1 = $this->repository->getData1();
    $data2 = $this->repository->getData2();

    //pass that data to the PDF API class, aka "the view"
    //and the class takes care of creating PDF pages
    //with the appropriate data
    $this->pdfApi->showView($data, $data2);
}

以上实现了Repository(仅返回数据),PDF API服务(接收数据,不需要关心或维护数据检索结构之间的清晰分离和控制器几乎只是要求数据,并将其传递给PDF API。一切顺利,直到我遇到这个问题:

问题

大多数每个页面都有一个带有消息的“页脚”,以及需要在页面上显示的“提案号”。有时它还有其他数据。由于PDF API类本身没有数据,因此有人必须将该数据传递给PDF API。作为函数参数的一部分,我每次都将上面的内容传递给信息片段,但它变得不方便 - 有太多的参数要传递,而且它们使代码混乱。

尝试解决方案

为了减少参数传递中的混乱,在我的Controller我为Repository$footerText等变量创建了拉取数据(通过$proposalNumber),然后使用它们我填充PDF API自己的类属性。这样的副作用是,现在我的PDF API具有直接嵌入在API中的相关数据位(我认为这是不合需要的,因为数据层现在强加到API类中)

到目前为止,我已经抵制了将整个Repository对象传递给PDF API的诱惑,因为这将完全相同 - 混合数据层和API层,此外,API层将具有对数据的无限制访问权限,这也是不受欢迎的。

实际问题

当我想要清晰的图层分离时,我的代码会被多个函数参数传递混乱。

当我将整个Repository传递给我的API类时,我会混合使用数据和API层,并且API层可以自由使用Repository类。

我可以以某种方式实现层分离,而不会出现上面提到的混乱或“混合层”问题吗?

如果你想看代码,下面是我的各种不成功尝试的代码:)

TL; DR:我各种不成功的尝试将图层分开或减少混乱被证明是不成功的

//in Controller - Exhibit 1 
//Separation achieved with only data parameter passing tying layers together
//but, too much clutter -- too many parameters

//maximum layer separation but lots of annoying data passing
$data1 = $this->repository->getData1();
....
$data24 = $this->repository->getData24();
$this->pdfApi->showView($data1, $data2, $data3, ... );
//in Controller - Exhibit 2
//Layers are mixed - my data is now tied into API

//in constructor
$data1 = $this->repository->getData1();
....
$data24 = $this->repository->getData24();
$this->pdfApi->setData1($data1);
$this->pdfApi->setData24($data24);

//inside function (API already has data as part of its own vars):
$this->pdfApi->showView();
//in Controller - Exhibit 3
//layers are mixed -- entire Repository got into my API  

//in constructor
$repo = new Repository();
$this->pdfApi->setRepository($repo);

//inside function (API has full Repository access gets its own data and more):
$this->pdfApi->showView();

1 个答案:

答案 0 :(得分:0)

我认为图表1是最正确的。

//inside Controller
$data = array(
    'data1' => $this->repository->getData1(),
    //...
    'data24' => $this->repository->getData4()
):

$this->pdfApi->showView($data);

我这样说是因为我使用的流行框架ZF2也归因于相同的模式。

//inside Controller
$data = array(
        'message' => 'Hello world',
);
$view = new ViewModel($data);

就我而言,View是PDF API