访问者模式能将算法与其所作用的对象隔离开来,分离数据结构与访问数据操作。例如 不同访问者 对不同 文件类型(要素)的操作权限不同。
设计模式,一定要敲代码理解
元素抽象(被访问的元素)
accept 方法实现 该元素被那个访问者访问
public interface Element {
void accept(Visitor v);
}
元素实现
例如 文件目录与 .doc文件
/**
* @author ggbond
* @date 2024年04月19日 08:46
*/
public class ElementA implements Element {
// 文件夹名
private String name;
private String permissions;
public ElementA(String name, String permissions) {
this.name = name;
this.permissions = permissions;
}
public String getName() {
return name;
}
public String getPermissions() {
return permissions;
}
@Override
public void accept(Visitor v) {
v.visit(this);
}
}
访问者抽象
包含对所有具体要素的操作方法
public interface Visitor {
void visit(ElementA a);
void visit(ElementB a);
}
访问者实现
普通用户 与 root用户
/**
* @author ggbond
* @date 2024年04月19日 08:48
*/
public class Normal implements Visitor {
private final List<String> permissions=new ArrayList<>(List.of("read"));
@Override
public void visit(ElementA a) {
if (permissions.contains(a.getPermissions())){
System.out.println("该用户有权利访问"+a.getName());
}else {
System.out.println("该用户无权利访问"+a.getName());
}
}
@Override
public void visit(ElementB a) {
if (permissions.contains(a.getPermissions())){
System.out.println("该用户有权利访问"+a.getName());
}else {
System.out.println("该用户无权利访问"+a.getName());
}
}
}
/**
* @author ggbond
* @date 2024年04月19日 08:48
*/
public class Root implements Visitor {
private final List<String> permissions=new ArrayList<>(List.of("read","write"));
@Override
public void visit(ElementA a) {
if (permissions.contains(a.getPermissions())){
System.out.println("该用户有权利访问"+a.getName());
}else {
System.out.println("该用户无权利访问"+a.getName());
}
}
@Override
public void visit(ElementB a) {
if (permissions.contains(a.getPermissions())){
System.out.println("该用户有权利访问"+a.getName());
}else {
System.out.println("该用户无权利访问"+a.getName());
}
}
}
对象结构(存储所有元素)
/**
* @author ggbond
* @date 2024年04月19日 09:13
* 包含 全部 具体要素
*/
public class ObjectStructure {
private List<Element> elementList = new LinkedList<>();
void addElement(Element element) {
elementList.add(element);
}
// 展示该电脑中的文件和文件夹
void visit(Visitor visitor) {
for (Element element: elementList) {
element.accept(visitor);
}
}
}
测试与结果
public class Main {
public static void main(String[] args) {
ObjectStructure obj=new ObjectStructure();
obj.addElement(new ElementA("ggbond 学Java.doc","write"));
obj.addElement(new ElementA("ggbond Java目录","read"));
//不同访问者权限不一样
obj.visit(new Normal());
System.out.println("------------");
obj.visit(new Root());
}
}
总结
满足开闭原则与 单一职责原则。 访问者必须知晓所有的具体元素类,实现所有具体元素的操作方法。