设计模式练习一

2016-07-09  本文已影响362人  茶色少年
class Point
{
public:
    int x;
    int y;
};

class Line
{
public:
    Point start;
    Point end;

    Line(const Point& start, const Point& end){
        this->start = start;
        this->end = end;
    }

};

class Rect
{
public:
    Point leftUp;
    int width;
    int height;

    Rect(const Point& leftUp, int width, int height){
        this->leftUp = leftUp;
        this->width = width;
        this->height = height;
    }

};

//增加
class Circle{


};

class MainForm : public Form
 {
private:
    Point p1;
    Point p2;

    vector<Line> lineVector;
    vector<Rect> rectVector;
    //改变
    vector<Circle> circleVector;

public:
    MainForm()
{
        //...
    }
protected:

    virtual void OnMouseDown(const MouseEventArgs& e);
    virtual void OnMouseUp(const MouseEventArgs& e);
    virtual void OnPaint(const PaintEventArgs& e);
};


void MainForm::OnMouseDown(const MouseEventArgs& e){
    p1.x = e.X;
    p1.y = e.Y;

    //...
    Form::OnMouseDown(e);
}

void MainForm::OnMouseUp(const MouseEventArgs& e){
    p2.x = e.X;
    p2.y = e.Y;

    if (rdoLine.Checked){
        Line line(p1, p2);
        lineVector.push_back(line);
    }
    else if (rdoRect.Checked){
        int width = abs(p2.x - p1.x);
        int height = abs(p2.y - p1.y);
        Rect rect(p1, width, height);
        rectVector.push_back(rect);
    }
    //改变
    else if (...){
        //...
        circleVector.push_back(circle);
    }

    //...
    this->Refresh();

    Form::OnMouseUp(e);
}

void MainForm::OnPaint(const PaintEventArgs& e){
//---------------------------------------------------------
    //针对直线
    for (int i = 0; i < lineVector.size(); i++){
        e.Graphics.DrawLine(Pens.Red,
            lineVector[i].start.x, 
            lineVector[i].start.y,
            lineVector[i].end.x,
            lineVector[i].end.y);
    }

    //针对矩形
    for (int i = 0; i < rectVector.size(); i++){
        e.Graphics.DrawRectangle(Pens.Red,
            rectVector[i].leftUp,
            rectVector[i].width,
            rectVector[i].height);
    }

    //改变
    //针对圆形
    for (int i = 0; i < circleVector.size(); i++){
        e.Graphics.DrawCircle(Pens.Red,
            circleVector[i]);
    }
//---------------------------------------------------------
    //...
    Form::OnPaint(e);
}

在OnPain中,画不同的图形,e.Graphics需要调用不同的画图函数,并且随着画的类型的增加,则需要不断地修改原先OnPain中的代码,利用类的多态性可以解决这个问题,用到了策略模式

class Shape//创建一个虚基类,分别让不同的图形类继承于它,相当于提供了一个接口。
{
public:
    virtual void Draw() = 0;
}

class Point{
public:
    int x;
    int y;
};

class Line:public Shape
{
public:
    Point start;
    Point end;

    Line(const Point& start, const Point& end){
        this->start = start;
        this->end = end;
    }
    
    void Draw(const Graphics& g)
    {
        g.DrawLine(start,end);
    }

};

class Rect:public Shape
{
private:
    Point leftUp;
    int width;
    int height;
public:
    Rect(const Point& leftUp, int width, int height){
        this->leftUp = leftUp;
        this->width = width;
        this->height = height;
    }
    void Draw(const Graphics& g)
    {
        g.DrawRectangle(leftUp,width,height);
    }
};

//增加
class Circle
{
private:
    Point center;
    int radius;
public:
    Circle(const &_center, int _radius)
    {
        this->center = _center;
        this->radius = radius;
    }
    void Draw(const Graphics &g)
    {
        g.DrawCircle(center,radius);
    }

};

class MainForm : public Form {
private:
    Point p1;
    Point p2;

    vector<Shape*> shapeVector;


public:
    MainForm(){
        //...
    }
protected:

    virtual void OnMouseDown(const MouseEventArgs& e);
    virtual void OnMouseUp(const MouseEventArgs& e);
    virtual void OnPaint(const PaintEventArgs& e);
};


void MainForm::OnMouseDown(const MouseEventArgs& e){
    p1.x = e.X;
    p1.y = e.Y;

    //...
    Form::OnMouseDown(e);
}

void MainForm::OnMouseUp(const MouseEventArgs& e){
    p2.x = e.X;
    p2.y = e.Y;

    if (rdoLine.Checked){
        Line *line = new line(p1, p2);
        shapeVector->push_back(line);
    }
    else if (rdoRect.Checked){
        int width = abs(p2.x - p1.x);
        int height = abs(p2.y - p1.y);
        Rect *rect = new Rect(p1, width, height);
        shapeVector->push_back(rect);
    }
    //改变
    else if (...){
        //...
        shapeVector->push_back(circle);
    }

    //...
    this->Refresh();

    Form::OnMouseUp(e);
}

void MainForm::OnPaint(const PaintEventArgs& e){

    //针对直线
    for (int i = 0; i < shapeVector.size(); i++){
        shapeVector[i]->Draw(e.Graphics);
    }
    //...
    Form::OnPaint(e);
}


可以看到,OnPaint函数简洁了很多,而且图形的类型增加,也不会影响这里的代码。

上一篇下一篇

猜你喜欢

热点阅读