访问者模式.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;
}