设计模式系列——享元模式

101 阅读2分钟

原创:花括号MC(微信公众号:huakuohao-mc),欢迎分享,转载请保留出处。

享元模式,就是共享原型的模式。充分共享已有的对象,而不是每次都创建新的对象。享元模式可以有效的降低对象数量,节省内存,提高效率。

举个例子

我们创建20个不同位置,五种不同颜色的圆形。按照享元模式的设计思想我们只需要创建五种不同颜色的圆形对象就OK了,而不是20个。主要实现思路是准备一个HashMap,颜色作为Key值,Value值为Circle对象。每次创建Circle对象时,先判断HashMap中是否存在对应颜色的对象,如果存在则直接使用,不存在则创建新的对象,并存储到HashMap中。

先来看一下UML图:

flyweight.png

再来看一下具体代码实现。

先定义一个Shape接口

public interface Shape {
   void draw();
}

定义具体实现类CIrcle

public class Circle implements Shape {

    private String color;
    private int x,y,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: Draw() [Color : " + color + ", x : " + x + ", y :" + y + ", radius :" + radius);
    }
}

定义一个工厂类,通过工厂类实现CIrcle的创建,工厂类里面有个HashMap容器,用来存储创建好的不同颜色的Circle对象

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 FlyweightPatternDemo {

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

    public static void main(String[] args){
        for (int i = 0; i < 20; i++){
            //享元模式的体现,并没有创建20个Circle对象。
            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);
    }
}

总结

享元模式是结构型模式之一,其核心思想是尽可能的复用已有的对象,对于创建复杂对象可以节省很多系统资源。同时要控制享元对象的数量,如果数量太大就得不偿失了,因为大量的享元对象也会占用内存空间。

本文参考 www.tutorialspoint.com/design_patt…

推荐阅读

1. Java并发编程那些事儿(十)——最后的总结

2. 程序员应该掌握的常用网络问题定位工具

3. Awk这件上古神兵你会用了吗

4. 手把手教你搭建一套ELK日志搜索运维平台