zoukankan      html  css  js  c++  java
  • 第19章组合模式

    一 概念

    • 组合模式,将对象组合成树形结构以表示‘部分-整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

    二 UML图

    • Component 组合中的对象声明接口,在适当情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component的子部件
    • Leaf 在组合中表示叶节点对象,叶节点没有子节点。
    • Composite 定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关的操作,比如增加Add和删除Remove

    三 何时使用组合模式

    • 需求是体现部分与整体层次的结构时,以及你希望用户可以忽略组合对象与单个对象的不同,统一的使用组合结构中的所有对象时,就应该考虑用组合模式了。

    四 C++代码实现

    #include "pch.h"
    #include <iostream>
    #include <string>
    #include <list>
    using namespace std;
    
    //公司类 抽象类或接口
    class Company
    {
    public:
    	Company() {}
    	Company(string str)
    		:name(str) {}
    	virtual void Add(Company* c) = 0;  //增加
    	virtual void Remove(Company* c) = 0;  //移除
    	virtual void Display(int depth) = 0;  //显示
    	virtual void LineOfDuty() = 0;  //履行职责  
    	inline bool operator==(const Company& company) const
    	{
    		return this->name == company.name;
    	}
    protected:
    	string name;
    };
    
    class ConcreteCompany : public Company
    {
    public:
    	ConcreteCompany(string name) : Company(name)
    	{
    		children = new list<Company*>;
    	}
    	void Add(Company* c) override
    	{
    		children->push_back(c);
    	}
    	void Remove(Company* c) override  //删除子节点
    	{
    
    		for (list<Company*>::iterator it = children->begin(); it != children->end(); ++it)
    		{
    			if (*(*it) == *c)
    			{
    				children->erase(it);
    				break;
    			}
    		}
    	}
    	void Display(int depth) override  //显示
    	{
    		for (int ix = 0; ix < depth; ++ix)
    		{
    			cout << "-";
    		}
    		cout << this->name << endl;
    		for (list<Company*>::iterator it = children->begin(); it != children->end(); ++it)
    		{
    			(*it)->Display(depth + 2);
    		}
    	}
    	virtual void LineOfDuty() override  //履行职责
    	{
    		for (list<Company*>::iterator it = children->begin(); it != children->end(); ++it)
    		{
    			(*it)->LineOfDuty();
    		}
    	}
    private:
    	list<Company*>* children;
    };
    
    //人力资源部 树叶节点
    class HRDepartment : public Company
    {
    public:
    	HRDepartment(string str) : Company(str) {}
    
    	void Add(Company* c) override  //增加
    	{
    
    	}
    	void Remove(Company* c) override  //移除
    	{
    
    	}
    	void Display(int depth) override  //显示
    	{
    		for (int ix = 0; ix < depth; ++ix)
    		{
    			cout << "-";
    		}
    		cout << name << endl;
    	}
    	void LineOfDuty() override  //履行职责  
    	{
    		cout << this->name << " 员工招聘培训管理" << endl;
    	}
    };
    
    class FinanceDepartment : public Company
    {
    public:
    	FinanceDepartment(string str) : Company(str) {}
    	void Add(Company* c) override  //增加
    	{
    
    	}
    	void Remove(Company* c) override  //移除
    	{
    
    	}
    	void Display(int depth) override  //显示
    	{
    		for (int ix = 0; ix < depth; ++ix)
    		{
    			cout << "-";
    		}
    		cout << name << endl;
    	}
    	void LineOfDuty() override  //履行职责  
    	{
    		cout << this->name << " 公司财务收支管理" << endl;
    	}
    };
    
    int main()
    {
    	Company* root = new ConcreteCompany("北京总公司");
    	root->Add(new HRDepartment("总公司人力资源部"));
    	root->Add(new FinanceDepartment("总公司财务部"));
    
    	ConcreteCompany* comp = new ConcreteCompany("上海华东分公司");
    	comp->Add(new HRDepartment("华东分公司人力资源部"));
    	comp->Add(new FinanceDepartment("华东分公司财务部"));
    	root->Add(comp);
    
    	ConcreteCompany* comp1 = new ConcreteCompany("南京办事处");
    	comp1->Add(new HRDepartment("南京办事处人力资源部"));
    	comp1->Add(new FinanceDepartment("南京办事处财务部"));
    	comp->Add(comp1);
    
    	ConcreteCompany* comp2 = new ConcreteCompany("杭州办事处");
    	comp2->Add(new HRDepartment("杭州办事处人力资源部"));
    	comp2->Add(new FinanceDepartment("杭州办事处财务部"));
    	comp->Add(comp2);
    
    	cout << "
    结构图" << endl;
    	root->Display(1);
    
    	cout << "
    职责:" << endl;
    	root->LineOfDuty();
    
    	return 0;
    }
    
    
  • 相关阅读:
    Linux/Unix中的#!和!#
    包含min函数的栈
    顺时针打印矩阵
    二叉树镜像
    数的子结构
    合并两个排序的链表
    反转链表
    链表中倒数第K个结点
    调整数组顺序使奇数位于偶数前面
    在O(1)时间删除链表结点
  • 原文地址:https://www.cnblogs.com/Manual-Linux/p/11139415.html
Copyright © 2011-2022 走看看