设计模式 - 适配器
设计模式 - 组合模式

设计模式 - 过滤器模式

violet posted @ 5 年前 in 笔记 with tags Design Pattern Golang , 211 阅读

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package main
 
import "fmt"
 
type Person struct {
    Name         string
    Gender       string
    MarialStatus string
}
 
func NewPerson(name, gender, marialStatus string) *Person {
    return &Person{
        Name:         name,
        Gender:       gender,
        MarialStatus: marialStatus,
    }
}
 
func (p *Person) GetName() string {
    return p.Name
}
 
func (p *Person) GetGender() string {
    return p.Gender
}
 
func (p *Person) GetMarialStatus() string {
    return p.MarialStatus
}
 
type Criteria interface {
    MeetCriteria(people []*Person) []*Person
}
 
type MaleCriteria struct{}
 
func (m *MaleCriteria) MeetCriteria(people []*Person) []*Person {
    male := []*Person{}
    for _, p := range people {
        if p.Gender == "male" {
            male = append(male, p)
        }
    }
 
    return male
}
 
type FemaleCriteria struct{}
 
func (f *FemaleCriteria) MeetCriteria(people []*Person) []*Person {
    female := []*Person{}
    for _, p := range people {
        if p.Gender == "female" {
            female = append(female, p)
        }
    }
 
    return female
}
 
type SingleCriteria struct{}
 
func (s *SingleCriteria) MeetCriteria(people []*Person) []*Person {
    single := []*Person{}
    for _, p := range people {
        if p.MarialStatus == "single" {
            single = append(single, p)
        }
    }
 
    return single
}
 
type AndCriteria struct {
    Criteria      Criteria
    OtherCriteria Criteria
}
 
func (a *AndCriteria) MeetCriteria(people []*Person) []*Person {
    result1 := a.Criteria.MeetCriteria(people)
    return a.OtherCriteria.MeetCriteria(result1)
}
 
type OrCriteria struct {
    Criteria      Criteria
    OtherCriteria Criteria
}
 
func (o *OrCriteria) MeetCriteria(people []*Person) []*Person {
    result1 := o.Criteria.MeetCriteria(people)
    hash := map[string]*Person{}
    for _, p := range result1 {
        hash[p.Name] = p
    }
    result2 := o.OtherCriteria.MeetCriteria(people)
    for _, p := range result2 {
        if _, ok := hash[p.Name]; !ok {
            result2 = append(result2, p)
        }
    }
 
    return result2
}
 
func main() {
    people := []*Person{}
    people = append(people, &Person{
        Name: "1", Gender: "male", MarialStatus: "single",
    })
    people = append(people, &Person{
        Name: "2", Gender: "female", MarialStatus: "single",
    })
    people = append(people, &Person{
        Name: "3", Gender: "male", MarialStatus: "married",
    })
    people = append(people, &Person{
        Name: "4", Gender: "male", MarialStatus: "married",
    })
    people = append(people, &Person{
        Name: "5", Gender: "female", MarialStatus: "single",
    })
    people = append(people, &Person{
        Name: "6", Gender: "female", MarialStatus: "single",
    })
    people = append(people, &Person{
        Name: "7", Gender: "female", MarialStatus: "single",
    })
 
    male := &MaleCriteria{}
    female := &FemaleCriteria{}
    single := &SingleCriteria{}
    singleFemale := &AndCriteria{single, female}
    singleOrMale := &OrCriteria{single, male}
 
    fmt.Println("===== male =====")
    for _, p := range male.MeetCriteria(people) {
        fmt.Println(p)
    }
    fmt.Println("===== female =====")
    for _, p := range female.MeetCriteria(people) {
        fmt.Println(p)
    }
    fmt.Println("===== single =====")
    for _, p := range single.MeetCriteria(people) {
        fmt.Println(p)
    }
    fmt.Println("===== single female =====")
    for _, p := range singleFemale.MeetCriteria(people) {
        fmt.Println(p)
    }
    fmt.Println("===== single or male =====")
    for _, p := range singleOrMale.MeetCriteria(people) {
        fmt.Println(p)
    }
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter