• 17 结构型模式-享元模式


    1 享元模式介绍

    在这里插入图片描述
    在这里插入图片描述

    2 享元模式原理

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    3 享元模式实现

    抽象享元类可以是一个接口也可以是一个抽象类,作为所有享元类的公共父类, 主要作用是提高系统的可扩展性.

    //* 抽象享元类
    public abstract class Flyweight {
    	public abstract void operation(String extrinsicState);
    }
    
    • 1
    • 2
    • 3
    • 4

    具体享元类
    具体享元类中要将内部状态和外部状态分开处理,内部状态作为具体享元类的成员变量,而外部状态通过注入的方式添加到具体享元类中.

    /**
     * 可共享的-具体享元类
     * 注意: 在具体享元类中,需要将内部状态和外部状态分开处理.
     **/
    public class ConcreteFlyweight extends Flyweight{
    
        //内部状态 : inState作为一个成员变量,同一个享元对象的内部状态是一致的.
        private String inState;
    
        public ConcreteFlyweight(String inState) {
            this.inState = inState;
        }
    
        /**
         * 外部状态在使用的时候,通常是有外部设置,不保存在享元对象中,即使是同一个对象
         * @param state
         */
        @Override
        public void operation(String state) {
    
            System.out.println("=== 享元对象的内部状态: " + inState + ",外部状态: " + state );
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    非共享享元类,不复用享元工厂内部状态,但是是抽象享元类的子类或实现类

    /**
     * 非共享的具体享元类
     **/
    public class UnsharedFlyweight  extends Flyweight{
    
        private String inState;
    
        public UnsharedFlyweight(String inState) {
            this.inState = inState;
        }
    
        @Override
        public void operation(String state) {
            System.out.println("=== 使用不共享对象,内部状态: " + inState + ",外部状态: " + state );
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    享元工厂类, 管理一个享元对象类的缓存池。它会存储享元对象之间需要传递的共有状态,比如,按照大写英文字母来作为状态标识,这种只在享元对象之间传递的方式就叫内部状态。同时,它还提供了一个通用方法getFlyweight(),主要通过内部状态标识来获取享元对象。

    /**
     * 享元工厂类
     * 作用: 作为存储享元对象的享元池.用户获取享元对象时先从享元池中获取,有则返回,没有创建新的返回给用户,
     * 并且在享元池中保存
     **/
    public class FlyweightFactory {
    
        //定义一个Map集合用于存储享元对象,实现享元池
        private Map<String,Flyweight> pool = new HashMap<>();
    
        //实现享元对象之间的状态传递
        public FlyweightFactory() {
            //添加对应的内部状态
            pool.put("A",new ConcreteFlyweight("A"));
            pool.put("B",new ConcreteFlyweight("B"));
            pool.put("C",new ConcreteFlyweight("C"));
        }
    
        //根据内部状态进行查找
        public Flyweight getFlyweight(String key){
            //对象是否存在
            if(pool.containsKey(key)){
                System.out.println("=== 享元池中存在,直接复用,key : " + key);
                return pool.get(key);
            }else{
                //如果对象不存在,就创建一个添加到享元池,然后返回
                System.out.println("=== 享元池中不存在,创建并复用,key: " + key);
                Flyweight fw = new ConcreteFlyweight(key);
                pool.put(key,fw);
                return  fw;
            }
        }
    }
    
    • 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
    • 32
    • 33
    public class Client {
    
        public static void main(String[] args) {
    
            //获取工厂对象
            FlyweightFactory factory = new FlyweightFactory();
    
            //通过工厂对象获取共享的享元对象
            Flyweight a1 = factory.getFlyweight("A");
            a1.operation("a1ExState");
    
            Flyweight a2 = factory.getFlyweight("A");
            a2.operation("a2ExState");
            System.out.println(a1 == a2);
    
            //获取非共享的享元对象
            UnsharedFlyweight u1 = new UnsharedFlyweight("A");
            UnsharedFlyweight u2 = new UnsharedFlyweight("A");
            System.out.println(u1 == u2);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    4 享元模式应用实例

    在这里插入图片描述
    在这里插入图片描述

    /**
     * 抽象享元类: 五子棋
     **/
    public abstract class GobangFlyweight {
    
        public abstract String getColor();
    
        public void display(){
            System.out.println("棋子颜色: " + this.getColor());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    /**
     * 共享享元类-白色棋子
     **/
    public class WriteGobang extends GobangFlyweight {
    
    
        @Override
        public String getColor() {
            return "白色";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    /**
     * 共享享元类-黑色棋子
     **/
    public class BlackGobang extends GobangFlyweight {
    
    
        @Override
        public String getColor() {
            return "黑色";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    /**
     * 享元工厂类-生产五子棋棋子
     **/
    public class GobangFactory {
    
        //享元池
        private static Map<String,GobangFlyweight> pool;
    
        //创建共享享元对象,设置对象的内部状态
        private GobangFactory() {
            pool = new HashMap<>();
            GobangFlyweight black = new BlackGobang(); //黑子
            GobangFlyweight write = new WriteGobang(); //白子
    
            pool.put("b",black);
            pool.put("w",write);
        }
    
    
        //获取唯一享元工厂对象的方法
        public static GobangFactory getInstance(){
           return SingletonHolder.INSTANCE;
        }
    
        //静态内部类
        private static class SingletonHolder{
            private static final GobangFactory INSTANCE = new GobangFactory();
        }
    
        //通过key获取集合中的享元对象
        public GobangFlyweight getGobang(String key){
            return pool.get(key);
        }
    
    }
    
    • 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
    • 32
    • 33
    • 34
    • 35
    public class Client {
    
        public static void main(String[] args) {
    
            GobangFactory instance = GobangFactory.getInstance();
    
            //获取3颗黑子
            GobangFlyweight b1 = instance.getGobang("b");
            GobangFlyweight b2 = instance.getGobang("b");
            GobangFlyweight b3 = instance.getGobang("b");
            System.out.println("判断黑子是否是同一对象: " + (b1 == b2));
    
            GobangFlyweight w1 = instance.getGobang("w");
            GobangFlyweight w2 = instance.getGobang("w");
            System.out.println("判断白子是否是同一对象: " + (w1 == w2));
    
            //显示棋子
            b1.display();
            b2.display();
            b3.display();
            w1.display();
            w2.display();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    在这里插入图片描述

    5 享元模式总结

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    idea启动dataX,开发金仓和达梦插件
    [架构之路-59]:目标系统 - 平台软件 - 基础中间件 - POSIX(可移植操作系统接口)与标准库函数libc
    【C++那些事儿】函数重载与C++中的“指针“——引用
    星岛专栏|从Web3发展看金融与科技的融合之道
    MODBUS-RTU从站通信(SMART PLC作为MODBUS-RTU从站)
    DO280管理和监控OpenShift平台--使用probes监视应用
    python二级题库(百分之九十原题) 刷题软件推荐
    VUE3.0+Antdv+Asp.net WebApi开发学生信息管理系统(三)
    广州蓝景分享—「web前端素材」使用CSS动画效果(上)
    基于Java实现EsriJson、GeoJson互相转换方法
  • 原文地址:https://blog.csdn.net/weixin_39563769/article/details/134036996