Structural.Flyweight (structural pattern - flyweight pattern)

Thinking about Flyweight

  ①The essence of Flyweight mode : separation and sharing. The key to Flyweight mode is to separate change and invariance. The unchanged part is regarded as the internal state of the Flyweight object , and the changed part is regarded as the external state , which is maintained by the outside. In this way, Flyweight objects can be shared, thereby reducing the number of objects. quantity, and save a lot of memory space.

  ② Changes and changes of Flyweight mode: Why should an interface be reserved in one place? A common reason is that there are changes here, and the existing implementation may need to be extended or changed in the future, and the reserved interface is used as a "pluggable" interface. guarantee"

  ③ Flyweight object: there are shared (ConcreteFlyweight) and unshared (UnsharedConcreteFlyweight) points. Unshared generally occurs when combined with the composition mode . Usually, the shared object is a leaf object. Generally, the unshared part is composed of the shared part. Since all fine-grained leaf objects have been cached, there is nothing to cache the combined object. significance. (For example , the "view" and "modify" of a security entity in permission management can be shared . If the "view" and "modify" are combined into the "operation" permission , the " operation" permission does not need to be cached (shared). , because it is already cached at a fine-grained level ). (see example later)

【Programming Experiment】Go Software Design

        ①Internal state: There are so many pieces in each Go, which can be set as Flyweight objects, with the following attributes: color, size, and shape.

        ②External state: the position of the piece on the chessboard. This is not shareable.

//declaration file

//Structural pattern: flyweight pattern
//Scenario: Go software design.
//Internal state - There are many Go pieces, but they are only divided into two categories: white and black.
// Has properties such as color, size, shape, etc., and is a sharable object.
//External state - the position of the piece on the board.

#include <iostream>
#include <string>
#include <map>

using namespace std;



//************************************Hyweight class ********* ****************
//Non-flyweight object: UnsharedConcreteFlyweight (external state)
class CPos{
private:
	int X;
	int Y;
public:
	CPos(int x, int y);
	void SetX(int x);
	int GetX();
	void SetY(int y);
	int GetY ();
};
// Flyweight abstract class
class CWeight{
protected:
	string strColor;
public:
	virtual ~CWeight();
	void SetColor(string color);
	string GetColor();
	//Display the position of the pieces on the chessboard
    //You can pass the external state into the flyweight object through this interface
	virtual void Disp(CPos& pos) = 0;
};

//Flyweight object: ConcreteFlyweight (internal state)
class CFly : public CWeight{
public:
	CFly(string color);
	~CFly();
	void Disp(CPos& pos);
};
//************************************Hygware Factory Class******** ********************
class CChessFac{
private:
	static map<string, CWeight*> mpChess;
public:
	static CWeight* GetChess(string color);
	static void RemoveAll();
};

//implementation file

//************************************Hyweight class ********* ****************
//Non-flyweight object: UnsharedConcreteFlyweight (external state)
CPos::CPos(int x, int y){X = x; Y = y;}
void CPos::SetX(int x){ X = x;}
int CPos::GetX(){return X;}
void CPos::SetY(int y){Y = y;}
int CPos::GetY(){return Y;}
// Flyweight abstract class
CWeight::~CWeight(){cout << "~CWeight" << endl;}
void CWeight::SetColor(string color){strColor = color;}
string CWeight::GetColor(){return strColor;}


//Flyweight object: ConcreteFlyweight (internal state)
CFly::CFly(string color){SetColor(color);}
CFly::~CFly(){cout << "~CFly" << endl; }
void CFly::Disp(CPos& pos)
{
	cout << "********************************************" << endl;
	cout << "Chess's Color : " << strColor << endl;
	cout << "Chess's Pos : (" << pos.GetX() << ", " << pos.GetY() << ")" << endl;
	cout << "********************************************" << endl << endl;
}
//************************************Hygware Factory Class******** ********************
map<string, CWeight*> CChessFac::mpChess;
CWeight* CChessFac::GetChess(string color)
{
	CWeight* pChess = mpChess[color];
	if(pChess == NULL){
		pChess = new CFly(color);
		mpChess[color] = pChess;
	}
	return pChess;
}
void CChessFac::RemoveAll()
{
	cout << "Before deleting... size = " << mpChess.size() << endl;
	for(map<string, CWeight*>::iterator it = mpChess.begin(); it != mpChess.end(); ){
		cout << it->first << " : " << it->second << endl;
		CWeight* pWeight = it->second;
		delete pWeight;
		it = mpChess.erase(it);
	}
	cout << "After deleted... size = " << mpChess.size() << endl;
}

//test client

void main()
{
	CWeight* pChess1 = CChessFac::GetChess("Black");
	CWeight* pChess2 = CChessFac::GetChess("White");
	CWeight* pChess3 = CChessFac::GetChess("Black");

	cout << "pChess1 : " << pChess1 << endl;
	cout << "pChess2 : " << pChess2 << endl;
	cout << "pChess3 : " << pChess3 << endl;

	pChess1->Disp(CPos(10,10));
	pChess2->Disp(CPos(20,20));
	pChess3->Disp(CPos(30,30));

	CChessFac::RemoveAll();
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324607376&siteId=291194637