享元模式

2018-09-19  本文已影响20人  sunhq
什么是享元

共享的方式高效的支持大量的细粒度对象,通过复用内存中已经存在的对象,降低系统创建对象实例的性能消耗。

享元的英文是Flyweight,是一个来自体育方面的专业术语,在拳击、摔跤和举重比赛中特指最轻量的级别。把这个单词移植到软件工程中,也是用来表示特别小的对象,即细粒度对象。

在享元模式中可以共享的相同内容称为内部状态(Intrinsic State),而那些需要外部环境来设置的不能共享的内容称为外部状态(Extrinsic State),其中外部状态和内部状态是相互独立的,外部状态的变化不会引起内部状态的变化。由于区分了内部状态和外部状态,因此可以通过设置不同的外部状态使得相同的对象可以具有一些不同的特征,而相同的内部状态是可以共享的。也就是说,享元模式的本质是分离与共享 : 分离变与不变,并且共享不变。把一个对象的状态分成内部状态和外部状态,内部状态即是不变的,外部状态是变化的;然后通过共享不变的部分,达到减少对象数量并节约内存的目的。

在享元模式中通常会出现工厂模式,需要创建一个享元工厂来负责维护一个享元池(Flyweight Pool)。

java中的String就是运用享元模式的一个例子,创建一个字符串对象,如果有就直接返回,如果没有就创建一个再返回。

String s1 = "hello world";
String s2 = "hello world";
s1 == s2
public interface Shape {

    void draw();
}

public class Circle implements Shape {

    //内部状态,
    private String color;
    //以下三个为外部状态
    private int x;
    private int y;
    private int radius;

    public Circle(String color){

        this.color = color;
    }

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

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

    public void setRadius(int radius){
        this.radius = radius;
    }

    @Override
    public void draw() {

        System.out.println("Circle:Color : " + color
                +", x : " + x +", y :" + y +", radius :" + radius);
    }
}
public class ShapeFactory {

    private static final HashMap<String,Shape> circleMap = new HashMap();

    public static Shape getCirCle(String color){

        Circle circle = (Circle) circleMap.get(color);
        if (circle == null){

            circle = new Circle(color);
            circleMap.put(color,circle);
            System.out.println("Creating circle of color:"+color);
        }

        return circle;
    }
}
public class Client {

    private static final String colors[] = {"Red", "Green", "Blue", "White", "Black"};

    public static void main(String[] args){

        for (int i = 0; i < 20; i++){

            Circle circle = (Circle) ShapeFactory.getCirCle(getRandomColor());
            circle.setX(getRandomX());
            circle.setY(getRandomY());
            circle.setRadius(100);
            circle.draw();
        }
    }

    private static String getRandomColor(){

        return colors[(int) (Math.random() * colors.length)];
    }

    private static int getRandomX(){

        return (int)Math.random() * 100;
    }

    private static int getRandomY(){

        return (int)Math.random() * 100;
    }

}
上一篇下一篇

猜你喜欢

热点阅读