GO设计模式——9、过滤器模式(结构型)

目录

[过滤器模式(Filter/Criteria Pattern)](#过滤器模式(Filter/Criteria Pattern))

代码实现


过滤器模式(Filter / Criteria Pattern)

过滤器模式(Filter Pattern)或标准模式(Criteria Pattern)是一种设计模式,这种模式允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来。这种类型的设计模式属于结构型模式,它结合多个标准来获得单一标准。可以自由组合不同的过滤条件。

代码实现

Go 复制代码
package main

import (
    "fmt"
    "log"
    "strconv"
    "strings"
)

type Request interface {
}

type Response interface {
}

type Filter interface {
    Process(data Request) (Response, error)
}

type SplitFilter struct {
    delimiter string
}

func NewSplitFilter(delimiter string) *SplitFilter {
    return &SplitFilter{delimiter}
}
func (sf *SplitFilter) Process(data Request) (Response, error) {
    str, ok := data.(string)
    if !ok {
       return nil, fmt.Errorf("输入数据必须为String类型")
    }
    parts := strings.Split(str, sf.delimiter)
    return parts, nil
}

type ToIntFilter struct {
}

func NewToIntFilter() *ToIntFilter {
    return &ToIntFilter{}
}
func (ttf *ToIntFilter) Process(data Request) (Response, error) {
    parts, ok := data.([]string)
    if !ok {
       return nil, fmt.Errorf("输入数据必须为[]String类型")
    }
    res := make([]int, 0)
    for _, part := range parts {
       s, err := strconv.Atoi(part)
       if err != nil {
          return nil, err
       }
       res = append(res, s)
    }
    return res, nil
}

type SumFilter struct {
}

func NewSumFilter() *SumFilter {
    return &SumFilter{}
}
func (sf *SumFilter) Process(data Request) (Response, error) {
    elms, ok := data.([]int)
    if !ok {
       return nil, fmt.Errorf("输入数据必须为[]int类型")
    }
    ret := 0
    for _, elem := range elms {
       ret += elem
    }
    return ret, nil
}

type Pipeline struct {
    Name    string
    Filters *[]Filter
}

func NewPipeline(name string, filters ...Filter) *Pipeline {
    return &Pipeline{
       Name:    name,
       Filters: &filters,
    }
}
func (p *Pipeline) Process(data Request) (Response, error) {
    var res interface{}
    var err error
    for _, filter := range *p.Filters {
       res, err = filter.Process(data)
       if err != nil {
          return res, err
       }
       data = res
    }
    return res, err
}

func main() {
    //将字符串分割,再转成int,再求和
    split := NewSplitFilter(",")
    toInt := NewToIntFilter()
    sum := NewSumFilter()
    p := NewPipeline("p1", split, toInt, sum)
    res, err := p.Process("4,5,6")
    if err != nil {
       log.Fatal(err)
    }
    if res != 15 {
       log.Fatalf("不是预期值:%d", res)
    }
    fmt.Println(res)
}
相关推荐
天天摸鱼的java工程师几秒前
八年 Java 开发经验:反射机制在实际业务中的深度应用解析
java·后端·面试
wjr9205035 分钟前
深入理解Spring Boot中的Filter机制:原理、注册与实战应用
java·spring boot·后端
bobz96512 分钟前
ovs iface-id
后端
熟悉的新风景14 分钟前
SpringBoot使用oshi获取服务器相关信息
服务器·spring boot·后端
天天摸鱼的java工程师18 分钟前
Java 内存模型与垃圾回收场景题实战解析
java·后端
chanalbert19 分钟前
Spring AOP 模块设计文档
后端·spring
CodeSheep22 分钟前
知名开源项目AList疑似被卖,玩家炸锅了!!
前端·后端·程序员
墨尊1 小时前
通过flv.js在网页中拉流进行视频播放
开发语言·javascript·音视频
这里有鱼汤1 小时前
为什么我现在做Python项目都用UV?你看完就懂了
后端·python
面朝大海,春不暖,花不开1 小时前
使用Spring Boot Actuator构建用户应用
java·spring boot·后端