1、访问者(Visitor)模式:表示一个作用于某对象结构中的各元素的操作,它使你在不改变各元素的类的前提下定义作用于这些元素的新操作。
类图:
访问者模式结构:
访问者角色(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()); } } }