享元模式定义
享元模式:“享”就是分享之意,指一物被众人共享,而这也正是该模式的宗旨所在。
享元模式有点类似于单例模式,都是只生成一个对象来被共享使用。
享元模式作用
享元模式的作用:主要用于减少创建对象的数量,以减少内存占用和提高性能。
比如:当一个系统中存在大量重复对象的时候,如果这些重复的对象是「不可变对象」,我们就可以利用享元模式将对象设计成享元,在内存中只保留一份实例,供多处代码引用,这样可以减少内存中对象的数量,起到节省内存的目的。
享元模式应用场景
享元模式经典的应用场景,典型的有两类:
- 一类就是:系统中存在大量的相似对象;
- 另外一类就是:就是池技术;
比如:String常量池、数据库连接池、缓冲池等等,都是享元模式的应用,享元模式是池技术的重要实现方式。
享元模式角色
享元模式主要包含4大角色,如下图所示:
1.抽象享元角色(Flyweight)角色
是所有的具体享元类的基类,为具体享元规范需要实现的公共接口,非享元的外部状态以参数的形式通过方法传入。
2.具体享元(Concrete Flyweight)角色
实现抽象享元角色中所规定的接口。
3.非享元(Unsharable Flyweight)角色
是不可以共享的外部状态,它以参数的形式注入具体享元的相关方法中。
4.享元工厂(Flyweight Factory)角色
负责创建和管理享元角色。当客户对象请求一个享元对象时,享元工厂检査系统中是否存在符合要求的享元对象,如果存在则提供给客户;如果不存在的话,则创建一个新的享元对象。
享元模式示例
下面我们来看一个享元模式的例子,源码如下:
package Flyweight; import java.util.ArrayList; import java.util.HashMap; public class Sportgame { private static final ArrayList<String> Consumption_msg = new ArrayList<String>(); private static void addmsg(String msg) { Consumption_msg.add(msg); } public static void main(String[] args) { addmsg("重庆体育馆"); addmsg("上海体育馆"); addmsg("北京体育馆"); addmsg("重庆体育馆"); addmsg("重庆体育馆"); addmsg("北京体育馆"); addmsg("上海体育馆"); addmsg("重庆体育馆"); addmsg("北京体育馆"); for (String e : Consumption_msg) { SoccerFactory.getSoccer(e).display(); } } } //享元工厂 class SoccerFactory{ private static HashMap<String,Gym> e = new HashMap<String,Gym>(); public static Gym getSoccer(String gymName) { Gym gym = e.get(gymName); if(gym == null) { gym = new Gym(gymName); e.put(gymName, gym); } return gym; } } //具体享元 class Gym implements Soccer{ String gymName; String sport = "足球"; double price = 500; public Gym(String gymName) { this.gymName = gymName; } public void setSport(String sport) { this.sport = sport; } public void setPrice(double price) { this.price = price; } @Override public void display() { // TODO Auto-generated method stub System.out.println("{In[" + gymName + "],[Progect:" + sport + "],[Price:" + price + "]["+this+"]}"); } } //抽象享元 interface Soccer{ public void display(); }
以上享元模式的4大角色分别对应:
- 抽象享元角色:Soccer类(足球);
- 具体享元角色:Gym类(体育馆);
- 非享元角色:本文将非享元角色类合并在具体享元角色中,例如:变量sport,price;
- 享元工厂角色:SoccerFactory类,负责创建和管理享元角色。
陈睿mikechen
10年+大厂架构经验,资深技术专家,就职于阿里巴巴、淘宝、百度等一线互联网大厂。
关注「mikechen」公众号,获取更多技术干货!
后台回复【面试】即可获取《史上最全阿里Java面试题总结》,后台回复【架构】,即可获取《阿里架构师进阶专题全部合集》