再战设计模式(十一)之享元模式

享元模式

场景:

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

核心:

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

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

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

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

现在有个需求,需要为围棋设置一个程序,那么围棋的棋子改如何设计?总共有很多黑子和白子,难道我们需要为每一个棋子生成一个对象吗?

显然这样的设计是不合理的.这个时候我们就可以用到享元模式!

类图:如下

类图的看比较复杂.我们来剖析下

chessFlyWeight:是一个接口,声明了一些公共的方法,这些方法可以向外提供内部状态,以及设置外部的状态

ChessFlyWeightImpl: 是一个享元对象的实例,可以存储内部状态(因为可以共享) ,可以获取外部状态的属性.如 x y

ChessCoordinateConcrete: 是享元对象的外部状态不可以共享,,可以随意设置

ChessFlyWeightFactory : 就是通过内部状态.获取对象..就像我们平时用的缓存一样.我把他设置成单例的了.

client: 可以具体的调用这里就不多说了.

代码:

/**
 * 享元类
 * @Created by xiaodao
 */
public interface ChessFlyWeight {

    void setColor(String color );
    String getColor();
    void display(ChessCoordinateConcrete c );

}

/**
 * 为内部对象,提供享元存储.!!
 * @Created by xiaodao
 */
public class ChessFlyWeightImpl implements ChessFlyWeight {
    private String color;

    public ChessFlyWeightImpl(String color) {
        this.color = color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public String getColor() {
        return this.color;
    }

    public void display(ChessCoordinateConcrete c) {

        System.out.println("chess‘s color = "+ color);
        System.out.println("chess;s position x = "+ c.getX() +"----- y = "+ c.getY());

    }
}

/**
 * 不可共享的外部结构
 * @Created by xiaodao
 */
public class ChessCoordinateConcrete {

    private int x,y;

    public ChessCoordinateConcrete(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }
}

/**
 * 享元 工厂 返回 接口...
 * @Created by xiaodao
 */
public class ChessFlyWeightFactory {

    private static  ChessFlyWeightFactory instance= new ChessFlyWeightFactory();

    private static HashMap<String,ChessFlyWeight> map = new HashMap<String, ChessFlyWeight>();

    public  ChessFlyWeight getChess(String color){
        if(map.get(color) !=null){
            return map.get(color);
        }else{
            ChessFlyWeight chessFlyWeight = new ChessFlyWeightImpl(color);
            map.put(color,chessFlyWeight);
            return  map.get(color);
        }

    }

    private ChessFlyWeightFactory() {
    }

    public static ChessFlyWeightFactory getInstance(){
        return instance;
    }
}
/**
 * @Created by xiaodao
 */
public class Client {

    public static void main(String[] args) {
        ChessFlyWeightFactory c =  ChessFlyWeightFactory.getInstance();

        ChessFlyWeight chess1 = c.getChess("黑色");

        chess1.display(new ChessCoordinateConcrete(10,20));

        ChessFlyWeight chess2 = c.getChess("黑色");
        System.out.println("-----------------");
        chess2.display(new ChessCoordinateConcrete(20,30));

        System.out.println(chess1);
        System.out.println(chess2);

    }

}

获取到的结果:

chess‘s color = 黑色
chess;s position x = 10----- y = 20
-----------------
chess‘s color = 黑色
chess;s position x = 20----- y = 30
[email protected]
[email protected]

这样的运行之后..我们就可以获取到同一个对象,但是他的外部不可共享的属性确不一样..这就可以节省很多内存空间.

角色:

享元模式实现:

– FlyweightFactory享元工厂类
• 创建并管理享元对象,享元池一般设计成键值对

– FlyWeight抽象享元类

• 通常是一个接口或抽象类,声明公共方法,这些方法可以向外界提供对象
的内部状态,设置外部状态。

– ConcreteFlyWeight具体享元类
• 为内部状态提供成员变量进行存储

– UnsharedConcreteFlyWeight非共享享元类

• 不能被共享的子类可以设计为非共享享元类

总结:

享元模式,我们在工作中很少用,写起来比较复杂.维护也不好维护,但是我们还是需要了解,这样对阅读源码是比较友好的.

优点:

  1. 极大的减少了内存中的对象数量
  2. 相同或者相似的对象内存中只有一份,节省空间
  3. 外部状态相对独立,不影响内部的属性

缺点:

  1. 模式比较复杂.看上面的类图就知道,感觉不够清晰,是程序逻辑复杂化
  2. 为了使对象可以共享,享元模式需要将享元对象的状态外部化,而读取外部状态使得运行时间变长。 用时间换取了空间

JDK或者项目中的使用

string 也是使用的享元模式,共享常量池.

integer: 中也使用了

   public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }
     Integer a = Integer.valueOf(100);
        Integer b = 100;

        Integer c =Integer.valueOf(1000);
        Integer d = Integer.valueOf(1000);
        System.out.println(a==b);
        System.out.println(c==d);

true
false

integer 最小是-128 最大是127 在缓存中,当然也可以设置.也是使用的享元模式

数据连接池还有各种pool 也是使用的这个模式

原文地址:https://www.cnblogs.com/bj-xiaodao/p/10859371.html

时间: 2024-07-31 21:19:04

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

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

场景:内存属于稀缺资源,不要随便浪费.如果有很多个完全相同或相似的对象,我们可以通过享元模式,节省内存. 核心:享元模式以共享的方式高效地支持大量细粒度对象的重用. 享元对象能做到共享的关键是区分了内部状态和外部状态. 内部状态:可以共享,不会随环境变化而改变. 外部状态:不可以共享,会随环境变化而改变. 例如: 围棋软件设计 每个围棋棋子都是一个对象,有如下属性:颜色.形状.大小(这些是可以共享的,称之为内部状态) 位置(这是不可以共享的,称之为外部状态) 享元模式实现: FlyWeightF

Java设计模式之《享元模式》及应用场景

原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6542449.html 享元模式:"享"就是分享之意,指一物被众人共享,而这也正是该模式的终旨所在. 享元模式有点类似于单例模式,都是只生成一个对象来被共享使用.这里有个问题,那就是对共享对象的修改,为了避免出现这种情况,我们将这些对象的公共部分,或者说是不变化的部分抽取出来形成一个对象.这个对象就可以避免到修改的问题. 享元的目的是为了减少不会要额内存消耗,将多个对同一对象的访

[设计模式] javascript 之 享元模式;

享元模式说明 定义:用于解决一个系统大量细粒度对象的共享问题: 关健词:分离跟共享: 说明: 享元模式分单纯(共享)享元模式,以及组合(不共享)享元模式,有共享跟不共享之分:单纯享元模式,只包含共享的状态,可共享状态是不可变,不可修改的,这是享元的内部状态:当然有外部状态就有外部状态,外部状态是可变的,不被共享,这个外部状态由客户端来管理,是可变化的:外部状态与内部状态是独立分开的,外部状态一般作为参数传入享元对象内,但不会影响内部状态的值:外部状态,一用用于获取共享的享元对象,或多或少与内部状

《Java设计模式》之享元模式

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

大话设计模式Python实现- 享元模式

享元模式(Flyweight Pattern):运用共享技术有效地支持大量细粒度的对象. 下面是一个享元模式的demo: 1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 __author__ = 'Andy' 5 """ 6 大话设计模式 7 设计模式--享元模式 8 享元模式(Flyweight Pattern):运用共享技术有效地支持大量细粒度的对象 9 对一个类进行的实例,只在第一次使用时建立,其他时候是用同一个

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

概念定义 享元(Flyweight)模式运用共享技术高效地支持大量细粒度对象的复用. 当系统中存在大量相似或相同的对象时,有可能会造成内存溢出等问题.享元模式尝试重用现有的同类对象,如果未找到匹配的对象则创建新对象,从而减少系统中重复创建对象实例的性能和内存消耗. 享元模式将对象的信息分为两个部分:内部状态(Internal State)和外部状态(External State).内部状态是对象可共享出来的信息,存储在享元对象内部并且不会随环境改变而改变.外部状态是随环境改变而改变的.不可共享的

java设计模式 GOF23 11 享元模式

一.享元模式简介 如果有很多相同或者相似的对象可以使用享元模式,从而节约内存. 二.关键点 享元对象需要区分内部状态和外部状态. 内部状态:可以共享,不会随着外部状态改变. 外部状态:不可以共享,随外部状态改变. 享元共享类实现享元池管理享元对象. 三.简单实现 package com.lz.flyWeight; /* * 享元模式 * 内部状态 * 模拟棋盘,因为一盘棋其中棋子的颜色都一样 * 只有位置不一样,所以可以将颜色共享,这样可以节省内存空间 * 棋盘接口 */ interface C

设计模式--13、享元模式

享元模式: 先让我们来看一个应用场景: 比如说一个文本系统,每个字母定一个对象,那么大小写字母一共就是52个,那么就要定义52个对象.如果有一个1M的文本,那么字母是何其的多,如果每个字母都定义一个对象那么内存早就爆了.那么如果要是每个字母都共享一个对象,那么就大大节约了资源.也就是说在一个系统中如果有多个相同的对象,那么只共享一份就可以了,不必每个都去实例化一个对象. 在Flyweight模式中,由于要产生各种各样的对象,所以在Flyweight(享元)模式中常出现Factory模式.Flyw

Java描述设计模式(18):享元模式

本文源码:GitHub·点这里 || GitEE·点这里 一.使用场景 应用代码 public class C01_InScene { public static void main(String[] args) { String c0 = "cicada" ; String c1 = "cicada" ; System.out.println(c0 == c1); // true } } String类型就是使用享元模式.String对象是final类型,对象一旦