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) 设计模式是前辈的一些经验总结之后的精髓,学习设计模式可以针对不同的问题给出更加优雅的解答 单例模式可分为俩种:懒汉模式和饿汉模式.俩种模式分别有不同的优势和缺 ...
随机推荐
- 基于Storm 分布式BP神经网络,将神经网络做成实时分布式架构
将神经网络做成实时分布式架构: Storm 分布式BP神经网络: http://bbs.csdn.net/topics/390717623 流式大数据处理的三种框架:Storm,Spark和Sa ...
- 第二百一十八天 how can I 坚持
真的是自以为是吗?或许是我想太多. 今天下雪了,2015年入冬以来的第一场雪,好冷. 又是一周. 睡觉吧,明天老贾生日. 没啥了,中午有点肚子疼,冬天了要注意.
- 关于Windows Azure 地缘组(Affinity Groups)
最近在和一些客户和朋友的沟通中,发现Windows Azure地缘组概念很少有了解.我的建议是使用地缘组来优化同一区域内的网络访问速度.如果我的说法有误,欢迎大家指正. 关于“地缘组”的概念(摘自MS ...
- HashSet与HashMap、Hashtable
(最近在老师叫我们用java去实现LRU算法,了解到要用双链表去做,要用到LinkHashMap去做,但自己对java的几大集合框架并不熟悉,在学习过程了解到了HashMap和HashSet,做个简单 ...
- compiled python files
[compiled python files] As an important speed-up of the start-up time for short programs that use a ...
- web.xml 详解
http://xmlns.jcp.org/xml/ns/javaee 重定向为 http://www.oracle.com/webfolder/technetwork/jsc/xml/ns/javae ...
- 深入浅出Spring(四) Spring实例分析
上次的博文中 深入浅出Spring(二) IoC详解 和 深入浅出Spring(三) AOP详解中,我们分别介绍了一下Spring框架的两个核心一个是IoC,一个是AOP.接下来我们来做一个Sprin ...
- angular实践第一弹:选项卡开发
在学习angular的过程中,实践是最好的方法. 在开发选项卡的过程中,不需要再像jquery一样以DOM操作为核心,那什么样的情况是以DOM操作为核心的Jquery的思想呢? 一想到改变什么,就想设 ...
- 通过css代码使边框变圆角(ie9以下浏览器不支持)
(从已经死了一次又一次终于挂掉的百度空间人工抢救出来的,发表日期2014-02-11) CSS代码: <style> #myDiv { border-radius: 4px; /*这句就是 ...
- xml和xsl配合使用实例
找到一个实际应用的例子,是英语统考打印准考证的实例,关于xml和xsl配合使用的. 下面看看xml文档 <?xml version='1.0' encoding='utf-8' ?> &l ...