範例:影片製作大師(樣板方法模式)

Pattern: 樣板方法模式

Class Diagram: 影片製作大師


情境:以下是某攝影棚的影片製作方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php

namespace App\TemplateMethodPattern\Video;

use App\TemplateMethodPattern\Video\UnboxVideo;

class Program
{
public function makeUnboxVideo()
{
return '選擇開箱項目、拍攝、剪輯出個人開箱的風格、上傳影片';
}

public function makeTutorialVideo()
{
return '設計教學內容、拍攝、剪輯出個人教學的風格、上傳影片';
}

public function makeStoryVideo()
{
return '選擇故事主題、拍攝、剪輯出個人說故事的風格、上傳影片';
}
}

老闆覺得影片製作,有些相同的環節,
希望我們開發程式解決,增加影片產生效率。


需求一:找出共同點,寫出樣板供大家使用

研究後發現,無論是哪種類型的影片,
製作上大致可以歸類出四個步驟:

  1. 主題發想
  2. 影片拍攝
  3. 剪輯
  4. 上傳

由於公司影片大多於攝影棚拍攝,且上傳的平台相同,
各個類型影片的差異,主要是在主題發想剪輯

  • 我們以此為基礎,設計出樣板
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    <?php

    namespace App\TemplateMethodPattern\Video;

    abstract class BasicVideo
    {
    public function make()
    {
    return $this->generateIdeas() . '、' .
    $this->shoot() . '、' .
    $this->editing() . '、' .
    $this->upload();
    }

    protected function shoot()
    {
    return '拍攝';
    }

    protected function upload()
    {
    return '上傳影片';
    }

    abstract protected function generateIdeas();

    abstract protected function editing();
    }

在make()方法中,我們定義了一個影片產生的流程。

而拍攝與上傳是每種類型影片的共同行為,
我們定義在shoot()方法及upload()方法中。


需求二:替各種類型的影片不同的部分作客製化

  • 首先是開箱型影片
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php

namespace App\TemplateMethodPattern\Video;

use App\TemplateMethodPattern\Video\BasicVideo;

class UnboxVideo extends BasicVideo
{
protected function generateIdeas()
{
return '選擇開箱項目';
}

protected function editing()
{
return '剪輯出個人開箱的風格';
}
}

  • 接著是教學型影片
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php

namespace App\TemplateMethodPattern\Video;

use App\TemplateMethodPattern\Video\BasicVideo;

class TutorialVideo extends BasicVideo
{
protected function generateIdeas()
{
return '設計教學內容';
}

protected function editing()
{
return '剪輯出個人教學的風格';
}
}

  • 再來是故事型影片
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php

namespace App\TemplateMethodPattern\Video;

use App\TemplateMethodPattern\Video\BasicVideo;

class StoryVideo extends BasicVideo
{
protected function generateIdeas()
{
return '選擇故事主題';
}

protected function editing()
{
return '剪輯出個人說故事的風格';
}
}

  • 最後修改原本的程式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php

namespace App\TemplateMethodPattern\Video;

use App\TemplateMethodPattern\Video\UnboxVideo;

class Program
{
public function makeUnboxVideo()
{
$unboxVideo = new UnboxVideo();
return $unboxVideo->make();
}

public function makeTutorialVideo()
{
$tutorialVideo = new TutorialVideo();
return $tutorialVideo->make();
}

public function makeStoryVideo()
{
$storyVideo = new StoryVideo();
return $storyVideo->make();
}
}

[單一職責原則]
我們將製作影片的流程製作影片的方式視作兩種不同的職責。

[開放封閉原則]
除了流程之外,不同影片的類型也歸類到不同的子類,
未來新增/修改影片類型製作方式時,也不會互相影響。

[依賴反轉原則]
客戶端的程式碼依賴抽象的父類基本影片。
不同類型的影片類別實作抽象的父類基本影片。

ʕ •ᴥ•ʔ:一個簡單易懂的模式,背後隱藏了很多設計模式的原則。