美文网首页
享元模式(Flyweight)

享元模式(Flyweight)

作者: jiahzhon | 来源:发表于2020-03-10 10:38 被阅读0次

    - 定义

    • 运用共享技术来有効地支持大量细粒度对象的复用。它通过共享已经存在的又橡来大幅度减少需要创建的对象数量、避免大量相似类的开销,从而提高系统资源的利用率。当用户需要对象时,首先从享元池中获取,如果享元池中不存在,则创建一个新的享元对象返回给用户,并在享元池中保存该新增对象。
    • 优点:
      • 相同对象只要保存一份,这降低了系统中对象的数量,从而降低了系统中细粒度对象给内存带来的压力。
    • 缺点:
      • 为了使对象可以共享,需要将一些不能共享的状态外部化,这将增加程序的复杂性。
      • 读取享元模式的外部状态会使得运行时间稍微变长。

    - 使用场景

    1. 系统中存在大量相同或相似的对象,这些对象耗费大量的内存资源。
    2. 大部分的对象可以按照内部状态进行分组,且可将不同部分外部化,这样每一个组只需保存一个内部状态。
    3. 由于享元模式需要额外维护一个保存享元的数据结构,所以应当在有足够多的享元实例时才值得使用享元模式。

    - 角色

    • 抽象享元角色(Flyweight):是所有的具体享元类的基类,为具体享元规范需要实现的公共接口,非享元的外部状态以参数的形式通过方法传入。
    • 具体享元(Concrete Flyweight)角色:实现抽象享元角色中所规定的接口。
    • 非享元(Unsharable Flyweight)角色:是不可以共享的外部状态,它以参数的形式注入具体享元的相关方法中。
    • 享元工厂(Flyweight Factory)角色:负责创建和管理享元角色。当客户对象请求一个享元对象时,享元工厂检査系统中是否存在符合要求的享元对象,如果存在则提供给客户;如果不存在的话,则创建一个新的享元对象。

    - 结构图

    3-1Q115161342242.gif

    - 实现代码

    package flyweight;
    import java.util.HashMap;
    public class FlyweightPattern
    {
        public static void main(String[] args)
        {
            FlyweightFactory factory=new FlyweightFactory();
            Flyweight f01=factory.getFlyweight("a");
            Flyweight f02=factory.getFlyweight("a");
            Flyweight f03=factory.getFlyweight("a");
            Flyweight f11=factory.getFlyweight("b");
            Flyweight f12=factory.getFlyweight("b");       
            f01.operation(new UnsharedConcreteFlyweight("第1次调用a。"));       
            f02.operation(new UnsharedConcreteFlyweight("第2次调用a。"));       
            f03.operation(new UnsharedConcreteFlyweight("第3次调用a。"));       
            f11.operation(new UnsharedConcreteFlyweight("第1次调用b。"));       
            f12.operation(new UnsharedConcreteFlyweight("第2次调用b。"));
        }
    }
    //非享元角色
    class UnsharedConcreteFlyweight
    {
        private String info;
        UnsharedConcreteFlyweight(String info)
        {
            this.info=info;
        }
        public String getInfo()
        {
            return info;
        }
        public void setInfo(String info)
        {
            this.info=info;
        }
    }
    //抽象享元角色
    interface Flyweight
    {
        public void operation(UnsharedConcreteFlyweight state);
    }
    //具体享元角色
    class ConcreteFlyweight implements Flyweight
    {
        private String key;
        ConcreteFlyweight(String key)
        {
            this.key=key;
            System.out.println("具体享元"+key+"被创建!");
        }
        public void operation(UnsharedConcreteFlyweight outState)
        {
            System.out.print("具体享元"+key+"被调用,");
            System.out.println("非享元信息是:"+outState.getInfo());
        }
    }
    //享元工厂角色
    class FlyweightFactory
    {
        private HashMap<String, Flyweight> flyweights=new HashMap<String, Flyweight>();
        public Flyweight getFlyweight(String key)
        {
            Flyweight flyweight=(Flyweight)flyweights.get(key);
            if(flyweight!=null)
            {
                System.out.println("具体享元"+key+"已经存在,被成功获取!");
            }
            else
            {
                flyweight=new ConcreteFlyweight(key);
                flyweights.put(key, flyweight);
            }
            return flyweight;
        }
    }
    
    例子:五子棋
    • 创建抽象棋子一AbstractChessman
    public abstract class AbstractChessman {
      // 棋子坐标
      protected int x;
      protected int y;
      // 棋子类别(黑|白)
      protected String chess;
      public AbstractChessman(String chess) {
        this.chess = chess;
      }
      // 点坐标设置
      public abstract void point(int x, int y);
      // 显示棋子信息
      public void show() {
        System.out.println(this.chess + "(" + this.x + "," + this.y + ")");
      }
    }
    
    • 创建黑子一BlackChessman
    public class BlackChessman extends AbstractChessman {
      /**
       * 构造方法 初始化黑棋子
       */
      public BlackChessman() {
        super("●");
        System.out.println("--BlackChessman Construction Exec!!!");
      }
      // 点坐标设置
      @Override
      public void point(int x, int y) {
        this.x = x;
        this.y = y;
        // 显示棋子内容
        show();
      }
    }
    
    • 创建白子一WhiteChessman
    public class WhiteChessman extends AbstractChessman {
      /**
       * 构造方法 初始化白棋子
       */
      public WhiteChessman() {
        super("○");
        System.out.println("--WhiteChessman Construction Exec!!!");
      }
      // 点坐标设置
      @Override
      public void point(int x, int y) {
        this.x = x;
        this.y = y;
        // 显示棋子内容
        show();
      }
    }
    
    • 创建棋子工厂一FiveChessmanFactory
    import java.util.Hashtable;
    import com.demo.flyweight.object.AbstractChessman;
    import com.demo.flyweight.object.BlackChessman;
    import com.demo.flyweight.object.WhiteChessman;
    public class FiveChessmanFactory {
      // 单例模式工厂
      private static FiveChessmanFactory fiveChessmanFactory = new FiveChessmanFactory();
      // 缓存存放共享对象
      private final Hashtable<Character, AbstractChessman> cache = new Hashtable<Character, AbstractChessman>();
      // 私有化构造方法
      private FiveChessmanFactory() {
      }
      // 获得单例工厂
      public static FiveChessmanFactory getInstance() {
        return fiveChessmanFactory;
      }
      /**
       * 根据字符获得棋子
       *
       * @param c
       *      (B:黑棋 W:白棋)
       * @return
       */
      public AbstractChessman getChessmanObject(char c) {
        // 从缓存中获得棋子对象实例
        AbstractChessman abstractChessman = this.cache.get(c);
        if (abstractChessman == null) {
          // 缓存中没有棋子对象实例信息 则创建棋子对象实例 并放入缓存
          switch (c) {
          case 'B':
            abstractChessman = new BlackChessman();
            break;
          case 'W':
            abstractChessman = new WhiteChessman();
            break;
          default:
            break;
          }
          // 为防止 非法字符的进入 返回null
          if (abstractChessman != null) {
            // 放入缓存
            this.cache.put(c, abstractChessman);
          }
        }
        // 如果缓存中存在 棋子对象则直接返回
        return abstractChessman;
      }
    }
    
    • 客户端实现一Client
    import java.util.Random;
    import com.demo.flyweight.factory.FiveChessmanFactory;
    import com.demo.flyweight.object.AbstractChessman;
    /**
     * 主应用程序
     *
     * @author
     */
    public class Client {
      /**
       * @param args
       */
      public static void main(String[] args) {
        // 创建五子棋工厂
        FiveChessmanFactory fiveChessmanFactory = FiveChessmanFactory
            .getInstance();
        Random random = new Random();
        int radom = 0;
        AbstractChessman abstractChessman = null;
        // 随机获得棋子
        for (int i = 0; i < 10; i++) {
          radom = random.nextInt(2);
          switch (radom) {
          // 获得黑棋
          case 0:
            abstractChessman = fiveChessmanFactory.getChessmanObject('B');
            break;
          // 获得白棋
          case 1:
            abstractChessman = fiveChessmanFactory.getChessmanObject('W');
            break;
          }
          if (abstractChessman != null) {
            abstractChessman.point(i, random.nextInt(15));
          }
        }
      }
    }
    

    相关文章

      网友评论

          本文标题:享元模式(Flyweight)

          本文链接:https://www.haomeiwen.com/subject/mxiidhtx.html