设计模式--享元模式

Posted bai3535

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式--享元模式相关的知识,希望对你有一定的参考价值。

享元模式

含义

  说到享元模式,第一个想到的应该就是池技术了,String常量池、数据库连接池、缓冲池等等都是享元模式的应用,所以说享元模式是池技术的重要实现方式。

  比如我们每次创建字符串对象时,都需要创建一个新的字符串对象的话,内存开销会很大,所以如果第一次创建了字符串对象“adam“,下次再创建相同的字符              串”adam“时,只是把它的引用指向”adam“,这样就实现了”adam“字符串再内存中的共享。

核心:享元模式以共享的方式高效地支持大量细粒度对象的重用。享元对象能够做到共享的关键是区分了内部状态和外部状态。

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

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

1)         FlyweightFactory享元工厂类

  创建并管理享元对象,享元池一般设计成键值对。

2)         FlyWeight抽象享元类

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

3)         ConcreteFlyWeight具体享元类

  为内部状态提供成员变量进行存储

4)         UnsharedConcreteFlyWeight非共享享元类

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

图示:技术图片              技术图片

 

 

package com.offcn.designpattern.flyweight;

import java.util.HashMap;
import java.util.Map;

public class FlyweightDemo {
    public static void main(String[] args) {
        ConcreteFlyWeight chess1 = new ConcreteFlyWeight("黑色");
        ConcreteFlyWeight chess2 = new ConcreteFlyWeight("黑色");
        System.out.println(chess1);
        System.out.println(chess2);
        System.out.println("======添加坐标=====");
        chess1.position(new Coordinate(10,10));
        chess2.position(new Coordinate(20,20));
    }
}

//1)    FlyweightFactory享元工厂类
class FlyWeightFactory{
    //创建并管理享元对象,享元池一般设计成键值对。
    private static Map<String,ConcreteFlyWeight> map = new HashMap<>();

    public static ConcreteFlyWeight getChess(String color){
        if(map.get(color) != null){
            return map.get(color);
        }else{
            ConcreteFlyWeight cfw = new ConcreteFlyWeight("黑色");
            map.put(color,cfw);
            return cfw;
        }
    }
}
//2)    FlyWeight抽象享元类
interface FlyWeigth{
    //棋子颜色,内部状态
    String getColor();
    //棋子位置,外部状态
    void position(Coordinate c);

}
//3)    ConcreteFlyWeight具体享元类
class ConcreteFlyWeight implements FlyWeigth{
    //为内部状态提供成员变量进行存储
    private String color;

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

    @Override
    public String getColor() {
        return color;
    }

    @Override
    public void position(Coordinate c) {
        System.out.println("棋子颜色:"+color);
        System.out.println("棋子位置:"+c.getX()+".."+c.getY());
    }
}

//4)    UnsharedConcreteFlyWeight非共享享元类
class Coordinate{
    private int x,y;

    public Coordinate(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;
    }
}

输出:

技术图片

优点

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

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

3)         外部状态相对独立,不影响内部状态

缺点

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

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

 

使用场景:内存属于稀缺资源,不要随便浪费,如果有很多个完全相同或相似的对象,我们可以通过享元模式节省内存。可以在任何“池”中操作,比如线程池,数据库池。

     String类的设计也是享元模式。

 

以上是关于设计模式--享元模式的主要内容,如果未能解决你的问题,请参考以下文章

设计模式课程 设计模式精讲 13-1 享元模式coding

常用设计模式系列之——享元模式

11-享元(Flyweight)模式Ruby实现

23种设计模式之享元模式代码实例

深入理解设计模式-享元模式

深入理解设计模式-享元模式