1.什麼是設計模式
“每一個模式描述了一個在我們周圍不斷重複發生着的問題,以及該問題的解決方案的核心。這樣,你就能一次又一次地使用該方案而不必做重複勞動“
----Christopher Alex
2.GOF設計模式書籍:
歷史性著作《設計模式:可複用面向對象軟件的基礎》
3.從面向對象說起
底層思維:向下,如何把握機器底層從微觀理解對象構造
語言轉換、編譯轉換、內存模型、運行時機制。
三大面向對象機制:
封裝,隱藏內部實現
繼承,複用現有代碼
多態,改寫對象行爲
抽象思維:向上,如何將我們周圍世界抽象爲程序代碼
面向對象、組件封裝、設計模式、架構模式
深刻把握面向對象機制所帶來的抽象意義,理解如何使用這些機制來表達現實世界,掌握什麼是“好的面向對象設計”
4.軟件設計複雜的根本原因:變化
那麼如何解決這種複雜性?
分解:人們面對複雜性有一個常見的作法:即分而治之,將大 xxx 解爲多個小問題,將複雜問題分解爲多個簡單問題。
抽象:更高層次來講,人們處理複雜性有一個通用的技術,即抽象。由於不能掌握全部的複雜對象,我們選擇忽視它的非本質xx而去處理泛化和理想化了的對象模型。
分解的方法,shape.h:
#pragma once
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;
}
};
MainForm.cpp:
#include <iostream>
#include "Shape.h"
#include <algorithm>
#include <stdio.h>
#include <vector>
class MainForm : public Form {
private:
Point p1;
Point p2;
vector<Line> lineVector;
vector<Rect> rectVector;
public:
MainForm() {
//...
}
protected:
virtual void onMouserDown(const MouseEventArgs& e);
virtual void onMouseUp(const MouseEventArgs& e);
virtual void onPaint(const PaintEventArgs& e);
};
void MainForm::onMouserDown(cosnt MouserEventArgs& e)
{
p1.x = e.X;
p1.y = e.Y;
//...
Form::onMouserDown(e);
}
void MainForm::onMouseUp(const MouserEventArgs& 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);
}
//...
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.DrawLine(Pens.Red,
rectVector[i].leftUp,
rectVector[i].width,
rectVector[i].height,
rectVector[i].end.y);
}
//...
Form::onPaint(e);
}
抽象的方法:shapegood.h
#pragma once
class Shape {
public:
virtual void Draw(const Graphices& 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;
}
virtual void Draw(const Graphices& 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;
}
virtual void Draw(cosnt Graphices& g) {
g.DrawRectangle(Pens.Red,
leftUp, width, height);
}
};
MainFormGood.cpp
#include "ShapeGood.h"
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <vector>
class MainForm : public Form {
private:
Point p1;
Point p2;
//針對所有形狀
vector<Shape*> shapeVector;
public:
MainForm() {
//...
}
protected:
virtual void onMouserDown(const MouseEventArgs& e);
virtual void onMouseUp(const MouseEventArgs& e);
virtual void onPaint(const PaintEventArgs& e);
};
void MainForm::onMouserDown(cosnt MouserEventArgs& e)
{
p1.x = e.X;
p1.y = e.Y;
//...
Form::onMouserDown(e);
}
void MainForm::onMouseUp(const MouserEventArgs& 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));
}
//...
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);
}
當項目需要增加更多的形狀的時候,第二種抽象的方式會更好。
軟件設計的目標:
什麼是好軟件,設計? 軟件的金科玉律: 複用