设计模式——享元模式

享元模式一般是使某个类的一个实例,提供许多虚拟实例的一种实现!Java String类型就实现了享元模式!

享元模式是为数不多的为提升性能而设计的模式!

享元模式的享元对象中的数据区分了内部状态和外部状态

内部状态:在享元对象中,不随外界环境改变而改变的共享部分的数据;

外部状态:在享元对象中,随着外界环境改变而改变的数据,不同虚拟对象不能共享!外部状态一般是在接口中,作为参数传入的!

享元模式中,一般包含如下几种角色:

抽象享元对象,规定了享元对象需要实现的接口;

具体享元角色,实现抽象享元对象规定的接口,一般由内部状态和外部状态两个维度!

享元工厂类,被客户端直接调用,一般包含一个容器用于存储已存在的享元对象,享元工厂类一般是单例模式

需要注意的是,客户端不可以直接创建享元对象,只能通过享元工厂获取享元对象!

 下面看一下具体实现:

首先定义抽象接口

/*
 * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved
 */

package com.pt.flyweight;

/**
 * @description
 * @author panteng
 * @date 17-2-20.
 */
public interface SnowDraw {
    void draw(int posX, int posY);
}
SnowDraw


定义具体的享元类

/*
 * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved
 */

package com.pt.flyweight;

/**
 * @description
 * @author panteng
 * @date 17-2-20.
 */
public class Snow implements SnowDraw {
    String size;
    public Snow(){
    }

    public Snow(String inSize){
        this.size = inSize;
    }

    public void draw(int posX, int posY){
        System.out.println("大小:" + this.size + " 位置:" + posX + "," + posY);
    }

    public String getSize(){
        return size;
    }
    public void setSize(String size){
        this.size = size;
    }
}
Snow

享元工厂类

/*
 * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved
 */

package com.pt.flyweight;

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

/**
 * @description 享元工厂类(单例)
 * @author panteng
 * @date 17-2-20.
 */
public class SnowFlyWeightFactory {
    static Map<Object, Snow> map = new HashMap<Object, Snow>();
    private static SnowFlyWeightFactory singleSnowFlyWeightFactory;

    private SnowFlyWeightFactory(){
    }

    public static SnowFlyWeightFactory getInstance(){
        if (singleSnowFlyWeightFactory == null) {
            synchronized (SnowFlyWeightFactory.class) {
                singleSnowFlyWeightFactory = new SnowFlyWeightFactory();
            }
        }
        return singleSnowFlyWeightFactory;
    }

    public Snow getSnow(String color){
        if (map.keySet().contains(color)) {
            return map.get(color);
        } else {
            Snow snow = new Snow(color);
            map.put(color, snow);
            return snow;
        }
    }

    public static long getSize(){
        return map.keySet().size();
    }
}
SnowFlyWeightFactory

测试:

/*
 * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved
 */

package com.pt.flyweight;

import org.junit.Test;

import java.util.Random;

/**
 * @description
 * @author panteng
 * @date 17-2-20.
 */
public class SnowFlyWeightFactoryTest {
    @Test
    public void flyWeightTest(){
        Snow[] snows = new Snow[20];
        for (int i = 0; i < snows.length; i++) {
            snows[i] = SnowFlyWeightFactory.getInstance().getSnow(new Random().nextInt(10) + "");
        }

        for (int i = 0; i < snows.length; i++) {
            snows[i].draw(new Random().nextInt(9999), new Random().nextInt(9999));
        }

        System.out.println("一共有:" + SnowFlyWeightFactory.getSize() + "个对象");

    }
}
SnowFlyWeightFactoryTest

 

外部状态是通过接口注入,然后和内部状态聚合的!

当有系统中需要大量对象,而这些对象的某些部分可以共享,这时候可以使用享元模式,节省内存!

 

===========================设计模式系列文章=========================

简单工厂模式

工厂方法模式

抽象工厂模式

建造者模式

原型模式

适配器模式

桥接模式

装饰模式

代理模式

组合模式

门面模式

享元模式

责任链模式

命令模式

中介者模式

备忘录模式

观察者模式

状态模式

策略模式

模板方法模式

访问者模式

posted @ 2017-02-20 11:41  沙中世界  阅读(247)  评论(0编辑  收藏  举报