享元模式学习笔记

六月ゝ 毕业季﹏ 提交于 2020-03-12 07:36:25

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

享元模式(Flyweight Pattern)又称为轻量级模式,是对象池的一种实现。类似于线程池,线程池
可以避免不停的创建和销毁多个对象,消耗性能。提供了减少对象数量从而改善应用所需的对象结构的
方式。其宗旨是共享细粒度对象,将多个对同一对象的访问集中起来,不必为每个访问者创建一个单独
的对象,以此来降低内存的消耗,属于结构型模式。

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

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

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

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

首先我们来看享元模式的通用UML类图:

从类图上看,享元模式有三个参与角色:

抽象享元角色(Flyweight):享元对象抽象基类或者接口,同时定义出对象的外部状态和内部状态
的接口或实现;

具体享元角色(ConcreteFlyweight):实现抽象角色定义的业务。该角色的内部状态处理应该与
环境无关,不能出现会有一个操作改变内部状态,同时修改了外部状态;

享元工厂(FlyweightFactory):负责管理享元对象池和创建享元对象。

package com.gupaoedu.vip.pattern.flyWeight;

import java.util.Random;

/**
 * @Author dawn Date on 2020/3/11  16:16
 */

public class TrainTicket implements ITicket {

  private String from;
  private String to;
  private Double price;

  public TrainTicket(String from, String to) {
    this.from = from;
    this.to = to;
  }

  public void showInfo(String bunk) {
    this.price=new Random().nextDouble()*500;
    //System.out.println(String.format("%s->%s: %s价格:  %s 元", this.from,this.to,bunk, this.price));
    System.out.println(String.format("%s->%s:%s价格: %s 元", this.from, this.to, bunk, this.price));
  }
}
package com.gupaoedu.vip.pattern.flyWeight;
/**
 * @Author dawn
 * Date on 2020/3/11  16:12
 */

public interface ITicket {
  void showInfo(String bunk);
}
package com.gupaoedu.vip.pattern.flyWeight;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author dawn
 * Date on 2020/3/11  16:21
 */

public class TicketFactory {
  private  static Map<String,ITicket> ticketPool =new ConcurrentHashMap<String,ITicket>();
  public  static  ITicket queryTicket(String form,String to){
    return new TrainTicket(form, to);
  }

  public  static  ITicket queryTicketCase(String form,String to){
    String key=form+"->"+to;
    if(!ticketPool.containsKey(key)){
      ITicket iTicket=new TrainTicket(form,to);
      ticketPool.put(key,iTicket);
      System.out.println("首次创建对象");
      return iTicket;
    }
    System.out.println("使用缓存对象");
    return ticketPool.get(key);
  }
}
package com.gupaoedu.vip.pattern.flyWeight;
/**
 * @Author dawn
 * Date on 2020/3/11  16:22
 * 享元模式demo
 */

public class FlyWeightTest {

  public static void main(String[] args) {
//    ITicket iTicket=TicketFactory.queryTicket("厦门北", "长汀南");
//    iTicket.showInfo("二等座");
    ITicket iTicket=TicketFactory.queryTicketCase("厦门北", "长汀南");
    iTicket.showInfo("二等座");
    iTicket=TicketFactory.queryTicketCase("厦门北", "长汀南");
    iTicket.showInfo("一等座");
    iTicket=TicketFactory.queryTicketCase("厦门北", "南昌南");
    iTicket.showInfo("一等座");
  }
}

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!