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 }
时间: 2025-01-11 03:47:04

c++ 设计模式总结1的相关文章

Java设计模式——创建型模式之单例模式

一.概述 作为第一个出场的设计模式,有必要先介绍一下设计模式(引用自百度百科): 设计模式(Design Pattern)是一套被反复使用.多数人知晓的.经过分类的.代码设计经验的总结. 使用设计模式的目的:为了代码可重用性.让代码更容易被他人理解.保证代码可靠性. 设计模式使代码编写真正工程化:设计模式是软件工程的基石脉络,如同大厦的结构一样. 设计模式概念的介绍,参见:http://blog.jobbole.com/101076/ 其中涉及的设计原则的概念,参见随笔:http://www.c

10大APP界面框架设计模式详解

随着移动互联网的发展,移动app已经成为了每个互联网公司的标配了,那作为产品经理,我们如何设计出更加符合用户体验的app产品呢?今天和大家分享的就是10中最常见的app界面光甲设计模式,一起来看看吧. 1.标签导航 标签导航是十大界面框架设计里最常用的界面框架设计,也是被业界之内公认的一种普遍使用的页面框架设计.那么这种页面框架设计在作业方面对一个用户来说也是最常见的一种页面框架设计,比如说微博.微信.手机百度.支付宝.淘宝,这些我们所谓的超级APP都是运用的标签导航,无一例外.从这个角度也可以

[js高手之路]设计模式系列课程-组合模式+寄生组合继承实战新闻列表

所谓组合模式,就是把一堆结构分解出来,组成在一起,现实中很多这样的例子,如: 1.肯德基套餐就是一种组合模式, 比如鸡腿堡套餐,一般是是由一个鸡腿堡,一包薯条,一杯可乐等组成的 2.组装的台式机同理,由主板,电源,内存条,显卡, 机箱,显示器,外设等组成的 把一个成型的产品组成部件,分成一个个独立的部件,这种方式可以做出很多灵活的产品,这就是组合模式的优势 比如:家用台式机电脑,要求配置比较低, 这个时候只需要主板+电源+内存条+机箱+显示器+外设就可以了,不需要配置独立显卡 鸡腿堡+鸡翅+紫薯

Happy 设计模式之适配器模式(JAVA)

设计模式-适配器模式 适配器模式定义 适配器模式,将一个类的的接口转换成客户或者产品希望的接口形式,就是原本不兼容或者甚至不相干的接口不能一起工作的接口一起工作,完成需求或者客户的需求. 适配器模式的使用场景 1.当你使用一个已经存在的类,而他的接口不符合你的需求. 2.你想要创建一个复用的类,该类可以与其相关的类或者不可见的类协同工作. 适配器角色 Target:目标接口 TargetImpl:目标实现类 Adapter:适配器 Adaptee:被适配者 代码解析: package com.d

设计模式 2/23 工厂模式

工厂模式是最常用的设计模式之一,用好了,代码优雅,可维护性高,对系统设计会上一个台阶 为什么这么说,因为工厂模式可以牵扯出抽象工厂模式,也有大家都会聊到的简单工厂模式 我们要了解一点,23中设计模式中,不包含简单工厂模式,之所以大家会去聊这个,四个字,渐进明细 通过对简单工厂模式的了解,我们引入工厂这个词,不然一个写代码的,天天给他讲工厂,工厂,工厂,西厂,东厂,会晕 同时,通过逐步的深入,从简单工厂,到工厂模式,再到抽象工厂,渐进明细的过程,逐步深入的理解,比较优劣,择优而为我们所用. 试想我

Java设计模式学习笔记,一:单例模式

开始学习Java的设计模式,因为做了很多年C语言,所以语言基础的学习很快,但是面向过程向面向对象的编程思想的转变还是需要耗费很多的代码量的.所有希望通过设计模式的学习,能更深入的学习. 把学习过程中的笔记,记录下来,只记干货. 第一部分:单例模式的内容 单例模式:类只能有一个实例. 类的特点:1.私有构造器:2.内部构造实例对象:3.对外提供获取唯一实例的public方法. 常见的单例模式实现有五种形式: 1.饿汉式. 2.懒汉式. 3.双重检查锁式. 4.静态内部类式. 5.枚举式. 以下分别

设计模式之单列模式

设计模式之单列模式 1,何为单列模式? 即singleton 在某个类采用了单列模式之后  其只能有一个实列对象 ,并且这个实列对象只能有内部自己创建并提供给外部的调用. 2.实现单列模式的方法 分为 :饿汉式 ,懒汉式 下面为饿汉式实现代码: public calss Singleton1{ //将构造函数私有化 防止外部通过new来创建对象 private Singleton1(){ } //创建一个私有静态变量并直接初始化 类加载的时候直接创建对象 private static Singl

设计模式之原型模式(Prototype)

1.初识原型模式 大家都知道连锁机构是现在灰常流行的商业模式,比如咖啡之翼,那么假设咖啡之翼要在长春新建立一个分店,所经营的产品和以前在其他的城市已经存在的店经营的产品差不多,那么面向对象开发的角度怎么解决这个问题呢?难道要重新的实例化一个咖啡之翼的店??这显然不太好吧,咖啡之翼里面经营的产品(假设是属性吧)都需要重新写,这就是在做大量的重复工作啊,这显然是不符合OO开发思想的.遇到这样的情况,并不是重新建立一个类来解决这样的问题,而是通过设计模式中的"原型模式"来解决这种问题.是这种

对设计模式的总结之简单工厂与策略模式

前言 面向对象编程追求的本质-提高扩展性.可维护性.灵活性和复用性.合理利用面向对象6个原则,能够很好的达到要求.如何利用好就是至关重要的了,前人总结了23+个设计模式能够让初学者更容易学到其中的精髓,本文就说说我对本人对简单工厂模式.策略模式的见解. 简单工厂模式与策略模式 简单工厂模式 工作中,常常遇到需要做一个功能(鸭子),这个功能中含有可控个数的子操作功能(鸭子叫,鸭子跑,鸭子飞),而且子功能在不同的情况下处理方式又不相同(成年鸭子/小鸭子叫,成年鸭子/小鸭子跑,成年鸭子/小鸭子飞).我

设计模式——介绍与工厂模式(扁平管理模式VS职业经理人模式)

本文主要对设计模式进行大概解说.特别是对工厂模式进行简明的解析: 一.设计模式的分类 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组合模式.享元模式. 行为型模式,共十一种:策略模式.模板方法模式.观察者模式.迭代子模式.责任链模式.命令模式.备忘录模式.状态模式.訪问者模式.中介者模式.解释器模式. 事实上还有两类:并发型模式和线程池模式. 二.设计模式的六大原则 1.开闭原则(Op