Intent
Structure
Consequences
- defines class hierarchies consisting of primitive objects and composite objects.
- makes the client simple.
- makes it easier to add new kinds of components.
- can make your design overly general.
// DesignPattern.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <share.h>
#include <list>
#include <vector>
#include <memory>
#define A std::cout <<
#define B << std::endl;
class Currency {
public:
Currency(int m) :m_(m){}
void operator=(int money_value) {
m_ = money_value;
}
Currency& operator+=(Currency iterator_count) {
m_ += iterator_count.value();
return (*this);
}
int value() {
return m_;
}
friend std::ostream& operator<<(std::ostream& o,const Currency c) {
o << c.m_ << std::endl;
return o;
}
private:
int m_;
};
template<class Item>
class Iterator {
public:
virtual void First() = 0;
virtual void Next() = 0;
virtual bool IsDone() const = 0;
virtual Item CurrentItem() const = 0;
void operator delete(void* ptr)
{
std::cout << "operator delete" << std::endl;
std::free(ptr);
}
protected:
Iterator() {}
};
template<class Item>
class ListIterator : public Iterator<Item> {
public:
ListIterator(std::list<Item>* aList) {
list_ = aList;
}
virtual void First() {
ite_ = list_->begin();
}
virtual void Next() {
ite_++;
}
virtual bool IsDone() const {
return ite_ != list_->end();
}
virtual Item CurrentItem() const {
return (*ite_);
}
private:
// 此处如果少了typename,又一波大惊喜
typename std::list<Item>::iterator ite_;
std::list<Item>* list_;
};
class Equipment {
public:
virtual ~Equipment() {
}
const char* Name() {
return name_;
}
// default currency value : 0
virtual Currency NetPrice() {
return Currency(0);
}
virtual void Add(Equipment* e) {
}
virtual void Remove(Equipment* e) {
}
virtual std::list<Equipment*> equipment() {
return std::list<Equipment*>{};
}
virtual Iterator<Equipment*>* CreateIterator() {
return new ListIterator<Equipment*>(nullptr);
}
protected:
// 父类没有默认构造,子类无法实现自定义构造
Equipment() {}
Equipment(const char* name):name_(name) {
}
private:
const char* name_;
};
// Currency value: 5
class FloppyDisk : public Equipment {
public:
FloppyDisk(const char* name) :Equipment(name){
}
virtual ~FloppyDisk() {
}
virtual Currency NetPrice() {
return Currency(5);
}
};
#define Has_more_one_child 1
class CompositeEquipment : public Equipment {
public:
virtual ~CompositeEquipment() {
}
virtual Currency NetPrice() {
Iterator<Equipment*>* i = CreateIterator();
Currency total = 0;
for (i->First(); i->IsDone(); i->Next()) {
total += (*i->CurrentItem()).NetPrice();
}
delete i;
return total;
}
virtual void Add(Equipment* e) {
if (e == nullptr)
return;
if (e->equipment().size() > 0) {
// for(auto ite = e->equipment().begin(); ite != e->equipment().end(); ite++)
// :error Expression: list iterators incompatible
std::list<Equipment*> equipment_list = e->equipment();
for (auto ite = equipment_list.begin(); ite != equipment_list.end(); ite++)
{
equipment_.push_back(*ite);
}
}
equipment_.push_back(e);
}
virtual void Remove(Equipment* e) {
equipment_.remove(e);
}
virtual std::list<Equipment*> equipment() {
return equipment_;
}
virtual Iterator<Equipment*>* CreateIterator() {
return new ListIterator<Equipment*>(&equipment_);
}
protected:
CompositeEquipment(const char*) {
}
private:
std::list<Equipment*> equipment_;
};
// Currency value: 3
class Card : public CompositeEquipment {
public:
Card(const char* name) :CompositeEquipment(name) {
}
virtual ~Card() {
}
virtual Currency NetPrice() {
return Currency(3);
}
};
// Currency value : 1
class Chassis : public CompositeEquipment {
public:
Chassis(const char* name) :CompositeEquipment(name) {
}
virtual ~Chassis() {
}
virtual Currency NetPrice() {
return Currency(1);
}
};
// currency value : 7
class Bus : public CompositeEquipment {
public:
Bus(const char* name) :CompositeEquipment(name) {
}
virtual ~Bus() {
}
virtual Currency NetPrice() {
return Currency(7);
}
};
// currency value : 9
class Cabinet : public CompositeEquipment {
public:
Cabinet(const char* name) :CompositeEquipment(name) {
}
virtual ~Cabinet() {
}
virtual Currency NetPrice() {
return Currency(9) += CompositeEquipment::NetPrice();
}
};
int main()
{
Cabinet* cabinet = new Cabinet("PC Cabinet");
Chassis* chassis = new Chassis("PC Chassis");
Bus* bus = new Bus("MCA Bus");
bus->Add(new Card("16Mbs Token Ring"));
chassis->Add(bus);
chassis->Add(new FloppyDisk("3.5in Floppy"));
cabinet->Add(chassis);
A "The net Price is " << cabinet->NetPrice() B
return 0;
}