【设计模式】第14章·享元模式

一、享元模式概述

定义:

享元模式:运用共享技术有效的支持大量细粒度对象的复用。

二、享元模式结构与实现

2.1 享元模式的结构

享元模式主要有4个角色:

  1. Flyweight(抽象享元类):声明类具体享元类公共的方法,一般是接口或抽象类。
  2. ConcreteFlyweight(具体享元类):实现了抽象享元接口,为内部状态提供了存储空间。
  3. UnsharedConcreteFlyweight(非共享具体享元类):不能被共享的抽象享元类的子类。
  4. FlyweightFactory(享元工厂类):用于创建并管理享元对象,它针对抽象享元类编程,将各种类型的具体享元对象存储在一个享元池中。

2.2 享元模式的实现

案例实现。

//抽象享元类

public abstract class BaseDoc {

    private String content;

    public void display(TextStyle ts) {
        System.out.println("文字内容:" + getContent() + ",颜色:" + ts.getColor() + ",文字大小:" + ts.getFontSize());
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}

//具体享元类

public class TextDoc extends BaseDoc{

    public TextDoc(String content) {
        super.setContent(content);
    }
}

//外部状态类

public class TextStyle {

    private String color;

    private String fontSize;

    public TextStyle(String color, String fontSize) {
        this.color = color;
        this.fontSize = fontSize;
    }
    public String getColor() {
        return color;
    }
    public void setColor(String color) {
        this.color = color;
    }
    public String getFontSize() {
        return fontSize;
    }
    public void setFontSize(String fontSize) {
        this.fontSize = fontSize;
    }
}

//享元工厂类

public class BaseDocFactory {

    public static Map<String, BaseDoc> flyweights = new HashMap<>();

    public static BaseDoc getBaseDoc(String key) {

        if (flyweights.containsKey(key)) {
            return flyweights.get(key);
        } else {
            BaseDoc baseDoc = new TextDoc(key);
            flyweights.put(key, baseDoc);
            return baseDoc;
        }
    }
}

//客户端

public class client {

    public static void main(String[] args) {

        /**
         * 案例需求描述:
         *  在屏幕中显示一个文本文档,其中相同的字符串共享一个对象,而这些字符串的颜色和大小可以不同。
         *  现使用享元模式设计一个方案实现字符串对象的共享。
         */

        BaseDoc hello = BaseDocFactory.getBaseDoc("hello");
        BaseDoc hello2 = BaseDocFactory.getBaseDoc("hello");
        System.out.println(hello==hello2);
        BaseDoc world = BaseDocFactory.getBaseDoc("world");
        BaseDoc java = BaseDocFactory.getBaseDoc("java");

        hello.display(new TextStyle("red","16px"));
        hello2.display(new TextStyle("blue","18px"));
        world.display(new TextStyle("pink","15px"));
        java.display(new TextStyle("black","20px"));

    }

}

三、享元模式优缺点和适用环境

3.1 享元模式的优点

  1. 可以减少内存中对象的数量,使得相同或者相似对象在内存中只保存一份,从而可以节约系统资源,提供系统性能。
  2. 享元模式的外部状态相对独立,而且不会影响其内部状态,从而使享元对象可以在不同的环境中被共享。

3.2 享元模式的缺点

  1. 享元模式使系统变得复杂,需要分离出内部状态和外部状态,这使得程序复杂化。
  2. 为了使对象可以共享,享元模式需要将享元对象的部分状态外部化,而读取外部状态将使运行时间变长。

3.3 享元模式的适用环境

  1. 一个系统有大量相同或者相似的对象,赵城内存的大量耗费;
  2. 对象的大部分状态可以外部化,可以将这些外部状态传入对象中;
  3. 需要多次重复使用享元对象。

四、其他

享元模式以共享的方式高效地支持大量细粒度对象的重用,享元对象能做到共享的关键是区分了内部状态和外部状态。

内部状态是存储在享元对象内部并且不会随环境改变而改变的状态,内部状态可以共享。

外部状态是随环境改变而改变的,不可用共享的状态。

【参考文献】:
本文是根据刘伟的《Java设计模式》一书的学习笔记,仅供学习用途,勿做其他用途,请尊重知识产权。

【本文代码仓库】:https://gitee.com/xiongbomy/java-design-pattern.git

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值