zoukankan      html  css  js  c++  java
  • 访问者模式Visitor

    访问者模式:表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素类的前提下定义作用于这个元素的新操作。

    访问者模式的组成结构:

    1) 访问者角色(Visitor):为该对象结构中具体元素角色声明一个访问操作接口。该操作接口的名字和参数标识了发送访问请求给具体访问者的具体元素角色。这样访问者就可以通过该元素角色的特定接口直接访问它。

    2) 具体访问者角色(Concrete Visitor):实现每个由访问者角色(Visitor)声明的操作。

    3) 元素角色(Element):定义一个Accept操作,它以一个访问者为参数。

    4) 具体元素角色(Concrete Element):实现由元素角色提供的Accept操作。

    5) 对象结构角色(Object Structure):这是使用访问者模式必备的角色。它要具备以下特征:能枚举它的元素;可以提供一个高层的接口以允许该访问者访问它的元素;可以是一个复合(组合模式)或是一个集合,如一个列表或一个无序集合。

    访问者模式适用的情况:

    1) 一个对象结构包含很多类对象,它们有不同的接口,而你想对这些对象实施一些依赖于其具体类的操作。

    2) 需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而你想避免让这些操作“污染”这些对象的类。Visitor使得你可以将相关的操作集中起来定义在一个类中。

    3) 当该对象结构被很多应用共享时,用Visitor模式让每个应用仅包含需要用到的操作。

    4) 定义对象结构的类很少改变,但经常需要在此结构上定义新的操作。改变对象结构类需要重定义对所有访问者的接口,这可能需要很大的代价。如果对象结构类经常改变,那么可能还是在这些类中定义这些操作较好。

     

     

    package com.qinsoft.design;
    
    import java.util.*;
    import junit.framework.*;
    
    //客户 测试程序
    public class Visitor extends TestCase
    {
    
        /*
         * 在这里你能看到访问者模式执行的流程: 首先在客户端先获得一个具体的访问者角色 遍历对象结构 对每一个元素调用accept方法,将具体访问者角色传入
         * 这样就完成了整个过程
         */
        //对象结构角色在这里才 组装 上
    
        List<Flower> flowers = new ArrayList<Flower>();
    
        public Visitor()
        {
            for (int i = 0; i < 10; i++)
                flowers.add(FlowerGenerator.newFlower());
        }
    
        VisitorInter sval;
        public void test()
        {
            //这个地方你可以修改以便使用另外一个具体访问者角色
            sval = new StringVal();
            java.util.Iterator<Flower> it = flowers.iterator();
            while (it.hasNext())
            {
                it.next().accept(sval);
                System.out.println(sval);
            }
        }
        public static void main(String args[])
        {
            junit.textui.TestRunner.run(Visitor.class);
        }
    }
    //访问者角色
    interface VisitorInter
    {
        void visit(Gladiolus g);
        void visit(Runuculus r);
        void visit(Chrysanthemum c);
    }
    
    //元素角色
    interface Flower
    {
        void accept(VisitorInter v);
    }
    
    //以下三个具体元素角色
    class Gladiolus implements Flower
    {
        public void accept(VisitorInter v)
        {
            v.visit(this);
        }
    }
    
    class Runuculus implements Flower
    {
        public void accept(VisitorInter v)
        {
            v.visit(this);
        }
    }
    
    class Chrysanthemum implements Flower
    {
    
        public void accept(VisitorInter v)
        {
            v.visit(this);
        }
    }
    
    //实现的具体访问者角色
    class StringVal implements VisitorInter
    {
        String s;
        public String toString()
        {
            return s;
        }
        public void visit(Gladiolus g)
        {
            s = "Gladiolus";
        }
        public void visit(Runuculus r)
        {
            s = "Runuculus";
        }
        public void visit(Chrysanthemum c)
        {
            s = "Chrysanthemum";
        }
    }
    
    //另一个具体访问者角色
    class Bee implements VisitorInter
    {
    
        public void visit(Gladiolus g)
        {
            System.out.println("Bee and Gladiolus");
        }
    
        public void visit(Runuculus r)
        {
            System.out.println("Bee and Runuculus");
        }
    
        public void visit(Chrysanthemum c)
        {
            System.out.println("Bee and Chrysanthemum");
        }
    }
    
    //这是一个对象生成器 
    //这不是一个完整的对象结构,这里仅仅是模拟对象结构中的元素
    class FlowerGenerator
    {
    
        private static Random rand = new Random();
    
        public static Flower newFlower()
        {
            switch (rand.nextInt(3))
            {
            default:
            case 0:
                return new Gladiolus();
            case 1:
                return new Runuculus();
            case 2:
                return new Chrysanthemum();
            }
        }
    }
  • 相关阅读:
    AWS 免费套餐
    UWP DEP0700: 应用程序注册失败。[0x80073CF9] 另一个用户已安装此应用的未打包版本。当前用户无法将该版本替换为打包版本。
    UWP 应用程序名称本地化以及商店显示名称本地化
    ES6知识整理(6)--Symbol函数
    【web前端】移动端控制台插件,手机端页面查看相关页面控制台信息
    ES6知识整理(5)--对象的扩展
    ES6知识整理(4)--数组的扩展
    【移动端web】软键盘兼容问题
    ES6知识整理(3)--函数的扩展
    ES6知识整理(2)--变量的解构赋值
  • 原文地址:https://www.cnblogs.com/hnhcc39/p/2789345.html
Copyright © 2011-2022 走看看