十八、设计模式 之 组合模式

目标:用组合模式实现规则的校验。

首先设计一个规则表,包括member_level、rule_type、condition_key、condition_value等字段。然后用树形结构来拼装规则,根节点是道具规格版本的id,第一层树枝节点是member_level,第二层是rule_type,第三层就是叶节点了,叶节点存储的是个map,map的key是condition_key,value是condition_value。

注意:

1.每个规则类型rule_type下可以有很多对condition_key、condition_value,只要满足其中任意一对即是满足了这种rule_type规则了。 

2.必须符合同一member_level下的所有的rule_type分支,如果某条记录的member_level字段为空,表示该规则适用于所有member_level,因此会将这条规则拼在所有等级的规则树里。

3.通过上述1和2两条规则实现了对规则的与、或的灵活组合,可根据实际业务需求调用不同的RuleOperate类中的静态方法isAllEmptyLeaves对并的规则进行验证、isHaveEmptyLeaves对与的规则进行校验。

 

public abstract class Node<T> {
	private int position;
	private String key;
	private T value;
	
	public Node(int _position,String _key,T _value){
		this.position = _position;
		this.key = _key;
		this.value = _value;
	}
	
	public int getPosition(){
		return position;
	}
	
	public String getKey(){
		return key;
	}
	
	public T getValue(){
		return value;
	}
}

 

public class Branch<T> extends Node{
	ArrayList<Node> children = new ArrayList<Node>();
	
	public Branch(int _position,String _key,T _value){
		super(_position,_key,_value);
	}
	
	public void addChild(Node node) {
		this.children.add(node);
	}
		
	public ArrayList<Node> getChildren() {
		return this.children;
	}

	public void setChildrenSizeTo0(){
		this.children = new ArrayList<Node>();
	}
	
	public void print(){
		String str = "position:"+getPosition()+"   key:"+getKey()+"    +value:"+getValue();
		System.out.println(str);
	}
}


 

public class Leaf<T> extends Node{
	public Leaf(int _position,String _key,T _value){
		super(_position,_key,_value);
	}
	
	public void print(){
		String str = "position:"+getPosition()+"   key:"+getKey()+"    +value:"+getValue();
		System.out.println(str);
	}
}




 

public class RuleOperate {
	
	public static Branch createRuleTree(List<TmallPropRuleConfineDO> lst){
		if(lst!=null&&lst.size()>0){
			Branch root = new Branch(0,"id",lst.get(0).getPropItemId()==0l?lst.get(0).getPropId():lst.get(0).getPropItemId());
            for (TmallPropRuleConfineDO aLst : lst) {
                Node matchNode = findContainsNode(root, aLst);
                //遍历树,如果没有匹配的节点则新建,如果有匹配的节点则延该路径继续遍历
                if (matchNode.getPosition() == 0) {
                    Branch f1 = new Branch(1, "member_level", aLst.getMemberLevel());
                    Branch f2 = new Branch(2, "rule_type", aLst.getRuleType());
                    Map leafPart = new HashMap();
                    leafPart.put(aLst.getConditionKey(), aLst.getConditionValue());
                    Leaf leaf = new Leaf(3, "condition", leafPart);
                    root.addChild(f1);
                    f1.addChild(f2);
                    f2.addChild(leaf);
                } else if (matchNode.getPosition() == 1) {
                    Branch f2 = new Branch(2, "rule_type", aLst.getRuleType());
                    Map leafPart = new HashMap();
                    leafPart.put(aLst.getConditionKey(), aLst.getConditionValue());
                    Leaf leaf = new Leaf(3, "condition", leafPart);
                    ((Branch) matchNode).addChild(f2);
                    f2.addChild(leaf);
                } else if (matchNode.getPosition() == 2) {
                    ArrayList<Node> leafNodes = ((Branch) matchNode).getChildren();
                    if (leafNodes.size() == 0) {
                        Map leafPart = new HashMap();
                        leafPart.put(aLst.getConditionKey(), aLst.getConditionValue());
                        Leaf leaf = new Leaf(3, "condition", leafPart);
                        ((Branch) matchNode).addChild(leaf);
                    } else {
                        Map existPart = (Map) leafNodes.get(0).getValue();
                        existPart.put(aLst.getConditionKey(), aLst.getConditionValue());
                    }
                }
            }
			return root;
		}else{
			return null;
		}
	}
	
	public static Node findContainsNode(Branch branch,TmallPropRuleConfineDO ruleConfineDO){
		Node node = branch;
		ArrayList<Node> children = branch.getChildren();
		int i = 0;
		for(Node node1 :children){
			int position = node1.getPosition();
			if(i<children.size()){
				//依次遍历子节点中的每一个
					switch(position){
					    case 1:
					    	if((Integer)node1.getValue()==ruleConfineDO.getMemberLevel()){
					    		node = findContainsNode((Branch)node1,ruleConfineDO);
					    	}
					    	break;
					    case 2:
					    	if((Integer)node1.getValue()==ruleConfineDO.getRuleType()){
					    		node = findContainsNode((Branch)node1,ruleConfineDO);
					    	}
					    	break;
					    case 3:
					    	return node;//尽管已经匹配到叶子节点,但仍返回的是其上一层
					    default: i++;break;
					}//switch
			}else{//当i已经>=子节点数,即在children中没有找到,则返回上一层的node
				return branch;
			}
		}
		return node;
	}
	
	public static Branch deleteTree(Branch branch,List<TmallPropRuleConfineDO> ruleConfines){
		Map map = new HashMap();
		for(int i = 0 ; i < ruleConfines.size() ; i++){
			TmallPropRuleConfineDO ruleConfine = ruleConfines.get(i);
			Node matchNode = findContainsNode(branch,ruleConfine);
			if(matchNode.getPosition()==2){
				ArrayList<Leaf> leafNodes = ((Branch)matchNode).getChildren();
				if(leafNodes!=null && leafNodes.size()>0){
					Map existPart = (Map) leafNodes.get(0).getValue();
					if(ruleConfine.getConditionValue()==null && (existPart.get(ruleConfine.getConditionKey())==null||"".equals(existPart.get(ruleConfine.getConditionKey())))){
						((Branch)matchNode).setChildrenSizeTo0();
					}else if(ruleConfine.getConditionValue().equals(existPart.get(ruleConfine.getConditionKey()))){
						map.put(ruleConfine.getConditionKey(), ruleConfine.getConditionValue());
					}
					if(i == ruleConfines.size()-1 && existPart.equals(map)){
						((Branch)matchNode).setChildrenSizeTo0();
					}
				}
			}
		}
		return branch;
	}
	
	public static boolean isAllEmptyLeaves(Branch branch){
		boolean boo = true;
		ArrayList<Node> children = branch.getChildren();
		for (Node childNode : children) {
			if (childNode.getPosition()==2) {
				if(((Branch)childNode).getChildren().size()==0){
					continue;
				}else{
					boo = false;
					break;
				}
			}
			boo = isAllEmptyLeaves((Branch)childNode);
		}
		return boo;
	}
	
	public static boolean isHaveEmptyLeaves(Branch branch,TmallPropRuleConfineDO ruleConfineDO){
		boolean boo = false;
		Node matchNode= findContainsNode(branch,ruleConfineDO);
		if(matchNode.getPosition()==2){
			if(((Branch) matchNode).getChildren().size()==0){
				boo = true;
			}
		}
		return boo;
	}
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值