享元模式详解(4大角色及应用场景实例)

享元模式详解(4大角色及应用场景实例)-mikechen

享元模式定义

享元模式:“享”就是分享之意,指一物被众人共享,而这也正是该模式的宗旨所在。

享元模式有点类似于单例模式,都是只生成一个对象来被共享使用。

 

享元模式作用

享元模式的作用:主要用于减少创建对象的数量,以减少内存占用和提高性能。

比如:当一个系统中存在大量重复对象的时候,如果这些重复的对象是「不可变对象」,我们就可以利用享元模式将对象设计成享元,在内存中只保留一份实例,供多处代码引用,这样可以减少内存中对象的数量,起到节省内存的目的。

 

享元模式应用场景

享元模式经典的应用场景,典型的有两类:

  • 一类就是:系统中存在大量的相似对象;
  • 另外一类就是:就是池技术;

比如:String常量池、数据库连接池、缓冲池等等,都是享元模式的应用,享元模式是池技术的重要实现方式。

 

享元模式角色

享元模式主要包含4大角色,如下图所示:

享元模式详解(4大角色及应用场景实例)-mikechen

1.抽象享元角色(Flyweight)角色

是所有的具体享元类的基类,为具体享元规范需要实现的公共接口,非享元的外部状态以参数的形式通过方法传入。

2.具体享元(Concrete Flyweight)角色

实现抽象享元角色中所规定的接口。

3.非享元(Unsharable Flyweight)角色

是不可以共享的外部状态,它以参数的形式注入具体享元的相关方法中。

4.享元工厂(Flyweight Factory)角色

负责创建和管理享元角色。当客户对象请求一个享元对象时,享元工厂检査系统中是否存在符合要求的享元对象,如果存在则提供给客户;如果不存在的话,则创建一个新的享元对象。

 

享元模式示例

下面我们来看一个享元模式的例子,源码如下:

  1. package Flyweight;
  2. import java.util.ArrayList;
  3. import java.util.HashMap;
  4. public class Sportgame {
  5. private static final ArrayList<String> Consumption_msg = new ArrayList<String>();
  6. private static void addmsg(String msg) {
  7. Consumption_msg.add(msg);
  8. }
  9. public static void main(String[] args) {
  10. addmsg("重庆体育馆");
  11. addmsg("上海体育馆");
  12. addmsg("北京体育馆");
  13. addmsg("重庆体育馆");
  14. addmsg("重庆体育馆");
  15. addmsg("北京体育馆");
  16. addmsg("上海体育馆");
  17. addmsg("重庆体育馆");
  18. addmsg("北京体育馆");
  19. for (String e : Consumption_msg) {
  20. SoccerFactory.getSoccer(e).display();
  21. }
  22. }
  23. }
  24. //享元工厂
  25. class SoccerFactory{
  26. private static HashMap<String,Gym> e = new HashMap<String,Gym>();
  27. public static Gym getSoccer(String gymName) {
  28. Gym gym = e.get(gymName);
  29. if(gym == null) {
  30. gym = new Gym(gymName);
  31. e.put(gymName, gym);
  32. }
  33. return gym;
  34. }
  35. }
  36. //具体享元
  37. class Gym implements Soccer{
  38. String gymName;
  39. String sport = "足球";
  40. double price = 500;
  41. public Gym(String gymName) {
  42. this.gymName = gymName;
  43. }
  44. public void setSport(String sport) {
  45. this.sport = sport;
  46. }
  47. public void setPrice(double price) {
  48. this.price = price;
  49. }
  50. @Override
  51. public void display() {
  52. // TODO Auto-generated method stub
  53. System.out.println("{In[" + gymName + "],[Progect:" + sport + "],[Price:" + price
  54. + "]["+this+"]}");
  55. }
  56. }
  57. //抽象享元
  58. interface Soccer{
  59. public void display();
  60. }

以上享元模式的4大角色分别对应:

  • 抽象享元角色:Soccer类(足球);
  • 具体享元角色:Gym类(体育馆);
  • 非享元角色:本文将非享元角色类合并在具体享元角色中,例如:变量sport,price;
  • 享元工厂角色:SoccerFactory类,负责创建和管理享元角色。

 

 

评论交流
    说说你的看法
欢迎您,新朋友,感谢参与互动!