【GeekBand】C++面向对象高级编程-第十周笔记

概念:将对象组合成树形结构以表示“部分-整体”的层次结构。Composite使得用户对单个对象和组合的使用具有一致性。

注意:组合模式有透明组合模式和安全组合模式。透明组合模式是将Addordinate和GetSubordinate这两个函数也抽象到CCorpNode基类里,这增加了操作叶子节点的难度,更易出现逻辑问题。所以尽量使用安全模式。

针对DrawingSystem中的基类Shape和各个子类Line、Rec、Circle,请使用某种模式来支持更复杂的形状,该复杂形状是各个形状的自由组合。使用松耦合面向对象设计方法和思想,可使用伪码表示设计。

经过思考,认为组合模式最适合这题目。
可以构想将这些子类作为叶子,而叶子可以在挂载在同一个节点上,那么这个节点便是复杂形状。由此,按照这个思路,完成了作业

//使用设计模式中的组合模式
//Shape为抽象基类
//ShapeNode 为节点类
//其他基本形状为Leaf。

#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;

class Shape
{
public:
    virtual ~Shape(){}
    virtual void Add(Shape *) = 0;           //加载元素
    virtual void Remove(unsigned int) = 0;   //移除指定位置元素
    virtual void Clear() = 0;                //清空元素
    virtual void GetInfo() = 0;              //获取形状信息
    virtual void Process() = 0;
};

class Line :public Shape
{
private:
    string info = "Line";
public:
    Line() { }
    void Add(Shape *pComponent){}
    void Remove(unsigned int num){}
    virtual void Clear() {}
    void GetInfo()
    {
        cout <<info << endl;
    }
    void Process()
    {
        //... 
    }
};

class Circle :public Shape
{
private:
    string info = "Circle";
public:
    Circle() { }
    void Add(Shape *pComponent){}
    void Remove(unsigned int num){}
    virtual void Clear() {}
    void GetInfo()
    {
        cout << info << endl;
    }
    void Process()
    {
        //... 
    }
};

class Rec :public Shape
{
private:
    string info = "Rec";
public:
    Rec() { }
    void Add(Shape *pComponent){}
    void Remove(unsigned int num){}
    virtual void Clear() {}
    void GetInfo()
    {
        cout <<info << endl;
    }
    void Process()
    {
        //... 
    }
};

class ShapeNode:public Shape
{
private:
    static int cnt;//用于统计有多少个节点
    int num;
    vector<Shape *> shapeNode;
public:
    typedef vector<Shape *>::iterator ShapeLiterator;
    ShapeNode(){ ++cnt; num = cnt; }
    ~ShapeNode()
    {
        ShapeLiterator it = shapeNode.begin();
        while (it != shapeNode.end())
        {
            if (*it != NULL)
            {
                delete *it;
                *it = NULL;
            }
            shapeNode.erase(it);
            it = shapeNode.begin();
        }
    }

    void Add(Shape *pComponent)
    {
        shapeNode.push_back(pComponent);
    }

    void Remove(unsigned int num)
    {
        if (num < shapeNode.size())
        {
            ShapeLiterator it = shapeNode.begin();
            shapeNode.erase(it + num);
        }
        else
        {
            cerr << "the num is OUT OF LIMIT, please Input again" << endl;
        }
    }
    void Clear()
    {
        if (!shapeNode.empty())
        {
            shapeNode.clear();
        }
    }

    void GetInfo()
    {
        if (!shapeNode.empty())
        {
            cout <<"I'm No."<<num<<" ShapeNode, I have "<<shapeNode.size()<< " Shapes:" << endl;
            for (ShapeLiterator it = shapeNode.begin(); it != shapeNode.end();it++)
            {
                (*it)->GetInfo();
            }
        }
        else
        {
            cout << "I'm No." << num << " ShapeNode, I have no Shapes!" << endl;
        }
    }
    void Process()
    {
        //... 
    }
};
int ShapeNode::cnt = 0;
void Process(Shape &shape)
{
    shape.Process();
}

int main()
{
    //创建第一个多组合形状及其元素
    Shape *pShape1 = new ShapeNode();
    Shape *pLineLeaf1 = new Line();
    Shape *pLineLeaf2 = new Line();
    Shape *pCircleLeaf1 = new Circle();
    //加载元素
    pShape1->Add(pLineLeaf1);
    pShape1->Add(pLineLeaf2);
    pShape1->Add(pCircleLeaf1);
    pShape1->GetInfo();
    
    cout << endl;
    //创建第二个多组合形状及其元素
    Shape *pShape2 = new ShapeNode();
    Shape *pRecLeaf1 = new Rec();
    Shape *pCircleLeaf2 = new Circle();
    Shape *pRecLeaf2 = new Rec();
    //加载元素
    pShape2->Add(pRecLeaf1);
    pShape2->Add(pCircleLeaf2);
    pShape2->Add(pRecLeaf2);
    pShape2->GetInfo();
    cout << endl;

    //测试删除指定元素函数
    pShape2->Remove(1);
    pShape2->GetInfo();

    pShape2->Remove(4);

    //测试清空元素函数
    pShape2->Clear();
    cout << endl;
    pShape2->GetInfo();

    Process(pShape1);
    //... 


}

推荐阅读更多精彩内容