1.学习目标

1)理解松耦合设计思想;

2)掌握面向对象设计原则;

3)掌握重构技法改善设计;

4)掌握GOF核心设计模式;

2.定义

每个设计模式描述了一个在我们周围不断重复发生的问题,以及该问题解决方案的核心。这样,你就能一次又一次地使用该方案而不必做重复劳动。

3.思维模型:

1)底层思维:向下,如何把握机器底层从微观理解对象构造。内容包括语言构造、编译转换、内存模型、运行时机制。

向下需要深入理解三大面向对象机制。

封装:隐藏内部实现

继承:复用现有代码

多态:改变对象行为

2)抽象思维:向上,如何将我们的周围世界抽象为成程序代码。内容包括面向对象、组件封装、设计模式、架构模式。

向上需要深刻把握面向对象机制所带来的抽象意义,理解如何使用这些机制来表达现实世界,掌握什么是“好的面向对象设计”。

4.软件设计复杂性的根本原因:变化

客户需求的变化、技术平台的变化、开发团队的变化、市场环境的变化。

5.如何解决复杂性

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

//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 = 0; 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 = 0; i < rectVector.size(); i++){
e.Graphics.DrawRectangle(Pens.Red,
rectVector[i].leftUp,
rectVector[i].width,
rectVector[i].height);
} //改变
//针对圆形
for (int i = 0; i < circleVector.size(); i++){
e.Graphics.DrawCircle(Pens.Red,
circleVector[i]);
}
//...
Form::OnPaint(e);
}

抽象:人们处理复杂性问题的通用技术,即抽象。由于不能掌握全部的复杂对象,我们选择忽视它的非本质细节,而去处理泛化和理想化了的对象模型。

//Shape2.h
class Shape{
public:
virtual void Draw(const Graphics& g)=0;
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,
...);
} };
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 = 0; i < shapeVector.size(); i++){ shapeVector[i]->Draw(e.Graphics); //多态调用,各负其责
} //...
Form::OnPaint(e);
}

在绘制点、线、矩形的问题上,分解和抽象两种思维下的解决方案是不一样的。在出现了新需求(画圆)后,两种方案应对策略也是不同的。

3.6 软件设计的目标:复用!

参考:《李建忠C++设计模式》视频

https://www.bilibili.com/video/av64805906/?p=1

学习记录:《C++设计模式——李建忠主讲》1.设计模式的更多相关文章

  1. 学习记录:《C++设计模式——李建忠主讲》2.面向对象设计原则

    1.课程内容: 重新认识面向对象:面向对象设计原则: 2.重新认识面向对象 1)理解隔离变化:从宏观层面来看,面向对象的构建方式更能适应软件的变化,将变化所带来的影响减为最小: 2)各司其职:从微观层 ...

  2. 学习记录:《C++设计模式——李建忠主讲》6.“状态变化”模式

    状态变化模式:在组件构建过程中,某些对象的状态经常面临变化,如何对这些变化进行有效的管理?同时又维持高层模块的稳定.状态变化模式为这一问题提供了一种解决方案. 典型模式:状态模式(State).备忘录 ...

  3. 学习记录:《C++设计模式——李建忠主讲》3.“组件协作”模式

    “组件协作”模式:现代软件专业分工之后的第一个结果是“框架与应用程序的划分”,“组件协作”模式通过晚期绑定,来实现框架与应用程序之间的松耦合,是二者之间协作时常用的模式.典型模式:Template M ...

  4. 学习记录:《C++设计模式——李建忠主讲》5.“对象性能”模式

    对象性能模式:面向对象很好地解决了抽象地问题,但是必不可免地要付出一定地代价.对于通常情况来讲,面向对象地成本大都可以忽略不计,但某些情况,面向对象所带来地成本必须谨慎处理. 典型模式:单件模式(Si ...

  5. 学习记录:《C++设计模式——李建忠主讲》4.“单一职责”模式

    单一职责模式:在软件组件的设计中,如果责任划分的不清晰,使用继承得到的结果往往是随着需求的变化,子类急剧膨胀,同时充斥着重复代码,这时候的关键是划清责任. 典型模式:装饰模式(Decorator).桥 ...

  6. 学习记录:《C++设计模式——李建忠主讲》7.“领域规则”模式

    领域规则模式:在特定领域中,某些变化虽然频繁,但可以抽象为某种规则.这时候,结合特定的领域,将问题抽象为语法规则,从而给出该领域下的一般性解决方案. 典型模式:解释器模式(Interpreter). ...

  7. 工厂模式(整理自李建忠<C++设计模式>视频)

    整理自李建忠<C++设计模式>视频 一.导入:"对象创建"模式和工厂模式 工厂模式只是该模式下的一种. 二.举例说明 有这样一个场景:需要在MainForm中设计一个按 ...

  8. Java设计模式学习记录-模板方法模式

    前言 模板方法模式,定义一个操作中算法的骨架,而将一些步骤延迟到子类中.使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤. 模板方法模式 概念介绍 模板方法模式,其实是很好理解的,具体 ...

  9. Java设计模式学习记录-状态模式

    前言 状态模式是一种行为模式,用于解决系统中复杂的对象状态转换以及各个状态下的封装等问题.状态模式是将一个对象的状态从该对象中分离出来,封装到专门的状态类中,使得对象的状态可以灵活多变.这样在客户端使 ...

随机推荐

  1. kaldi使用cvte模型进行语音识别

    操作系统 : Unbutu18.04_x64 gcc版本 :7.4.0 该模型在thch30数据集上测试的错误率只有8.25%,效果还是不错的. 模型下载地址: http://www.kaldi-as ...

  2. java架构之路-(MQ专题)RabbitMQ安装和基本使用

    RabbitMQ安装 我这里安装是使用阿里云的CentOS7.5来安装的,使用CentOS版本低于7的可能会报错. 1.安装rabbitmq所需要的依赖包 输入$ yum install build- ...

  3. HTTP 结构详解

    转至 :https://blog.csdn.net/u010256388/article/details/68491509?utm_source=copy   引用 学习Web开发不好好学习HTTP报 ...

  4. 数据结构(四十五)选择排序(1.直接选择排序(O(n²))2.堆排序(O(nlogn)))

    一.选择排序的定义 选择排序的基本思想是:每次从待排序的数据元素集合中选取最小(或最大)的数据元素放到数据元素集合的最前(或最后),数据元素集合不断缩小,当数据元素集合为空时排序过程结束.常用的选择排 ...

  5. go map数据结构和源码详解

    目录 1. 前言 2. go map的数据结构 2.1 核心结体体 2.2 数据结构图 3. go map的常用操作 3.1 创建 3.2 插入或更新 3.3 删除 3.4 查找 3.5 range迭 ...

  6. 基于verdaccio的npm私有仓库搭建

    详见个人博客:https://shengchangwei.github.io/verdaccio/ 一.使用npm安装 npm install --global verdaccio 二.cmd 启动 ...

  7. [Python]python面向对象 __new__方法及单例设计

    __new__ 方法 使用 类名() 创建对象时,Python 的解释器 首先 会 调用 __new__ 方法为对象 分配空间 __new__ 是一个 由 object 基类提供的 内置的静态方法,主 ...

  8. 跳跳棋——二分+建模LCA

    题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置.我们要通过最少的跳动把他们的位置移动 ...

  9. 如何在双向绑定的Image控件上绘制自定义标记(wpf)

    我们的需求是什么? 答:需要在图片上增加一些自定义标记,例如:2个图片对比时,对相同区域进行高亮. 先上效果图: 设计思路 1.概述 1.通过TargeUpdated事件,重新绘制图片进行替换. 2. ...

  10. 大数据之路week01--自学之集合_2(Iterator迭代器)

    选代器:是遍历集合的一种方式.迭代器是依赖于集合而存在的.我有一个集合: Collection c = new ArrayList();我们给集合中添加元素: c. add("hello' ...