• 享元模式


    享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。

    享元模式尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象。

    假设一个场景:有一盘围棋,有黑白二色旗子,对于任意一方来说,每一个棋子长得都是一样的,但是我们需要用位置来区分每个棋子。如果我们为每一个棋子创建一个对象,显然会创建大量的对象,这增加了大量的小对象,造成了对象管理的困难。所以我们引入了享元模式,把棋子共有的颜色等属性抽象出来,把棋子不共有的,如位置等,另外构成一个类。

    FlyWeight接口

     1 package top.bigking.flyWeight;
     2 
     3 /**
     4  * @Author ABKing
     5  * @since 2020/2/25 下午10:12
     6  **/
     7 public interface FlyWeight {
     8     void getColor();
     9     void getPosition(UnsharedConcreteFlyWeight position);
    10 }

    FlyWeight的实现类,ConcreteFlyWeight类,增加了内部状态(共有的)

     1 package top.bigking.flyWeight;
     2 
     3 /**
     4  * @Author ABKing
     5  * @since 2020/2/25 下午10:13
     6  * 内部状态 ConcreteFlyWeight
     7  **/
     8 public class ConcreteFlyWeight implements FlyWeight {
     9     private String color;
    10 
    11     public ConcreteFlyWeight(String color) {
    12         this.color = color;
    13     }
    14 
    15     @Override
    16     public void getColor() {
    17         System.out.println("颜色是: " + color);
    18     }
    19 
    20     @Override
    21     public void getPosition(UnsharedConcreteFlyWeight position) {
    22         System.out.println("位置是: " + position);
    23     }
    24 
    25 
    26 }

    外部状态,UnsharedConcreteFlyWeight类

     1 package top.bigking.flyWeight;
     2 
     3 /**
     4  * @Author ABKing
     5  * @since 2020/2/25 下午10:14
     6  * 外部状态 UnsharedConcreteFlyWeight
     7  **/
     8 public class UnsharedConcreteFlyWeight {
     9     private String x, y;
    10 
    11     public UnsharedConcreteFlyWeight(String x, String y) {
    12         this.x = x;
    13         this.y = y;
    14     }
    15 
    16     @Override
    17     public String toString() {
    18         return "x是" + x + ", y是" + y;
    19     }
    20 
    21     public String getX() {
    22         return x;
    23     }
    24 
    25     public void setX(String x) {
    26         this.x = x;
    27     }
    28 
    29     public String getY() {
    30         return y;
    31     }
    32 
    33     public void setY(String y) {
    34         this.y = y;
    35     }
    36 }

    享元模式通常与工厂模式结合起来使用,写一个FlyWeightFactory类

     1 package top.bigking.flyWeight;
     2 
     3 import java.util.HashMap;
     4 import java.util.Map;
     5 
     6 /**
     7  * @Author ABKing
     8  * @since 2020/2/25 下午10:34
     9  **/
    10 public class FlyWeightFactory {
    11     //享元池
    12     private static Map<String, FlyWeight> map = new HashMap<>();
    13 
    14     public static FlyWeight getFlyWeight(String color){
    15         FlyWeight flyWeight = map.get(color);
    16         if(flyWeight != null){//池中有对象
    17             return flyWeight;
    18         }else {//池中无对象
    19             FlyWeight fw = new ConcreteFlyWeight(color);
    20             map.put(color, fw);
    21             return fw;
    22         }
    23     }
    24 }

    JUnit单元测试:

     1 package top.bigking.flyWeight;
     2 
     3 import org.junit.Test;
     4 
     5 /**
     6  * @Author ABKing
     7  * @since 2020/2/25 下午10:40
     8  **/
     9 public class TestFlyWeight {
    10     @Test
    11     public void testFlyWeight(){
    12         FlyWeight flyWeight = FlyWeightFactory.getFlyWeight("黑色");
    13         FlyWeight flyWeight2 = FlyWeightFactory.getFlyWeight("黑色");
    14         System.out.println(flyWeight == flyWeight2);
    15         flyWeight.getColor();
    16         flyWeight2.getColor();
    17         flyWeight.getPosition(new UnsharedConcreteFlyWeight("10", "15"));
    18         flyWeight2.getPosition(new UnsharedConcreteFlyWeight("20", "20"));
    19     }
    20 }

    优点:

    • 极大减少内存中对象的数量
    • 相同或相似对象内存中只存一份,极大地节约资源,提高系统性能。
    • 外部状态相对独立,不影响内部状态。

    缺点:

    • 模式较复杂,使程序逻辑复杂化
    • 为了节省内存,共享了内部状态,分理出外部状态,而读取外部状态使运行时间边长。用时间换取了空间。
    • 由于是共享同一个对象,所以后一个改变外部状态会影响前一个的外部状态。

    享元模式开发应用中的场景:

    享元模式由于其共享的特性,可以在任何池中操作,比如:线程池,数据库连接池

    String类的设计也是享元模式

    金麟岂是池中物,一遇风云便化龙!
  • 相关阅读:
    python实战===python程序打包成exe
    python基础===100盏灯的问题
    安全测试===dos攻击和ddos攻击
    Ubuntu16.04安装Consul
    kerberos相关
    Linux终端复制粘贴后前后会多出0~和~1
    Superset配置impala数据源
    Airflow使用指南
    Superset配置hive数据源
    Superset配置mysql数据源
  • 原文地址:https://www.cnblogs.com/ABKing/p/12363807.html
Copyright © 2020-2023  润新知