设计模式(十一)享元模式

场景:内存属于稀缺资源,不要随便浪费。如果有很多个完全相同或相似的对象,我们可以通过享元模式,节省内存。



核心:享元模式以共享的方式高效地支持大量细粒度对象的重用。

   享元对象能做到共享的关键是区分了内部状态和外部状态。

     内部状态:可以共享,不会随环境变化而改变。

     外部状态:不可以共享,会随环境变化而改变。

例如:

围棋软件设计

每个围棋棋子都是一个对象,有如下属性:颜色、形状、大小(这些是可以共享的,称之为内部状态)

位置(这是不可以共享的,称之为外部状态)



享元模式实现:

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


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

  • 享元模式由于其共享的特性,可以在任何“池”中操作,比如:线程池,数据库连接池
  • String类的设计也是享元模式


优点:

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

缺点:

  • 模式较复杂,使程序逻辑复杂化
  • 为了节省内存,共享了内部状态,分离出外部状态,而读取外部状态使运行时间变长。用时间换取了空间。


例:

1. 创建外部状态类

 1 package com.ztq.flyweight;
 2
 3 /***
 4  * 外部状态UnSharedConcreteFlyWeight
 5  * @author ZTQ
 6  *
 7  */
 8 public class Coordinate {
 9     private int x, y;
10
11     public Coordinate(int x, int y){
12         this.x = x;
13         this.y = y;
14     }
15
16     public int getX() {
17         return x;
18     }
19
20     public void setX(int x) {
21         this.x = x;
22     }
23
24     public int getY() {
25         return y;
26     }
27
28     public void setY(int y) {
29         this.y = y;
30     }
31
32
33 }

2. 创建享元接口,并创建具体享元类实现该接口

 1 package com.ztq.flyweight;
 2
 3 /***
 4  * 享元类
 5  * @author ZTQ
 6  *
 7  */
 8 public interface ChessFlyWeight {
 9     void setColor(String c);
10     String getColor();
11     void display(Coordinate c);
12 }
13
14 class ConcreteChess implements ChessFlyWeight{
15
16     private String color;
17
18     public ConcreteChess(String color){
19         this.color = color;
20     }
21
22     @Override
23     public void setColor(String c) {
24         this.color = c;
25     }
26
27     @Override
28     public String getColor() {
29         return color;
30     }
31
32     @Override
33     public void display(Coordinate c) {
34         System.out.println("棋子颜色:" + color);
35         System.out.println("棋子位置:" + c.getX() + "---" + c.getY());
36     }
37
38 }

3. 创建享元工厂类

 1 package com.ztq.flyweight;
 2
 3 import java.util.HashMap;
 4 import java.util.Map;
 5
 6 /***
 7  * 享元工厂类
 8  * @author ZTQ
 9  *
10  */
11 public class ChessFlyWeightFactory {
12     //享元池
13     private static Map<String, ChessFlyWeight> map = new HashMap<String, ChessFlyWeight>();
14
15     public static ChessFlyWeight getChess(String color){
16         if(map.get(color) != null){
17             return map.get(color);
18         }
19         else{
20             ChessFlyWeight cfw = new ConcreteChess(color);
21             map.put(color, cfw);
22             return cfw;
23         }
24     }
25 }

4. 创建测试类Client

 1 package com.ztq.flyweight;
 2
 3 public class Client {
 4     public static void main(String[] args) {
 5         ChessFlyWeight chess1 = ChessFlyWeightFactory.getChess("黑色");
 6         ChessFlyWeight chess2 = ChessFlyWeightFactory.getChess("黑色");
 7         System.out.println(chess1);
 8         System.out.println(chess2);
 9
10         System.out.println("增加外部状态的处理");
11         chess1.display(new Coordinate(10, 10));
12         chess2.display(new Coordinate(20, 20));
13
14     }
15 }

结果:

[email protected]
[email protected]
增加外部状态的处理
棋子颜色:黑色
棋子位置:10---10
棋子颜色:黑色
棋子位置:20---20

UML图:

时间: 2024-10-08 03:35:37

设计模式(十一)享元模式的相关文章

设计模式之享元模式

Flyweight在拳击比赛中指最轻量级,即"蝇量级"或"雨量级",这里选择使用"享元模式"的意译,是因为这样更能反映模式的用意.享元模式是对象的结构模式.享元模式以共享的方式高效地支持大量的细粒度对象. Java中的String类型 在JAVA语言中,String类型就是使用了享元模式.String对象是final类型,对象一旦创建就不可改变.在JAVA中字符串常量都是存在常量池中的,JAVA会确保一个字符串常量在常量池中只有一个拷贝.Stri

纵横之设计模式(享元模式-性能与对象访问)

声明:本系列文章内容摘自<iOS设计模式> 享元模式:运用共享技术有效地支持大量细粒度的对象. 何为享元模式 实现享元模式需要两个关键组件,通常是可共享的享元对象和保存它们的池.某种中央对象维护这个池,并从它返回适当的实例,工厂是这一角色的理想候选.它可以通过一个工厂方法,根据父类型返回各种类型的具体享元对象.其主要目的就是维护池中的享元对象,并适当的从中返回享元对象. 何时使用享元模式 1.应用程序使用很多对象: 2.在内存中保存对象会影响内存性能: 3.对象的多处持有状态(外在状态)可以放

Java设计模式之享元模式实例详解

本文实例讲述了Java设计模式之享元模式.分享给大家供大家参考,具体如下: 解释一下概念:也就是说在一个系统中如果有多个相同的对象,那么只共享一份就可以了,不必每个都去实例化一个对象.比如说一个文本系统,每个字母定一个对象,那么大小写字母一共就是52个,那么就要定义52个对象.如果有一个1M的文本,那么字母是何其的多,如果每个字母都定义一个对象那么内存早就爆了.那么如果要是每个字母都共享一个对象,那么就大大节约了资源. 在Flyweight模式中,由于要产生各种各样的对象,所以在Flyweigh

Java设计模式菜鸟系列(二十一)享元模式建模与实现

转载请注明出处:http://blog.csdn.net/lhy_ycu/article/details/40021651 享元模式(Flyweight):运用共享的技术有效地支持大量细粒度的对象.主要目的是实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销.在某种程度上,你可以把单例看成是享元的一种特例. 一.uml建模: 二.代码实现 /** * 享元模式(Flyweight):运用共享的技术有效地支持大量细粒度的对象. * * 主要目的是实现对象的共享,即共享池,当系统中对象

javascript设计模式学习之十一——享元模式

一.享元模式的定义及使用场景 享元模式是一种用于性能优化的模式,如果系统中因为创建了大量类似对象而导致内存占用过高,享元模式就非常有用了.享元模式的核心是运用共享技术来有效支持大量细粒度的对象. 享元模式的关键是区分内部状态和外部状态,剥离了外部状态的对象成为共享对象,外部状态在必要时被传入共享对象来组装成一个完整的对象.那些可以被对象共享的属性通常就被划分为内部状态.

Head First设计模式之享元模式(蝇量模式)

一.定义 享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能.这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式. 享元模式尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象.我们将通过创建 5 个对象来画出 20 个分布于不同位置的圆来演示这种模式.由于只有 5 种可用的颜色,所以 color 属性被用来检查现有的 Circle 对象. 二.结构 三.实现 namespace DesignPattern

设计模式:享元模式(Flyweight)

?运用共享技术有效地支持大量细粒度的对象.又名"蝇量模式". ?在Java语言中,String类型就是使用了享元模式.String对象是final类型,对象一旦创建就不可改变.在JAVA中字符串常量都是存在常量池中的,Java会确保一个字符串常量在常量池中只有一个拷贝.譬如: String a = "abc"; String b = "abc"; System.out.println(a==b); ?输出结果:true.这就说明了a和b量引用都指

设计模式之享元模式--- Pattern Flyweight

模式的定义 享元模式(Flyweight Pattern)是沲技术的重要实现方式,其定义如下: Use sharing to support large numbers of fine-grained objects efficiently. 使用共享对象可有效地支持大量的细粒度的对象. 享元模式的定义提出了二个要求:细粒度的对象和共享对象.分配太多的对象将有损程序的性能,同时还容易造成内存溢出.避免这种情况,就是使用享元模式中的共享技术. 细粒度的状态分为内部状态(instrinsic)和外部

设计模式-12 享元模式(结构型模式)

一 享元模式 享元模式的主要目的是实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销,通常与工厂模式一起使用. 主要解决:在有大量对象时,有可能会造成内存溢出,我们把其中共同的部分抽象出来,如果有相同的业务请求,直接返回在内存中已有的对象,避免重新创建. 关键代码:存储相似的对象 使用场景: 1.系统有大量相似对象. 2.需要缓冲池的场景. 类图 : 二 实现代码 Java里面的JDBC连接池,适用于作共享的一些个对象,他们有一些共有的属性,就拿数据库连接 池来说,url.driv

【设计模式】享元模式

享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能.这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式. 享元模式尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象.我们将通过创建 5 个对象来画出 20 个分布于不同位置的圆来演示这种模式.由于只有 5 种可用的颜色,所以 color 属性被用来检查现有的 Circle 对象. 介绍 意图:运用共享技术有效地支持大量细粒度的对象. 主要解决:在有大量对象