实现:
1) cShape:抽象接口;
cShape*:具体实现的接口;
2) cFactory:按照传入参数color来区别对象, 如果已经创建过, 那就返回已有的, 否则创建新的.
使用:
传入参数, 获取被创建的对象(创建尽可能少的对象)
1) 设计框架
/*shape.hpp*/
#pragma once
#ifndef __SHAPE_HPP
#define __SHAPE_HPP
#include <string>
namespace __flyweight{
class cShape{
public:
virtual ~cShape();
public:
void setColor(std::string const &color);
void setX(int x);
void setY(int y);
public:
virtual void draw() = 0;
virtual void setRadius(int radius);
virtual void setWidth(int width);
virtual void setHeight(int height);
protected:
cShape(std::string const&color, int x, int y);
std::string _M_color;
int _M_x;
int _M_y;
};
}
#include "shape_circle.hpp"
#include "shape_rectangle.hpp"
#include "shape_square.hpp"
#endif
/*shape_circle.hpp*/
#pragma once
#ifndef __SHAPE_CIRCLE_HPP
#define __SHAPE_CIRCLE_HPP
#include "shape.hpp"
namespace __flyweight{
class cCircle:virtual public cShape{
public:
cCircle(std::string const &color, int x = 0, int y = 0, int radius = 0);
public:
void draw() override;
void setRadius(int radius) override;
private:
int _M_radius;
};
}
#endif
/*shape_rectangle.hpp*/
#pragma once
#ifndef __SHAPE_RECTANGLE__HPP
#define __SHAPE_RECTANGLE__HPP
#include "shape.hpp"
namespace __flyweight{
class cRectangle:virtual public cShape{
public:
cRectangle(std::string const &color, int x = 0, int y = 0, int width = 0, int height = 0);
public:
void draw() override;
void setWidth(int width) override;
void setHeight(int height) override;
private:
int _M_width;
int _M_height;
};
}
#endif
/*shape_square.hpp*/
#pragma once
#ifndef __SHAPE_SQUARE_HPP
#define __SHAPE_SQUARE_HPP
#include "shape.hpp"
namespace __flyweight{
class cSquare:virtual public cShape{
public:
cSquare(std::string const &color, int x = 0, int y = 0, int width = 0);
public:
void draw() override;
void setWidth(int width) override;
private:
int _M_width;
};
}
#endif
/*factory.hpp*/
#ifndef __FLYWEIGHT__HPP
#define __FLYWEIGHT__HPP
#include "shape.hpp"
#include <string>
#include <map>
namespace __flyweight{
class cFactory{
public:
~cFactory();
public:
cShape *getCircle(std::string const &color);
cShape *getRectangle(std::string const &color);
cShape *getSquare(std::string const&color);
private:
std::map<std::string /*color*/, cShape*> _M_circles;
std::map<std::string /*color*/, cShape*> _M_rectangles;
std::map<std::string /*color*/, cShape*> _M_squares;
};
}
#endif
2) 实现框架
/*shape.cpp*/
#include "shape.hpp"
#include <stdio.h>
#include <string.h>
#include <ctype.h>
namespace __flyweight{
cShape::~cShape(){
}
cShape::cShape(std::string const&color, int x, int y)
:_M_color(color), _M_x(x), _M_y(y)
{
}
void cShape::setColor(std::string const &color){
_M_color = color;
}
void cShape::setX(int x){
_M_x = x;
}
void cShape::setY(int y){
_M_y = y;
}
void cShape::setRadius(int radius){
}
void cShape::setWidth(int width){
}
void cShape::setHeight(int height){
}
}
/*shape_circle.cpp*/
#include "shape_circle.hpp"
#include <stdio.h>
namespace __flyweight{
cCircle::cCircle(std::string const &color, int x, int y, int radius)
:cShape(color, x, y)
{
setRadius(radius);
}
void cCircle::setRadius(int radius)
{
_M_radius = radius;
}
void cCircle::draw()
{
printf("cCircle::color(%s),x(%d),y(%d),radius(%d)\n", _M_color.c_str(), _M_x, _M_y, _M_radius );
}
}
/*shape_rectangle.cpp*/
#include "shape_rectangle.hpp"
#include <stdio.h>
namespace __flyweight{
cRectangle::cRectangle(std::string const &color, int x, int y, int width, int height)
:cShape(color, x, y)
{
setWidth(width);
setHeight(height);
}
void cRectangle::setWidth(int width)
{
_M_width = width;
}
void cRectangle::setHeight(int height)
{
_M_height = height;
}
void cRectangle::draw()
{
printf("cRectangle::color(%s),x(%d),y(%d),width(%d),height(%d)\n", _M_color.c_str(), _M_x, _M_y, _M_width, _M_height );
}
}
/*shape_square.cpp*/
#include "shape_square.hpp"
#include <stdio.h>
namespace __flyweight{
cSquare::cSquare(std::string const &color, int x, int y, int width)
:cShape(color, x, y)
{
setWidth(width);
}
void cSquare::setWidth(int width)
{
_M_width = width;
}
void cSquare::draw()
{
printf("cSquare::color(%s),x(%d),y(%d),width(%d)\n", _M_color.c_str(), _M_x, _M_y, _M_width);
}
}
/*factory.cpp*/
#include "factory.hpp"
#include <stdio.h>
namespace __flyweight{
cFactory::~cFactory()
{
while( !_M_circles.empty() )
{
auto it = _M_circles.begin();
delete it->second, it->second = nullptr;
_M_circles.erase( it );
}
while( !_M_rectangles.empty() )
{
auto it = _M_rectangles.begin();
delete it->second, it->second = nullptr;
_M_rectangles.erase( it );
}
while( !_M_squares.empty() )
{
auto it = _M_squares.begin();
delete it->second, it->second = nullptr;
_M_squares.erase( it );
}
}
cShape *cFactory::getCircle(std::string const &color)
{
cShape *ret = nullptr;
auto it = _M_circles.find(color);
if( it == _M_circles.end() )
{
if( (ret = new cCircle(color) ) )
{
_M_circles.insert(std::make_pair(color, ret));
}
}
else
{
ret = it->second;
}
return ret;
}
cShape *cFactory::getRectangle(std::string const &color)
{
cShape *ret = nullptr;
auto it = _M_rectangles.find(color);
if( it == _M_rectangles.end() )
{
if( (ret = new cRectangle(color) ) )
{
_M_rectangles.insert(std::make_pair(color, ret));
}
}
else
{
ret = it->second;
}
return ret;
}
cShape *cFactory::getSquare(std::string const &color)
{
cShape *ret = nullptr;
auto it = _M_squares.find(color);
if( it == _M_squares.end() )
{
if( (ret = new cSquare(color) ) )
{
_M_squares.insert(std::make_pair(color, ret));
}
}
else
{
ret = it->second;
}
return ret;
}
}
3) 用户调用
#include "factory.hpp"
#include <cstdlib>
#include <cstdio>
#include <time.h>
static char const *sg_colors[]={
"Red", "Green", "Blue", "White", "Black"
};
#define COLOR_SIZE (sizeof(sg_colors)/sizeof(sg_colors[0]))
std::string getRandomColor()
{
return sg_colors[ abs(rand())%COLOR_SIZE ];
}
int getRandomX()
{
return rand();
}
int getRandomY()
{
return rand();
}
int getRandomRadius()
{
return rand();
}
int getRandomWidth()
{
return rand();
}
int getRandomHeight()
{
return rand();
}
int main(int argc, char *argv[])
{
if( argc != (1 + 1)){
fprintf(stderr, "Usage:%s <object-count>\n", argv[0]);
return EXIT_FAILURE;
}
long long OBJ_SIZE = atoll(argv[1]);
time(nullptr);
__flyweight::cFactory shapeFactory;
{
printf("---------------------------------\n");
__flyweight::cShape * circle = nullptr;
for(int iobj = 0; iobj < OBJ_SIZE; iobj++ )
{
circle = shapeFactory.getCircle( getRandomColor() );
circle->setX( getRandomX() );
circle->setY( getRandomY() );
circle->setRadius( getRandomRadius() );
circle->draw();
}
}
{
printf("---------------------------------\n");
__flyweight::cShape * rectangle = nullptr;
for(int iobj = 0; iobj < OBJ_SIZE; iobj++ )
{
rectangle = shapeFactory.getRectangle( getRandomColor() );
rectangle->setX( getRandomX() );
rectangle->setY( getRandomY() );
rectangle->setWidth( getRandomWidth() );
rectangle->setHeight( getRandomHeight() );
rectangle->draw();
}
}
{
printf("---------------------------------\n");
__flyweight::cShape * square = nullptr;
for(int iobj = 0; iobj < OBJ_SIZE; iobj++ )
{
square = shapeFactory.getSquare( getRandomColor() );
square->setX( getRandomX() );
square->setY( getRandomY() );
square->setWidth( getRandomWidth() );
square->draw();
}
}
return EXIT_SUCCESS;
}
4) 编译与运行