责任链模式

组成:由多个处理器及处理器处理标志串联组成

作用:常用于处理流水线事务,利用多个处理器对同一个对象进行处理,可以利用各处理器开关

场景:常见逻辑层处理逻辑:获取参数、fetch数据、逻辑处理数据、返回参数一系列数据处理

优点:将复杂的流水线处理逻辑简化为一个个单元,操作较为便捷,可以随意在处理器之间串联穿插新处理器

package burden_chain

import "fmt"

/*
责任链模式
组成:由多个处理器及处理器处理标志串联组成
作用:常用于处理流水线事务,利用多个处理器对同一个对象进行处理,可以利用各处理器开关
场景:常见的获取参数、fetch数据、逻辑处理数据、返回参数一系列数据连续化处理
优点:将复杂的流水线处理逻辑简化为一个个单元,操作较为便捷,可以随意在处理器之间串联穿插新处理器
*/ // CalProcessor 处理器抽象接口
type CalProcessor interface {
SetNextProcessor(processor CalProcessor)
ProcessFor(calIdentity *CalIdentity)
} // CalIdentity 处理对象实体
type CalIdentity struct {
A int
B int
sum int
hasGetA bool // GetAProcessor开关:是否获取到A
hasGetB bool // GetBProcessor开关:是否获取到B
hasAdd bool // SumProcessor开关:A与B是否相加
isComplete bool // CompleteProcessor开关:完成计算
} // baseCalProcessor 基类实现CalProcessor
type baseCalProcessor struct {
nextCalProcessor CalProcessor
} // SetNextProcessor 用于串联处理器
func (b *baseCalProcessor) SetNextProcessor(processor CalProcessor) {
b.nextCalProcessor = processor
} // ProcessFor 用于承接处理器的执行逻辑
func (b *baseCalProcessor) ProcessFor(calIdentity *CalIdentity) {
if b.nextCalProcessor != nil {
b.nextCalProcessor.ProcessFor(calIdentity)
}
} // GetAProcessor 获取数字A处理器
type GetAProcessor struct {
baseCalProcessor
} func (g *GetAProcessor) ProcessFor(calIdentity *CalIdentity) {
if !calIdentity.hasGetA {
fmt.Println("getting number A.")
}
fmt.Println("A")
calIdentity.hasGetA = true
g.nextCalProcessor.ProcessFor(calIdentity)
} // GetBProcessor 获取数字B处理器
type GetBProcessor struct {
baseCalProcessor
} func (g *GetBProcessor) ProcessFor(calIdentity *CalIdentity) {
if !calIdentity.hasGetA {
fmt.Println("didn't get number A.")
return
}
fmt.Println("B")
calIdentity.hasGetB = true
g.nextCalProcessor.ProcessFor(calIdentity)
} // SumProcessor 加法处理器
type SumProcessor struct {
baseCalProcessor
} func (g *SumProcessor) ProcessFor(calIdentity *CalIdentity) {
if !calIdentity.hasGetA || !calIdentity.hasGetB {
fmt.Println("didn't get number A or B")
return
}
fmt.Println("A plus B")
calIdentity.hasAdd = true
g.nextCalProcessor.ProcessFor(calIdentity)
} // CompleteProcessor 完成处理器
type CompleteProcessor struct {
baseCalProcessor
} func (c *CompleteProcessor) ProcessFor(calIdentity *CalIdentity) {
if !calIdentity.hasGetA || !calIdentity.hasGetB || !calIdentity.hasAdd {
fmt.Println("cal not done.")
return
}
fmt.Println("done")
calIdentity.isComplete = true
return
}

测试类

package burden_chain

import "testing"

func TestChainResponsibility(t *testing.T) {
calProcessor := BuildCalProcessorChain()
calIdentity := &CalIdentity{
A: 0,
B: 0,
sum: 0,
hasGetA: false,
hasGetB: true,
hasAdd: false,
isComplete: false,
}
calProcessor.ProcessFor(calIdentity)
} // BuildCalProcessorChain: GetAProcessor -> GetBProcessor -> SumProcessor -> CompleteProcessor
func BuildCalProcessorChain() CalProcessor {
completeCheckNode := &CompleteProcessor{} sumCheckNode := &SumProcessor{}
sumCheckNode.SetNextProcessor(completeCheckNode) getBCheckNode := &GetBProcessor{}
getBCheckNode.SetNextProcessor(sumCheckNode) getACheckNode := &GetAProcessor{}
getACheckNode.SetNextProcessor(getBCheckNode) return getACheckNode
}

命令模式

组成:接受者、指令触发器

作用:将请求方法参数化,将指令抽象,便于在指令与指令之间建立独立的逻辑操作关系

场景:适用于任务定制需求,比如818活动等等,在特点的时间节点,使用特定的功能需求。

优点:将指令单元化,通过统一的的Execute接口方法进行调用,屏蔽各个请求的差异,便于多命令组装、回滚,屏蔽各个请求的差异

接受者

package order_pattern

type ReceiverA struct {
height int
width int
} func (s *ReceiverA) SetHeight(height int) {
s.height = height
} func (s *ReceiverA) SetWidth(width int) {
s.width = width
} func (s *ReceiverA) Shutdown() string {
return "shut down this formulation."
}

指令触发器

package order_pattern

import "fmt"

/*
命令模式
组成:接受者、指令触发器
作用:将请求方法参数化,将指令抽象,便于在指令与指令之间建立独立的逻辑操作关系
优点:将指令单元化,通过统一的的Execute接口方法进行调用,屏蔽各个请求的差异,便于多命令组装、回滚,屏蔽各个请求的差异
*/ type CalCommand interface {
Execute() string
} // CalCircleCommand 计算周长
type CalCircleCommand struct {
receiver *ReceiverA
} // 指令将接受者内嵌
func NewCalCircleCommand(receiver *ReceiverA) *CalCircleCommand {
return &CalCircleCommand{receiver: receiver}
} // 利用各个指令内置方法,将不同指令的执行过程屏蔽,便于扩展
func (c *CalCircleCommand) Execute() string {
c.receiver.SetWidth(2)
c.receiver.SetHeight(3)
return fmt.Sprintf("the circle of receiver is %.2f", float64(2*(c.receiver.width+c.receiver.height)))
} // CalAreaCommand 计算面积
type CalAreaCommand struct {
receiver *ReceiverA
} func NewCalAreaCommand(receiver *ReceiverA) *CalAreaCommand {
return &CalAreaCommand{receiver: receiver}
} func (c *CalAreaCommand) Execute() string {
c.receiver.SetWidth(2)
c.receiver.SetHeight(3)
return fmt.Sprintf("the area of receiver is %.2f", float64(c.receiver.height*c.receiver.width))
} type CommandInvoker struct {
calCommand CalCommand
} func (c *CommandInvoker) SetCommand(calCommand CalCommand) {
c.calCommand = calCommand
} func (c *CommandInvoker) ExecuteCommand() string {
return c.calCommand.Execute()
}

测试类

package order_pattern

import (
"fmt"
"testing"
) func TestOrderPattern(t *testing.T) {
receiver := new(ReceiverA)
commandInvoker := new(CommandInvoker) circleCommand := NewCalCircleCommand(receiver)
commandInvoker.SetCommand(circleCommand)
fmt.Println(commandInvoker.ExecuteCommand()) areaCommand := NewCalAreaCommand(receiver)
commandInvoker.SetCommand(areaCommand)
fmt.Println(commandInvoker.ExecuteCommand())
}

迭代器模式

组成:创建迭代器的工厂方法接口Iterable、迭代器本身本身的接口memberIterator

作用:用于在不暴露集合底层表现形式的情况下遍历集合中的所有元素,即在迭代器的帮助下,客户端可以用一个迭代器接口以相似的方法遍历不同集合中的元素

场景:适用于为迭代遍历来自两个及以上不同类型的集合中的元素,无视集合的底层类型,只通过暴露出的Next和HasNext来访问元素

实体类

package iterator_pattern

import "fmt"

// Member 成员抽象接口
type Member interface {
Info() string
} // Teacher 教师实体
type Teacher struct {
Name string
Subject string
} // NewTeacher 创建教师实体
func NewTeacher(name, subject string) *Teacher {
return &Teacher{
Name: name,
Subject: subject,
}
} // Info 返回教师信息
func (t *Teacher) Info() string {
return fmt.Sprintf("%s老师负责的科目-%s", t.Name, t.Subject)
} // Student 学生实体
type Student struct {
Name string
SumScore int
} // NewStudent 创建学生实体
func NewStudent(name string, score int) *Student {
return &Student{
Name: name,
SumScore: score,
}
} // Info 返回学生信息
func (s *Student) Info() string {
return fmt.Sprintf("%s同学考试分数:%d", s.Name, s.SumScore)
}

迭代器

package iterator_pattern

/*
迭代器模式
组成:创建迭代器的工厂方法接口Iterable、迭代器本身本身的接口memberIterator
作用:用于在不暴露集合底层表现形式的情况下遍历集合中的所有元素,即在迭代器的帮助下,客户端可以用一个迭代器接口以相似的方法遍历不同集合中的元素
场景:适用于为迭代遍历来自两个及以上不同类型的集合中的元素,无视集合的底层类型,只通过暴露出的Next和HasNext来访问元素
*/ // Iterator 迭代器抽象接口
type Iterator interface {
Next() Member
HasNext() bool
} // memberIterator 迭代器实现类
type memberIterator struct {
class *Class
index int
} // Next 获取迭代器中的下一个元素
func (m *memberIterator) Next() Member {
if m.index == -1 { // 若游标是-1,则返回老师
m.index++
return m.class.Teacher
} student := m.class.Students[m.index] // 游标大于等于0,则返回学生
m.index++
return student
} // HasNext 判断是否存在下一个元素
func (m *memberIterator) HasNext() bool { // 判断是否还有剩余需要迭代的元素
return m.index < len(m.class.Students)
} // Iterable 可迭代集合接口,实现此接口返回迭代器
type Iterable interface {
CreateIterator() Iterator
} // Class 包括班级id、老师和同学
type Class struct {
Id int
Teacher *Teacher
Students []*Student
} // NewClass 根据班级id、老师创建班级
func NewClass(id int, teacherName, subject string) *Class {
return &Class{
Id: id,
Teacher: NewTeacher(teacherName, subject),
}
} // GetClassID 获取班级id
func (c *Class) GetClassID() int {
return c.Id
} // AddStudent 增加学生
func (c *Class) AddStudent(students ...*Student) {
c.Students = append(c.Students, students...)
} // CreateIterator 创建班级迭代器
// 迭代器两要素:班级实体、迭代索引
func (c *Class) CreateIterator() Iterator {
return &memberIterator{
class: c, // 待迭代容器
index: -1, // 迭代索引初始化为-1,从老师开始迭代
}
}

测试类

package iterator_pattern

import (
"fmt"
"testing"
) func TestIterator(t *testing.T) {
class := NewClass(1, "cjh", "CS")
class.AddStudent(NewStudent("张三", 410),
NewStudent("李四", 400)) fmt.Printf("%d班级成员如下:\n", class.GetClassID())
classIterator := class.CreateIterator()
for classIterator.HasNext() {
member := classIterator.Next()
fmt.Println(member.Info())
}
}

最新文章

  1. Xamarin.IOS之快速入门
  2. 【HDU】3506 Monkey Party
  3. java 15 - 9 集合框架之 栈、队列、数组 和 链表
  4. HDU(1853),最小权匹配,KM
  5. 获取Asp.net GridView控件当中总的记录数量
  6. [转]python起步之卡尔曼滤波
  7. js压缩、混淆和加密
  8. Chrome浏览器插件VisualEvent,可以方便的查看页面绑定的事件
  9. 读书笔记之 - javascript 设计模式 - 门面模式
  10. SQL VIEW(视图)
  11. 团队作业10——复审和事后分析(Beta版本)
  12. javascript的数组之slice()
  13. 更改MAC地址,突破公司绑定MAC地址的限制
  14. detail
  15. [c/c++] programming之路(21)、字符串(二)
  16. 代理ARP--善意的欺骗
  17. 高通Trustzone and QSEE介绍
  18. 生成word附件和word域动态赋值
  19. 09 - JavaSE之线程
  20. 简单计算器的C实现-函数指针,main函数传参

热门文章

  1. 开源持续测试平台--MerterSphere
  2. 分时问候——时间类、if语句
  3. 在orangepi 3 lts上使用SmartCardReader(读卡器)
  4. ASP.NET Core 部署在Docker容器当中(1)
  5. Deer_GF之IOS出热更包
  6. SQL Server查看端口号及修改端口号
  7. React-Navigation 5.x 的 demo案例
  8. 基于excel的自动化框架
  9. pkill 直接对进程对名字进行操作,可以同时杀死多个进程。
  10. docker compose服务编排简介、基于发布包构建多个webapi容器 和 基于镜像实现Nginx反向代理webapi