享元模式

享元模式(Flyweight)是一种结构型设计模式,它的出现是为了在使用大量细粒度对象时节省空间。在使用大量细粒度对象时,它们彼此之间往往有所相同,又有所不同。比如在一个PPT文档中,可能多处出现了“A”这个字母。它们之间的共同处是字形一样,都是A;不同是颜色不同,有的地方字体颜色为黑,有的地方为灰。

我们把这些对象之间相同的地方抽象出来称为“内蕴状态”,不同的地方称为“外蕴状态”。在使用享元模式时,内蕴状态相同的共用一个对象,不同的外蕴状态由使用该对象的客户端传入,并在此对象的方法中体现。也就是说,我们让同一个对象(保存了内蕴状态“A”)创建黑色的“A”和灰色的“A”,但是在创建时由客户端向创建方法中传入字体颜色(外蕴状态),这样能够大量节省空间。

在享元模式中享元工厂有至关重要的作用,它维护了一个共用享元对象池,防止享元对象的重复,并为客户端提供需要的享元对象。也就是说,所有已经被创建的字形对象被存入享元工厂,客户端向工厂申请某一个字形,如果已经存在,取出返回;如果不存在,创建并存入对象池,然后将其返回。

享元模式又分为简单享元模式和复合享元模式。复合享元模式中多了不共用的复合享元对象,它其实是由共用的享元对象构成的。复合享元对象对应了这样一种情况,我打算创建一段颜色统一的文字,所以先将文字(每个不同的文字对应一个简单享元对象)放入复合享元对象,再在进行创建时传入字体颜色,这一创建实际是由复合享元对象依次调用它的简单享元对象并传入颜色完成的。

简单享元模式包括:

  • 抽象享元接口
  • 共用的享元类
  • 享元工厂
  • 客户端

复合享元模式包括:

  • 抽象享元接口
  • 共用的享元类
  • 不共用的复合享元类
  • 享元工厂
  • 客户端
package DesignPattern;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
//抽象享元接口
interface Prototype {
    void operation(String color);
}
//简单享元具体类
class SimpleFlyweight implements Prototype {
    //word为内蕴状态
    Character word;
    SimpleFlyweight(Character _word) {
        word = _word;
    }
    //color为外蕴状态
    public void operation(String color) {
        System.out.println(word + "(" + color + ")" + " ");
    }
}
//复合享元具体类
class CompositeFlyweight implements Prototype {
    List<SimpleFlyweight> lst = new ArrayList<>();
    void add(SimpleFlyweight obj) {
        lst.add(obj);
    }
    public void operation(String color) {
        for(SimpleFlyweight n : lst) {
            n.operation(color);
        }
    }
}
//享元工厂
class Factory {
    Map<Character,SimpleFlyweight> map = new HashMap<>();
    int getSize() { return map.size(); }
    SimpleFlyweight factory(Character word) {
        SimpleFlyweight res = map.get(word);
        if(res == null) {
            res = new SimpleFlyweight(word);
            map.put(word,res);
        }
        return res;
    }
    CompositeFlyweight factory(List<Character> lst) {
        CompositeFlyweight res = new CompositeFlyweight();
        for(Character ch : lst) {
            res.add(this.factory(ch));
        }
        return res;
    }
}
//客户端
public class Flyweight {
    public static void main(String[] args) {
        Factory fac = new Factory();
        //简单享元模式测试
        SimpleFlyweight obj1 = fac.factory('A');
        SimpleFlyweight obj2 = fac.factory('A');
        obj1.operation("blue");
        obj2.operation("red");
        //size=1,obj1=obj2,可见两个A共用了享元对象
        System.out.println(fac.getSize());
        System.out.println(obj1 == obj2);
        //符合享元测试
        List<Character> lst = new ArrayList<>();
        lst.add('A');
        lst.add('A');
        lst.add('A');
        lst.add('A');
        CompositeFlyweight obj3 = fac.factory(lst);
        CompositeFlyweight obj4 = fac.factory(lst);
        obj3.operation("green");
        obj4.operation("black");
        //size=1,可见复合享元对象底层共用了简单享元对象
        //obj3!=obj4,可见复合享元对象本身不共享
        System.out.println(fac.getSize());
        System.out.println(obj3 == obj4);
    }
}
/*
output:
A(blue) 
A(red) 
1
true
A(green) 
A(green) 
A(green) 
A(green) 
A(black) 
A(black) 
A(black) 
A(black) 
1
false
*/

总结

当你的对象有大量数目的时候,且拥有相同的属性,只有某些属性不同的时候,享元模式可以大量节省内存哦。享元模式又称蝇量模式,顾名思义,flyweight,轻量级啊。

抽取变化:不变的是这些对象共有的基础属性,变化的是这些对象独特的个性属性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值