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 :
//Shape1.h
// 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{ }; //Mainform1.cpp
// 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 = ; 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 = ; i < rectVector.size(); i++){
e.Graphics.DrawRectangle(Pens.Red,
rectVector[i].leftUp,
rectVector[i].width,
rectVector[i].height);
} //改变
//针对圆形
for (int i = ; i < circleVector.size(); i++){
e.Graphics.DrawCircle(Pens.Red,
circleVector[i]);
} //...
Form::OnPaint(e);
}
shape2 & Mainform2 :
//Shape2
//
class Shape{
public:
virtual void Draw(const Graphics& g)=;
virtual ~Shape() { }
}; 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;
} //实现自己的Draw,负责画自己
virtual void Draw(const Graphics& g){
g.DrawLine(Pens.Red,
start.x, start.y,end.x, end.y);
} }; class Rect: public Shape{
public:
Point leftUp;
int width;
int height; Rect(const Point& leftUp, int width, int height){
this->leftUp = leftUp;
this->width = width;
this->height = height;
} //实现自己的Draw,负责画自己
virtual void Draw(const Graphics& g){
g.DrawRectangle(Pens.Red,
leftUp,width,height);
} }; //增加
class Circle : public Shape{
public:
//实现自己的Draw,负责画自己
virtual void Draw(const Graphics& g){
g.DrawCircle(Pens.Red,
...);
} }; //Mainform2
//
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){
shapeVector.push_back(new Line(p1,p2));
}
else if (rdoRect.Checked){
int width = abs(p2.x - p1.x);
int height = abs(p2.y - p1.y);
shapeVector.push_back(new Rect(p1, width, height));
}
//改变 (使用工厂模式这里的变化也可消除)
else if (...){
//...
shapeVector.push_back(circle);
} //...
this->Refresh(); Form::OnMouseUp(e);
} void MainForm::OnPaint(const PaintEventArgs& e){ //针对所有形状
for (int i = ; i < shapeVector.size(); i++){ shapeVector[i]->Draw(e.Graphics); //多态调用,各负其责
} //...
Form::OnPaint(e);
}
c++ 设计模式1的更多相关文章
- MVVM设计模式和WPF中的实现(四)事件绑定
MVVM设计模式和在WPF中的实现(四) 事件绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...
- java EE设计模式简介
1.何为设计模式 设计模式提供了对常见应用设计问题的解决方案.在面向对象的编程中,设计模式通常在解决与对象创建和交互相关的问题,而非整体软件架构所面对的大规模问题,它们以样板代码的形式提供了通用的解决 ...
- 计算机程序的思维逻辑 (54) - 剖析Collections - 设计模式
上节我们提到,类Collections中大概有两类功能,第一类是对容器接口对象进行操作,第二类是返回一个容器接口对象,上节我们介绍了第一类,本节我们介绍第二类. 第二类方法大概可以分为两组: 接受其他 ...
- 《JavaScript设计模式 张》整理
最近在研读另外一本关于设计模式的书<JavaScript设计模式>,这本书中描述了更多的设计模式. 一.创建型设计模式 包括简单工厂.工厂方法.抽象工厂.建造者.原型和单例模式. 1)简单 ...
- 《JavaScript设计模式与开发实践》整理
最近在研读一本书<JavaScript设计模式与开发实践>,进阶用的. 一.高阶函数 高阶函数是指至少满足下列条件之一的函数. 1. 函数可以作为参数被传递. 2. 函数可以作为返回值输出 ...
- 设计模式之行为类模式大PK
行为类模式大PK 行为类模式包括责任链模式.命令模式.解释器模式.迭代器模式.中介者模式.备忘录模式.观察者模式.状态模式.策略 ...
- .NET设计模式访问者模式
一.访问者模式的定义: 表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作. 二.访问者模式的结构和角色: 1.Visitor 抽象访问者角色,为该 ...
- Java开发中的23种设计模式详解
[放弃了原文访问者模式的Demo,自己写了一个新使用场景的Demo,加上了自己的理解] [源码地址:https://github.com/leon66666/DesignPattern] 一.设计模式 ...
- java 设计模式
目录: 设计模式六大原则(1):单一职责原则 设计模式六大原则(2):里氏替换原则 设计模式六大原则(3):依赖倒置原则 设计模式六大原则(4):接口隔离原则 设计模式六大原则(5):迪米特法则 设计 ...
- 设计模式之单例模式(Singleton)
设计模式之单例模式(Singleton) 设计模式是前辈的一些经验总结之后的精髓,学习设计模式可以针对不同的问题给出更加优雅的解答 单例模式可分为俩种:懒汉模式和饿汉模式.俩种模式分别有不同的优势和缺 ...
随机推荐
- 给Adobe Reader添加书签功能
Adobe Acrobat Professional和Adobe Reader都是Adobe公司的产品.前者用来编辑制作PDF文档,后者只能用来阅读PDF.令人郁闷的是Adobe Reader中虽然有 ...
- 2013-2014集训之DP
第一周: 经过漫长的时间,终于有时间来写一下结题报告. 地址http://acm.hust.edu.cn/vjudge/contest/view.action?cid=36180#overview A ...
- shutdown 和closesocket
来,咱们彻底的来讨论一下这个shutdown 和closesocket 从 函数调用上来分析(msdn):一旦完成了套接字的连接,应当将套接字关闭,并且释放其套接字句柄所占用的所有资源.真正释放一 ...
- PetaPoco T4模板修改生成实体
PetaPoco T4 模板生成的实体类全部包含再一个.CS文件中.通过修改PetaPoco的T4模板,生成单文件实体. 1.生成单CS文件模板: SigleFile.ttinclude <#@ ...
- chrome 41 空格
chrome 41对半角空格的解析 当做一个汉字宽度来处理了. 导致很多网站出现异常. 目前能想到的方法是删掉用来规范格式的空格. 老版chrome chrome41 和讯网也有这种问题 有更好的处理 ...
- nginx 配置虚拟主机(支持php)
配置步骤: 1.在nginx安装目录下,找到nginx.conf所在文件夹,新建vhost文件夹 2.在nginx.conf http{} 末端加入 include vhost/*.conf; 3.进 ...
- ActionBar ShareActionProvider
添加share按钮 添加share按钮的主要步骤: 1. 在ActionBar中添加share按钮 2. 从item中获取ShareActionProvider ShareActionProvider ...
- Objective-C运行时编程 - 方法混写 Method Swizzling
摘要: 本文描述方法混写对实例.类.父类.不存在的方法等情况处理,属于Objective-C(oc)运行时(runtime)编程范围. 编程环境:Xcode 6.1.1, Yosemite,iOS 8 ...
- SAE/ISO standards for Automotive
On-Board Diagnostics J1962 Diagnostic Connector Equivalent to ISO/DIS 15031-3: December 14, 2001J201 ...
- CUDA Memories--CUDA记忆体(翻译+整理+测试)
一边学习一边记录(本文中英结合,专业名词统统不翻译) 在CUDA里,host和devices有不同的记忆体空间. 首先呢,CUDA的memory有很多种类啦 1. Global memory 2. C ...