DAY 27:Chain of Responsibility,将实作透过串串乐串起来

什麽是 Chain of Responsibility?

将 if...else 的行为抽象成物件,将 if...else 行为以物件串接的方式来操作

问题情境

在 PS5 的设计中,假设会依照不同的游戏调整晶片,例如 3D 游戏会启用 3D 模式、高效能显示会加强显示晶片、音乐有用环绕音效会启用音效晶片的环绕音效模式,

会设计成以下的 code:

package main

import "fmt"

type Game struct {
	Name      string
	Type      string
	GraphType string
	AudioType string
}

type PS5 struct{}

func (PS5) PlayGame(game Game) {
	if game.Type == "3D游戏" {
		fmt.Println("3D模式")
	}
	if game.GraphType == "高效能显示" {
		fmt.Println("加强显示晶片")
	}
	if game.AudioType == "环绕音效" {
		fmt.Println("环绕音效模式")
	}
	fmt.Printf("play %s", game.Name)
}

func main() {
	ps5 := PS5{}
	ps5.PlayGame(
		Game{
			Name:      "最终幻想",
			Type:      "3D游戏",
			GraphType: "高效能显示",
			AudioType: "环绕音效",
		},
	)
}

如果要在新增不同的晶片调整,就必须修改PS5{}.PlayGame()的 code,这不符合开闭原则,我们需要一个方式解决。

解决方式

可以在PS5{}新增一个middleware slice 成员,并把调整晶片的逻辑都抽象成GameMiddleware()GraphMiddleware()AudioMiddleware()middlewares,透过PS5{}.AddMiddleware()来新增这些 middleware,在最後PS5{}.PlayGame()的时候再一次运行所有 middleware 并且运行游戏

package main

import "fmt"

type Game struct {
	Name      string
	Type      string
	GraphType string
	AudioType string
}

type PS5 struct {
	middlewares []func(game Game)
}

func (p *PS5) AddMiddleware(middleware func(game Game)) *PS5 {
	p.middlewares = append(p.middlewares, middleware)
	return p
}

func (p PS5) PlayGame(game Game) {
	for _, middleware := range p.middlewares {
		middleware(game)
	}
	fmt.Printf("play %s", game.Name)
}

func GameMiddleware(game Game) {
	if game.Type == "3D游戏" {
		fmt.Println("3D模式")
	}
}

func GraphMiddleware(game Game) {
	if game.GraphType == "高效能显示" {
		fmt.Println("加强显示晶片")
	}
}

func AudioMiddleware(game Game) {
	if game.AudioType == "环绕音效" {
		fmt.Println("环绕音效模式")
	}
}

func main() {
	ps5 := PS5{}
	ps5.
		AddMiddleware(GameMiddleware).
		AddMiddleware(GraphMiddleware).
		AddMiddleware(AudioMiddleware)
	ps5.PlayGame(
		Game{
			Name:      "最终幻想",
			Type:      "3D游戏",
			GraphType: "高效能显示",
			AudioType: "环绕音效",
		},
	)
}

<<:  Day25 - 针对 Metasploitable 3 进行渗透测试(6) - 使用 Meterpreter

>>:  [Day25] 第二十五章-新增空白的point表单 (跨资料查询还有对应细节)

[第十二天]从0开始的UnityAR手机游戏开发-如何在辨识图卡时拨放影片01

小试身手解答: 点击File→Save As... 跳出此视窗,将场景命名为ARVideo储存在此 ...

从零开始学习3D游戏开发:程序基础 Part.3 回圈

这是 Roblox 从零开始系列,入门章节的第六个单元,在这个单元你将学到 Lua 程序语言中非常重...

媒体分析为公司带来的5项好处及4个常见使用情境

近几年,媒体产业当中,以及社群软件的应用,使得影片、声音和图像这些不同形式的内容正飞速的增长。不管是...

【Day13-计数】如何快速统计资料出现频率?——使用Counter或groupby快速计算元素出现个数

当拿到资料之後,我通常的第一步一定是先看一下这笔资料大致长什麽样子 这个时候有了能统计每个类别出现了...

[第22天]理财达人Mx. Ada-MACD 指标

前言 本文说明MACD技术指标。 MACD 指标 MACD指标(Moving Average Con...