享元模式定义
享元模式:“享”就是分享之意,指一物被众人共享,而这也正是该模式的宗旨所在。
享元模式有点类似于单例模式,都是只生成一个对象来被共享使用。
享元模式作用
享元模式的作用:主要用于减少创建对象的数量,以减少内存占用和提高性能。
比如:当一个系统中存在大量重复对象的时候,如果这些重复的对象是「不可变对象」,我们就可以利用享元模式将对象设计成享元,在内存中只保留一份实例,供多处代码引用,这样可以减少内存中对象的数量,起到节省内存的目的。
享元模式应用场景
享元模式经典的应用场景,典型的有两类:
- 一类就是:系统中存在大量的相似对象;
- 另外一类就是:就是池技术;
比如: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类,负责创建和管理享元角色。