设计模式 - 过滤器模式
过滤器模式(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) } } |