设计模式(一)——何为设计模式,从重构开始设计模式

从重构入手,了解设计模式。

一、实现软件

完成一个图形软件,画出Line和我Rect

方法一:分解

#include <iostream>
#include <vector>
using namespace std;
//画图
class Point
{
public:
	int m_x;
	int m_y;
};

class Line
{
public:
	Line(){std::cout << "Line" << std::endl;}
	void draw (int i){std::cout << "draw line" << std::endl;}
};
class Rect
{
public:
	Rect() {std::cout << "Rect" << std::endl;}
	void draw (int i){std::cout << "draw Rect" << std::endl;}
};

class Paint
{
public:
	vector<Line> m_vecLine;
	vector<Rect> m_vecRect;

	//添加
	void paintData(int type)
	{
		if (type == 1)
		{
			Line line;
			m_vecLine.push_back(line);
		}
		else if(type == 2)
		{
			Rect rect;
			m_vecRect.push_back(rect);
		}
	}
	//显示(分解处理)
	void paintShow() 
	{
		for(vector<Line>::iterator ite = m_vecLine.begin(); ite != m_vecLine.end(); ite++)
		{
			ite->draw(1);
		}
		for(vector<Rect>::iterator ite = m_vecRect.begin(); ite != m_vecRect.end(); ite++)
		{
			ite->draw(1);
		}
	}

	
};


int main()
{
	Paint p;
	//添加图形
	p.paintData(1);
	p.paintData(2);
	//显示图形
	p.paintShow();
}
//打印以下内容
Line
Rect
draw line
draw Rect

方法二:抽象

#include <iostream>
#include <vector>
using namespace std;
//画图
class Point
{
public:
	int m_x;
	int m_y;
};

class sharpe //不同处
{
public:
	virtual ~sharpe(){};
	virtual void draw(int i){};
};
class Line : public sharpe
{
public:
	Line(){std::cout << "Line" << std::endl;}
	void draw (int i){std::cout << "draw line" << std::endl;}
};
class Rect : public sharpe
{
public:
	Rect() {std::cout << "Rect" << std::endl;}
	void draw (int i){std::cout << "draw Rect" << std::endl;}
};

class Paint
{
public:
	vector<sharpe *> m_vecPic;//不同处

	//添加
	void paintData(int type)
	{
		if (type == 1)
		{
			m_vecPic.push_back(new Line);
		}
		else if(type == 2)
		{
			m_vecPic.push_back(new Rect);
		}
	}
	//显示(抽象统一处理)
	void paintShow() 
	{
          //不同处
		for(vector<sharpe*>::iterator ite = m_vecPic.begin(); ite != m_vecPic.end(); ite++)
		{
			(*ite)->draw(1);
		}
	}
};


int main()
{
	Paint p;
	//添加图形
	p.paintData(1);
	p.paintData(2);
	//显示图形
	p.paintShow();
}


//打印以下内容
Line
Rect
draw line
draw Rect

二、实现一需求更改

现在把上面的需求再增加一个,多了一个circle打印圆形的功能

方法一:分解(更改后,需要修改5个地方)

#include <iostream>
#include <vector>
using namespace std;
//画图
class Point
{
public:
	int m_x;
	int m_y;
};

class Line
{
public:
	Line(){std::cout << "Line" << std::endl;}
	void draw (int i){std::cout << "draw line" << std::endl;}
};
class Rect
{
public:
	Rect() {std::cout << "Rect" << std::endl;}
	void draw (int i){std::cout << "draw Rect" << std::endl;}
};

class Circle //1
{
public:
	Circle() {std::cout << "Circle" << std::endl;}
	void draw (int i){std::cout << "draw Circle" << std::endl;}
};

class Paint
{
public:
	vector<Line> m_vecLine;
	vector<Rect> m_vecRect;
	vector<Circle> m_vecCircle; //2

	//添加
	void paintData(int type)
	{
		if (type == 1)
		{
			Line line;
			m_vecLine.push_back(line);
		}
		else if(type == 2)
		{
			Rect rect;
			m_vecRect.push_back(rect);
		}
		else if(type == 3) //3
		{
			Circle circle;
			m_vecCircle.push_back(circle);
		}
	}
	//显示
	void paintShow() 
	{
		for(vector<Line>::iterator ite = m_vecLine.begin(); ite != m_vecLine.end(); ite++)
		{
			ite->draw(1);
		}
		for(vector<Rect>::iterator ite = m_vecRect.begin(); ite != m_vecRect.end(); ite++)
		{
			ite->draw(1);
		}
		for(vector<Circle>::iterator ite = m_vecCircle.begin(); ite != m_vecCircle.end(); ite++) //4
		{
			ite->draw(1);
		}
	}

	
};


int main()
{
	Paint p;
	//添加图形
	p.paintData(1);
	p.paintData(2);
	p.paintData(3);
	//显示图形
	p.paintShow();
}

方法二:抽象(更改后,只更改了两个地方)

#include <iostream>
#include <vector>
using namespace std;
//画图
class Point
{
public:
	int m_x;
	int m_y;
};

class sharpe
{
public:
	virtual ~sharpe(){};
	virtual void draw(int i){};
};
class Line : public sharpe
{
public:
	Line(){std::cout << "Line" << std::endl;}
	void draw (int i){std::cout << "draw line" << std::endl;}
};
class Rect : public sharpe
{
public:
	Rect() {std::cout << "Rect" << std::endl;}
	void draw (int i){std::cout << "draw Rect" << std::endl;}
};
class Circle : public sharpe  //1
{
public:
	Circle() {std::cout << "Circle" << std::endl;}
	void draw (int i){std::cout << "draw Circle" << std::endl;}
};

class Paint
{
public:
	vector<sharpe *> m_vecPic;

	//添加
	void paintData(int type)
	{
		if (type == 1)
		{
			m_vecPic.push_back(new Line);
		}
		else if(type == 2)
		{
			m_vecPic.push_back(new Rect);
		}
		else if(type == 3)
		{
			m_vecPic.push_back(new Circle);  //2
		}
	}
	//显示
	void paintShow() 
	{
		for(vector<sharpe*>::iterator ite = m_vecPic.begin(); ite != m_vecPic.end(); ite++)
		{
			(*ite)->draw(1);
		}
	}
};


int main()
{
	Paint p;
	//添加图形
	p.paintData(1);
	p.paintData(2);
	p.paintData(3);
	//显示图形
	p.paintShow();
}

//打印以下内容
Line
Rect
Circle
draw line
draw Rect
draw Circle

结论:

抽象比分解解决问题修改起来更方便,可复用性强

C++小知识

class A;
class B;
class C;继承自B
vector<A> t; 
vector<B*> t; //使用指针可以使用多态
#include <iostream>
#include <vector>
using namespace std;
enum COLOR
{
      RED=1, YELLO, BLACK, WHITE
};
//画图
class Point
{
public:
	int m_x;
	int m_y;
};

class sharpe
{
public:
	virtual ~sharpe(){};
	virtual void draw(int i){}; //3,没有变化的draw1、draw2\ 5继承的人都有用到draw
};

class Color
{
public:
    int curColor(){}
};

class Pen
{
public:
    Color color;
    void setColor(int i) {}      
};

class Line : public sharpe
{
public:
    Pen m_pen; //6 
    //Color Ccolor;//8 color在pen里面使用,这里不能使用
    void setPen(Pen &pen){ m_pen = pen; }
	Line(){std::cout << "Line" << std::endl;}
	void draw (int i){drawTest();std::cout << "draw line" << std::endl;}
private:
    void drawTest(){}  //5
};
class Rect : public sharpe
{
public:
	Rect() {std::cout << "Rect" << std::endl;}
	void draw (int i){std::cout << "draw Rect" << std::endl;}
};
class Circle : public sharpe  
{
public:
	Circle() {std::cout << "Circle" << std::endl;}
	void draw (int i){std::cout << "draw Circle" << std::endl;}
};

class Paint
{
public:
	vector<sharpe *> m_vecPic;  //1   4-1

	//添加
	void paintData(int type)
	{
		if (type == 1)
		{
			m_vecPic.push_back(new Line);//4-2
		}
		else if(type == 2)
		{
			m_vecPic.push_back(new Rect);
		}
		else if(type == 3)
		{
			m_vecPic.push_back(new Circle);  //2
		}
	}
	//显示
	void paintShow() 
	{
		for(vector<sharpe*>::iterator ite = m_vecPic.begin(); ite != m_vecPic.end(); ite++)
		{
			(*ite)->draw(1);  //2(不是每个Line\Rect都要重新固定,重新写)
		}
	}
};


int main()
{
	Paint p;
	//添加图形
	p.paintData(1);
	p.paintData(2);
	p.paintData(3);
	//显示图形
	p.paintShow();
}

//打印以下内容
Line
Rect
Circle
draw line
draw Rect
draw Circle

设计模式七大原则(C++描述)

7大设计模式原则

1.依赖倒置原则DIP(面对接口编程,不要对实现编程)
高层模块(稳定)不依赖底层模块(变化),二者都要依赖抽象(稳定)
抽象(稳定)不依赖实现细节(变化),实现细节应该依赖抽象(稳定)
如:vector m_vecPic; 针对接口,而不是真实类型
在这里插入图片描述
2.开放封闭原则(OCP)
对扩展开放,对更改封闭
如上例需要添加画圆圈,秩序添加Class Circle即可,其他不用更改
3.单一职责原则(SRP)
一个类只有一个引起它变化的原因,比如:
比如:sharp类只有一个draw类是变化的,需要与众不同的。
4.Liskov替换原则(LSP)
子类必须能替换父类(父类的功能,子类不能有父类同名的非虚函数)
继承表达,类型抽象(Line和Rect两个对外统一为sharpe替换)
5.接口隔离原则(ISP)
接口要小(不是接口的函数都用private)
继承的接口类那些虚函数都要有用到,不然就把他拆分掉,使用多继承
6.优先使用对象组合而不是类继承(继承应该是生物和动物的包含关系,而不是简单的父亲和儿子的继承关系)
继承子类和父类耦合度高
对象组合要求对象接口的合作,耦合度低
7.封装变化点
封装变化点,一侧稳定,一侧变化。稳定如Paint类,是变化的,而Sharpe是稳定的,Line和Rect是变化的。
8.迪米特原则(最少知道原则)
一个类里面不管属性还是行为,用到的其他类尽量少。

设计模式需要遵循

需求变化的点和稳定的点
提高复用
重构而不是直接使用设计模式

设计模式从重构开始-重构关键方法

a 静态-》动态(A::test() 调用改为 a->test();)
b 早绑定-》晚绑定 (void printTest(A &a){ a.test(); } A应该只是一个接口类,并且test是一个虚函数)https://blog.csdn.net/a133900029/article/details/80185428
c 继承-》组合(类A继承类B 改为 类A包含类B元素)
d 编译时依赖-》运行时依赖()
e 紧耦合-》松耦合(分接口出来)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章