结构型设计模式之享元模式
Posted 丨Jack_Chen丨
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了结构型设计模式之享元模式相关的知识,希望对你有一定的参考价值。
@TOC
享元模式
概述
目的
1、系统有大量相似对象。
2、需要缓冲池的场景。
例如
1、JAVA中的String,如果有则返回,如果没有则创建一个字符串保存在字符串缓存池里面。
2、数据库的数据池。
优缺点
优点:
1.减少对象的创建,降低内存中对象的数量,降低系统的内存,提高效率。
2.减少内存之外的其他资源占用。
缺点:
1.关注内、外部状态、关注线程安全问题。
2.提高了系统的复杂度,需要分离出外部状态和内部状态,而且外部状态具有固有化的性质,不应该随着内部状态的变化而变化,否则会造成系统的混乱。
主要角色
1.抽象享元角色(Flyweight)
2.具体享元角色(ConcreteFlyweight)
3.享元工厂(FlyweightFactory)
享元模式结构
内部状态和外部状态
内部状态指与外部状态
例如
public interface ITicket
/**
* 查询票信息
*/
void query();
创建具体享元角色
public class TrainTicket implements ITicket
/**
* 出发地
*/
private String from;
/**
* 目的地
*/
private String to;
/**
* 票种类
*/
private String type;
/**
* 票价
*/
private int price;
public TrainTicket(String from, String to, String type)
this.from = from;
this.to = to;
this.type = type;
public void query()
this.price = new Random().nextInt(100);
int num = new Random().nextInt(10);
System.out.println(String.format("从%s到%s,%s,票价:%s元,剩余车票:%s", this.from, this.to, this.type, this.price, num));
创建享元工厂
将相同查询票的信息对象进行缓存,复用该对象进行查询,减少对象的创建,降低内存的压力。
public class TicketFactory
private static Map<String, ITicket> ticketPool = new ConcurrentHashMap<String, ITicket>();
public static ITicket queryTicket(String from, String to, String type)
String key = "出发站:"+from + " 目的站:" + to + " 坐席类型:" + type;
if (TicketFactory.ticketPool.containsKey(key))
System.out.println("使用缓存查询:" + key);
return TicketFactory.ticketPool.get(key);
System.out.println("第一次查询,创建对象: " + key);
ITicket ticket = new TrainTicket(from, to, type);
TicketFactory.ticketPool.put(key, ticket);
return ticket;
客户端调用
public static void main(String[] args)
ITicket ticket = TicketFactory.queryTicket("A", "B", "特等座");
ticket.query();
ticket = TicketFactory.queryTicket("A", "B","一等座");
ticket.query();
ticket = TicketFactory.queryTicket("A", "B","特等座");
ticket.query();
第一次查询,创建对象: 出发站:A 目的站:B 坐席类型:特等座
从A--->B,特等座,票价:38元,剩余车票:8
第一次查询,创建对象: 出发站:A 目的站:B 坐席类型:一等座
从A--->B,一等座,票价:0元,剩余车票:4
使用缓存查询:出发站:A 目的站:B 坐席类型:特等座
从A--->B,特等座,票价:62元,剩余车票:6
总结
享元模式实现数据库连接池
创建数据库连接池
@Data
public class ConnectionPool
private Vector<Connection> pool;
private String url = "jdbc:mysql://localhost:3306/demo";
private String username = "root";
private String password = "123456";
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();
/**
* 获取连接
* @return
*/
public synchronized Connection getConnection()
if (pool.size() > 0)
Connection conn = pool.get(0);
pool.remove(conn);
return conn;
return null;
/**
* 释放归还连接
* @param conn
*/
public synchronized void release(Connection conn)
pool.add(conn);
使用数据库连接池
public static void main(String[] args)
ConnectionPool connectionPool = new ConnectionPool();
Connection conn = connectionPool.getConnection();
System.out.println("获取一个连接:" + conn + "连接池中剩余:" + connectionPool.getPool().size());
try
Thread.sleep(2000);
catch (InterruptedException e)
throw new RuntimeException(e);
finally
connectionPool.release(conn);
System.out.println("归还连接池,连接池总数: " + connectionPool.getPool().size());
获取一个连接:com.mysql.jdbc.JDBC4Connection@7fad8c79连接池中剩余:99
归还连接池,连接池总数: 100
以上是关于结构型设计模式之享元模式的主要内容,如果未能解决你的问题,请参考以下文章