[07]Go设计模式:过滤器模式(FilterPattern)

过滤器模式

一、简介

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

二、代码

package main

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

// Request is the input of the filter
type Request interface{}

// Response is the output of the filter
type Response interface{}

// Filter interface is the definition of the data processing components
// Pipe-Filter structure
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("input data must be string")
	}
	parts := strings.Split(str, sf.delimiter)
	return parts, nil
}


type ToIntFilter struct {
}

func NewToIntFilter() *ToIntFilter {
	return &ToIntFilter{}
}

func (tif *ToIntFilter) Process(data Request) (Response, error) {
	parts, ok := data.([]string)
	if !ok {
		return nil, fmt.Errorf("input data should be []string")
	}
	ret := make([]int, 0)
	for _, part := range parts {
		s, err := strconv.Atoi(part)
		if err != nil {
			return nil, err
		}
		ret = append(ret, s)
	}
	return ret, 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, errors.New("input data should be []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,
	}
}

// call each filter's process function
func (p *Pipeline) Process(data Request) (Response, error) {
	var ret interface{}
	var err error
	for _, filter := range *p.Filters {
		ret, err = filter.Process(data)
		if err != nil {
			return ret, err
		}
		data = ret
	}
	return ret, err
}


func main() {
	//例子中将字符串分割,再转成int,再求和
	split := NewSplitFilter(",")
	converter :=NewToIntFilter()
	sum := NewSumFilter()
	p :=NewPipeline("p1", split, converter, sum)
	ret, err := p.Process("4,5,6")
	if err != nil {
		log.Fatal(err)
	}
	if ret != 15 {
		log.Fatalf("The expected is 6, but the actual is %d", ret)
	}
	fmt.Println(ret)
}

完整代码:https://gitee.com/ncuzhangben/GoStudy/tree/master/go-design-pattern/07-Filter

三、参考链接

1、https://www.runoob.com/design-pattern/filter-pattern.html

posted @ 2019-12-22 13:49  0pandas0  阅读(822)  评论(0编辑  收藏  举报