今天看到<<软件设计师>>面向对象第七章讲到几种设计模式,其中一种为Visitor模式。这种设计模式通过访问者对象的建立,在访问过程中将访问者作为参数传到被访问对象的函数中,实现了有选择性的访问不同类的资源。
其中有一个Visitor模式设计的应用,参考书中的代码,在本地测试跑了一下。
//
// library_visitor.cpp
// data_structure
/*某图书管理系统中管理者两种类型的文献:图书和论文。现在要求统计所有馆藏文献的总页码(假设图书馆中有一本
540页的图书和两篇各25页的论文,那么馆藏文献的总页码就是590页)。适合采用Visitor模式实现该要求。*/
// Created by simon zhao on 2021/4/4.
// Copyright © 2021 simon zhao. All rights reserved.
//
#include "library_visitor.hpp"
#include <string>
#include <iostream>
using namespace std;
//声明访问者类
class LibraryVisitor;
//定义被访问者基类
class LibraryItemInterface{
public:
virtual void accept(LibraryVisitor * visitor){};
};
//定义被访问-文章类
class Article:LibraryItemInterface{
private:
string m_title;//论文名
string m_author;//论文作者
int m_start_page;
int m_end_page;
public:
Article(string p_title,string p_author,int p_start_page,int p_end_page);
int getNumberOfPages();//获取论文的页数
void accept(LibraryVisitor* visitor);//vistor模式下将visitor作为参数传递通过accept函数访问
};
//定义被访问-图书类
class Book:LibraryItemInterface{
private:
string m_title;
string m_author;
int m_pages;
public:
Book(string p_title,string p_author,int p_page);
int getNumberOfPages();
void accept(LibraryVisitor* visitor);
};
//方法实现 BOOK
Book::Book(string p_title,string p_author,int p_page){
m_title=p_title;
m_author=p_author;
m_pages=p_page;
};
int Book::getNumberOfPages(){
cout<<m_title<<"加入统计:"<<m_pages<<"页"<<endl;
return m_pages;
}
//方法实现 Article
Article::Article(string p_title,string p_author,int p_start_page,int p_end_page){
m_title=p_title;
m_author=p_author;
m_start_page=p_start_page;
m_end_page=p_end_page;
}
int Article::getNumberOfPages(){
cout<<m_title<<"加入统计:"<<m_end_page-m_start_page<<"页"<<endl;
return m_end_page-m_start_page;
}
//定义访问者基类
class LibraryVisitor{
public:
virtual void visit(Article* article){};
virtual void visit(Book* book){};
virtual void printSum(){};
};
//被访问者的accpet方法实现
void Book::accept(LibraryVisitor* visitor){
visitor->visit(this);
};
void Article::accept(LibraryVisitor* visitor){
visitor->visit(this);
}
//访问者执行的子类
class LibrarySumPrintVisitor:public LibraryVisitor{
private:
int total_sum;
public:
LibrarySumPrintVisitor(){
cout<<"初始化对象"<<endl;
}//构造方法
void visit(Article* article){
total_sum += article->getNumberOfPages();
}
void visit(Book* book){
total_sum += book->getNumberOfPages();
}
void printSum(){
cout<<"一共的页数"<<total_sum<<endl;
};
};
int main(){
//初始化被访问者
Book b1 = Book("狂人日记", "鲁迅", 540);
Article a1 = Article("神经网络", "bengio", 12, 37);
Article a2 = Article("NLP","bengio",8,33);
//初始化访问者
LibrarySumPrintVisitor vistor =LibrarySumPrintVisitor();
//第一次错误理解访问者模式代码
// vistor.visit(&b1);
// vistor.visit(&a1);
// vistor.visit(&a2);
//评论区@将手伸向星空指正后修改
b1.accept(&visitor);
a1.accept(&visitor);
a2.accept(&visitor);
vistor.printSum();
};
在本地编译运行了一下结果:
XX_USER:$ gcc -lstdc++ library_visitor.cpp -o test
XX_USER:$ ./test
初始化对象
狂人日记加入统计:540页
神经网络加入统计:25页
NLP加入统计:25页
一共的页数590
由于C++才刚开始学习,本文主要目的是为了做记录,如有代码不规范的地方请大家批评指正。