67.重构
- 本系列文章为
laracasts.com
的系列视频教程——Let's Build A Forum with Laravel and TDD 的学习笔记。若喜欢该系列视频,可去该网站订阅后下载该系列视频, 支持正版 ;- 视频源码地址:github.com/laracasts/Lets-Build-a-...;
- 本项目为一个 forum(论坛)项目,与本站的第二本实战教程 《Laravel 教程 - Web 开发实战进阶》 类似,可互相参照。
本节说明
- 对应视频教程第 67 小节:Isolating Knowledge
本节内容
上一节我们利用 Redis 存储了热门话题的信息,这一节我们来做点重构。我们新建一个类文件,将存储和读取缓存的逻辑抽取出来:
forum\app\Trending.php
<?php
namespace App;
use Illuminate\Support\Facades\Redis;
class Trending
{
public function get()
{
return array_map('json_decode',Redis::zrevrange('trending_threads',0,4));
}
public function push($thread)
{
Redis::zincrby('trending_threads',1,json_encode([
'title' => $thread->title,
'path' => $thread->path()
]));
}
}
现在我们可以修改控制器:
forum\app\Http\Controllers\ThreadsController.php
<?php
namespace App\Http\Controllers;
use App\Trending;
.
.
class ThreadsController extends Controller
{
.
.
public function index(Channel $channel,ThreadsFilters $filters,Trending $trending)
{
$threads = $this->getThreads($channel, $filters);
if(request()->wantsJson()){
return $threads;
}
return view('threads.index',[
'threads' => $threads,
'trending' => $trending->get()
]);
}
.
.
public function show($channel,Thread $thread,Trending $trending)
{
if(auth()->check()){
auth()->user()->read($thread);
}
$trending->push($thread);
return view('threads.show',compact('thread'));
}
.
.
}
运行测试:
现在有点小问题要考虑:我们在测试环境和开发环境使用了相同的键来存储缓存。如果你不介意这样做,当然也可以。但是我们仍然来做点重构:
forum\app\Trending.php
<?php
namespace App;
use Illuminate\Support\Facades\Redis;
class Trending
{
public function get()
{
return array_map('json_decode',Redis::zrevrange($this->cacheKey(),0,4));
}
public function push($thread)
{
Redis::zincrby($this->cacheKey(),1,json_encode([
'title' => $thread->title,
'path' => $thread->path()
]));
}
public function cacheKey()
{
return app()->environment('testing') ? 'testing_trending_threads' : 'trending_threads';
}
public function reset()
{
Redis::del($this->cacheKey());
}
}
我们通过cacheKey()
方法,根据不同环境获取不同键名,然后获取或者删除不同环境的缓存。我们来相应修改测试:
forum\tests\Feature\TrendingThreadsTest.php
<?php
namespace Tests\Feature;
use App\Trending;
use Tests\TestCase;
use Illuminate\Foundation\Testing\DatabaseMigrations;
class TrendingThreadsTest extends TestCase
{
use DatabaseMigrations;
protected function setUp()
{
parent::setUp();
$this->trending = new Trending();
$this->trending->reset();
}
/** @test */
public function it_increments_a_thread_score_each_time_it_is_read()
{
$this->assertEmpty($this->trending->get());
$thread = create('App\Thread');
$this->call('GET',$thread->path());
$this->assertCount(1,$trending = $this->trending->get());
$this->assertEquals($thread->title,$trending[0]->title);
}
}
我们来运行该测试:
运行全部测试: