访问者模式.cpp
# include <iostream>
# include <list>
# include <memory>
using namespace std;
namespace ns1
{
class Medicine
{
public :
virtual ~ Medicine ( ) { }
virtual string getMdcName ( ) const = 0 ;
virtual float getPrice ( ) const = 0 ;
} ;
class M_asplcrp : public Medicine
{
public :
string getMdcName ( ) const override
{
return "Aspirin enteric-coated tablets" ;
}
float getPrice ( ) const override
{
return 46.8f ;
}
} ;
class M_fftdnhsp : public Medicine
{
public :
string getMdcName ( ) const override
{
return "Fluvastatin sodium sustained-release tablets" ;
}
float getPrice ( ) const override
{
return 111.3f ;
}
} ;
class M_dlx : public Medicine
{
public :
string getMdcName ( ) const override
{
return "Deanxit" ;
}
float getPrice ( ) const override
{
return 122.0f ;
}
} ;
class MedicineProc
{
list< shared_ptr< Medicine>> m_mdclist;
public :
void addMedicine ( const shared_ptr< Medicine> & p_mdc) { m_mdclist. push_back ( p_mdc) ; }
void procAction ( const string & strvisitor)
{
if ( strvisitor == "Toll collector" )
{
float totalcost = 0.0f ;
for ( auto iter = m_mdclist. begin ( ) ; iter != m_mdclist. end ( ) ; ++ iter)
{
float tmpprice = ( * iter) -> getPrice ( ) ;
totalcost += tmpprice;
cout << "yao: " << ( * iter) -> getMdcName ( ) << ", price: " << tmpprice << endl;
}
cout << "total price: " << totalcost << ", Toll collector charges a fee!" << endl;
}
else if ( strvisitor == "Drug taking personnel" )
for ( auto iter = m_mdclist. begin ( ) ; iter != m_mdclist. end ( ) ; ++ iter)
cout << "Drug taking personnel give " << ( * iter) -> getMdcName ( ) << " to me!" << endl;
else if ( strvisitor == "dietitian" )
cout << "Nutritionist suggested: match coarse grains with staple foods and eat meat properly!" << endl;
else if ( strvisitor == "Fitness coach" )
cout << "The fitness coach suggested: do more aerobic exercises such as jogging (35 minutes), warm up before and after jogging, avoid anxiety, avoid staying up late, and take a bed rest before 22:30!" << endl;
}
} ;
}
namespace ns2
{
class Visitor ;
class Medicine
{
public :
virtual ~ Medicine ( ) { }
virtual void Accept ( shared_ptr< Visitor> & pvisitor) = 0 ;
public :
virtual string getMdcName ( ) = 0 ;
virtual float getPrice ( ) = 0 ;
} ;
class M_asplcrp : public Medicine
{
public :
string getMdcName ( ) override { return "Aspirin enteric-coated tablets" ; }
float getPrice ( ) override { return 46.8f ; }
public :
void Accept ( shared_ptr< Visitor> & pvisitor) override ;
} ;
class M_fftdnhsp : public Medicine
{
public :
string getMdcName ( ) override { return "Fluvastatin sodium sustained-release tablets" ; }
float getPrice ( ) override { return 111.3f ; }
public :
void Accept ( shared_ptr< Visitor> & pvisitor) override ;
} ;
class M_dlx : public Medicine
{
public :
string getMdcName ( ) override { return "Deanxit" ; }
float getPrice ( ) override { return 122.0f ; }
public :
void Accept ( shared_ptr< Visitor> & pvisitor) override ;
} ;
class Visitor
{
public :
virtual ~ Visitor ( ) { }
virtual void Visit_elm_asplcrp ( M_asplcrp * pelem) = 0 ;
virtual void Visit_elm_fftdnhsp ( M_fftdnhsp * pelem) = 0 ;
virtual void Visit_elm_dlx ( M_dlx * pelem) = 0 ;
} ;
class Visitor_SFRY : public Visitor
{
float m_totalcost = 0.0f ;
public :
void Visit_elm_asplcrp ( M_asplcrp * pelem) override
{
float tmpprice = pelem-> getPrice ( ) ;
cout << "yao: " << pelem-> getMdcName ( ) << ", price: " << tmpprice << endl;
m_totalcost += tmpprice;
}
void Visit_elm_fftdnhsp ( M_fftdnhsp * pelem) override
{
float tmpprice = pelem-> getPrice ( ) ;
cout << "yao: " << pelem-> getMdcName ( ) << ", price: " << tmpprice << endl;
m_totalcost += tmpprice;
}
void Visit_elm_dlx ( M_dlx * pelem) override
{
float tmpprice = pelem-> getPrice ( ) ;
cout << "yao: " << pelem-> getMdcName ( ) << ", price: " << tmpprice << endl;
m_totalcost += tmpprice;
}
float getTotalCost ( ) const { return m_totalcost; }
} ;
class Visitor_QYRY : public Visitor
{
public :
void Visit_elm_asplcrp ( M_asplcrp * pelem) override
{
cout << "Drug taking personnel give " << pelem-> getMdcName ( ) << " to me!" << endl;
}
void Visit_elm_fftdnhsp ( M_fftdnhsp * pelem) override
{
cout << "Drug taking personnel give " << pelem-> getMdcName ( ) << " to me!" << endl;
}
void Visit_elm_dlx ( M_dlx * pelem) override
{
cout << "Drug taking personnel give " << pelem-> getMdcName ( ) << " to me!" << endl;
}
} ;
class Visitor_YYS : public Visitor
{
public :
void Visit_elm_asplcrp ( M_asplcrp * pelem) override
{
cout << "The nutritionist suggested: Eating more coarse grains and less oil can effectively prevent blood clots!" << endl;
}
void Visit_elm_fftdnhsp ( M_fftdnhsp * pelem) override
{
cout << "The nutritionist suggested: Eating more mushrooms, onions, and kiwifruit can effectively reduce blood lipids!" << endl;
}
void Visit_elm_dlx ( M_dlx * pelem) override
{
cout << "The nutritionist suggested: Go out more to breathe fresh air, get more sunshine, go to more crowded places, and keep an optimistic and cheerful mood!" << endl;
}
} ;
void M_asplcrp :: Accept ( shared_ptr< Visitor> & pvisitor)
{
pvisitor-> Visit_elm_asplcrp ( this ) ;
}
void M_fftdnhsp :: Accept ( shared_ptr< Visitor> & pvisitor)
{
pvisitor-> Visit_elm_fftdnhsp ( this ) ;
}
void M_dlx :: Accept ( shared_ptr< Visitor> & pvisitor)
{
pvisitor-> Visit_elm_dlx ( this ) ;
}
class ObjectStructure
{
list< shared_ptr< Medicine>> m_mdclist;
public :
void addMedicine ( const shared_ptr< Medicine> & p_mdc)
{
m_mdclist. push_back ( p_mdc) ;
}
void procAction ( shared_ptr< Visitor> & pvisitor)
{
for ( auto iter = m_mdclist. begin ( ) ; iter != m_mdclist. end ( ) ; ++ iter)
( * iter) -> Accept ( pvisitor) ;
}
} ;
}
namespace ns3
{
class Medicine ;
class Visitor
{
public :
virtual ~ Visitor ( ) { }
virtual void Visit ( Medicine * const pelem) = 0 ;
} ;
class Medicine
{
public :
virtual ~ Medicine ( ) { }
virtual void Accept ( shared_ptr< Visitor> & pvisitor) { pvisitor-> Visit ( this ) ; }
public :
virtual string getMdcName ( ) const = 0 ;
virtual float getPrice ( ) const = 0 ;
} ;
class M_asplcrp : public Medicine
{
public :
string getMdcName ( ) const override { return "Aspirin enteric-coated tablets" ; }
float getPrice ( ) const override { return 46.8f ; }
} ;
class M_fftdnhsp : public Medicine
{
public :
string getMdcName ( ) const override { return "Fluvastatin sodium sustained-release tablets" ; }
float getPrice ( ) const override { return 111.3f ; }
} ;
class M_dlx : public Medicine
{
public :
string getMdcName ( ) const override { return "Deanxit" ; }
float getPrice ( ) const override { return 122.0f ; }
} ;
class Visitor_SFRY : public Visitor
{
float m_totalcost = 0.0f ;
public :
void Visit ( Medicine * const m) override
{
float tmpprice = m-> getPrice ( ) ;
m_totalcost += tmpprice;
cout << "yao: " << m-> getMdcName ( ) << ", price: " << tmpprice << endl;
}
float getTotalCost ( ) const { return m_totalcost; }
} ;
class Visitor_QYRY : public Visitor
{
public :
void Visit ( Medicine * const m) override
{
cout << "Drug taking personnel give " << m-> getMdcName ( ) << " to me!" << endl;
}
} ;
class Visitor_YYS : public Visitor
{
public :
void Visit ( Medicine * const m) override
{
cout << "The nutritionist suggested: Eating more coarse grains and less oil can effectively prevent blood clots!" << endl;
cout << "The nutritionist suggested: Eating more mushrooms, onions, and kiwifruit can effectively reduce blood lipids!" << endl;
cout << "The nutritionist suggested: Go out more to breathe fresh air, get more sunshine, go to more crowded places, and keep an optimistic and cheerful mood!" << endl;
}
} ;
class ObjectStructure
{
list< shared_ptr< Medicine>> m_mdclist;
public :
void addMedicine ( const shared_ptr< Medicine> & p_mdc)
{
m_mdclist. push_back ( p_mdc) ;
}
void procAction ( shared_ptr< Visitor> & pvisitor)
{
for ( auto iter = m_mdclist. begin ( ) ; iter != m_mdclist. end ( ) ; ++ iter)
( * iter) -> Accept ( pvisitor) ;
}
} ;
}
int main ( )
{
# if 0
using namespace ns1;
shared_ptr< Medicine> pm1 ( new M_asplcrp ( ) ) ;
shared_ptr< Medicine> pm2 ( new M_fftdnhsp ( ) ) ;
shared_ptr< Medicine> pm3 ( new M_dlx ( ) ) ;
MedicineProc mdcprocobj;
mdcprocobj. addMedicine ( pm1) ;
mdcprocobj. addMedicine ( pm2) ;
mdcprocobj. addMedicine ( pm3) ;
mdcprocobj. procAction ( "Toll collector" ) ;
mdcprocobj. procAction ( "Drug taking personnel" ) ;
# endif
# if 1
using namespace ns3;
shared_ptr< Medicine> mdc_asplcrp ( new M_asplcrp ( ) ) ;
shared_ptr< Medicine> mdc_fftdnhsp ( new M_fftdnhsp ( ) ) ;
shared_ptr< Medicine> mdc_dlx ( new M_dlx ( ) ) ;
shared_ptr< Visitor> visitor_sf ( new Visitor_SFRY ( ) ) ;
mdc_asplcrp-> Accept ( visitor_sf) ;
mdc_fftdnhsp-> Accept ( visitor_sf) ;
mdc_dlx-> Accept ( visitor_sf) ;
cout << "total price: " << dynamic_pointer_cast < Visitor_SFRY> ( visitor_sf) -> getTotalCost ( ) << ", the toll collector charged me!" << endl;
shared_ptr< Visitor> visitor_qy ( new Visitor_QYRY ( ) ) ;
mdc_asplcrp-> Accept ( visitor_qy) ;
mdc_fftdnhsp-> Accept ( visitor_qy) ;
mdc_dlx-> Accept ( visitor_qy) ;
shared_ptr< Visitor> visitor_yys ( new Visitor_YYS ( ) ) ;
mdc_asplcrp-> Accept ( visitor_yys) ;
mdc_fftdnhsp-> Accept ( visitor_yys) ;
mdc_dlx-> Accept ( visitor_yys) ;
shared_ptr< ObjectStructure> objstruc ( new ObjectStructure ( ) ) ;
objstruc-> addMedicine ( mdc_asplcrp) ;
objstruc-> addMedicine ( mdc_fftdnhsp) ;
objstruc-> addMedicine ( mdc_dlx) ;
objstruc-> procAction ( visitor_yys) ;
# endif
cout << "Over!\n" ;
return 0 ;
}