设计模式(22)-享元模式

定义
对象的属性通常有共享属性(如岗位,等级,部门)和个性属性(如姓名,id)之分,共享属性的值往往是可以列举出或可预估数量的.为避免对象的大量重复创建造成内存资源的浪费,通可将共享属性单独抽离成对象,而个性属性作为方法中的参数传入.这就是享元模式.

注:设计模式之禅中的举例并不合适,将共享属性和个性属性封装在同一个对象中,一旦对象发生个性属性的set操作,则必然全局可见,发生线程安全问题.

注:从全局map中取出的对象必然是全局共有,所有线程通过get取出的对象为同一个对象.

实例
享元模式应用很常见,如Java中的字符串对象即为享元对象,文档中的字母亦为享元对象.

1.接口

public interface Shape {
    public void draw(int x,int y,int r);
}

2.享元对象

public class Circle implements Shape{
    //正常考虑下,x坐标,y坐标,r半径都是属性,而享元模式中只将值有限的颜色作为属性
    private final String color; //颜色

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

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


    @Override
    public void draw(int x,int y,int r) {
        System.out.println("绘制圆形:颜色为"+color+",x坐标为"+x+",y坐标为"+y+"半径为"+r);
    }
}

3.享元工厂

public class CircleFlyweightFactory {
    //将颜色属性作为key,具体对象作为value
    private final static HashMap<String,Circle> flyweights = new HashMap<String,Circle>();

    public static Circle getCircle(String color){
        Circle circle = null;
        //双重校验,如果对象已存在直接返回对象,如果对象为空,进入同步块再次严谨判定.
        if(flyweights.containsKey(color)){
            circle = flyweights.get(color);
        }else{
            synchronized(CircleFlyweightFactory.class){
                if(!flyweights.containsKey(color)){
                    circle = new Circle(color);
                    flyweights.put(color, circle);
                }
            }
        }
        return circle;
    }
}

4.运行

public class Client {
    public static void main(String[] args) {
        Random random = new Random();
        String[] colors = {"红色","黄色","蓝色"};
        for(int i=0;i<20;i++){
            Shape circle = CircleFlyweightFactory.getCircle(colors[random.nextInt(3)]);
            circle.draw(random.nextInt(100), random.nextInt(100), random.nextInt(100));
        }
    }
}

结果:

绘制圆形:颜色为黄色,x坐标为4,y坐标为51,半径为79
绘制圆形:颜色为蓝色,x坐标为44,y坐标为72,半径为36
绘制圆形:颜色为蓝色,x坐标为63,y坐标为10,半径为3
绘制圆形:颜色为红色,x坐标为42,y坐标为25,半径为60
绘制圆形:颜色为蓝色,x坐标为92,y坐标为16,半径为71
绘制圆形:颜色为黄色,x坐标为28,y坐标为61,半径为50
绘制圆形:颜色为红色,x坐标为68,y坐标为28,半径为94
绘制圆形:颜色为黄色,x坐标为89,y坐标为4,半径为35
绘制圆形:颜色为蓝色,x坐标为24,y坐标为46,半径为9
绘制圆形:颜色为蓝色,x坐标为81,y坐标为56,半径为29
绘制圆形:颜色为红色,x坐标为39,y坐标为71,半径为25
绘制圆形:颜色为蓝色,x坐标为52,y坐标为74,半径为13
绘制圆形:颜色为蓝色,x坐标为59,y坐标为6,半径为3
绘制圆形:颜色为黄色,x坐标为27,y坐标为90,半径为22
绘制圆形:颜色为红色,x坐标为50,y坐标为44,半径为87
绘制圆形:颜色为黄色,x坐标为63,y坐标为83,半径为89
绘制圆形:颜色为红色,x坐标为70,y坐标为80,半径为52
绘制圆形:颜色为黄色,x坐标为83,y坐标为80,半径为44
绘制圆形:颜色为红色,x坐标为11,y坐标为48,半径为52
绘制圆形:颜色为红色,x坐标为31,y坐标为48,半径为9

猜你喜欢

转载自blog.csdn.net/chixiaoen/article/details/79541785