规格模式

2022-10-14  本文已影响0人  三流之路

根据条件查询对象,每一种查找条件定义一个类。

public class User { //姓名
    private String name;  
    private int age;  
    public User(String _name,int _age){
        this.name = _name; this.age = _age;
    }  
    // getter/setter
}

现在有许多 User 对象,根据 name 和 age 之类的条件查询出匹配的对象。

public class UserProvider {
    private ArrayList<User> userList; 
    public UserProvider(ArrayList<User> _userList){
        this.userList = _userList;
    }  
    public ArrayList<User> findUserByAgeThan(int age) {
        ArrayList<User> result = new ArrayList<User>(); 
        for(User u:userList){
            if(u.getAge()>age){ 
                result.add(u);
            }
        }
        return result;
    }  

    public ArrayList<User> findUserByNameEqual(String name) {
        ArrayList<User> result = new ArrayList<User>(); 
        for(User u:userList){
            if(u.getName().equals(name)){
                result.add(u);
            }
        }
    } 
}

两个方法,遍历查询指定名字和年龄大于指定值的用户。

缺点在于增加一种查询条件,就要在 UserProvider 里添加方法,不符合开闭。

所以想把查询条件封装成对象 Condition,这样查询指定姓名的叫 NameEqualCondition,年龄大于指定值的叫 AgeThanCondition,然后自然而然的就写成了下面这样。

public interface Condition {
    public boolean match(User user); // 这个user是否满足我的条件
}
public class NameEqualCondition implements Condition {
    private String name;
    public NameEqualCondition(String name) {
        this.name = name;
    }
    public boolean match(User user) {
        return user.name.equals(name);
    }
}
public class AgeThanCondition implements Condition {
    private int age;
    public AgeThanCondition(int age) {
        this.age = age;
    }
    public boolean match(User user) {
        return user.age > age;
    }
}
public class UserProvider {
    private ArrayList<User> userList; 
    public UserProvider(ArrayList<User> _userList){
        this.userList = _userList;
    }  
    public ArrayList<User> findUser(Condition condition) {
        ArrayList<User> result = new ArrayList<User>(); 
        for(User u:userList){
            if(condition.match(u)){ 
                result.add(u);
            }
        }
        return result;
    }
}

然后一些逻辑关系,比如姓名相等且年龄大于多少,逻辑条件也作为一种 Condition。由于它是两个 Condition 的逻辑关系,所以构造的参数是别的 Condition。比如

public class AndCondition implements Condition {
    private Condition c1;
    private Condition c2;
    public AndCondition(Condition c1, Condition c2) {
        this.c1 = c1;
        this.c2 = c2;
    }
    public boolean match(User user) {
        return c1(user) && c2(user);
    }
}

这内部的参数应该是普通的 Condition,不能是逻辑条件,所以普通的判断条件和逻辑条件,应该分别派生出一个接口出来,两者区分开来,这里就不写了。

// 然后外面这么调用就行了
Condition condition = new AndCondition( new NameEqualCondition("zhangsan"), new AgeThanCondition(15) );
condition.match(user);
上一篇下一篇

猜你喜欢

热点阅读