Java中的23种设计模式之——访问者(Visitor)模式(7)

摘要:
也就是说,在元素类数目不确定的情况下,应该慎用访问者模式。假如一组对象中,存在着相似的操作,为了避免出现大量重复的代码,也可以将这些重复的操作封装到访问者中去。

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

类图:

Java中的23种设计模式之——访问者(Visitor)模式(7)第1张



访问者模式结构:
访问者角色(Visitor): 为该对象结构中具体元素角色声明一个访问操作接口.
具体访问者角色(Concrete Visitor): 实现每个由访问者角色(Visitor)声明的操作.
元素角色(Element): 定义一个Accept操作,它以一个访问者为参数.
具体元素角色(Concrete Element): 实现由元素角色提供的Accept操作.
对象结构角色(Object Structure): 这是使用访问者模式必备的角色. 它要具备以下特征: 能枚举它的元素; 可以提供一个高层的接口以允许该访问者访问它的元素; 可以是一个复合(组合模式)或是一个集合, 如一个列表或一个无序集合.

实例:

统计论文或者图书的页数,其中

(Visitor):抽象访问者
interfaceLibraryVisitor{
    void visit(Book p_book);//(1)
    void visit(Article p_article);//(2)
    voidprintSum();
}
(Concrete Visitor):访问者
class LibrarySumPrintVisitor implementsLibraryVisitor{
    private int sum = 0;
    public voidvisit(Book p_book){
        sum = sum +p_book.getNumberOfPages();
    }
    public voidvisit(Article p_article){
        sum = sum +p_article.getNumberOfPages();
    }
    @Override
    public voidprintSum() {
        System.out.println("sum="+sum);
    }
    }
(Element):元素
interfaceLibraryItemInterface{
public voidaccept(LibraryVisitor visitor);
}
(Concrete Element):具体元素
class Article implementsLibraryItemInterface{
        private String m_title;//论文名
        private String m_author;//论文作者
        private intm_start_page;
        private intm_end_page;
        public Article(String p_author,String p_title,int p_start_page,intp_end_page){
            m_title =p_title;
            m_author =p_author;
            m_start_page =p_start_page;
            m_end_page =p_end_page;
        }
        public intgetNumberOfPages(){
            return m_end_page -m_start_page;
        }
        @Override
        public voidaccept(LibraryVisitor visitor){
System.out.println("Article"); visitor.visit(
this); } } class Book implementsLibraryItemInterface{ private String m_title;//书名 private String m_author;//作者 private int m_pages;//页数 public Book(String p_title, String p_author, intp_pages) { super(); this.m_title =p_title; this.m_author =p_author; this.m_pages =p_pages; } public intgetNumberOfPages(){
System.out.println("book");
returnm_pages; } @Override public voidaccept(LibraryVisitor visitor){
System.out.println("book"); visitor.visit(
this); } }
(Object Structure):结构对象
classObjectStruture {    
    public static List<Book>getList(){    
        List<Book> list = new ArrayList<Book>();    
        Random ran = newRandom();    
        for(int i=0; i<10; i++){    
            int a = ran.nextInt(100);    
            if(a>50){    
                list.add(new Book("图书", "dsf", 440));    
            }else{    
                list.add(new Book("图书", "dsf", 540));    
            }    
        }    
        returnlist;    
    }    
} 
客户端:
public classVisitor {
    public static voidmain(String[] args) {
        List<LibraryItemInterface> list =ObjectStruture.getList();    
            for(LibraryItemInterface e: list){    
                e.accept(newLibrarySumPrintVisitor());    
            }    
        }    
}
运行结果:
3、优点
符合单一职责原则:凡是适用访问者模式的场景中,元素类中需要封装在访问者中的操作必定是与元素类本身关系不大且是易变的操作,使用访问者模式一方面符合单一职责原则,另一方面,因为被封装的操作通常来说都是易变的,所以当发生变化时,就可以在不改变元素类本身的前提下,实现对变化部分的扩展。
扩展性良好:元素类可以通过接受不同的访问者来实现对不同操作的扩展。
4、缺点:
增加新的元素类比较困难。通过访问者模式的代码可以看到,在访问者类中,每一个元素类都有它对应的处理方法,也就是说,每增加一个元素类都需要修改访问者类(也包括访问者类的子类或者实现类),修改起来相当麻烦。也就是说,在元素类数目不确定的情况下,应该慎用访问者模式。所以,访问者模式比较适用于对已有功能的重构,比如说,一个项目的基本功能已经确定下来,元素类的数据已经基本确定下来不会变了,会变的只是这些元素内的相关操作,这时候,我们可以使用访问者模式对原有的代码进行重构一遍,这样一来,就可以在不修改各个元素类的情况下,对原有功能进行修改。
5、适用场景
假如一个对象中存在着一些与本对象不相干(或者关系较弱)的操作,为了避免这些操作污染这个对象,则可以使用访问者模式来把这些操作封装到访问者中去。
假如一组对象中,存在着相似的操作,为了避免出现大量重复的代码,也可以将这些重复的操作封装到访问者中去。

免责声明:文章转载自《Java中的23种设计模式之——访问者(Visitor)模式(7)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇EC中的QEvent[开荒啦]ECS服务器初体验下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

c#中的23种设计模式

C# 23种设计模式汇总 创建型模式 工厂方法(Factory Method) 在工厂方法模式中,工厂方法用来创建客户所需要的产品,同时还向客户隐藏了哪种具体产品类将被实例化这一细节。工厂方法模式的核心是一个抽象工厂类,各种具体工厂类通过抽象工厂类将工厂方法继承下来。如此使得客户可以只关心抽象产品和抽象工厂,完全不用理会返回的是哪一种具体产品,也不用...

【Unity3D与23种设计模式】桥接模式(Bridge)

GoF定义: “将抽象与实现分离,使二者可以独立的变化” 游戏中,经常有这么一种情况 基类角色类(ICharacter),下面有子类士兵类(ISoldier)、敌军类(IEnemy) 基类武器类(IWeapon),下面有子类枪类(IGun)、炮类(ICannon) 当然,有用枪的士兵,有用炮的士兵 这么一组合,就是2*2 = 4个类 游戏后期,当角...

Java设计模式(23)——行为模式之访问者模式(Visitor)

一、概述 概念 作用于某个对象群中各个对象的操作。它可以使你在不改变这些对象本身的情况下,定义作用于这些对象的新操作。 引入 试想这样一个场景,在一个Collection中放入了一大堆的各种对象的引用,取出时却需要根据这些对象的不同具体类型执行不同操作,那我们有如下方案: public voidshow(Collection c) {...

23种设计模式之一(单例模式)

单例模式:(确保一个类最多只有一个实例,并提供一个全局访问点)      存在的意义:   有些对象我们只需要一个,如:线程池、缓存、硬件设备等;如果使用多个实例就会造成冲突、不一致等;   比如打印机这个类,如果多个对象同时使用它的输出,打印机类就产生了多个实例,就可能造成打印顺序和内容的混乱; 线程最安全,效率最高的一种写法: 1 public c...

C#设计模式-访问者模式

一、 访问者(Vistor)模式 访问者模式是封装一些施加于某种数据结构之上的操作。一旦这些操作需要修改的话,接受这个操作的数据结构则可以保存不变。访问者模式适用于数据结构相对稳定的系统, 它把数据结构和作用于数据结构之上的操作之间的耦合度降低,使得操作集合可以相对自由地改变。 数据结构的每一个节点都可以接受一个访问者的调用,此节点向访问者对象传入节点对象...

Java开发中的23种设计模式详解(转)

设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如...