设计模式之过滤器模式(7)

作者: _兜兜转转_ | 来源:发表于2019-05-21 18:01 被阅读1次

    过滤器模式

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

    实现

    我们将创建一个 Person 对象、Criteria 接口和实现了该接口的实体类,来过滤 Person 对象的列表。CriteriaPatternDemo,我们的演示类使用 Criteria 对象,基于各种标准和它们的结合来过滤 Person 对象的列表。

    过滤器模式的 UML 图

    创建一个类,在该类上应用标准。

    @interface Person_2 : NSObject
    @property (nonatomic,copy,readonly) NSString *name;
    @property (nonatomic,copy,readonly) NSString *gender;
    @property (nonatomic,copy,readonly) NSString *maritalStatus;
    
    - (NSString *)getName;
    - (NSString *)getGender;
    - (NSString *)getMaritalStatus;
    - (instancetype)initWithName:(NSString *)name gender:(NSString *)gender maritalStatus:(NSString *)maritalStatus;
    @end
    

    步骤 2
    为标准(Criteria)创建一个接口。

    @protocol Criteria <NSObject>
    -(NSMutableArray<Person_2 *> *)meetCriteria:(NSMutableArray<Person_2 * > *)list;
    @end
    

    步骤 3
    创建实现了 Criteria 接口的实体类。

    @interface CriteriaMale : NSObject <Criteria>
    - (NSMutableArray<Person_2 *> *)meetCriteria:(NSMutableArray<Person_2 *> *)list;
    @end
    @interface CriteriaSingle : NSObject <Criteria>
    - (NSMutableArray<Person_2 *> *)meetCriteria:(NSMutableArray<Person_2 *> *)list;
    @end
    @implementation CriteriaMale
    
    -(NSMutableArray *)meetCriteria:(NSMutableArray *)list{
        NSMutableArray *newList=[NSMutableArray array];
        for (Person_2 *item in list) {
            if ([item.getGender.uppercaseString isEqualToString:@"MALE"]) {
                [newList addObject:item];
            }
        }
        return newList;
    }
    @end
    @implementation CriteriaSingle
    
    -(NSMutableArray *)meetCriteria:(NSMutableArray *)list{
        NSMutableArray *newList=[NSMutableArray array];
        for (Person_2 *item in list) {
            if ([item.getMaritalStatus.lowercaseString isEqualToString:@"single"]) {
                [newList addObject:item];
            }
        }
        return newList;
    }
    @end
    

    and 和or

    @interface andCriteria : NSObject <Criteria>
    
    @property (nonatomic,strong) id<Criteria> _Nullable criteria;
    @property (nonatomic,strong) id<Criteria> _Nullable otherCriteria;
    
    - (NSMutableArray<Person_2 *> *)meetCriteria:(NSMutableArray <Person_2 *>*)list;
    
    @end
    @interface orCriteria : NSObject <Criteria>
    
    @property (nonatomic,strong) id<Criteria> _Nullable criteria;
    @property (nonatomic,strong) id<Criteria> _Nullable otherCriteria;
    
    - (NSMutableArray<Person_2 *> *)meetCriteria:(NSMutableArray <Person_2 *>*)list;
    
    @end
    
    @implementation andCriteria
    
    - (NSMutableArray<Person_2 *> *)meetCriteria:(NSMutableArray <Person_2 *>*)list{
        NSMutableArray<Person_2 *> *newList2=[NSMutableArray array];
        [newList2 addObjectsFromArray:[self.criteria performSelector:@selector(meetCriteria:)
                                                          withObject:list]];
        return [self.otherCriteria performSelector:@selector(meetCriteria:) withObject:newList2];
    }
    @end
    @implementation orCriteria
    
    - (NSMutableArray<Person_2 *> *)meetCriteria:(NSMutableArray <Person_2 *>*)list{
        NSMutableArray<Person_2 *> *newList1=[NSMutableArray array];
        NSMutableArray<Person_2 *> *newList2=[NSMutableArray array];
        [newList2 addObjectsFromArray:[self.criteria performSelector:@selector(meetCriteria:)
                                                          withObject:list]];
        [newList1 addObjectsFromArray:[self.criteria performSelector:@selector(meetCriteria:)
                                                          withObject:list]];
        for (Person_2 *item in newList2) {
            if ([newList1 containsObject:item] == NO) {
                [newList1 addObject:item];
            }
        }
        return newList1;
    }
    @end
    

    步骤4
    使用不同的标准(Criteria)和它们的结合来过滤 Person 对象的列表。

    NSMutableArray *list1 =[NSMutableArray array];
        [list1 addObject:[[Person_2 alloc]initWithName:@"Join" gender:@"Male" maritalStatus:@"single"]];
        [list1 addObject:[[Person_2 alloc]initWithName:@"Bob" gender:@"Single" maritalStatus:@"single"]];
        [list1 addObject:[[Person_2 alloc]initWithName:@"Mike" gender:@"Single" maritalStatus:@"Male"]];
        
        CriteriaMale *male=[CriteriaMale new];
        CriteriaSingle *signle=[CriteriaSingle new];
        andCriteria *and=[andCriteria new];
        orCriteria *or=[orCriteria new];
        NSLog(@"Males:%@",[male meetCriteria:list1]);
        NSLog(@"Single:%@",[signle meetCriteria:list1]);
        and.criteria = male;
        and.otherCriteria = signle;
        NSLog(@"and:%@",[and meetCriteria:list1]);
        or.criteria = male;
        or.otherCriteria = signle;
        NSLog(@"or:%@",[or meetCriteria:list1]);
    

    步骤 5
    执行程序,输出结果:

    2019-05-21 17:55:31.172443+0800 test[82594:19349590] Males:(
        "<Person_2: 0x6000001a00e0>"
    )
    2019-05-21 17:55:31.172659+0800 test[82594:19349590] Single:(
        "<Person_2: 0x6000001a00e0>",
        "<Person_2: 0x6000001a0100>"
    )
    2019-05-21 17:55:31.172819+0800 test[82594:19349590] and:(
        "<Person_2: 0x6000001a00e0>"
    )
    2019-05-21 17:55:31.172955+0800 test[82594:19349590] or:(
        "<Person_2: 0x6000001a00e0>"
    )
    

    过滤器比较简单,就是将过滤的条件封装成抽象类,然后继承这个抽象类,可以封装各种各样的条件,最终返回想要的结果。

    参考资料
    runoob

    相关文章

      网友评论

        本文标题:设计模式之过滤器模式(7)

        本文链接:https://www.haomeiwen.com/subject/wngjzqtx.html