zoukankan      html  css  js  c++  java
  • java设计模式-享元模式

    模式导读:

           世上没有相同的两片叶子,尽管它们可能非常相似,无论是颜色,大小亦或是重量等等,也会有不同之处,比如纹理,厚度等等。当我们需要将两片叶子用语言描述出来时,你是会选择两者分开描述,从颜色到厚度,从抽象到具体等等还是会选择两者同时描述,将共同点抽取出来然后细话两者不同。显然后者相比于前者既省时间又提高了辨识度,效率明显提升。享元模式在生活中随处可见,抽取相同属性放入一个容器以便共享,并且可以保证该属性不会随外部环境变化而发生变化。这便是享元模式。

    核心:
    享元模式以共享的方式高效的支持大量细粒度对象的重用。
    享元对象能做到共享的关键是区分了内部状态和外部状态。
    内部状态:可以共享,不会随环境变化而变化。
    外部状态:不可以共享,会随环境变化而变化。
    参考类图:

    FlyweightFactory(享元工厂类):创建并管理享元对象,享元池一般设计成键值对。
    FlyWeight(抽象享元类):通常是一个接口或抽象类,声明公共方法,这些方法可以向外界提供对象的内部状态,设置外部状态。
    ConcretFlyWeight(具体享元类):为内部状态提供成员变量进行存储。
    UnsharedConcreteFlyWeight(非共享享元类):不能被共享的子类可以设计为非共享享元类。

    代码实现:

    1.抽象享元类

    1 package com.etc;
    2 //抽象享元类 ->内存卡
    3 public interface AbstractMemoryCard {
    4     //内存卡的颜色获取
    5     String  getColor();
    6     void setColor(String c);
    7     void showMessage(ExternalState state);
    8 }

    2.具体享元类

     1 package com.etc;
     2 //具体的享元类
     3 public class MemoryCard implements AbstractMemoryCard {
     4 
     5     private String color;
     6     
     7     //构造器
     8     public MemoryCard(String color) {
     9         super();
    10         this.color = color;
    11     }
    12 
    13     @Override
    14     public String getColor() {
    15         return color;
    16     }
    17 
    18     @Override
    19     public void setColor(String color) {
    20         this.color=color;
    21     }
    22 
    23     @Override
    24     public void showMessage(ExternalState state) {
    25         System.out.println("******内存卡信息:*******");
    26         System.out.println("*颜色:"+color);
    27         System.out.println("*品牌:"+state.getBrand());
    28         System.out.println("*内存大小:"+state.getStoreSize()+"g");
    29         System.out.println("*********************");
    30     }
    31 
    32 }

    3.非共享享元类

     1 package com.etc;
     2 //非共享享元类(外部状态类)->包含内存卡的内存大小,以及相应的品牌
     3 public class ExternalState {
     4     
     5     private int storeSize;
     6     private String brand;
     7     
     8     public ExternalState(int storeSize, String brand) {
     9         super();
    10         this.storeSize = storeSize;
    11         this.brand = brand;
    12     }
    13     public int getStoreSize() {
    14         return storeSize;
    15     }
    16     public void setStoreSize(int storeSize) {
    17         this.storeSize = storeSize;
    18     }
    19     public String getBrand() {
    20         return brand;
    21     }
    22     public void setBrand(String brand) {
    23         this.brand = brand;
    24     }
    25     
    26 
    27 }

    4.享元工厂

     1 package com.etc;
     2 
     3 import java.util.HashMap;
     4 import java.util.Map;
     5 
     6 //享元工厂类
     7 public class Factory {
     8     //建立享元池
     9     private static Map<String,AbstractMemoryCard> map=new HashMap<String,AbstractMemoryCard>();
    10     //通过内存卡的共同属性color返回对象地址
    11     public static AbstractMemoryCard getMemoryCard(String color) {
    12         //如果获取的color不为空直接返回color
    13         if(map.get(color)!=null) {
    14             return map.get(color);
    15         }else {
    16             //为空则初始化color并将其放入享元池中
    17             AbstractMemoryCard amc=new MemoryCard(color);
    18             map.put(color, amc);
    19             return amc;
    20         }
    21     }
    22     
    23 }

    5.客户端

     1 package com.etc;
     2 
     3 public class Client {
     4 
     5     public static void main(String[] args) {
     6         
     7         //因为color属性为共享属性,所以在此已经初始化了color的值为黑色
     8         AbstractMemoryCard amc=Factory.getMemoryCard("黑色");
     9         //color的值已经存在,所以返回相同的对象
    10         AbstractMemoryCard amc2=Factory.getMemoryCard("黑色");
    11         System.out.println(amc==amc2?"两个对象相同":"两个对象不相同");
    12         
    13         ExternalState state=new ExternalState(16,"三星");
    14         ExternalState state2=new ExternalState(32,"闪迪");
    15         //信息展示
    16         amc.showMessage(state);
    17         amc2.showMessage(state2);
    18     }
    19 
    20 }

    效果截图:

    享元模式优缺点:

    优点:

    1.极大的减少了内存中对象的数量

    2.相同或相似的对象在内存中只占一份,极大的节约资源,提高了系统性能。

    3.外部状态相对独立,不会影响内部状态。

    缺点:

    1.模式较复杂,使程序逻辑复杂化

    2.为了节省内存,共享了内部状态,分离出外部状态,而读取外部状态使运行时间变长,用时间换取了空间。

    适用场景:

    1.可以在任何"池"中操作,比如线程池,数据库连接池。

    2.String类的设计也是享元模式

  • 相关阅读:
    重定向syste.out.print
    文件与文件夹的拷贝
    List和Set转Long数组
    Struts2验证错误信息的两个经典方法-addFieldError&addActionError
    OA项目---笔记
    三种给<s:a>,<a>标签传值的方式
    [整理]免费电子书网站
    [整理]Visual Studio 的Application Insights
    [转载]CSS Tools: Reset CSS
    [转载]AngularJS之Factory vs Service vs Provider
  • 原文地址:https://www.cnblogs.com/weekstart/p/10880135.html
Copyright © 2011-2022 走看看