1.享元模式
享元模式(Flyweight Pattern):运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。由于享元模式要求能够共享的对象必须是细粒度对象,因此它又称为轻量级模式,它是一种对象结构型模式。
2.uml图
3.代码
package com.wuhuiskiff.www.flyweight.code.chars;
/**
* @Auther: 一叶扁舟
* @Date: 2019/2/15 12:37
* @Description:
*/
public abstract class FlyWeight {
public abstract void operation(String extrinsicState);
}
package com.wuhuiskiff.www.flyweight.code.chars;
/**
* @Auther: 一叶扁舟
* @Date: 2019/2/15 12:58
* @Description:具体的享远类
*/
public class ConcreteFlyweight extends FlyWeight {
// 内部的状态
private String intrinsicState;
@Override
public void operation(String extrinsicState) {
}
}
package com.wuhuiskiff.www.flyweight.code.chars;
/**
* @Auther: 一叶扁舟
* @Date: 2019/2/15 13:00
* @Description:非共享具体享元类
*/
public class UnsharedConcreteFlyweight extends FlyWeight{
private String allState;
@Override
public void operation(String extrinsicState) {
}
}
package com.wuhuiskiff.www.flyweight.code.chars;
import java.util.HashMap;
/**
* @Auther: 一叶扁舟
* @Date: 2019/2/15 13:02
* @Description:享元工厂
*/
public class FlyweightFactory {
private HashMap flyweights = new HashMap();
public FlyWeight getFlyweight(String key){
if(flyweights.containsKey(key)){
return (FlyWeight) flyweights.get(key);
}else{
FlyWeight flyWeight = new ConcreteFlyweight();
flyweights.put(key,flyWeight);
return flyWeight;
}
}
public static void main(String args[])
{
String str1="abcd";
String str2="abcd";
String str3="ab" + "cd";
String str4="ab";
str4+="cd";
System.out.println(str1==str2); // true
System.out.println(str1==str3); // true
System.out.println(str1==str4); // false
System.out.println(str4); //abcd
}
}
定义的一个字符类:
package com.wuhuiskiff.www.flyweight.code.character;
/**
* @Auther: 一叶扁舟
* @Date: 2019/2/15 20:57
* @Description:
*/
public class MyCharacter {
private char character;
public MyCharacter(char character){
this.character = character;
}
public void display(){
System.out.println(this.character);
}
}
package com.wuhuiskiff.www.flyweight.code.character;
import java.util.HashMap;
/**
* @Auther: 一叶扁舟
* @Date: 2019/2/15 21:03
* @Description:
*/
public class MyFactory {
private HashMap flyweights;
public MyFactory() {
this.flyweights = new HashMap<Character,MyCharacter>();
}
public MyCharacter getCharacter(Character character){
MyCharacter cha = (MyCharacter) flyweights.get(character);
if(cha == null){
cha = new MyCharacter(character);
this.flyweights.put(character,cha);
}
return cha;
}
}
package com.wuhuiskiff.www.flyweight.code.character;
/**
* @Auther: 一叶扁舟
* @Date: 2019/2/15 21:12
* @Description:
*/
public class Client {
public static void main(String[] args) {
// MyCharacter myCharacter1 = new MyCharacter('a');
// MyCharacter myCharacter2 = new MyCharacter('b');
// MyCharacter myCharacter3 = new MyCharacter('c');
// MyCharacter myCharacter4 = new MyCharacter('a');
//
// myCharacter1.display();
// myCharacter2.display();
// myCharacter3.display();
// myCharacter4.display();
// if(myCharacter1 == myCharacter2){ // false 不是一个对象
// System.out.println("true");
// }else{
// System.out.println("false");
// }
//
MyFactory myFactory = new MyFactory();
MyCharacter a = myFactory.getCharacter('a');
MyCharacter b = myFactory.getCharacter('b');
MyCharacter c = myFactory.getCharacter('c');
MyCharacter a1 = myFactory.getCharacter('a');
a.display();
b.display();
c.display();
a1.display();
System.out.println(a == a1);
}
}
4.优缺点
享元模式的优点
- 享元模式的优点在于它可以极大减少内存中对象的数量,使得相同对象或相似对象在内存中只保存一份。
- 享元模式的外部状态相对独立,而且不会影响其内部状态,从而使得享元对象可以在不同的环境中被共享。
享元模式的缺点
- 享元模式使得系统更加复杂,需要分离出内部状态和外部状态,这使得程序的逻辑复杂化。
- 为了使对象可以共享,享元模式需要将享元对象的状态外部化,而读取外部状态使得运行时间变长。
5.运用
在以下情况下可以使用享元模式:
- 一个系统有大量相同或者相似的对象,由于这类对象的大量使用,造成内存的大量耗费。
- 对象的大部分状态都可以外部化,可以将这些外部状态传入对象中。
- 使用享元模式需要维护一个存储享元对象的享元池,而这需要耗费资源,因此,应当在多次重复使用享元对象时才值得使用享元模式。
运用场景:
享元模式在编辑器软件中大量使用,如在一个文档中多次出现相同的图片,则只需要创建一个图片对象,通过在应用程序中设置该图片出现的位置,可以实现该图片在不同地方多次重复显示。
在JDK类库中定义的String类使用了享元模式。
6.总结
- 享元模式包含四个角色:抽象享元类声明一个接口,通过它可以接受并作用于外部状态;具体享元类实现了抽象享元接口,其实例称为享元对象;非共享具体享元是不能被共享的抽象享元类的子类;享元工厂类用于创建并管理享元对象,它针对抽象享元类编程,将各种类型的具体享元对象存储在一个享元池中。
- 享元模式以共享的方式高效地支持大量的细粒度对象,享元对象能做到共享的关键是区分内部状态和外部状态。其中内部状态是存储在享元对象内部并且不会随环境改变而改变的状态,因此内部状态可以共享;外部状态是随环境改变而改变的、不可以共享的状态。