设计模式——访问者模式
访问者模式是一种行为模式,一般用于封装操作的变化,即对于一组对象(或一个对象)数据结构相对固定,但操作方法上有很多变化,这时候可以使用此设计模式;
角色:抽象的访问者角色,定义访问者针对此组对象需要实现的方法约束;
具体访问者角色,实现抽象访问者的约束
抽象被访问者角色,主要定义需要接受访问者的约束,一般是 void accept(Abstractvisitor visitor)
具体的被访问者角色。
访问者模式将数据结构和作用在数据结构上的操作解耦和;
下面看个示例;
/* * Copyright (c) 2017. panteng.Co.Ltd All rights reserved */ package com.pt.visitor; /** * @description 抽象元素角色(被访问者角色) * 定义元素需要实现的接受访问者的方法 * @author panteng * @date 17-3-6. */ public interface Element { void accept(Visitor visitor); }
/* * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved */ package com.pt.visitor; /** * @description * @author panteng * @date 17-3-6. */ public class Number implements Element { double a; double b; public Number(){ } public Number(double a, double b){ this.a = a; this.b = b; } public void accept(Visitor visitor){ visitor.visit(this); } public double getA(){ return a; } public void setA(double a){ this.a = a; } public double getB(){ return b; } public void setB(double b){ this.b = b; } }
/* * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved */ package com.pt.visitor; import java.util.List; /** * @description * @author panteng * @date 17-3-6. */ public class MyCollection implements Element { List<Object> list1; List<Object> list2; public MyCollection(){ } public MyCollection(List<Object> list1, List<Object> list2){ this.list1 = list1; this.list2 = list2; } public void accept(Visitor visitor){ visitor.visit(this); } public List<Object> getList1(){ return list1; } public void setList1(List<Object> list1){ this.list1 = list1; } public List<Object> getList2(){ return list2; } public void setList2(List<Object> list2){ this.list2 = list2; } }
/* * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved */ package com.pt.visitor; /** * @description 抽象访问者,定义访问操作接口 * @author panteng * @date 17-3-6. */ public interface Visitor { void visit(Number num); void visit(MyCollection set); }
/* * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved */ package com.pt.visitor; /** * @description * @author panteng * @date 17-3-6. */ public class Add implements Visitor { public void visit(MyCollection set){ System.out.print(set.getList1() + " + " + set.getList2() + " = "); set.getList1().addAll(set.getList2()); System.out.println(set.getList1()); } public void visit(Number num){ System.out.println(num.getA() + " + " + num.getB() + " = " + (num.getA() + num.getB())); } }
/* * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved */ package com.pt.visitor; /** * @description * @author panteng * @date 17-3-6. */ public class Sub implements Visitor { public void visit(MyCollection set){ System.out.print(set.getList1() + " - " + set.getList2() + " = "); set.getList1().removeAll(set.getList2()); System.out.println(set.getList1()); } public void visit(Number num){ System.out.println(num.getA() + " - " + num.getB() + " = " + (num.getA() - num.getB())); } }
/* * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved */ package com.pt.visitor; import org.junit.Test; import java.util.ArrayList; import java.util.List; /** * @description * @author panteng * @date 17-3-6. */ public class VisitorTest { @Test public void visitorTest(){ Visitor addVisitor = new Add(); Visitor subVisitor = new Sub(); Number number = new Number(3, 9); List<Object> list1 = new ArrayList<Object>(); list1.add(1); list1.add(2); list1.add(3); List<Object> list2 = new ArrayList<Object>(); list2.add(3); list2.add(4); list2.add(5); MyCollection set = new MyCollection(list1, list2); number.accept(addVisitor); set.accept(addVisitor); number.accept(subVisitor); set.accept(subVisitor); } }
此设计模式有其优势,但也有一定的不足,假如想增加一个除法操作类,对于集合并没除法操作,但操作类必须实现除法操作(空函数,或友情提示没有此操作)!似乎违反了接口最小化原则
===========================设计模式系列文章=========================