1.讲解享元模式(结构型)

1.1享元模式定义

运用共享技术有效地支持大量细粒度对象.
享元:把内部状态共享出来

1.2享元模式要点

重点在于分离变与不变。

把一个对象的状态分为内部状态和外部状态,内部状态不变,外部状态可变。

内部状态就是在对象里通过内部方法管理,而外部信息可以在通过外部删除或者保存。

1.3享元模式的结构图以及说明




享元模式所涉及的角色有抽象享元角色、具体(单纯)享元角色、复合享元角色、享员工厂角色,以及客户端角色等。

抽象享元角色(Flyweight):此角色是所有的具体享元类的超类,为这些类规定出需要实现的公共接口或抽象类。那些需要外蕴状态(External State)的操作可以通过方法的参数传入。抽象享元的接口使得享元变得可能,但是并不强制子类实行共享,因此并非所有的享元对象都是可以共享的。

具体享元(ConcreteFlyweight)角色:实现抽象享元角色所规定的接口。如果有内蕴状态的话,必须负责为内蕴状态提供存储空间。享元对象的内蕴状态必须与对象所处的周围环境无关,从而使得享元对象可以在系统内共享。有时候具体享元角色又叫做单纯具体享元角色,因为复合享元角色是由单纯具体享元角色通过复合而成的。

复合享元(UnsharableFlyweight)角色:复合享元角色所代表的对象是不可以共享的,但是一个复合享元对象可以分解成为多个本身是单纯享元对象的组合。复合享元角色又称做不可共享的享元对象。这个角色一般很少使用。

享元工厂(FlyweightFactoiy)角色:本角色负责创建和管理享元角色。本角色必须保证享元对象可以被系统适当地共享。当一个客户端对象请求一个享元对象的时候,享元工厂角色需要检查系统中是否已经有一个符合要求的享元对象,如果已经有了,享元工厂角色就应当提供这个已有的享元对象;如果系统中没有一个适当的享元对象的话,享元工厂角色就应当创建一个新的合适的享元对象。

客户端(Client)角色:本角色还需要自行存储所有享元对象的外蕴状态。

1.4享元模式的示例代码

package demo19.flyweight.example2;

/***
* 享元接口,通过这个接口享元可以接受并作用于外部状态
*/
public interface Flyweight {
/**
* 示例操作,传入外部状态
*
* @param extrinsicState
* 示例参数,外部状态
*/
public void operation(String extrinsicState);
}
**************************************************************************************************
package demo19.flyweight.example2; /**
* 享元对象
*/
public class ConcreteFlyweight implements Flyweight {
/**
* 示例,描述内部状态
*/
private String intrinsicState; /**
* 构造方法,传入享元对象的内部状态的数据
*
* @param state
* 享元对象的内部状态的数据
*/
public ConcreteFlyweight(String state) {
this.intrinsicState = state;
} public void operation(String extrinsicState) {
// 具体的功能处理,可能会用到享元内部、外部的状态
}
}
**************************************************************************************************
package demo19.flyweight.example2; /**
* 不需要共享的Flyweight对象, 通常是将被共享的享元对象作为子节点,组合出来的对象
*/
public class UnsharedConcreteFlyweight implements Flyweight {
/**
* 示例,描述对象的状态
*/
private String allState; public void operation(String extrinsicState) {
// 具体的功能处理
}
}
**************************************************************************************************
package demo19.flyweight.example2; import java.util.HashMap;
import java.util.Map; /**
* 享元工厂
*/
public class FlyweightFactory {
/**
* 缓存多个flyweight对象,这里只是示意一下
*/
private Map<String, Flyweight> fsMap = new HashMap<String, Flyweight>(); /**
* 获取key对应的享元对象
*
* @param key
* 获取享元对象的key,只是示意
* @return key对应的享元对象
*/
public Flyweight getFlyweight(String key) {
// 这个方法里面基本的实现步骤如下:
// 1:先从缓存里面查找,是否存在key对应的Flyweight对象
Flyweight f = fsMap.get(key);
// 2:如果存在,就返回相对应的Flyweight对象
if (f == null) {
// 3:如果不存在
// 3.1:创建一个新的Flyweight对象
f = new ConcreteFlyweight(key);
// 3.2:把这个新的Flyweight对象添加到缓存里面
fsMap.put(key, f);
// 3.3:然后返回这个新的Flyweight对象
}
return f;
}
}
**************************************************************************************************
package demo19.flyweight.example2; /**
* Client对象,通常会维持一个对flyweight的引用, 计算或存储一个或多个flyweight的外部状态
*/
public class Client {
// 具体的功能处理
}

1.5享元模式的本质

分离与共享

1.6享元模式的优缺点

优点:减少对象数量,节省内存空间


缺点:维护共享对象,需要额外开销

1.7何时选用?

1.7.1如果一个程序大量使用了细粒度对象

1.7.2如果对象的大多数状态都可以变为外部状态(比如可以通过计算得到),或是从外部传入等,可以使用享元模式进行内部状态和外部状态的分离。

2.使用享元模式解决的案例

比如围棋有300颗棋子,用一般的设计模式,创建一个类,每个棋子都用一个对象的话,那就会非常麻烦,并且各自定义各自在棋盘的位置.....等等,而使用 亨元模式 来实现的话,就用两个对象 :一个黑,一个白。这样就可以了,至于棋子的方位不同,那只是对象的不同的外部表现形式或者说是外部状态。这样三百多个对象就减到了两个对象。享元模式以共享的方式高效地支持大量的细粒度对象,说的再具体一些是将所有具有相同状态的对象指向同一个引用,从而解决了系统在创建大量对象时所带来的内存压力。

示例代码如下

2.1享元接口,通过这个接口享元可以接受并作用于外部状态

package demo19.flyweight.example1;

/**
* 抽象棋子的接口
*
* @author 王玉超
* @date 2013-7-31
*/
public interface IChessFlyWeight {
public String getColor(); public void show(Point point);
}

2.2享元对象

package demo19.flyweight.example1;

/**
* 具体棋子对象的实现类
*
* @author 王玉超
* @date 2013-7-31
*/
public class ConcreteChessFlyWeight implements IChessFlyWeight { private String color; public String getColor() {
return color;
} public ConcreteChessFlyWeight(String color) {
this.color = color;
} public void show(Point point) {
System.out.println("This Chess is " + color + ",Point X:" + point.getX() + " Y:" + point.getY());
}
}

2.3不需要共享的对象,即外部动态该变量

package demo19.flyweight.example1;

/**
* 棋子外部动态变动的属性
*
* @author 王玉超
* @date 2013-7-31
*/
public class Point {
private int x;
private int y; public Point(int x, int y) {
this.x = x;
this.y = y;
} public int getX() {
return x;
} public int getY() {
return y;
} @Override
public String toString() {
return "Point [x=" + x + ", y=" + y + "]";
}
}

2.4享元模型对象工厂

package demo19.flyweight.example1;

import java.util.HashMap;
import java.util.Map; /**
* 享元模型对象工厂
*
* @author 王玉超
* @date 2013-7-31
*/
public class ChessFlyWeightFactory { private Map<String, IChessFlyWeight> chessMap = new HashMap<String, IChessFlyWeight>(); public IChessFlyWeight getChess(String key) {
if (!chessMap.containsKey(key)) {
chessMap.put(key, new ConcreteChessFlyWeight(key));
} return chessMap.get(key);
}
}

2.5客户端调用

package demo19.flyweight.example1;

public class Client {
public static void main(String[] args) {
ChessFlyWeightFactory factory = new ChessFlyWeightFactory();
Point point; String white = "白";
String black = "黑"; point = new Point(0, 0);
factory.getChess(white).show(point); point = new Point(10, 10);
factory.getChess(white).show(point); point = new Point(100, 100);
factory.getChess(black).show(point); point = new Point(200, 200);
factory.getChess(black).show(point);
}
}

代码仔细对应示例代码以后,发现没有【不需要共享的Flyweight对象】实际上,就是Point类,只不过,Point类没有继承Flyweight接口而已。那个不需要共享的对象一般很少用。

设计模式21---设计模式之享元模式(Flyweight)(结构型)的更多相关文章

  1. 享元模式 FlyWeight 结构型 设计模式(十五)

    享元模式(FlyWeight)  “享”取“共享”之意,“元”取“单元”之意. 意图 运用共享技术,有效的支持大量细粒度的对象. 意图解析 面向对象的程序设计中,一切皆是对象,这也就意味着系统的运行将 ...

  2. 设计模式(十)享元模式Flyweight(结构型)

    设计模式(十)享元模式Flyweight(结构型) 说明: 相对于其它模式,Flyweight模式在PHP实现似乎没有太大的意义,因为PHP的生命周期就在一个请求,请求执行完了,php占用的资源都被释 ...

  3. 设计模式11: Flyweight 享元模式(结构型模式)

    Flyweight 享元模式(结构型模式) 面向对象的代价 面向对象很好的解决了系统抽象性的问题,同时在大多数情况下也不会损及系统的性能.但是,在某些特殊应用中,由于对象的数量太大,采用面向对象会给系 ...

  4. Java设计模式15:常用设计模式之享元模式(结构型模式)

    1. Java之享元模式(Flyweight Pattern) (1)概述:       享元模式是对象池的一种实现,英文名为"Flyweight",代表轻量级的意思.享元模式用来 ...

  5. 面向对象设计模式之Flyweight享元模式(结构型)

    动机:采用纯粹对象方案的问题在于大量细粒度的对象会很快充斥在系统中,从而带来很高的运行代价——主要指内存需求方面的代价.如何在避免大量细粒度对象问题的同 时,让外部客户程序仍然能够透明地使用面向对象的 ...

  6. 设计模式 笔记 享元模式 Flyweight

    //---------------------------15/04/20---------------------------- //Flyweight 享元模式------对象结构型模式 /* 1 ...

  7. 乐在其中设计模式(C#) - 享元模式(Flyweight Pattern)

    原文:乐在其中设计模式(C#) - 享元模式(Flyweight Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 享元模式(Flyweight Pattern) 作者:weba ...

  8. 设计模式-11享元模式(Flyweight Pattern)

    1.模式动机 在面向对象程序设计过程中,有时会面临要创建大量相同或相似对象实例的问题.创建那么多的对象将会耗费很多的系统资源,它是系统性能提高的一个瓶颈. 享元模式就是把相同或相似对象的公共部分提取出 ...

  9. 设计模式系列之享元模式(Flyweight Pattern)——实现对象的复用

    说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...

  10. 二十四种设计模式:享元模式(Flyweight Pattern)

    享元模式(Flyweight Pattern) 介绍运用共享技术有效地支持大量细粒度的对象. 示例有一个Message实体类,某些对象对它的操作有Insert()和Get()方法,现在要运用共享技术支 ...

随机推荐

  1. 【POJ2761】【fhq treap】A Simple Problem with Integers

    Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. On ...

  2. 一个中型项目:本地校园App

    好暨: 这个项目的起源于课堂老师作业的要求.老师要求一年下来完成一个构想并实现Demo.思考良久,在要提交构想的那个晚上,想到了校园App,当时团队只有两个人,但我感觉到:就是它了!项目启动时间——2 ...

  3. C宏系统缺陷

    这两天稍稍看了一下boost的preprocessor库,发觉boost那帮疯子竟然利用各种奇技淫巧定义出各种数据类型和结构,还在上面定义出加减乘除等等各种运算,在快速浏览的过程中,还瞄到了很眼熟的各 ...

  4. aix7安装was7、打补丁、更改访问端口、手动启动was、配置was7、部署项目

    1:准备工作  首先了解下我们下面即将用到的aix命令,以及安装包.补丁安装工具.补丁 was7的安装包以及补丁工具都是压缩包形式并且以.tar.gz结尾的 安装包在800MB左右,通常为****_w ...

  5. Java字符串学习

    Java中字符串是String类的实例,字符串也是对象,所以 Java将字符串作为对象进行管理 Java使用java.lang 包中的String类来创建字符串. 1.定义字符串: 使用 " ...

  6. Python Tutorial 学习(九)--Classes

    ## 9. Classes 类 Compared with other programming languages, Python's class mechanism adds classes wit ...

  7. 简单学C——第一天

    基本功 一.数据类型: 在C语言中,有数据类型这一说法.为何有这一说法?是因为在现实生活中存在着不同的数据,(例如整数,小数,字符即a b c d , . ; "  之类).由于计算机中所有 ...

  8. Unable to find the ncurses libraries or the required header files解决

    问题: 解决方法: sudo apt-get install ncurses-dev 参考:Unable to find the ncurses libraries or the required h ...

  9. .Echo 命令中经常提到回显,是什么意思?

    C:\>echo on C:\>date /t2006-08-06 星期日 C:\>以上内容是在打开回显的情况下执行的,其实我们想看到的只有2006-08-06 星期日这一行内容,但 ...

  10. 董的博客 hadoop

    董的博客 https://issues.apache.org/jira/browse/MAPREDUCE 很重要,把MAPREDUCE改为YARN即可 直接下载patch即可 http://horto ...