• 设计模式:享元模式


      享元模式中的享指的共享的意思,该模式以共享的方式支持某些对象的重用(特别是一些大的对象)以此节约空间。典型的是以时间换空间的做法。

    例如:java语言中String类型就是使用享元模式。对于JVM来说,String对象都是共享的。如果一个系统中两个String对象所包含的字符串内容相同,jvm

    实际上只创建一个String对象提供两个引用。

      享元模式一般的角色:

        享元工厂类(FlyWeight享元工厂类):管理享元对象

        抽象享元类(FlyWeight抽象类):接口或抽象类,向外界提供对象内部状态。

        具体享元类(ConcreteFlyWeight):继承自抽象享元类。为内部状态提供成员变量存储。

        非共享享元类(UnshareConcreteFlyWeight):不能被共享的一些子类。

      享元对象能作为共享的的关键是区分内部状态和外部状态。

        内部状态:可以共享。

        外部状态:不可以共享。

    例子:

      描述一个围棋软件,每个棋子是一个对象(颜色,形状等)这些是可以共享的,对应内部状态。只有棋子的位置不是共享的,对应外部状态。  

    /**
     * 享元类 
     */
    public interface ChessFlyWeight {
       //颜色  
        void setColor(String c);
        String getColor();
        //描述位置  
        void display(Position c);
    }
    

      

    class OneChess implements ChessFlyWeight{
      //为内部状态提供成员变量存储。
        private String color;
    
        public OneChess(String color) {
            super();
            this.color = color;
        }
    
        @Override
        public void display(Position c) {
            System.out.println("棋子颜色:"+color);
            System.out.println("棋子位置:"+c.getX()+"----"+c.getY());
        }
    
        @Override
        public String getColor() {
            return color;
        }
    
        @Override
        public void setColor(String c) {
            this.color = c;
        }
    }
    

      外部状态位置单独设计一个类

    /**
     * 外部状态UnSharedConcreteFlyWeight
     * 非共享狀態
     */
    public class Position {
        private int x;
        private int y;
    
        public Position(int x, int y) {
            this.x = x;
            this.y = y;
        }
    
        public int getX() {
            return x;
        }
    
        public void setX(int x) {
            this.x = x;
        }
    
        public int getY() {
            return y;
        }
    
        public void setY(int y) {
            this.y = y;
        }
    }
    

      

      享元工厂类

    /**
     * 享元工厂类 
     * 创建和管理享元对象
     */
    public class ChessFlyWeightFactory {
    
        //享元池  
        private static Map<String,ChessFlyWeight> map = new HashMap<String, ChessFlyWeight>();
    
        public static ChessFlyWeight  getChess(String color){
    
            if(map.get(color)!=null){
                return map.get(color);
            }else{
                ChessFlyWeight cfw = new OneChess(color);
                map.put(color, cfw);
                return cfw;
            }
    
        }
    }
    

      

    public class Client {
        public static void main(String[] args) {
            ChessFlyWeight chess1 = ChessFlyWeightFactory.getChess("黑色");
            ChessFlyWeight chess2 = ChessFlyWeightFactory.getChess("黑色");
            System.out.println(chess1 == chess2);
    
            System.out.println("增加位置外部状态");
            chess1.display(new Position(1, 12));
            chess2.display(new Position(50, 60));
    
        }
    }
    

      

      使用享元模式一般步骤:

        1. 抽象享元对象,内部状态采用享元类处理

        2. 外部状态(可变状态,非共享)单独抽取类处理

        3. 设计享元工厂类,采用对象池管理享元对象。

      一般使用场景是对象池,将对象缓存。极大减少内存中对象的数量相同或相似对象内存中只存一份,极大的节约资源,提高系统性能

      

        

  • 相关阅读:
    [CentOS5]安装VirtualBox
    [Java]一则自定义的XStream转换器,主要用于POJO XML反序列化为Map/List
    [CentOS5]开启vsftpd中本地用户的上传权限
    [CSS]强制TD不换行
    [CentOS5]快速关闭SeLinux
    [vba]获取PPT幻灯片中的所有标题
    [VBA]批量转换xls为csv
    [OTHER]玩具的报复 绿化版 注册表
    [CentOS]在vsftpd中为本地用户指定默认目录
    递归读取输出无限分类目录
  • 原文地址:https://www.cnblogs.com/gcm688/p/10252515.html
Copyright © 2020-2023  润新知