设计模式——访问者模式

访问者模式是一种行为模式,一般用于封装操作的变化,即对于一组对象(或一个对象)数据结构相对固定,但操作方法上有很多变化,这时候可以使用此设计模式;

角色:抽象的访问者角色,定义访问者针对此组对象需要实现的方法约束;

        具体访问者角色,实现抽象访问者的约束

    抽象被访问者角色,主要定义需要接受访问者的约束,一般是 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;
    }
}
元素1
/*
 * 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;
    }
}
元素2
/*
 * 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()));
    }
}
操作类1
/*
 * 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()));
    }
}
操作类2

 

/*
 * 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);
    }
}
测试

此设计模式有其优势,但也有一定的不足,假如想增加一个除法操作类,对于集合并没除法操作,但操作类必须实现除法操作(空函数,或友情提示没有此操作)!似乎违反了接口最小化原则

 

 

 

 

===========================设计模式系列文章=========================

简单工厂模式

工厂方法模式

抽象工厂模式

建造者模式

原型模式

适配器模式

桥接模式

装饰模式

代理模式

组合模式

门面模式

享元模式

责任链模式

命令模式

中介者模式

备忘录模式

观察者模式

状态模式

策略模式

模板方法模式

访问者模式

 

posted @ 2017-03-05 10:08  沙中世界  阅读(187)  评论(0编辑  收藏  举报