结合功能

时间:2014-09-28 00:08:27

标签: php oop laravel laravel-4

试图了解下面的逻辑。

我有3张图片和两张static functions。我相信它可以创建一个功能,但缺乏如何实现这一点的知识,并将问题置于文字中是很难的,所以谷歌目前没有任何帮助。

3个图像中的1个在视图中的foreach循环之外,因此在模型中我创建了两个公共静态函数。这是我的问题,有没有更好的方法,然后使用2个功能?

数据库中的表是"图像"并包括以下内容:

  • ID
  • 图像
  • 列表

目前模型看起来像这样:

class Images extends Eloquent {

public static function indexPageTL() 
  {
    $images = DB::table('images')
        ->where('page', 'index')
        ->whereBetween('list', array(0,1))
        ->orderBy('list', 'asc')
    ->get();

    return $images;
  }

  public static function indexPageMR() 
  {
    $images = DB::table('images')
        ->where('page', 'index')
        ->whereBetween('list', array(2,4))
        ->orderBy('list', 'asc')
    ->get();

    return $images;
  }
}

正如您在模型中看到的,我使用数组来选择我需要的项目,以便将它们分开(因此这两个函数)。我将此传递给我的服务以更好地组合数据:

namespace Services;

use Images;

class IndexService
{
  public function indexData() 
  {
    $data = array(
      'images'  => Images::indexPageMR(),
      'imagesTL'  => Images::indexPageTL()
    );
    return $data;
  }
}

然后在我的控制器中:

use Services\IndexService;

class IndexController extends BaseController
{

public function index() {
   return View::make('index', with(new IndexService())->indexData());
    }
}   

最后在视图中:

@foreach($imagesTL as $fetch)
 <img src="{{ $fetch->image }}" class="img-responsive">
 @endforeach 

//then further down the page I call the indexPageMR()

@foreach($imagesMR as $fetch)
 <img src="{{ $fetch->image }}" class="img-responsive">
 @endforeach 

问题本质上,我是否需要2个单独的public static functions或者我可以将它们组合起来,如果我可以将它们组合起来我该怎么办?

道歉,如果不清楚,正如我所说,很难说出来。

1 个答案:

答案 0 :(得分:1)

这里有两个独立的问题:一个是您的问题,您可以将两个图像采集功能合二为一(即简化模型中的逻辑);另一个问题是OOP原则的正确实现,以使您的代码可测试且灵活。

(免责声明:我也是这一切的新手,所以希望更有经验的人会在评论中插入并纠正我的任何错误。)

在您深入研究OO处理此问题的方法之前,让我们让您的业务逻辑本身变得更简单,更灵活,更像&#34; Laravel-like&#34;。

首先,模型(当你实现完整的OO原则时最终会改变):

class Image extends Eloquent {

    public function scopeOnPage($query, $index)
    {
        return $query->wherePage($index);
    }

    public function scopeLocationBetween($query, $location)
    {
        return $query->whereBetween('list', $location);
    }

    public function getIndexPageImages($index, $location)
    {
        return $this->onPage($index)->locationBetween($location)->orderBy('list')->get();
    }

}

此处的更改包括:

  • 避免静态功能;相反,功能将作用于 我们在其他地方创建的图像对象。
  • 使我们的主要方法getIndexPageImages更加灵活 可重复使用,而不是location的值中的硬编码。我们的 模型不需要知道TL,MR或什么列表值 构成那些。
  • 利用Eloquent使查询更简单,更易读。 我在这里使用了query scopes, 这将允许您在模型中的其他位置重用该逻辑 需要的。

现在,从我们的控制器,我们可以要求我们的Image模型准确地给出我们想要的东西(再次,与模型一样,一旦你进入全OOP,这将会改变......但这是起点):

class IndexController extends BaseController {
    public function showIndex($index)
    {
        $images = new Image;
        $data['images_TL'] = $images->getIndexPageImages($index, [0,1]);
        $data['images_MR'] = $images->getIndexPageImages($index, [2,4]); 
        return View::make('showIndex', with($data));
    }
}

...和我们的路线:

Route::get('images/{index}', 'IndexController@showIndex');

我们的路由将index参数传递给控制器​​。在控制器中,我们实例化一个新的Image对象,然后询问它我们想要的特定图像,除以TL和MR。 (由于这个逻辑不再硬编码到我们的模型中,我们可以灵活地询问其他图像分组,如果我们想要,而不必进入并更改我们的模型。)然后我们将该数据传递给视图,您可以在$images_TL循环中循环$images_MRforeach,就像现在一样。

所以现在我们有一个更薄的&#39;模特,一个胖子&#39;控制器(即它包含最好保存在其他地方的逻辑),当我们更好地利用Eloquent对象时,我们仍然不是完全OO。

这导致了第二个问题:在这种情况下如何正确实施OOP,更一般地说,如何学习如何做到这一点?

我们的控制器不应该为视图收集数据,它应该给予它(通过依赖注入)。我们需要在模型和控制器之间进行一层抽象,这样我们才能与Eloquent ORM紧密结合。 存储库模式将解决这个问题,并带您进入全OOP天堂。

  • 存储库实现接口,其中列出了(作为 &#39;合同&#39;)存储库必须具有哪些方法。
  • 存储库与模型通信以收集数据 我们的业务逻辑。&#39;
  • 然后,服务提供商绑定接口和存储库 在一起,这样我们就可以注入界面和Laravel了 解决绑定并提供我们的存储库。
  • 最后,将接口注入到__construct方法中 控制器(或者,在Laravel 5中,你可以将它直接注入到 方法,如果整个控制器都不需要它。)

如何设置这些内容部分取决于您的问题中未提及的应用程序详细信息。但是这里有一些很棒的实用资源可供帮助:

这两本书都值得他们付出代价,因为他们对OOP和SOLID原则有了深刻的理解,更重要的是 - 看到它们在行动中,应用于Laravel应用程序。

最后,订阅Laracasts并让Jeffrey Way尽可能地教你所有这些。

祝你好运。