抠门是一种艺术

在很多游戏场景中,会有一大片草地,如果每根草都是一个对象,我们需要给它一个显示图片,很自然的写下如下代码

1
2
3
4
5
6
7
8
9
10
11
class Grass {
public:
void show() {
img = new Image("img/grass.png");
opengl::show(x, y, img);
}
private:
int x;
int y;
Image* img;
}

草越多,占用的内存越多,但是他们又长得一样,我何必每个对象里都new一个,大家共享一个它不香吗? 于是乎我们这么改,把可以变化的座标x,y保留,把不会变化的img拆分出去

1
2
3
4
5
6
7
8
9
class Grass {
public:
void show(Image* img) {
opengl::show(x, y, img);
}
private:
int x;
int y;
}

而img由外界工厂生产

1
2
3
4
5
6
7
8
9
10
11
12

class GrassFactory {
public:
Image* GetGrass(std::string type) {
if(!m_map.count(type)) {
m_map[type] = new Image("img/" + type + ".png");
}
return m_map[type];
}
private:
std::unordered_map<std::string, Image*> m_map;
}

无论你让工厂生产的是”grass”,还是”芦苇”,还是”蒲公英”,内存里只占了一份。

有人说那我直接把img设为static,所有对象也是共享一份,算不算享元?我也有这个疑问,AI告诉我不算,但我不是很同意,我认为享元模式是一种共享资源的思想,不应该限制于具体的代码实现