Laravel 5 - 干净的代码,在哪里保存业务逻辑(控制器示例)

Laravel 5 - Clean code, where to keep business logic (controller example)

下面是我的控制器 Admin/MoviesController 的 'store' 方法示例。它已经看起来很大了,'update'方法会更大。

算法是:

  1. 验证 CreateMovieRequest 中的请求数据并创建新电影 包含所有可填写字段。
  2. 上传海报
  3. 填写并保存所有重要但非必需的字段(元标题、元描述..)
  4. 然后是 4 个代码块,解析并附加到流派、演员、导演、国家/地区的电影。
  5. 使用 third-party API
  6. 请求 IMDB 评级

我的问题:

如果您需要在另一个 classes 或项目模块中使用它,您需要考虑如何重新利用代码。首先,您可以这样做:

电影模型,可以改进为:

  • 管理属性的设置方式
  • 在函数中创建漂亮的函数include/manage关系数据

看看Movie是如何实现功能的:

class Movie{

    public function __construct(){

        //If 'Meta Title' is empty, then fill it with the name of the movie
        $this->seo_title = empty($movie->seo_title)
            ? $movie->title 
            : $otherValue;

        //If 'Meta Description' is empty, 
        //then fill it with the description of the movie
        $movie->seo_description = empty($movie->seo_description)
            ? $movie->description 
            : $anotherValue;

        $this->updateKinopoisk();
    }

    /* 
    * Parsing comma separated string of countries and attaching them to movie 
    */
    public function attachCountries($countries){

        foreach($countries as $item) {
            $name = mb_strtolower(trim($item), 'UTF-8');

            $country = Country::where('name', $name)->first();

            if ( empty($country) ) {
                $country = new Country();
                $country->fill(['name' => $name])->save();
            }

            $movie->countries()->attach($country->id);
        }
    }

    /*
     * Update Kinopoisk information
     */
     public function updateKinopoisk(){}

    /*
     * Directors
     */
     public function attachDirectors($directors){ ... }

     /*
      * Actores
      */
      public function attachActors($actors){ ... }

      /*
       * Genders
       */
       public function attachActors($actors){ ... }
}

海报,你可以考虑使用服务提供商(我会展示这个例子,因为我不知道你的海报型号 看起来像):

public class PosterManager{

    public static function upload($file, $movie){
        $poster = \Image::make($file);
        $poster->fit(250, 360, function ($constraint) {
            $constraint->upsize();
        });

         $path = config('app.images') . $movie->id.'/';

         if(! \File::exists($path)) {
            \File::makeDirectory($path);
        }

        $filename = time() . '.' . $file->getClientOriginalExtension();
        $poster->save($path . $filename);

        return $poster;
    }
}

配置文件 尝试使用配置文件存储相关应用程序constanst/data,例如存储电影图像路径:

'images' => storage_path() . '/images/movies/';

现在,您可以在全球范围内调用 $path = config('app.images');。如果需要更改路径,只需设置配置文件即可。

注入的控制器 class。 最后,控制器用作class,您只需要注入代码:

public function store(CreateMovieRequest $request) {
    $movie = Movies::create($request->except('poster'));

    /* Uploading poster */
    if ($request->hasFile('poster')) {
        $file = $request->file('poster');
        $poster = \PosterManager::upload($file, $movie);
        $movie->poster = $poster->filename;
    }

    if (!empty($request->input('genres'))) {
        $genres = explode(',', $request->input('genres'));

        $movie->attachGenders($genders);
    }

    // movie->attachDirectors();
    // movie->attachCountries();

    // Apply all changes
    $movie->save();

    return redirect('/admin/movies');
}