设计模式之享元模式

设计模式之享元模式

享元模式是对象的结构模式。享元模式以共享的方式高效地支持大量的细粒度对象。它用于通过尽可能多地与类似对象共享来最小化内存使用或计算开销。

应用场景

  1. 应用中需要大量的对象,大量的对象可能造成存储对象的开销。
  2. 对象变化的状态大多是外部状态。一旦外部状态被移除,许多对象组可被相对较少的共享对象替换。这也就是享元模式利用的点。
  3. 因为在享元模式中对象是共享的,所以在含义上的不同对象使用equels实际返回的是true。

享元模式结构

享元模式采用一个共享来避免大量拥有相同内容对象的开销。这种开销最常见、最直观的就是内存的损耗。享元对象能做到共享的关键是区分内蕴状态(Internal State)和外蕴状态(External State)。

内蕴状态决定对象本身的状态,不会随着环境的变化而变化,而外蕰状态是由客户端将状态传递给享元对象的,外蕴状态类似同一个对象的不同的行为,内蕴状态和外蕰状态是相互独立,互不影响的。

享元模式主要这几三个部分:抽象享元类,具体享元类和享元工厂类。具体可以参考下面代码。

享元模式

代码

在Java中,String类就符合享元模式,string a = "aa"string b ="aa" 是相等的。

在下面例子中,构造抽象享元类“MyString” 和它的具体实现类,使用到相同的对象,因为享元模式,可以对这些对象进行共享使用。

第一部分:抽象享元类

1
2
3
4
5
6
7
public interface MyString {
void create(String outerState);
}
//枚举类
public enum InstanceType {
INSTANCE1,INSTANCE2
}

第二部分:具体享元类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class StringIns1 implements MyString {

// 内部状态,不可随时变化的
String innerState;

public StringIns1(String innerState) {
this.innerState = innerState;
}

@Override
public void create(String outerState) {
System.out.println("create instance 1 -> innerState:"+this.innerState);
//外部状态,需要客户端传进来,这个值是可变化的
System.out.println("create instance 1 -> outerState:"+outerState);
}
}

public class StringIns2 implements MyString {

String innerState;

public StringIns2(String innerState) {
this.innerState = innerState;
}

@Override
public void create(String outerState) {
System.out.println("create instance 2 -> innerState:"+this.innerState);
System.out.println("create instance 2 -> outerState:"+outerState);
}
}

第三部分:享元工厂类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class FlyWeight {
Map<InstanceType,MyString> store;

FlyWeight() {
store = new HashMap<>();
}

public MyString factory(InstanceType instanceType){
MyString curr = store.get(instanceType);
if(curr == null){
// 如果对象不存在,新建对应的对象
if(instanceType.equals(InstanceType.INSTANCE1)){
// 根据内部状态决定生成哪个类型的子类
curr= new StringIns1(instanceType.toString());
} else if(instanceType.equals(InstanceType.INSTANCE2)){
curr= new StringIns2(instanceType.toString());
}
}
store.put(instanceType,curr);
return curr;
}
}

第四部分:客户端调用

1
2
3
4
5
6
7
8
9
10
public class App {
public static void main(String[] args) {
FlyWeight flyWeight = new FlyWeight();
MyString ins1 = flyWeight.factory(InstanceType.INSTANCE1);
MyString ins2 = flyWeight.factory(InstanceType.INSTANCE1);
System.out.println(ins1.equals(ins2));//true 是同一个对象 内部状态相同
ins1.create("*****"); //针对外部状态打印不同内容
ins2.create("-----");
}
}

结果:

1
2
3
4
5
true
create instance 1 -> innerState:INSTANCE1
create instance 1 -> outerState:*****
create instance 1 -> innerState:INSTANCE1
create instance 1 -> outerState:-----
-------------本文结束感谢您的阅读-------------

本文标题:设计模式之享元模式

文章作者:NanYin

发布时间:2019年06月13日 - 12:06

最后更新:2019年08月12日 - 13:08

原始链接:https://nanyiniu.github.io/2019/06/13/2019-06-13-%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E4%BA%AB%E5%85%83%E6%A8%A1%E5%BC%8F/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。