使用模式的一个简单例子——画图程序

使用原型模式和抽象工厂模式

      部门进行mfc的基础培训,一共4课时,要求最后能够实现一个简单的画图程序。其实我从学C++开始,就一直听人在说,mfc怎么怎么落后,怎么怎么不面向对象,当时什么也不懂,就一直隔着没碰,做编程实践,也仅仅是一些简单的控制台程序,对于比较高级一些的线程编程也就是在学java时才练了一下。网络编程根本没有接触。现在想想,原来很多东西(特别是软件工程和设计模式)都是纸上谈兵,做了一个如此简单的画图程序,才突然发现原来的抽象工厂、原型模式。。。是这样用的,有了一种醍醐灌顶的感觉。

     作为风光一时的霸主级IDE——VC6.0大大简化了win32编程,单从这一点来看,他就很成功。虽然据说他面向对象部分做的很不好,但是作为M$的成熟的应用程序框架,还是有必要学习一下的,就像侯捷老师所说的那样,每一个程序员都应该掌握framework的思想。而且用VC也一样可以写出封装较好的程序,一样可以把OO做的不错。关键的不是IDE,而是我们自己的大脑,所以看csdn上的很多关于比较javaIDE哪个好的文章都感觉很无聊。

    由于讲授mfc的老师拿到的课时比较少,而且我们对mfc的基础基本为零,所以老师就以最简单的方式给我们讲mfc如何运作,如何使用mfc画一条线等等,是面向过程的方式。听明白了以后,我就想把他以面向对象的方式实现。

    基本要求很简单,就是完成画图功能,画简单的直线,画曲线,画各种形状,所以抽象出一个公共基类:shape,然后从这个类派生出一些子类,如linecurverectangle等。

  class  CShape :  public  CObject  
{
public:
    CShape();
    
virtual ~CShape();
    
    
//原型模式
    virtual CShape* Clone() = 0;
    
    
//设置画图为纯虚函数
    virtual void DrawShape(CClientDC &dc) = 0;
    
    
//取得鼠标按下点的消息
    virtual void GetStartPoint(CPoint point) = 0;
    
    
virtual void GetEndPoint(CPoint point) = 0;
    
    
virtual void GetPoint(CClientDC &dc, CPoint point) = 0;
    
    
//设置画笔宽度
    void SetPenWidth(int width)
    
{
        m_iPenWidth 
= width;
    }

    
    
//设置画笔颜色
    void SetPenColor(COLORREF color)
    
{
        m_iPenColor 
= color;
    }

    
protected:
    
int    m_iPenWidth;
    COLORREF    m_iPenColor;    

private:
    
//禁止复制操作
    CShape(const CShape&);
    CShape
& operator=(const CShape&);    
}
;   

class  CLine :  public  CShape  
{
public:
                      ...
protected:
    CPoint m_ptStart;
    CPoint m_ptEnd;
}
;   

class  CCurve :  public  CShape  
{
public:
                      ...    
protected:
    CArray
<CPoint, CPoint> m_arrPointArray;
}
;                                                    

    这里小用了一把abstract factory模式将shape做成一个类似于工厂的抽象类,它其中定义了设置画笔颜色、宽度两个普通函数,然后是响应按键信息的纯虚函数GetStartPointGetEndPointGetMovePoint。子类派生的时候只需要实现这三个函数就好了。不同的子类拥有不同的数据成员,如直线拥有两个点对象,分别保存直线起始点和终止点的位置;曲线拥有一系列点的数组。

    当用户需要画直线的时候只需要想windows自带的画图程序那样,在画笔选择框上选中相应的图形即可,这时mfc相应一个何种画笔的信息,如果是直线,返回一个直线对象,如果是曲线,返回一个曲线对象,用户利用这个对象画图即可。View类中只有一个抽象类shape的指针,Doc类中保存图形中点的信息。选择操作都是由shape类型的这个指针完成。这就是一个简单的抽象工厂模式。

    当然用户不愿意每画一条线就点选一次画笔,Windows的画图程序有记忆上一次画线种类的方法,这个功能可以用另一个模式完成:原型模式,即在shape中添加一个纯虚函数clone,他的返回值是shape类型的指针,子类实现他,返回子类本身的一个对象。

CShape *  CCurve::Clone()
{
    
return new CCurve;
}


CShape
*  CLine::Clone()
{
    
return new CLine;
}

   

   这样在处理时,访问Doc类中保存图形信息的数组的最后一个元素,这样就可通过调用这个对象的clone操作完成,生成一个新对象的操作,而且这个对象与上一次的对象相同。

    让我比较郁闷的是,之前精心画的UML图和工厂模式图无法添加进来!CSDN赶紧改一下~

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值