`
wangwengcn
  • 浏览: 175816 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

22.享元模式(Flyweight Pattern)

阅读更多

1.定义

使用共享对象可有效地支持大量的细粒度的对象。
是对象池技术的重要实现方式。

 

2.享元模式的使用场景

  • 系统中存在大量的相似对象。
  • 细粒度的对象都具备较接近的外部状态,而且内部状态与环境无关,也就是说对象没有特定身份。
  • 需要缓冲池的场景。

请看例子程序,学生和学校的关系:

 

package _22FlyweightPattern;

/**
 * 班级类
 */
public class School {

	// 学校id
	private int id;
	// 学校名称
	private String schoolName;
	// 某学生对该学校的映像
	private String desc;
	
	// 还有很多信息,比较占内存…………
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getSchoolName() {
		return schoolName;
	}
	public void setSchoolName(String schoolName) {
		this.schoolName = schoolName;
	}
	public String getDesc() {
		return desc;
	}
	public void setDesc(String desc) {
		this.desc = desc;
	}
}
 
package _22FlyweightPattern;

/**
 * 学生类
 */
public class Student {

	// 学生id
	private int id;
	// 学生姓名
	private String name;
	// 学生家庭住址
	private String homeAddress;
	// 所在学校
	private School school;
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getHomeAddress() {
		return homeAddress;
	}
	public void setHomeAddress(String homeAddress) {
		this.homeAddress = homeAddress;
	}
	public School getSchool() {
		return school;
	}
	public void setSchool(School school) {
		this.school = school;
	}
}

 

由于多个学生可以共用一个School对象,因此我们使用享元模式来分析School类。

我们将一个可共用的细粒度对象(上例中的School对象)的信息分为两类

  • 内部状态:类似于上面School类中的id、schoolName等等,不会随着环境的变化而变化。
  • 外部状态:类似于上面School类中的desc属性,但是要注意,内部状态和外部状态不应该互相影响。外部状态与对象本身无必然关系,外部状态总是因为外界环境的改变而变化,也就是说外部状态是由外界环境来决定的,无论你对学校的映像如何,学校都是同一个。

所谓的享元模式就是将一个类中可共享的部分抽取出来放进对象池,以避免重复创建相同(业务意义上的相同)的对象。
也就是下图所表示的,要将第一张图重构成第二张图:

 

 

 

3.享元模式的四个角色

享元角色就是可共享的角色。

  • Flyweight-抽象享元角色:它简单的说就是一个产品的抽象类,同事定义了对象的外部状态和内部状态的接口或实现。
  • ConcreteFlyweight-具体享元角色:具体的一个产品类,实现抽象角色定义的业务。该角色需要注意的是内部状态处理应该与环境无关,不应该出现一个操作改变了内部状态,同事又改变了外部状态,这是绝对不允许的。(使用享元模式尽量不要修改内部状态)
  • unsharedConcreteFlyweight不可共享的享元角色:一般由N个具体享元角色组合而成,因此它本身不需要被缓存,不必出现在享元工厂中。
  • FlyweightFactory享元工厂:职责非常简单,就是构造一个池容器,同事提供从池中获得对象的方法。

下面是享元模式的类图:

 

 

4.享元模式的通用代码

 

package _22FlyweightPattern;

/**
 * 抽象享元角色
 */
public abstract class Flyweight {
	// 内部状态
	private String intrinsic;
	// 外部状态
	protected final String extrinsic;
	
	// 强制享元角色必须接受外部状态
	public Flyweight(String extrinsic)
	{
		this.extrinsic = extrinsic;
	}

	public String getIntrinsic() {
		return intrinsic;
	}

	public void setIntrinsic(String intrinsic) {
		this.intrinsic = intrinsic;
	}
	
	// 定义业务逻辑
	public abstract void operate();
}

 

package _22FlyweightPattern;

/**
 * 具体享元角色
 */
public class ConcreteFlyweight extends Flyweight {

	public ConcreteFlyweight(String extrinsic) {
		super(extrinsic);
	}

	@Override
	public void operate() {
		// 业务逻辑
	}
}
 
package _22FlyweightPattern;

import java.util.HashMap;
import java.util.Map;

/**
 * 享元工厂
 */
public class FlyweightFactory {

	// 定义一个池容器
	private static Map<String, Flyweight> pool = new HashMap<String, Flyweight>();
	
	// 享元工厂
	// 线程安全问题需要另外解决
	public static Flyweight getFlyweight(String extrinsic) 
	{
		// 需要返回的对象
		Flyweight flyweight = null;
		// 先在池中查找对象
		if(pool.containsKey(extrinsic))
		{
			flyweight = pool.get(extrinsic);
		}else {
			flyweight = new ConcreteFlyweight(extrinsic);
			pool.put(extrinsic, flyweight);
		}
		return flyweight;
	}
	
}

 

5.享元模式的优缺点

享元模式是一个非常简单的模式,它可以大大减少应用程序创建的对象(比如你使用new School()的方式10000个学生对象就会产生10000个School对象,而通过缓存技术,那么只存在一个School对象),降低程序内存的占用,增强程序的性能,但它同时也提高了系统复杂性,需要分理处内部和外部状态,而且外部状态具有固化特效,不应该随内部状态改变而改变,否则导致系统的逻辑混乱。

 

6.最佳实践

外部状态最好使用Java的基本类型作为标志,如String、int等,可以大幅提升效率(Map的key值)。
享元模式在Java API中随处可见,比如String会对字符串进行缓存,Integer会对-128到127的数字进行缓存。String的intern方法:如果String对象池中有该类型的值,那么直接返回对象池中的对象。

分享到:
评论

相关推荐

    设计模式(C#)之享元模式(Flyweight Pattern)

    享元模式是设计模式中的一种结构型模式,它主要通过共享已有对象来减少内存中对象的数量,从而提高系统性能。在C#编程中,享元模式尤其适用于那些创建大量相似对象且内存消耗较大的场景。本篇文章将深入探讨享元模式...

    C#设计模式_设计模式_C#_

    享元模式(Flyweight Pattern) 12. 代理模式(Proxy Pattern) 行为型: 13. 模板方法(Template Method) 14. 命令模式(Command Pattern) 15. 迭代器模式(Iterator Pattern) 16. 观察者模式(Observer Pattern) 17. ...

    享元模式flyweight

    享元模式(Flyweight Pattern)是一种结构型设计模式,它能有效地减少系统中对象的数量,从而降低内存消耗,提高性能。这种模式通过共享大量相似对象的内部状态来达到这一目标,而只保留对象的外部状态在外部管理。...

    23种设计模式 (创建型,结构型,行为型)

    享元模式(Flyweight Pattern) 12. 代理模式(Proxy Pattern) 13. 模板方法(Template Method) 14. 命令模式(Command Pattern) 15. 迭代器模式(Iterator Pattern) 行为型: 16. 观察者模式(Observer Pattern...

    设计模式代码——c#

    11. 享元模式(Flyweight Pattern) 12. 代理模式(Proxy Pattern) 行为型 13. 模板方法(Template Method) 14. 命令模式(Command Pattern) 15. 迭代器模式(Iterator Pattern) 16. 观察者模式(Observer Pattern...

    32种设计模式

    享元模式(Flyweight Pattern) 12. 代理模式(Proxy Pattern) 13. 模板方法(Template Method) 14. 命令模式(Command Pattern) 15. 迭代器模式(Iterator Pattern) 行为型: 16. 观察者...

    6.设计模式-享元模式1

    享元模式(Flyweight Pattern)是结构型模式的一种,主要用于减少大量相似对象的内存占用,提高系统的性能和效率。 模式定义 享元模式的定义是:运用共享技术有效地支持大量细粒度的对象。该模式将一个对象的状态...

    c++-设计模式之享元模式(Flyweight)

    享元模式(Flyweight Pattern)是一种结构型设计模式,用于减少创建大量小对象所带来的内存开销。通过共享对象,享元模式能够有效地支持大量细粒度的对象,减少内存使用并提高性能。它常用于需要大量重复对象的场景...

    学习php设计模式 php实现享元模式(flyweight)

    享元模式(Flyweight Pattern)是软件设计中的一种结构型设计模式,它通过共享技术来支持大量细粒度的对象,以此来降低内存中对象的数量。在PHP中实现享元模式,可以帮助我们优化程序性能,特别是在对象数目过多时,...

    系统开发二十三种设计模式

    22. 享元模式(Flyweight Pattern):运用共享技术有效地支持大量细粒度的对象,减少内存消耗。 23. 外观模式(Facade Pattern):为子系统提供一个一致的接口,使得这些子系统更容易使用。 以上就是系统开发中...

    C++设计模式课件13_Flyweight_享元模式.pdf

    享元模式(Flyweight Pattern)是设计模式中的一种优化模式,主要用于减少创建大量相似对象所需的内存消耗。在C++程序设计中,当系统中存在大量的相同或相似的对象时,使用享元模式可以有效地降低内存占用,提高系统...

    JavaScript设计模式.pdf

    7.享元模式(Flyweight Pattern): 享元模式是用来优化系统性能的设计模式。它的主要作用是减少对象的数量,提高系统的性能和可扩展性。 8. 代理模式(Proxy Pattern): 代理模式是控制对象的访问,包括推迟对其...

    C#23种设计模式【完整】.pdf

    11. 享元模式(Flyweight Pattern):使用共享技术来最小化对象的存储空间,避免大量相同对象的创建。 12. 代理模式(Proxy Pattern):为其他对象提供一个代理,以控制对这个对象的访问。 13. 模板方法模式...

    java设计模式.txt

    享元模式(Flyweight Pattern) 享元模式运用共享技术有效地支持大量细粒度的对象。它可以极大地减少内存中的对象数量,从而优化性能。 #### 12. 代理模式(Proxy Pattern) 代理模式为其他对象提供一个代理以控制...

    享元模式1

    享元模式(Flyweight Pattern)是一种结构型设计模式,旨在减少大量相似对象的创建,降低系统资源的开销和内存压力。该模式通过共享已经存在的对象来大幅减少需要创建的对象数量,避免创建大量相似类带来的开销,...

    Java设计模式之禅

    6. 享元模式(Flyweight Pattern):运用共享技术有效地支持大量细粒度的对象。 7. 门面模式(Front Controller Pattern):提供一个统一的接口来访问子系统。 8. 中介者模式(Mediator Pattern):用一个中介对象来...

    C# 24种设计模式代码示例

    10. 享元模式(Flyweight Pattern):在大量细粒度对象中节省内存,通过共享尽可能多的对象状态。 11. 组合模式(Composite Pattern):允许你将对象组合成树形结构,以表示“部分-整体”的层次结构。 12. 责任链...

    java设计模式详解,java design pattern

    4. 享元模式(Flyweight Pattern):运用共享技术有效地支持大量细粒度的对象。 5. 外观模式(Facade Pattern):为子系统中的一组接口提供一个统一的界面,定义一个高层接口,让子系统更容易使用。 6. 桥接模式...

    C#23种设计模式【完整】(亲测可用)

    12. 享元模式(Flyweight Pattern):在不影响功能的情况下,减少对象的创建,以节约内存资源。 13. 代理模式(Proxy Pattern):为其他对象提供一种代理以控制对这个对象的访问。 14. 责任链模式(Chain of ...

Global site tag (gtag.js) - Google Analytics