• 设计模式学习08:享元模式


    设计模式学习08:享元模式

    参考资料

    https://www.jianshu.com/p/a2aa75939766

    https://www.cnblogs.com/adamjwh/p/9070107.html

    简介

      Use sharing to support large numbers of fine-grained objects efficiently.

      使用共享对象可有效地支持大量的细粒度的对象。

      享元模式(Flyweight)又称为 轻量级模式,它是一种对象结构型模式。

      面向对象技术可以很好地解决一些灵活性或可扩展性问题,但在很多情况下需要在系统中增加类和对象的个数。当对象数量太多时,将导致运行代价过高,带来性能下降等问题。享元模式 正是为解决这一类问题而诞生的。

      享元模式 是对象池的一种实现。类似于线程池,线程池可以避免不停的创建和销毁多个对象,消耗性能。享元模式 也是为了减少内存的使用,避免出现大量重复的创建销毁对象的场景。

      享元模式 的宗旨是共享细粒度对象,将多个对同一对象的访问集中起来,不必为每个访问者创建一个单独的对象,以此来降低内存的消耗。

      享元模式 把一个对象的状态分成内部状态和外部状态,内部状态即是不变的,外部状态是变化的;然后通过共享不变的部分,达到减少对象数量并节约内存的目的。

      享元模式 本质:缓存共享对象,降低内存消耗

    主要解决

      当系统中多处需要同一组信息时,可以把这些信息封装到一个对象中,然后对该对象进行缓存,这样,一个对象就可以提供给多处需要使用的地方,避免大量同一对象的多次创建,消耗大量内存空间。

      享元模式 其实就是 工厂模式 的一个改进机制,享元模式 同样要求创建一个或一组对象,并且就是通过工厂方法生成对象的,只不过 享元模式 中为工厂方法增加了缓存这一功能。

    优点

      享元模式 可以极大减少内存中对象的数量,使得相同对象或相似对象在内存中只保存一份,降低内存占用,增强程序的性能;

      享元模式 的外部状态相对独立,而且不会影响其内部状态,从而使得享元对象可以在不同的环境中被共享;

    缺点

      享元模式 使得系统更加复杂,需要分离出内部状态和外部状态,这使得程序的逻辑复杂化;

      为了使对象可以共享,享元模式 需要将享元对象的状态外部化,而且外部状态必须具备固化特性,不应该随内部状态改变而改变,否则会导致系统的逻辑混乱;

    使用场景

      系统中存在大量的相似对象;

      细粒度的对象都具备较接近的外部状态,而且内部状态与环境无关,也就是说对象没有特定身份;

      需要缓冲池的场景;

    经典案例

    抽象父类
    public abstract class FlyWeight {
    
        public String intrinsic;
    
        protected final String extrinsic;
    
    
        public FlyWeight(String extrinsic) {
            this.extrinsic = extrinsic;
        }
    
        public abstract  void operate(int extrinsic);
    
        public String getIntrinsic() {
            return intrinsic;
        }
    
        public void setIntrinsic(String intrinsic) {
            this.intrinsic = intrinsic;
        }
    }
    
    //共享子类
    public class ConcreteFlyWeight extends  FlyWeight {
    
        public ConcreteFlyWeight(String extrinsic) {
            super(extrinsic);
        }
    
        @Override
        public void operate(int extrinsic) {
            System.out.println("共享的具体FlyWright:" + extrinsic);
        }
    }
    //不共享子类
    public class UnsharedConcreteFlyweight extends  FlyWeight {
    
        public UnsharedConcreteFlyweight(String extrinsic) {
            super(extrinsic);
        }
    
        @Override
        public void operate(int extrinsic) {
            System.out.println("不共享的具体FlyWright:" + extrinsic);
        }
    }
    //工厂
    public class FlyweightFactory {
    
        private static HashMap<String, FlyWeight> pool = new HashMap<>();
    
        public static FlyWeight getFlyweight(String extrinsic){
            FlyWeight flyWeight = null;
            if(pool.containsKey(extrinsic)){
                flyWeight = pool.get(extrinsic);
                System.out.print("已有 " + extrinsic + " 直接从池中取---->");
            }else{
                flyWeight = new ConcreteFlyWeight(extrinsic);
                pool.put(extrinsic,flyWeight);
                System.out.print("创建 " + extrinsic + " 并从池中取出---->");
            }
            return flyWeight;
        }
    }
    //客户端测试
    public class Client {
    
        public static void main(String[] args) {
            int extrinsic = 22;
    
            FlyWeight flyweightX = FlyweightFactory.getFlyweight("X");
            flyweightX.operate(++ extrinsic);
    
            FlyWeight flyweightY = FlyweightFactory.getFlyweight("Y");
            flyweightY.operate(++ extrinsic);
    
            FlyWeight flyweightZ = FlyweightFactory.getFlyweight("Z");
            flyweightZ.operate(++ extrinsic);
            FlyWeight flyweightReX = FlyweightFactory.getFlyweight("X");
            flyweightReX.operate(++ extrinsic);
    
            FlyWeight unsharedFlyweight = new UnsharedConcreteFlyweight("X");
            unsharedFlyweight.operate(++ extrinsic); }
    }
    测试结果
    创建 X 并从池中取出---->共享的具体FlyWright:23
    创建 Y 并从池中取出---->共享的具体FlyWright:24
    创建 Z 并从池中取出---->共享的具体FlyWright:25
    已有 X 直接从池中取---->共享的具体FlyWright:26
    不共享的具体FlyWright:27
  • 相关阅读:
    无刷电机控制基本原理
    SPI 串行Flash闪存W25Q128FV 的使用(STM32F407)_软件篇
    CAN总线简介
    RS-232串口特性
    PLSQL 安装教程
    JS 常用正则表达式备忘录
    JS数组去重
    Js中Map对象的使用
    JS操作字符串
    前端小技巧
  • 原文地址:https://www.cnblogs.com/wobuchifanqie/p/11993208.html
Copyright © 2020-2023  润新知