zoukankan      html  css  js  c++  java
  • c++ 设计模式1

    从面向对象谈起

    1)

    底层思维:向下,如何把握及其底层,从微观理解对象构造 

                 (语言构造、编译转换、内存模型、运行时机制)

    抽象思维: 向上,如何将我们的周围世界抽象为程序代码

         (面向对象、组件封装、设计模式、架构模式)

    2)

    深入理解面向对象 

    向下: 深入理解三大面向对象机制(封装、继承、多态)

    向上:深刻把握面向对象机制所带来的抽象意义,掌握如何使用这些机制来表达现实世界。

             掌握什么是”好的面向对象设计“。 (不是使用了封装、继承、多态就是面向对象)

    3)

    软件设计复杂的根本原因: 变化!

    4)如何解决复杂性? (分解与抽象

    分解:分而治之,将大问题分解为多个小问题,复杂问题分解为简单问题

    抽象:更高层次来讲,人们处理复杂性有一个通用的技术,即抽象。

            由于不能掌握全部的复杂对象,我们选择忽略它的非本质细节,而去处理泛化和理想化的对象模型

    5)代码示例:画图简单工具代码描述 (伪代码,关注业务逻辑,体会分解与抽象的不同)

    两种实现方法描述

    第一种实现:(分解)

    Shape1 中, 各自建立Point,Line,Rec类

    Mainform1中,建立存储不同类型图形的数据结构(vector<Point>, vector<Line>...);

           鼠标点击时根据类型判断存储在不同结构中;

           Onpaint方法依次实现不同图形画法。

    第二种实现:(抽象)

    Shape2中,建立Shape基类和draw虚函数;

          Point Line Rec等继承Shape类,并override draw函数,自己画自己。

    Mainform2中,建立存储基类指针的数据结构(vector<Shape*>),实现对所有形状存储;

           鼠标点击时根据类型判断以不同方式存储在 vector<Shape*>中, 如 = new Rec() 或 = new Line()

           Onpaint方法,多态调用,各负其责。

    孰优孰劣? 评判标准?

    功能均可实现,但考虑实现好坏的标准应该要考虑变化!

    变化: 增加circle类和其画法

    对于第一种实现: 36-40行 增加circle类; 53行 增加vector<Circle>;  89-93行 增加对Circle判断和存储; 120 -125行增加画circle的

    对于第二种实现:54-62行 增加circle类继承shape;    107-111行增加对Circle判断和存储(采用工厂模式也可消除该变化)

    可以看出第二种是实现代码变更部分更少(尤其不必修改内部代码,只是额外添加),代码复用性更强,抵御变化能力更强。

    6) 回到软件设计的目标

    软件设计的金科玉律: 复用!

    shape1 & Mainform1 :

      1 //Shape1.h
      2 //
      3 
      4 class Point{
      5 public:
      6     int x;
      7     int y;
      8 };
      9 
     10 class Line{
     11 public:
     12     Point start;
     13     Point end;
     14 
     15     Line(const Point& start, const Point& end){
     16         this->start = start;
     17         this->end = end;
     18     }
     19 
     20 };
     21 
     22 class Rect{
     23 public:
     24     Point leftUp;
     25     int width;
     26     int height;
     27 
     28     Rect(const Point& leftUp, int width, int height){
     29         this->leftUp = leftUp;
     30         this->width = width;
     31         this->height = height;
     32     }
     33 
     34 };
     35 
     36 //增加
     37 class Circle{
     38 
     39 
     40 };
     41  
     42 //Mainform1.cpp
     43 //
     44 
     45 class MainForm : public Form {
     46 private:
     47     Point p1;
     48     Point p2;
     49 
     50     vector<Line> lineVector;
     51     vector<Rect> rectVector;
     52     //改变
     53     vector<Circle> circleVector;
     54 
     55 public:
     56     MainForm(){
     57         //...
     58     }
     59 protected:
     60 
     61     virtual void OnMouseDown(const MouseEventArgs& e);
     62     virtual void OnMouseUp(const MouseEventArgs& e);
     63     virtual void OnPaint(const PaintEventArgs& e);
     64 };
     65 
     66 
     67 void MainForm::OnMouseDown(const MouseEventArgs& e){
     68     p1.x = e.X;
     69     p1.y = e.Y;
     70 
     71     //...
     72     Form::OnMouseDown(e);
     73 }
     74 
     75 void MainForm::OnMouseUp(const MouseEventArgs& e){
     76     p2.x = e.X;
     77     p2.y = e.Y;
     78 
     79     if (rdoLine.Checked){
     80         Line line(p1, p2);
     81         lineVector.push_back(line);
     82     }
     83     else if (rdoRect.Checked){
     84         int width = abs(p2.x - p1.x);
     85         int height = abs(p2.y - p1.y);
     86         Rect rect(p1, width, height);
     87         rectVector.push_back(rect);
     88     }
     89     //改变
     90     else if (...){
     91         //...
     92         circleVector.push_back(circle);
     93     }
     94 
     95     //...
     96     this->Refresh();
     97 
     98     Form::OnMouseUp(e);
     99 }
    100 
    101 void MainForm::OnPaint(const PaintEventArgs& e){
    102 
    103     //针对直线
    104     for (int i = 0; i < lineVector.size(); i++){
    105         e.Graphics.DrawLine(Pens.Red,
    106             lineVector[i].start.x, 
    107             lineVector[i].start.y,
    108             lineVector[i].end.x,
    109             lineVector[i].end.y);
    110     }
    111 
    112     //针对矩形
    113     for (int i = 0; i < rectVector.size(); i++){
    114         e.Graphics.DrawRectangle(Pens.Red,
    115             rectVector[i].leftUp,
    116             rectVector[i].width,
    117             rectVector[i].height);
    118     }
    119 
    120     //改变
    121     //针对圆形
    122     for (int i = 0; i < circleVector.size(); i++){
    123         e.Graphics.DrawCircle(Pens.Red,
    124             circleVector[i]);
    125     }
    126 
    127     //...
    128     Form::OnPaint(e);
    129 }

    shape2 & Mainform2 :

      1 //Shape2
      2 //
      3 class Shape{
      4 public:
      5     virtual void Draw(const Graphics& g)=0;
      6     virtual ~Shape() { }
      7 };
      8 
      9 
     10 class Point{
     11 public:
     12     int x;
     13     int y;
     14 };
     15 
     16 class Line: public Shape{
     17 public:
     18     Point start;
     19     Point end;
     20 
     21     Line(const Point& start, const Point& end){
     22         this->start = start;
     23         this->end = end;
     24     }
     25 
     26     //实现自己的Draw,负责画自己
     27     virtual void Draw(const Graphics& g){
     28         g.DrawLine(Pens.Red, 
     29             start.x, start.y,end.x, end.y);
     30     }
     31 
     32 };
     33 
     34 class Rect: public Shape{
     35 public:
     36     Point leftUp;
     37     int width;
     38     int height;
     39 
     40     Rect(const Point& leftUp, int width, int height){
     41         this->leftUp = leftUp;
     42         this->width = width;
     43         this->height = height;
     44     }
     45 
     46     //实现自己的Draw,负责画自己
     47     virtual void Draw(const Graphics& g){
     48         g.DrawRectangle(Pens.Red,
     49             leftUp,width,height);
     50     }
     51 
     52 };
     53 
     54 //增加
     55 class Circle : public Shape{
     56 public:
     57     //实现自己的Draw,负责画自己
     58     virtual void Draw(const Graphics& g){
     59         g.DrawCircle(Pens.Red,
     60             ...);
     61     }
     62 
     63 };
     64 
     65 //Mainform2
     66 //
     67 class MainForm : public Form {
     68 private:
     69     Point p1;
     70     Point p2;
     71 
     72     //针对所有形状
     73     vector<Shape*> shapeVector;
     74 
     75 public:
     76     MainForm(){
     77         //...
     78     }
     79 protected:
     80 
     81     virtual void OnMouseDown(const MouseEventArgs& e);
     82     virtual void OnMouseUp(const MouseEventArgs& e);
     83     virtual void OnPaint(const PaintEventArgs& e);
     84 };
     85 
     86 
     87 void MainForm::OnMouseDown(const MouseEventArgs& e){
     88     p1.x = e.X;
     89     p1.y = e.Y;
     90 
     91     //...
     92     Form::OnMouseDown(e);
     93 }
     94 
     95 void MainForm::OnMouseUp(const MouseEventArgs& e){
     96     p2.x = e.X;
     97     p2.y = e.Y;
     98 
     99     if (rdoLine.Checked){
    100         shapeVector.push_back(new Line(p1,p2));
    101     }
    102     else if (rdoRect.Checked){
    103         int width = abs(p2.x - p1.x);
    104         int height = abs(p2.y - p1.y);
    105         shapeVector.push_back(new Rect(p1, width, height));
    106     }
    107     //改变  (使用工厂模式这里的变化也可消除)
    108     else if (...){
    109         //...
    110         shapeVector.push_back(circle);
    111     }
    112 
    113     //...
    114     this->Refresh();
    115 
    116     Form::OnMouseUp(e);
    117 }
    118 
    119 void MainForm::OnPaint(const PaintEventArgs& e){
    120 
    121     //针对所有形状
    122     for (int i = 0; i < shapeVector.size(); i++){
    123 
    124         shapeVector[i]->Draw(e.Graphics); //多态调用,各负其责
    125     }
    126 
    127     //...
    128     Form::OnPaint(e);
    129 }
  • 相关阅读:
    Java学习-021-Properties 获取配置项对应的值
    Java学习-020-Properties 判断是否存在对应的 key 项
    Java学习-019-Properties 文件读取实例源代码
    Java学习-018-EXCEL 文件写入实例源代码
    Redis进阶实践之九 独立封装的RedisClient客户端工具类
    Redis进阶实践之八Lua的Cjson在Linux下安装、使用和用C#调用Lua脚本
    Redis进阶实践之七Redis和Lua初步整合使用
    Redis进阶实践之六Redis Desktop Manager连接Windows和Linux系统上的Redis服务
    Redis进阶实践之五Redis的高级特性
    Redis进阶实践之四Redis的基本数据类型
  • 原文地址:https://www.cnblogs.com/wangxiaobao/p/5141710.html
Copyright © 2011-2022 走看看