享元模式(Flyweight Pattern)

高效飞快地生成类的实例以提高性能称为享元模式。它是结构设计模式之一,常常被使用在独特的字符或是屏幕上的图标等。

使用场合和优势:

  1. 需要实例化大量小型且可以很好颗粒化的类。
  2. 需要图标来展示对象。
  3. 一个对象外部的状态能够通过类来共享。
  4. 享元模式减少了对象的创建,降低了内存的花费和提升了性能。
相关的模式:
  1. 组合模式支持迭代的结构而一个享元仅仅被应用到一个对象。
  2. 抽象工厂模式基于方法的集合去产生具体的对象而一个享元则是使用它来减少对象的创建。
  3. 策略模式允许一个独立变化的算法去适合它的需要而一个享元是基于这样的一个策略而已。
下面,我们结合工厂模式来写一个简单的示例程序。
我们扩展了java GUI API,在window面板上绘制小的圆圈。通过使用享元模式,大大提高了程序的性能。
public class Flyweight extends JFrame{
    //define the color array
    private static final Color colors[] = {
               Color.red, Color.green, Color.blue,
               Color.black, Color.gray, Color.orange
    };
    private static final int WIDTH = 400,
                             HEIGHT = 400,
                             NUMBER_OF_CIRCLES = 1000;
    Flyweight(){
        Container container = this.getContentPane();

        Button button = new Button("Draw Circle");
        final JPanel panel = new JPanel();

        //add the components to the container
        container.add(panel, BorderLayout.CENTER);
        container.add(button, BorderLayout.SOUTH);
        //set the properties of JFrame
        this.setSize(WIDTH, HEIGHT);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);

        //add the listener
        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Graphics g = panel.getGraphics();
                for(int i = 0; i < NUMBER_OF_CIRCLES; i++){
                    Circle c= CircleFactory.getInstance(getRandomColor());
                    c.draw(g, getRandomX(), getRandomY(), getRandomR());
                    //Since we have 6 different colors, we have 6 objects created.
                }
            }
        });

    }
    private int getRandomX(){
        return (int)(Math.random()*WIDTH);
    }
    private int getRandomY(){
        return (int)(Math.random()*HEIGHT);
    }
    private int getRandomR(){
        return (int) (Math.random()*(HEIGHT/10));
    }

    //get the random color
    private Color getRandomColor(){
        return colors[(int)(Math.random()*(colors.length))];
    }
   //text the case
    public static void main(String []args){
        new Flyweight();
/**
        String s1 = "hello";
        String s2 = "hello"; //store in a string pool.
        String s3 = new String("hello");

        System.out.println(s1==s2); //true, share the same memmory address
        System.out.println(s1==s3); //false
* */ }}
 
 
 
 

 在面板上绘制1000个圆圈,采用工厂设计模式, CircleFactory代码如下:
 
 
 
 
 
 
 
public class CircleFactory {

	private static final Hashtable<Color, Circle> circleByColor = new Hashtable<Color, Circle>();

	public static Circle getInstance(Color color) {
		Circle circle = (Circle) circleByColor.get(color);
		if (circle == null) {
			circle = new Circle(color);
			circleByColor.put(color, circle);
			System.out.println("---------create " + circle + " color");
		}
		return circle;
	}

}

public class Circle {
    private Color color;

    Circle(Color color){
        this.color = color;
    }

    public void draw(Graphics g, int a, int b, int r){
        g.setColor(color);
        g.drawOval(a, b, r, r);
    }
}


运行结果:


细心的朋友一定会注意到最后段注释了代码,说的也是享元的是。String类是采用了享元设计模式。当你创建一个字符串常量时,这样的常量会存储在一个池中。当第二个string被创建时,它将会检测这个常量是否以前创建过。如果string池中有这个常量,它将直接采用这个池中的常量而不会再创建。
        String s1 = "hello";
        String s2 = "hello"; //store in a string pool.
        String s3 = new String("hello");

        System.out.println(s1==s2); //true, share the same memmory address
        System.out.println(s1==s3); //false

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值