用户注册



邮箱:

密码:

用户登录


邮箱:

密码:
记住登录一个月忘记密码?

发表随想


还能输入:200字

机箱    -  云代码空间

——

设计模式--结构模式--享元模式--Java

2013-03-09|2705阅||

摘要:Flyweight Intent 目的 Use sharing to support large numbers of fine-grained objects efficiently

Flyweight

Intent 目的

Use sharing to support large numbers of fine-grained objects efficiently
利用共享,使大量细粒度的对象得到有效的利用

Applicability 适用性

Anapplication uses a large number of objects
应用程序大量使用一些对象

Storagecosts are high because of the sheer quantity of objects
存储大量对象开销大

Mostobject state can be made extrinsic
大多数对象的状态可以由外部提供

Manygroupsof objects may be replaced by relatively few shared objects once extrinsicstate is removed
假设不包含外部状态,大量的对象可由少量共享的对象取代

UML



Participants 参与者

Flyweight
declaresan interface through which flyweights can receive and act on extrinsic state
定义一个接口,可以用于flyweight接收外部状态

ConcreteFlyweight
implementsthe Flyweight interface and adds storage for intrinsic state, if any. AConcreteFlyweight object must be sharable. Any state it stores must beintrinsic; that is, it must be independent of the ConcreteFlyweight object'scontext

实现flyweight接口,为内部状态提供存储空间。 ConcreteFlyweight 必须是可共享的,这些内部状态必须独立于ConcreteFlyweight 对象上下文。

UnsharedConcreteFlyweight 

notall Flyweight subclasses need to be shared. The Flyweight interfaceenablessharing; it doesn't enforce it. It's common forUnsharedConcreteFlyweight objectsto have ConcreteFlyweight objects as children at some level in the flyweightobject structure (as the Row and Column classes have)

并不是所有的Flyweight子类都需要共享。在F l y w e i g h t对象结构的某些层次,U n s h a r e d C o n c r e t e F ly w e i g h t对象通常将C o n c r e t e F l y w e i g h t对象作为子节点

FlyweightFactory

createsand manages flyweight objects. ensures that flyweights are shared properly.When a client requests  a flyweight, the FlyweightFactory object supplies an existinginstance or creates one, if none exists.

 创建和管理flyweight 对象。确保flyweights 对象恰当的共享。当客户端需要一个flyweight对象时,工厂返回一个存在的实例,如果不存在,创建一个并返回

Client

maintainsa reference to flyweight(s). computes or stores the extrinsic state offlyweight(s).

 持有flyweight(s引用,计算或者存储flyweight外部状态

Tank War example

exm1

     游戏中会用到享元模式,譬如Tank发射的炮弹,发射一次new一次,当炮弹超出屏幕或者打到敌军坦克,炮弹便销毁了,游戏异常激烈,而VM每隔一段时间会进行一次垃圾处理,所以对性能上有所影响(这个原因在小游戏中是次要的),主要原因为同一种炮弹都包含了一些固定不变的信息,如炮弹的速度,边缘,等,主要变化的是位置,方向与存活状态。
     这个时候我们会想到这不就可以利用享元模式么!
     下面是我曾经做的游戏的局部代码,化繁为简,便于阅读理解:
@Override
	public void fire() {
		factory.newBullet().shoot(centerPoint, direction);
	}
     其中factory为炮弹工厂,每次Tank发射时,都通过factory创建出一个炮弹,并且通过炮弹的外部状态设置接口将当前炮口位置与方向传给炮弹。此次发射就算完成了。当子弹超出屏幕窗口,打到敌军坦克则Bullet调用setAlive(false)方法。
    下面看下factory中的局部代码:
     
public Weapon newBullet(){
		for (int i = 0; i < bullets.size(); i++) {
			Weapon bullet = bullets.get(i);
			if (!bullet.isAive()) {
				return bullet;
			}
		}
		return Weapon.NullWeapon;
	}

        当tank需要发射炮弹时,factory会找到第一个已经死亡的炮弹,如果炮弹都处于激活状态,则返回一个空炮弹(此处利用NULL Object Patterns)。
        其中炮弹集合bullets是限制大小,要不然tank炮弹一连串从屏幕这头打到屏幕那头,那就太变态了。

        下面在看看其中一种类型Bullet的shoot方法:
@Override
	public void shoot(Point2D.Double centerPoint, Direction direction) {
		setPoint(centerPoint);
		setDirection(direction);
		setAlive(true);
	}

       首先设置位置,其次方向,最后比较重要的是将其激活。

       综上所述,利用了flyweight模式,显而易见地可以减少垃圾对象,减轻gc负担,另一方面使大量细粒度的对象得到有效的利用。






来源:http://blog.csdn.net/changsheng1453052832/article/details/8652376

顶 4踩 4收藏
文章评论
    发表评论