设计模式之享元模式-池技术的指导思想(Flyweight)

问题

众所周知,我的电脑城以台式机高度定制出名,客户到店后经理都会根据客户的需求配置他所希望的电脑。在前期的时候,顾客量少,我们会给顾客提供的配置清单基本不会重复。但是呢,随着生意越来越好,顾客越来越多,出现重复配置的情况越来越多,但是呢,因为我们之前不存档,所以每次都需要给客户开一份新的一样的清单。对于经理来说,其实在这方面完全可以提高效率的。怎么提高呢?那就是我们的今天要聊的享元模式了。

简介

先总结下上面的问题:工作中会遇到大量重复的清单数据,而因为没有存档,而会导致每一次遇到清单数据时,都需要重新创建一份,无论是否曾经是否创建过。所以,显而易见的解决方式就是存档,如果出现相同清单的话,就直接复用之前的清单即可。享元模式解决的问题和思路基本上都是很好理解的,java的很多底层技术都采用了享元模式,解决了很复杂的问题。

解决问题:解决系统中大量重复对象

解决方法:使用缓存,若缓存中有的话,直接取出,没有再创建

实例:java的池技术:线程池,连接池,常量池等。常量池最常见的就是String常量池,java虚拟机为避免大量重复string保存在内存中,而是用了常量池技术。

实现

定义以需要为主的Computer

public class Computer {

    private String demand;

    public Computer(String demand){
        this.demand = demand;
    }


    public void play() {
        System.out.println("play computer with demand  " + demand);
    }
}

定义电脑缓存池

public class ComputerPool {

    private ComputerPool() {
    }

    private static volatile ComputerPool computerPool;

    public static ComputerPool getInstance() {
        if (computerPool == null) {
            synchronized (ComputerPool.class) {
                if (computerPool == null) {
                    computerPool = new ComputerPool();
                }
            }
        }
        return computerPool;
    }

    private static HashMap<String, Computer> map = new HashMap<>();

    public Computer getComputer(String demand) {
        if (map.containsKey(demand)) {
            System.out.println("get computer from pool");
            return map.get(demand);
        }
        Computer computer = new Computer(demand);
        map.put(demand, computer);
        return computer;
    }
}

定义顾客

public class Custom {

    public void buy(String demand) {
        Computer computer = ComputerPool.getInstance().getComputer(demand);
        computer.play();
    }
}

执行代码

    public static void main(String[] args) {
        Custom custom = new Custom();
        custom.buy("game");

        Custom custom1 = new Custom();
        custom1.buy("design");


        Custom custom2 = new Custom();
        custom2.buy("game");

        Custom custom3 = new Custom();
        custom3.buy("design");
    }

执行结果

play computer with demand  game
play computer with demand  design
get computer from pool
play computer with demand  game
get computer from pool
play computer with demand  design

简化了实现,将以需求为key,电脑作为缓存对象(配置清单作为缓存对象更贴切)。若发现用户的需求在缓存池中存在的话,则直接从缓存池中返回,而无需重新创建对象返回。以此,若在需要大量重复对象的情形下,会大量减少对象的创建,减少内存的占用,可大大提高系统性能。

总结

优点:大大减少对象的创建,降低系统的内存,使效率提高

缺点:提升了系统的复杂性(虽然我上面写的复用实现比较简单,但大家都清楚java内的线程池,常量池的实现都较为复杂,对于java开发者来说是个难啃的骨头,并且经常会在面试中被提及。这其中原因是因为池中复用缓存的对象都较为复杂,需要去分离出外部状态和内部状态)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值