在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
问题描述上图,是一个公司的组织结构图,总部下面有多个子公司,同时总部也有各个部门,子公司下面有多个部门。如果对这样的公司开发一个OA系统,作为程序员的你,如何设计这个OA系统呢?先不说如何设计实现,接着往下看,看完了下面的内容,再回过头来想怎么设计这样的OA系统。 什么是组合模式?在GOF的《设计模式:可复用面向对象软件的基础》一书中对组合模式是这样说的:将对象组合成树形结构以表示“部分-整体”的层次结构。组合(Composite)模式使得用户对单个对象和组合对象的使用具有一致性。 组合模式(Composite)将小对象组合成树形结构,使用户操作组合对象如同操作一个单个对象。组合模式定义了“部分-整体”的层次结构,基本对象可以被组合成更大的对象,而且这种操作是可重复的,不断重复下去就可以得到一个非常大的组合对象,但这些组合对象与基本对象拥有相同的接口,因而组合是透明的,用法完全一致。 我们这样来简单的理解组合模式,组合模式就是把一些现有的对象或者元素,经过组合后组成新的对象,新的对象提供内部方法,可以让我们很方便的完成这些元素或者内部对象的访问和操作。我们也可以把组合对象理解成一个容器,容器提供各种访问其内部对象或者元素的API,我们只需要使用这些方法就可以操作它了。 UML类图Component:
Leaf:
Composite:
Client: 通过Component接口操作组合部件的对象。 代码实现1 #include <iostream> 2 #include <string> 3 #include <vector> 4 using namespace std; 5 // 抽象的部件类描述将来所有部件共有的行为 6 class Component 7 { 8 public: 9 Component(string name) : m_strCompname(name){} 10 virtual ~Component(){} 11 virtual void Operation() = 0; 12 virtual void Add(Component *) = 0; 13 virtual void Remove(Component *) = 0; 14 virtual Component *GetChild(int) = 0; 15 virtual string GetName() 16 { 17 return m_strCompname; 18 } 19 virtual void Print() = 0; 20 protected: 21 string m_strCompname; 22 }; 23 class Leaf : public Component 24 { 25 public: 26 Leaf(string name) : Component(name) 27 {} 28 void Operation() 29 { 30 cout<<"I'm "<<m_strCompname<<endl; 31 } 32 void Add(Component *pComponent){} 33 void Remove(Component *pComponent){} 34 Component *GetChild(int index) 35 { 36 return NULL; 37 } 38 void Print(){} 39 }; 40 class Composite : public Component 41 { 42 public: 43 Composite(string name) : Component(name) 44 {} 45 ~Composite() 46 { 47 vector<Component *>::iterator it = m_vecComp.begin(); 48 while (it != m_vecComp.end()) 49 { 50 if (*it != NULL) 51 { 52 cout<<"----delete "<<(*it)->GetName()<<"----"<<endl; 53 delete *it; 54 *it = NULL; 55 } 56 m_vecComp.erase(it); 57 it = m_vecComp.begin(); 58 } 59 } 60 void Operation() 61 { 62 cout<<"I'm "<<m_strCompname<<endl; 63 } 64 void Add(Component *pComponent) 65 { 66 m_vecComp.push_back(pComponent); 67 } 68 void Remove(Component *pComponent) 69 { 70 for (vector<Component *>::iterator it = m_vecComp.begin(); it != m_vecComp.end(); ++it) 71 { 72 if ((*it)->GetName() == pComponent->GetName()) 73 { 74 if (*it != NULL) 75 { 76 delete *it; 77 *it = NULL; 78 } 79 m_vecComp.erase(it); 80 break; 81 } 82 } 83 } 84 Component *GetChild(int index) 85 { 86 if (index > m_vecComp.size()) 87 { 88 return NULL; 89 } 90 return m_vecComp[index - 1]; 91 } 92 void Print() 93 { 94 for (vector<Component *>::iterator it = m_vecComp.begin(); it != m_vecComp.end(); ++it) 95 { 96 cout<<(*it)->GetName()<<endl; 97 } 98 } 99 private: 100 vector<Component *> m_vecComp; 101 }; 102 int main(int argc, char *argv[]) 103 { 104 Component *pNode = new Composite("Beijing Head Office"); 105 Component *pNodeHr = new Leaf("Beijing Human Resources Department"); 106 Component *pSubNodeSh = new Composite("Shanghai Branch"); 107 Component *pSubNodeCd = new Composite("Chengdu Branch"); 108 Component *pSubNodeBt = new Composite("Baotou Branch"); 109 pNode->Add(pNodeHr); 110 pNode->Add(pSubNodeSh); 111 pNode->Add(pSubNodeCd); 112 pNode->Add(pSubNodeBt); 113 pNode->Print(); 114 Component *pSubNodeShHr = new Leaf("Shanghai Human Resources Department"); 115 Component *pSubNodeShCg = new Leaf("Shanghai Purchasing Department"); 116 Component *pSubNodeShXs = new Leaf("Shanghai Sales department"); 117 Component *pSubNodeShZb = new Leaf("Shanghai Quality supervision Department"); 118 pSubNodeSh->Add(pSubNodeShHr); 119 pSubNodeSh->Add(pSubNodeShCg); 120 pSubNodeSh->Add(pSubNodeShXs); 121 pSubNodeSh->Add(pSubNodeShZb); 122 pNode->Print(); 123 // 公司不景气,需要关闭上海质量监督部门 124 pSubNodeSh->Remove(pSubNodeShZb); 125 if (pNode != NULL) 126 { 127 delete pNode; 128 pNode = NULL; 129 } 130 return 0; 131 }
实现要点
组合模式的优点将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。 使用场景
引用大话设计模式的片段:“当发现需求中是体现部分与整体层次结构时,以及你希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,就应该考虑组合模式了。” 总结通过上面的简单讲解,我们知道了,组合模式意图是通过整体与局部之间的关系,通过树形结构的形式进行组织复杂对象,屏蔽对象内部的细节,对外展现统一的方式来操作对象,是我们处理更复杂对象的一个手段和方式。现在再结合上面的代码,想想文章开头提出的公司OA系统如何进行设计。 |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论