享元模式
又称轻量级模式,是对象池的一种实现,类似线程池,可以避免不停的创建和消耗对象,消耗性能。提供了减少对象数量从而改善对象的使用方式,宗旨就是聚集各种细粒度对象,提供统一访问,也是一种结构型模式。
使用场景
常常应用于系统底层开发,以便解决系统性能问题,如果有大量相似对象,需要缓冲,经常使用享元模式
demo1.数据库连接池
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Vector;
public class ConnectionPool {
private Vector<Connection> pool;
private String url = "jdbc:mysql://xxxxxx:3306/test";
private String username = "xxx";
private String password = "xxx";
private String driver="com.mysql.jdbc.Driver";
public ConnectionPool(int poolSize) {
for (int n = 0; n < poolSize; n++) {
try {
Class.forName(driver);
Connection connection = DriverManager.getConnection(url, username, password);
pool.add(connection);
}catch (Exception e){
e.printStackTrace();
}
}
}
public Connection getConnection(){
if(pool.size()> 0){
return pool.get(0);
}
return null;
}
public void release(Connection connection){
pool.add(connection);
}
}
demo2.12306抢票软件
// 1. 享元接口
public interface ITicket {
public void showInfo();
}
// 2. 共享资源
import java.util.Random;
public class TrainTicket implements ITicket {
public String from;
public String to;
public int price;
public TrainTicket(String from, String to) {
this.from = from;
this.to = to;
}
@Override
public void showInfo() {
this.price = new Random().nextInt(500);
System.out.println("from ->" + from + ";to ->" + to + "; price: " + price);
}
}
// 3. 享元工厂
import java.util.HashMap;
import java.util.Map;
public class TicketFactory {
private Map<String, ITicket> pool = new HashMap<String, ITicket>();
public ITicket query(String from, String to){
String key = "from->"+from+",to->"+to;
if(pool.containsKey(key)){
return pool.get(key);
}
TrainTicket trainTicket = new TrainTicket(from, to);
pool.put(key, trainTicket);
return trainTicket;
}
}
源码中的使用
- String的优化处理(会将可见的字符串放到常量池)
// 判断下列字符的相等(==),自行测试
public class StringTest {
public static void main(String[] args) {
String s1 = "hello";
String s2 = "hello";
String s3 = "he" + "llo";
String s4 = "hel" + new String("lo");
String s5 = new String("hello");
String s6 = s5.intern();
String s7 = "h";
String s8 = "ello";
String s9 = s7 + s8;
}
}
- Integer/Long.valueOf()缓存-127到128
Integer a = Integer.valueOf(100);
Integer b = 100;
Integer c = Integer.valueOf(1000);
Integer d = 1000;
System.out.println(a == b);
System.out.println(c == d);
3.ObjectPool 对象池
享元模式的内部状态和外部转态
- 内部状态:指享元对象不会随环境改变而改变的状态
- 外部状态: 指享元对象会改变的状态,如是否在使用,是否回收等等
优点
- 通过享元模式,减少对象创建,减少内存,cpu等资源使用
- 减少外部资源的使用,如创建连接等
缺点
- 需要关注内外部状态变化
- 逻辑会更复杂