十八、設計模式 之 組合模式

目標:用組合模式實現規則的校驗。

首先設計一個規則表,包括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;
	}
}


 

發佈了42 篇原創文章 · 獲贊 0 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章