装饰器模式
发布于: 2020 年 11 月 08 日
golang 设计模式
https://github.com/kaysun/go_design_pattern.git
装饰器模式,在运行期动态地给对象添加额外的职责,比子类更灵活。有两种不同的使用方式,一种为增强功能,一种为添加功能。
添加功能
// package decorator 装饰者模式,在运行期动态地给对象添加额外的指责,比子类更灵活。第二个功能:用于添加功能的装饰模式。
// 若不想修改原来的接口,则可以使用装饰者。go这种语言,若增加接口的方法,则原来实现接口的结构体都需要增加一个新方法,这样就不符合开闭原则了。
package decorator
import "fmt"
// Booker 书的接口
type Booker interface {
// Reading 读书
Reading()
}
// Book 书,实现Booker接口
type Book struct {
}
// Reading 读书,实现Booker接口
func (book Book) Reading() {
fmt.Println("我正在读书")
}
// Underliner 划线接口,装饰者接口
type Underliner interface {
// Booker 继承Booker接口
Booker
// Underline 划线
Underline()
}
// NotesTaker 记笔记接口,装饰者接口
type NotesTaker interface {
// Booker 继承Booker接口
Booker
// TakeNotes 记笔记
TakeNotes()
}
// ConcreteUnderline 具体的划线类,实现Underliner接口
type ConcreteUnderline struct {
// Booker 书的接口对象
Booker Booker
}
// ReadingBooks ConcreteUnderline提供读书的方法,包装了Booker接口
func (underline ConcreteUnderline) Reading() {
underline.Booker.Reading()
}
// Underline 划线,实现Underliner接口
func (underline ConcreteUnderline) Underline() {
fmt.Println("我正在划线")
}
// ConcreteNotesTake 具体的记笔记类,实现NotesTaker接口
type ConcreteNotesTake struct {
// Booker 书的接口对象
Booker Booker
}
// ReadingBooks ConcreteNotesTake提供读书的方法,包装了Booker接口
func (notesTake ConcreteNotesTake) Reading() {
notesTake.Booker.Reading()
}
// Underline 划线,实现NotesTaker接口
func (notesTake ConcreteNotesTake) TakeNotes() {
fmt.Println("我正在记笔记")
}
复制代码
package decorator
import (
"fmt"
"testing"
)
func Test(t *testing.T) {
t.Run("decorator_add: ", DecoratorAdd)
}
func DecoratorAdd(t *testing.T) {
var book Booker
book = &Book{}
book.Reading()
fmt.Println("============")
var notesTake NotesTaker
notesTake = &ConcreteNotesTake{Booker: book}
notesTake.Reading()
notesTake.TakeNotes()
fmt.Println("============")
var Underline Underliner
Underline = &ConcreteUnderline{Booker: book}
Underline.Reading()
Underline.Underline()
}
复制代码
输出
我正在读书
============
我正在读书
我正在记笔记
============
我正在读书
我正在划线
复制代码
增强功能
// package decorator 装饰者模式,在运行期动态地给对象添加额外的指责,比子类更灵活。第一个功能:用于增强功能的装饰模式。
package decorator
// HappinessIndex 幸福指数接口
type HappinessIndex interface {
// GetHappinessIndex 获取幸福指数
GetHappinessIndex() int
}
// MySelf 我自己,实现HappinessIndex接口。当然,MySelf也可以嵌套HappinessIndex接口。
type MySelf struct{}
// GetHappinessIndex 获取幸福指数,实现HappinessIndex接口
func (myself MySelf) GetHappinessIndex() int {
return 100
}
// DrinkCoffee 喝咖啡
type DrinkCoffee struct {
// HappinessIndex 幸福指数对象
HappinessIndex HappinessIndex
}
// GetHappinessIndex 获取幸福指数,实现HappinessIndex接口
func (coffee DrinkCoffee) GetHappinessIndex() int {
return coffee.HappinessIndex.GetHappinessIndex() + 20
}
// EatFriedChicken 吃炸鸡,实现HappinessIndex接口
type EatFriedChicken struct {
// HappinessIndex 幸福指数对象
HappinessIndex HappinessIndex
}
// GetHappinessIndex 获取幸福指数,实现HappinessIndex接口
func (friedChicken EatFriedChicken) GetHappinessIndex() int {
return friedChicken.HappinessIndex.GetHappinessIndex() + 50
}
复制代码
package decorator
import (
"fmt"
"testing"
)
func Test(t *testing.T) {
t.Run("decorator_strengthen: ", DecoratorStrengthen)
}
func DecoratorStrengthen(t *testing.T) {
var myself, drinkCoffee, eatFriedChicken HappinessIndex
myself = &MySelf{}
fmt.Println(fmt.Sprintf("我的幸福指数是:%d", myself.GetHappinessIndex()))
drinkCoffee = &DrinkCoffee{HappinessIndex: MySelf{}}
fmt.Println(fmt.Sprintf("喝了咖啡后,我的幸福指数是:%d", drinkCoffee.GetHappinessIndex()))
eatFriedChicken = &EatFriedChicken{HappinessIndex: drinkCoffee}
fmt.Println(fmt.Sprintf("吃了炸鸡,喝了咖啡后,我的幸福指数是:%d", eatFriedChicken.GetHappinessIndex()))
fmt.Println("============")
}
复制代码
输出
我的幸福指数是:100
喝了咖啡后,我的幸福指数是:120
吃了炸鸡,喝了咖啡后,我的幸福指数是:170
============
复制代码
划线
评论
复制
发布于: 2020 年 11 月 08 日阅读数: 24
版权声明: 本文为 InfoQ 作者【猴子胖胖】的原创文章。
原文链接:【http://xie.infoq.cn/article/b10a9aa17bc1d447a940df3e9】。文章转载请联系作者。
猴子胖胖
关注
6年ios开发,1年golang开发 2020.05.09 加入
还未添加个人简介
评论