设计模式之享元模式笔记

说明

记录下学习设计模式-享元模式的写法。JDK使用版本为1.8版本。

Flyweight(享元)

意图:运用共享技术有效地支持大量细粒度的对象。
结构:
在这里插入图片描述

其中:

  • Flyweight描述一个接口,通过这个接口Flyweight可以接受并作用于外部状态。
  • ConcreteFlyweight实现Flyweight接口,并为内部状态(如果有)增加存储空间。ConcreteFlyweight对象必须是可共享的。它所存储的状态必须是内部的,即它必须独立于ConcreteFlyweight对象的场景。
  • 并非所有的Flyweight子类都需要被共享。Flyweight接口使共享成为可能,但它并不强制共享。在Flyweight对象结构的某些层次,UnsharedConcreteFlyweight对象通常将ConcreteFlyweight对象作为子节点。
  • FlyweightFactory创建并管理Flyweight对象;确保合理地共享Flyweight,当用户请求一个Flyweight时,FlyweightFactory对象提供一个已创建的实例或者在不存在时创建一个实例。
  • Client维持一个对Flyweight的引用:计算或存储一个或多个Flyweight的外部状态。

适用性:

  • 一个应用程序使用了大量的对象。
  • 完全由于使用大量的对象,造成很大的存储开销。
  • 对象的大多数状态都可变为外部状态。
  • 如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象。
  • 应用程序不依赖于对象标识。由于Flyweight对象可以被共享,所以对于概念上明显有别的对象,标识测试将返回真值。

使用场景:

  • 一个系统有大量相同或者相似的对象,造成内存的大量耗费。
  • 对象的大部分状态都可以外部化,可以将这些外部状态传入对象中。
  • 在使用享元模式时需要维护一个存储享元对象的享元池,而这需要耗费一定的系统资源,因此,应当在需要多次重复使用享元对象时才值得使用享元模式。

目录

在这里插入图片描述

享元模式示例类图

在这里插入图片描述
在这里插入图片描述
以该UML类图实现享元模式示例。

抽象图形类

package com.example.deesign_patterns.flyweight;

//抽象享元角色
public abstract class AbstractBox {
    
    

    //获取图形的方法
    public abstract String getShape();

    //显示图形及颜色
    public void display(String color){
    
    
        System.out.println("方块形状:"+getShape()+",方块颜色:"+color);
    }
}

I图形类

package com.example.deesign_patterns.flyweight;

//I图形类(具体享元角色)
public class IBox extends AbstractBox{
    
    

    @Override
    public String getShape() {
    
    
        return "I";
    }
}

L图形类

package com.example.deesign_patterns.flyweight;

//L图形类(具体享元角色)
public class LBox extends AbstractBox{
    
    

    @Override
    public String getShape() {
    
    
        return "L";
    }
}

O图形类

package com.example.deesign_patterns.flyweight;

//O图形类(具体享元角色)
public class OBox extends AbstractBox{
    
    

    @Override
    public String getShape() {
    
    
        return "O";
    }
}

工厂类

package com.example.deesign_patterns.flyweight;

import java.util.HashMap;

//工厂类,将该类设计为单例
public class BoxFactory {
    
    

    private HashMap<String,AbstractBox> map;

    //使用单例模式-饿汉式静态成员变量方式
    private static BoxFactory factory=new BoxFactory();

    //在构造方法中进行初始化操作
    public BoxFactory() {
    
    
        map=new HashMap<String,AbstractBox>();
        map.put("I",new IBox());
        map.put("L",new LBox());
        map.put("O",new OBox());
    }

    //提供一个方法获取该工厂类对象
    public static BoxFactory getInstance(){
    
    
        return factory;
    }

    //根据名称获取图形对象
    public AbstractBox getShape(String name){
    
    
        return map.get(name);
    }
}

测试类

package com.example.deesign_patterns.flyweight;

//测试类
public class Client {
    
    

    public static void main(String[] args) {
    
    
        //获取I图形对象
        AbstractBox box1 = BoxFactory.getInstance().getShape("I");
        box1.display("灰色");
        //获取L图形对象
        AbstractBox box2 = BoxFactory.getInstance().getShape("L");
        box2.display("绿色");
        //获取O图形对象
        AbstractBox box3 = BoxFactory.getInstance().getShape("O");
        box3.display("灰色");
        //获取O图形对象
        AbstractBox box4 = BoxFactory.getInstance().getShape("O");
        box4.display("红色");
        System.out.println("两次获取到的O图形对象是否是同一个对象:"+(box3==box4));
    }
}

在这里插入图片描述

好处:

  • 极大减少内存中相似或相同对象数量,节约系统资源,提供系统性能。
  • 享元模式中的外部状态相对独立,且不影响内部状态。

缺点:
为了使对象可以共享,需要将享元对象的部分状态外部化,分离内部状态和外部状态,使程序逻辑复杂。

猜你喜欢

转载自blog.csdn.net/weixin_48040732/article/details/131351716