zoukankan      html  css  js  c++  java
  • java设计模式之享元模式

    享元模式的定义:

      享元模式又叫作轻量级模式,是对象池的一种实现。类似线程池,线程池可以避免不停的创建和销毁多个对象,消耗性能。

    享元模式提供了减少对象数量从而改善应用所需的对象结构的方式。其宗旨是共享细粒度的对象,将多个对同一对象的访问集

    中起来,不必为每个访问者都创建单独的对象,以此来降低内存的消耗,属于结构型设计模式。

    享元模式的应用场景:

    • 常应用于系统底层的开发,以便解决系统的性能问题。
    • 系统有大量相似对象、需要缓冲池场景。

    享元模式的UML类图:

     

     由上图可以看到,享元模式主要包含3个角色。

    • 抽象享元角色(IFlyweight):享元对象抽象基类或者接口,同时定义出对象的外部状态和内部状态的接口实现。
    • 具体享元角色(ConcreteFlyweight):实现抽象角色定义的业务。该角色的内部状态处理应用与环境无关,不会出现一个操作改变内部状态、同时修改了外部状态的情况。
    • 享元工厂(FlyweightFactory):负责管理享元对象池和创建享元对象。

    享元模式的通用写法:

    package com.gupaoedu.vip.pattern.flyweight.general;
    
    import java.util.HashMap;
    import java.util.Map;
    
    /* *
     * @Author liuyi
     * @Description //TODO 
     * @Date 2020/11/15 13:13 
     * @Param 
     * @return 
     **/
    public class Client {
        public static void main(String[] args) {
            FlyweightFactory flyweightFactory = new FlyweightFactory();
            IFlyweight flyweight1 = flyweightFactory.getFlyweight("aa");
            IFlyweight flyweight2 = flyweightFactory.getFlyweight("bb");
            flyweight1.operation("a");
            flyweight2.operation("b");
        }
    
        interface IFlyweight {
            void operation(String extrinsicState);
        }
    
        // 具体享元角色
        static class ConcreteFlyweight implements IFlyweight {
            private String intrinsicState;
    
            public ConcreteFlyweight(String intrinsicState) {
                this.intrinsicState = intrinsicState;
            }
    
            public void operation(String extrinsicState) {
                System.out.println("Object address: " + System.identityHashCode(this));
                System.out.println("IntrinsicState: " + this.intrinsicState);
                System.out.println("ExtrinsicState: " + extrinsicState);
            }
        }
    
        // 享元工厂
        static class FlyweightFactory {
    
            private static Map<String, IFlyweight> pool = new HashMap<String, IFlyweight>();
    
            // 因为内部状态具备不变性,因此作为缓存的键
            public static IFlyweight getFlyweight(String intrinsicState) {
                if (!pool.containsKey(intrinsicState)) {
                    IFlyweight flyweight = new ConcreteFlyweight(intrinsicState);
                    pool.put(intrinsicState, flyweight);
                }
                return pool.get(intrinsicState);
            }
        }
    }

    使用享元模式实现简单的数据库连接池:

      我们在用java'操作数据库的时候,首先必须要创建Connection和数据建立连接,才能操作数据库,而创建和关闭连接都十分的

    消耗性能。所以数据库连接池就产生了,它的基本原理是将Connection对象缓冲起来,每次取得时候从缓冲中取,用完之后再放回

    缓冲中,达到资源重复利用得目的,代码如下:

    package com.gupaoedu.vip.pattern.flyweight.pool;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.util.Vector;
    
    /* *
     * @Author liuyi
     * @Description //TODO 
     * @Date 2020/11/15 13:34 
     * @Param 
     * @return 
     **/
    public class ConnectionPool {
    
        private Vector<Connection> pool;
    
        private String url = "jdbc:mysql://localhost:3306/test";
        private String username = "root";
        private String password = "root";
        private String driverClassName = "com.mysql.jdbc.Driver";
        private int poolSize = 100;
    
        public ConnectionPool() {
            pool = new Vector<Connection>(poolSize);
    
            try{
                Class.forName(driverClassName);
                for (int i = 0; i < poolSize; i++) {
                    Connection conn = DriverManager.getConnection(url,username,password);
                    pool.add(conn);
                }
            }catch (Exception e){
                e.printStackTrace();
            }
    
        }
    
        public synchronized Connection getConnection(){
            if(pool.size() > 0){
                Connection conn = pool.get(0);
                pool.remove(conn);
                return conn;
            }
            return null;
        }
    
        public synchronized void release(Connection conn){
            pool.add(conn);
        }
    }

    享元模式得内部状态和外部状态:

      享元模式得定义提出两个要求:细粒度和共享对象。因为要求细粒度,所以不可避免地会使对象数量多且性质相近,此时我们就将这些对象地信息

    分为两个部分:内部状态和外部状态。

      内部状态指对象共享出来地信息,存储在享元对象内部,并且不会随环境地改变而改变。外部状态指对象得以依赖地一个标记,随环境地改变而改变

    不可共享。

      比如连接池中的连接对象,保存了连接对象的用户名,密码,URL等信息,在创建对象的时候就设置好了,不会随着环境的改变而改变,所以这些属

    于内部状态。而当每个连接要被收回利用时,我们需要将它标记为可用状态,这些属于外部状态。

    享元模式的优点:

    • 减少对象的创建,降低内存中对象的数量,降低系统的内存消耗,提高效率。
    • 减少内存之外的其他资源占用。

    享元模式的缺点:

    • 需要关注内、外部状态,关注线程安全问题。
    • 使系统、程序的逻辑复杂化。
  • 相关阅读:
    新的一天,新的一周
    mysql重启失败,报错:starting mysql。 the server quit without updating pid file (/[failed]l/mysql/data/hostname.pid])
    rpm包安装、配置与卸载
    python高效运用(十)———文件(File)、输入输出的基本操作
    paramiko--------远程服务器连接工具
    main
    thread同步测试
    实验二测试
    《信息安全系统设计与实现》学习笔记9
    实验二 OpenSSL API使用
  • 原文地址:https://www.cnblogs.com/liu-yi/p/13976526.html
Copyright © 2011-2022 走看看