上天赋予的生命,就是要为人类的繁荣和平和幸福而奉献。——松下幸之助
本节我们要学习的设计模式叫做一装饰器模式, 何为装饰器模式?假如我们现在有一个视频video需要播放,如果在video播放上加上弹幕,那我们的视频播放还是之前的播放,只不过在原有播放功能上加入了弹幕功能,同样地,我们可以在视频播放上加入3D效果,这样就有了3D播放功能。**这种在原有基础上进行装饰,来添加新的功能的模式 其实就叫做装饰器模式,简称装饰模式。**最直观地就是我们买房后的装修,无非是对原有对象(房子)的一种额外装饰,我们在开头就讲过,软件设计模式其实是从建筑领域延申过来的,这样看来,一点没错。
下面我们列举一个比较简 单的例子,争取以最通俗的语言进行模式的讲解。
示例程序的功能是为了给视频播放添加弹幕功能,所谓的弹幕,我们这里比较简单只是单纯的演示使用,就是在原有视频内容的基础.上添加弹幕内容,听起来是不是很炫,其实比较简单,我们一步步来看,首先是我们的示例程序的类图说明:
先来看看抽象类图
具体类图:
import (
"fmt"
"time"
)
type MediaPlayer interface {
GetMediaName() string
GetMediaSeconds() int
GetMediaContent() string
play()
}
type VideoPlay struct {
MediaPlayer
videoContent string
videoName string
}
func (v *VideoPlay) GetMediaName() string {
return v.videoName
}
func (v *VideoPlay) GetMediaSeconds() int {
return len(v.videoContent)
}
func (v *VideoPlay) GetMediaContent() string {
return v.videoContent
}
// 模拟媒体播放
func (m *VideoPlay) play() {
fmt.Println("Media:",m.GetMediaName(),
"(累计时长:",m.GetMediaSeconds(),"秒)正在播放")
for i:=0;i<m.GetMediaSeconds();i++ {
time.Sleep(time.Millisecond)
fmt.Println("当前播放第",i,"秒"+m.GetMediaContent())
}
}
type BarrageVideoPlay struct {
MediaPlayer
}
原有的视频播放太过单调,我们现在想在其基础上加入弹幕播放的功能,BarrageVideoPlay抽象类用于定义我们要实现的弹幕播放功能,该类往往只是一个抽象类,内部持有MediaPlay 类的引用,所以其子类可以比较方便的保留使用MediaPlay的既有功能,该类的代码实现如下
// 实现弹幕播放的类,具体的修饰器的实现类
type BarrageRedVideoPlay struct {
BarrageVideoPlay
}
func (b *BarrageRedVideoPlay) GetMediaName () string {
return b.MediaPlayer.GetMediaName()+"开启弹幕"
}
func (b *BarrageRedVideoPlay)GetMediaSeconds() int {
return b.MediaPlayer.GetMediaSeconds()
}
func (b *BarrageRedVideoPlay)GetMediaContent() string {
return "弹幕中---"+b.MediaPlayer.GetMediaContent()
}
// 模拟媒体播放
func (m *BarrageRedVideoPlay) play() {
fmt.Println("Media:",m.GetMediaName(),
"(累计时长:",m.GetMediaSeconds(),"秒)正在播放")
for i:=0;i<m.GetMediaSeconds();i++ {
time.Sleep(time.Millisecond)
fmt.Println("当前播放第",i,"秒"+m.GetMediaContent())
}
}
mediaplay1 := &VideoPlay{
videoContent: "射雕英雄传",
videoName: "郭靖战欧阳锋",
}
mediaplay := &BarrageRedVideoPlay{BarrageVideoPlay{mediaplay1}}
// 不加修饰时候的播放
mediaplay1.play()
Media: 郭靖战欧阳锋 (累计时长: 15 秒)正在播放
当前播放第 0 秒射雕英雄传
当前播放第 1 秒射雕英雄传
当前播放第 2 秒射雕英雄传
当前播放第 3 秒射雕英雄传
当前播放第 4 秒射雕英雄传
当前播放第 5 秒射雕英雄传
当前播放第 6 秒射雕英雄传
当前播放第 7 秒射雕英雄传
当前播放第 8 秒射雕英雄传
当前播放第 9 秒射雕英雄传
当前播放第 10 秒射雕英雄传
当前播放第 11 秒射雕英雄传
当前播放第 12 秒射雕英雄传
当前播放第 13 秒射雕英雄传
当前播放第 14 秒射雕英雄传
// 添加修饰后的播放
mediaplay.play()
Media: 郭靖战欧阳锋开启弹幕 (累计时长: 15 秒)正在播放
当前播放第 0 秒弹幕中---射雕英雄传
当前播放第 1 秒弹幕中---射雕英雄传
当前播放第 2 秒弹幕中---射雕英雄传
当前播放第 3 秒弹幕中---射雕英雄传
当前播放第 4 秒弹幕中---射雕英雄传
当前播放第 5 秒弹幕中---射雕英雄传
当前播放第 6 秒弹幕中---射雕英雄传
当前播放第 7 秒弹幕中---射雕英雄传
当前播放第 8 秒弹幕中---射雕英雄传
当前播放第 9 秒弹幕中---射雕英雄传
当前播放第 10 秒弹幕中---射雕英雄传
当前播放第 11 秒弹幕中---射雕英雄传
当前播放第 12 秒弹幕中---射雕英雄传
当前播放第 13 秒弹幕中---射雕英雄传
当前播放第 14 秒弹幕中---射雕英雄传