【2013.1.31】好朋友就是你的东西是我的,我的东西还是我的——Flyweight(使用Vector)

// // // // // // // // //

///2013.1.31

// // // // // // // // //

Flyweight模式,

有一个有趣的翻译:

——蝇量模式。


【核心】将大量粒度(小的)的对象进行共性与特殊性的分离,用'提取'代替'创建'重复的部分。


UML图:


其目的非常单纯,

在程序中大量应用的重复小数据,

就像这篇文章中的文字——例如'的',

在它重复大量出现的时候,

如果每一次的实现都为其实例化一次,

将会造成大量重复的开销。

为此,

Flyweight会将这些重复的归为一类(放到一个大字典中),

在需要的时候提取出来就好了。


当然即使是拥有共性的物体也可能具有各自的特殊性:

例如'的'有以下几种形式:

   


都是同一个字,

但却有不同的表现形式,

这种时候,

就是UML图中的没有进行共享的那一部分:

——外部状态的设计目的了。


代码实例:


【大致思路】

FlyWeight作为虚基类,其衍生类ConcreteFlyWeight在构造函数中将FlyWeight内部状态keyName(共享、通用的)初始化。

并通过Operation以及其参数——外部状态Style(如Color之类的)来创建不同形式的Key.

FlyWeightFactory拥有一个FlyWeight类型的集合,每次在创建相应Key的时候都检查是否已含有此KeyName,

如果有,则调用;没有,则创建。


FlyWeight.h

#ifndef _FLYWEIGHT_H_
#define _FLYWEIGHT_H_
#include<iostream>
#include<string>

using namespace std;

class FlyWeight
{
public:
	virtual void Operation(string style) = 0;
	string getKeyName();

protected:
	FlyWeight(string cn);
	string keyName;
};

class ConcreteFlyWeight:public FlyWeight
{
public:
	ConcreteFlyWeight(string key);
	string getKeyName();
	void Operation(string style);
};
#endif

FlyWeight.cpp

#include"FlyWeight.h"

using namespace std;

FlyWeight::FlyWeight(string cn)
{
	this->keyName = cn;
}

string FlyWeight::getKeyName()
{
	return this->keyName;
}

ConcreteFlyWeight::ConcreteFlyWeight(string cn):FlyWeight(cn)
{
}

void ConcreteFlyWeight::Operation(string style)
{
	cout<<"KeyName: "<<keyName<<endl;
	cout<<"Style: "<<style<<endl;
}

string ConcreteFlyWeight::getKeyName()
{
	return this->keyName;
}

FlyWeightFactory,h

#ifndef _FLYWEIGHTFACTORY_H_
#define _FLYWEIGHTFACTORY_H_

#include"FlyWeight.h"
#include<vector>

class FlyWeightFactory
{
public:
	FlyWeightFactory();
	FlyWeight* getFlyWeight(string cn);

private:
	std::vector<FlyWeight*> flyWeightPool;
};

#endif

FlyWeightFactory.cpp

#include"FlyWeightFactory.h"
using namespace std;

FlyWeightFactory::FlyWeightFactory()
{

}

FlyWeight* FlyWeightFactory::getFlyWeight(string key)
{
	vector<FlyWeight*>::iterator itr;

	for(itr = flyWeightPool.begin();itr != flyWeightPool.end();itr++)
	{
		if((*itr)->getKeyName() == key)
		{
			cout<<"Get this key: "<<key<<endl;
			//If pool has this key.
			return (*itr);
		}
	}

		//If hasn't this key in the pool.Then Create...
		FlyWeight* newFlyWeight = new ConcreteFlyWeight(key);
		//And Add it to the pool.
		flyWeightPool.push_back(newFlyWeight);

		cout<<"Create this key: "<<key<<endl;
		return newFlyWeight;
}

main.cpp

#include"FlyWeightFactory.h"

int main()
{
	FlyWeightFactory* factory = new FlyWeightFactory();
	FlyWeight* key1 = new ConcreteFlyWeight("Fly");

	//Create and add to factory's pool. 
	factory->getFlyWeight("Fly")->Operation("Red Color");

	std::cout<<std::endl;                                                                                                        
	//Get Key from factory's pool
	factory->getFlyWeight("Fly")->Operation("Black Color");

	return 0;
}

输出结果:



【注意事项】

此模式核心的地方是在于对比每个创建的对象是否拥有共同状态,

没有,则创建;有,就提取。

因此,代码中的getFlyWeight需要着重去理解。

当然,

作为讲解之用,

这里使用Vector,

其实更多时候,

应该用一个Hash表来作为集合收容这些FlyWeight(例如C#中的Dictionary)。


顺便一提,

笔者作为游戏开发者,

看到此模式的第一眼就想到了图片Texture的调用。

在制作游戏中,

一张图片总是会重复使用多次,

如果每次调用都重新创建的话,

那太过不环保。

因此很多优秀的引擎(例如Cocos2d系列),

都提供了一个图片池,

只需要将Sprite加入其中,

这样即使大量重复调用也不会比调用一次占更多内存(可忽略不计)。


其原理,

就是这个简单的FlyWeight模式。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
非常抱歉,我误解了你的问题。你的第一句话是"java设计模式"。那么,接下来我将为你介绍一些常见的 Java 设计模式。 Java 设计模式是一套被广泛应用于面向对象软件设计的可重用解决方案。它们提供了一种在软件开发过程中常见问题的解决方案,并帮助开发人员写出易于理解、可维护和可扩展的代码。 以下是一些常见的 Java 设计模式: 1. 创建型模式(Creational Patterns):包括工厂模式(Factory Pattern)、抽象工厂模式(Abstract Factory Pattern)、单例模式(Singleton Pattern)、建造者模式(Builder Pattern)和原型模式(Prototype Pattern)等。 2. 结构型模式(Structural Patterns):包括适配器模式(Adapter Pattern)、桥接模式(Bridge Pattern)、装饰器模式(Decorator Pattern)、组合模式(Composite Pattern)、外观模式(Facade Pattern)、享元模式(Flyweight Pattern)和代理模式(Proxy Pattern)等。 3. 行为型模式(Behavioral Patterns):包括策略模式(Strategy Pattern)、模板方法模式(Template Method Pattern)、观察者模式(Observer Pattern)、迭代器模式(Iterator Pattern)、责任链模式(Chain of Responsibility Pattern)、命令模式(Command Pattern)、备忘录模式(Memento Pattern)、状态模式(State Pattern)、访问者模式(Visitor Pattern)和中介者模式(Mediator Pattern)等。 这些设计模式都有各自的特点和应用场景,可以根据实际需求选择合适的模式来优化和改进你的 Java 代码。希望这些信息对你有所帮助!如有更多问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值