设计模式--组合模式尝试

/*****************************************************************//**
* \file   组合模式.cpp
* \brief  组合模式案例, 对单片机中设备管理的尝试, 仅用于学习, 如果
*		  用于商业用途概不负责。
* \author 迷糊的lakes
* \date   November 2023
* ********************************************************************/
#include <iostream>
#include <string>
#include <unordered_map>
#include <list>

/**
 * 抽象设备类.
 */
using DEVICE_ID = unsigned int;
using DEV_INFO = std::tuple<DEVICE_ID, std::string>;
using DEV_RUN_CALLBACK = void(*)(DEV_INFO);
class AbstractaDevice {
public:
	AbstractaDevice(DEV_INFO devInfo, DEV_RUN_CALLBACK runCallback) : m_devInfo(devInfo), m_runCallback(runCallback){ }
	virtual ~AbstractaDevice() { }
	void setParent(AbstractaDevice* pDev) { 
		m_parent = pDev;  
	}
	AbstractaDevice* getParent() {
		return m_parent;
	}
	DEV_INFO& getDevInfo() {
		return m_devInfo;
	}
	virtual bool hasChild() {
		return false;
	}
	virtual void add(AbstractaDevice* pDev) { }
	virtual void remove(AbstractaDevice* pDev) { }
	virtual void run() = 0;
	virtual void displayRelation() = 0;
private:
	DEV_INFO m_devInfo;
	AbstractaDevice* m_parent = nullptr;
protected:
	DEV_RUN_CALLBACK m_runCallback;
};

/**
 * 叶子节点类.
 */
class LeafDevice final : public AbstractaDevice {
public:
	using AbstractaDevice::AbstractaDevice;
	bool hasChild() override {
		return false;
	}
	void run() override {
		auto [dev_id, dev_name] = getDevInfo();
		std::cout << "====================================================================================" << std::endl;
		std::cout << "[ID: " << dev_id << "  name: " << dev_name << "] run!!!" << std::endl;
		std::cout << "====================================================================================" << std::endl;
	}

	void displayRelation() override {	
		auto [dev_id, dev_name] = getParent()->getDevInfo();
		std::cout << "====================================================================================" << std::endl;
		std::cout << "[parent ID: " << dev_id << "  parent name: " << dev_name << "] " << std::endl;
		std::cout << "====================================================================================" << std::endl;
	}
	~LeafDevice() {
		auto [dev_id, dev_name] = getDevInfo();
		std::cout << "[ID: " << dev_id << "  name: " << dev_name << "] exit!!!" << std::endl;
	}
};

/**
 * 管理者节点类.
 */
class ManageDevice final : public AbstractaDevice {
public:
	using AbstractaDevice::AbstractaDevice;
	bool hasChild() override {
		return true;
	}
	void run() override {
		if (m_runCallback) {
			m_runCallback(getDevInfo());
		}

	}

	void displayRelation() override {
		auto [dev_id, dev_name] = getDevInfo();
		std::cout << "====================================================================================" << std::endl;
		std::cout << "[管理者 ID: " << dev_id << "   name: " << dev_name << "] " << std::endl;
		for (const auto& dev : m_childs) {
			auto [child_dev_id, child_dev_name] = dev->getDevInfo();
			std::cout << "[ID: " << child_dev_id << "  name: " << child_dev_name << "] run!!!" << std::endl;
		}
		std::cout << "====================================================================================" << std::endl;
	}

	void add(AbstractaDevice* pDev) override { 
		pDev->setParent(this);
		m_childs.push_back(pDev);
	}

	void remove(AbstractaDevice* pDev) override { 
		pDev->setParent(nullptr);
		m_childs.remove(pDev);
	}

	std::list<AbstractaDevice*>& getChilds() {
		return m_childs;
	}

	~ManageDevice() {
		auto [dev_id, dev_name] = getDevInfo();
		std::cout << "[ID: " << dev_id << "  name: " << dev_name << "] exit!!!" << std::endl;
	}

private:
	std::list<AbstractaDevice*> m_childs;
};


void deleteAllDevs(AbstractaDevice* root) {
	if (root == nullptr) {
		return;
	}
	if (root->hasChild()) {
		ManageDevice* pManagerDev = dynamic_cast<ManageDevice*>(root);
		std::list<AbstractaDevice*> childs = pManagerDev->getChilds();
		for (const auto& dev : childs) {
			deleteAllDevs(dev);
		}
	}
	delete root;
}

void run(DEV_INFO info)  {
	auto [dev_id, dev_name] = info;
	std::cout << "====================================================================================" << std::endl;
	std::cout << "[管理者ID: " << dev_id << "  name: " << dev_name << "] run!!!" << std::endl;
	std::cout << "====================================================================================" << std::endl;
}

int main()
{
	AbstractaDevice* pManagerDev = new ManageDevice(std::make_tuple(0, "root_dev"), run);
	std::string dev_names[] = {"红外设备", "蜂鸣器设备", "陀螺仪", "显示器"};
	for (int index = 0; const auto & d_n : dev_names) {	
		AbstractaDevice* pDev = new ManageDevice(std::make_tuple(index, dev_names[index]), run);
		pManagerDev->add(pDev);
		if (index == 2) {
			AbstractaDevice* pLeaf = new LeafDevice(std::make_tuple(index, "收尾设备"), run);
			pDev->add(pLeaf);
		}
		pDev->run();
		pDev->displayRelation();
		index++;
	}
	pManagerDev->run();
	pManagerDev->displayRelation();
	deleteAllDevs(pManagerDev);
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值