前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java设计模式(12)-享元模式

Java设计模式(12)-享元模式

作者头像
爱敲代码的猫
发布2019-10-16 11:20:19
2570
发布2019-10-16 11:20:19
举报
文章被收录于专栏:爱敲代码的猫爱敲代码的猫

这篇推文分享一下结构型模式的最后一种---享元模式

享元模式:

代码语言:javascript
复制
    · 享元模式的主要目的是实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销,通常与工厂模式一起使用。

    · 内部状态:在享元对象内部不随外界环境改变而改变的共享部分。

    · 外部状态:随着环境的改变而改变,不能够共享的状态就是外部状态。

    · 内部状态存储于享元对象内部,而外部状态则应该由客户端来考虑。

    · 享元模式的核心在于享元工厂类,享元工厂类的作用在于提供一个用于存储享元对象的享元池,用户需要对象时,首先从享元池中获取,如果享元池中不存在,则创建一个新的享元对象返回给用户,并在享元池中保存该新增对象。

形状类:

代码语言:javascript
复制
public abstract class Shape {
    public abstract void draw();
    public abstract void name();
}

绘制图形的具体享元类:

代码语言:javascript
复制
public class Circle extends Shape{
   //内部状态共享属性
    private String color;
    public Circle(String color){
        this.color = color;
    }

    public void draw() {
        System.out.println("画了一个 " + color +" 的圆形");
    }
    
    public void name(CircleName cn) {
        System.out.println("这个圆形叫:" + cn.get );
    }
    
}

外部状态类(不共享):

代码语言:javascript
复制
public class CircleName{
    private String name;
    
    public CircleName(String name){
        this.name = name;
    }
    
    //省略get、set
}

享元工厂类:

代码语言:javascript
复制
public class FlyweightFactory{
    static Map<String, Shape> shapes = new HashMap<String, Shape>();
    
    public static Shape getShape(String key){
        Shape shape = shapes.get(key);
        //如果shape==null,表示不存在,则新建,并且保持到共享池中
        if(shape == null){
            shape = new Circle(key);
            shapes.put(key, shape);
        }
        return shape;
    }
    
    public static int getSum(){
        return shapes.size();
    }
}

测试

代码语言:javascript
复制
public class ClientTest {
    public static void main(String[] args) {
        Shape shape1 = FlyweightFactory.getShape("红色");
        shape1.draw();
        shape1.name(new CircleName("红色圆形"));//增加外部状态
        
        Shape shape2 = FlyweightFactory.getShape("灰色");
        shape2.draw();
        shape2.name(new CircleName("灰色圆形"));//增加外部状态
        
        Shape shape3 = FlyweightFactory.getShape("绿色");
        shape3.draw();
         shape2.name(new CircleName("绿色圆形"));//增加外部状态
        
        System.out.println("一共绘制了"+FlyweightFactory.getSum()+"种颜色的圆形");
    }
}
代码语言:javascript
复制
画了一个 红色 的圆形
这个圆形叫:红色圆形

画了一个 灰色 的圆形
这个圆形叫:灰色圆形

画了一个 绿色 的圆形
这个圆形叫:绿色圆形

一共绘制了3种颜色的圆形

数据库连接池也同样使用了这种模式:

代码语言:javascript
复制
    享元模式适用于作共享的一些个对象,他们有一些共有的属性,就拿数据库连接池来说,url、driverClassName、username、password及dbname,这些属性对于每个连接来说都是一样的,所以就适合用享元模式来处理,建一个工厂类,将上述类似属性作为内部数据,其它的作为外部数据,在方法调用时,当做参数传进来,这样就节省了空间,减少了实例的数量。
代码语言:javascript
复制
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;  
    private static ConnectionPool instance = null;  
    Connection conn = null;  
  
    /*构造方法,做一些初始化工作*/  
    private ConnectionPool() {  
        pool = new Vector<Connection>(poolSize);  
  
        for (int i = 0; i < poolSize; i++) {  
            try {  
                Class.forName(driverClassName);  
                conn = DriverManager.getConnection(url, username, password);  
                pool.add(conn);  
            } catch (ClassNotFoundException e) {  
                e.printStackTrace();  
            } catch (SQLException e) {  
                e.printStackTrace();  
            }  
        }  
    }  
  
    /* 返回连接到连接池 */  
    public synchronized void release() {  
        pool.add(conn);  
    }  
  
    /* 返回连接池中的一个数据库连接 */  
    public synchronized Connection getConnection() {  
        if (pool.size() > 0) {  
            Connection conn = pool.get(0);  
            pool.remove(conn);  
            return conn;  
        } else {  
            return null;  
        }  
    }  
}
代码语言:javascript
复制
通过连接池的管理,实现了数据库连接的共享,不需要每一次都重新创建连接,节省了数据库重新创建的开销,提升了系统的性能!

优缺点:

代码语言:javascript
复制
优点:
    · 享元模式的优点在于它能够极大的减少系统中对象的个数。
    · 享元模式由于使用了外部状态,外部状态相对独立,不会影响到内部状态,所以享元模式使得享元对象能够在不同的环境被共享。

缺点:
    · 由于享元模式需要区分外部状态和内部状态,使得应用程序在某种程度上来说更加复杂化了。
    · 为了使对象可以共享,享元模式需要将享元对象的状态外部化,而读取外部状态使得运行时间变长。 
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-03-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 爱敲代码的猫 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档