享元模式flyweight

Posted 碎格子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了享元模式flyweight相关的知识,希望对你有一定的参考价值。

  • 享元模式属于结构型模式。

  • 享元模式是池技术的重要实现方式,它可以减少重复对象的创建,使用缓存来共享对象,从而降低内存的使用。

  • 细粒度的对象其状态可以分为两种:内部状态和外部状态。

应用场景
  • 系统存在大量相似或相同的对象。

  • 外部状态相同类似情况下。

  • 需要缓冲池时。

下面将由一个例子讲解享元模式的创建和使用:

假设我们有一个系统需要实现图形的绘制,通过形状划分,所有图形都可以实现绘制颜色的功能。这里形状是图形的内部状态,颜色是图形的外部状态,内部状态是不受外界条件影响而改变。

如果我要绘制白色的圆形,黑色的方形,红色的圆形,这个时候就可以使用享元模式,圆形共享一个对象,方形共享一个对象。

角色说明:
  • Flyweight --> IShape(抽象享元角色):接口或抽象类,可以同时定义出对象的外部状态和内部状态的接口或实现。

  • ConcreteFlyweight --> Circle,Rectangle(具体享元角色):实现抽象享元角色中定义的业务。

  • FlyweightFactory --> ShapeFactory(享元工厂):管理对象池和创建享元对象。

定义图形接口:

public interface IShape 
    void draw(String color);

圆形实现接口,实现圆形的绘制方法:

public class Circle implements IShape 
    String mShapeName = "圆形";

    @Override
    public void draw(String color) 
        System.out.println("绘制" + mShapeName + ": " + color);
    

方形实现接口,实现方形的绘制方法:

public class Rectangle implements IShape 
    String mShapeName = "方形";

    @Override
    public void draw(String color) 
        System.out.println("绘制" + mShapeName + ": " + color);
    

定义一个工厂类,创建缓存池和对应图形对象:

public class ShapeFactory 
    private Map<String, IShape> mShapeMap = new HashMap<>();

    public IShape getShape(Class<?> clazz) 
        IShape iShape = mShapeMap.get(clazz.getCanonicalName());
        if (iShape == null) 
            if (clazz == Circle.class) 
                System.out.println("创建Circle...");
                iShape = new Circle();
             else if (clazz == Rectangle.class) 
                System.out.println("创建Rectangle...");
                iShape = new Rectangle();
            
            mShapeMap.put(clazz.getCanonicalName(), iShape);
        
        return iShape;
    

具体调用:

public class TestMain 
    public static void main(String[] args) 
        ShapeFactory factory = new ShapeFactory();
        IShape circle = factory.getShape(Circle.class);
        circle.draw("white");
        IShape rectangle = factory.getShape(Rectangle.class);
        rectangle.draw("black");
        IShape circle2 = factory.getShape(Circle.class);
        circle2.draw("red");

        System.out.println("circle:" + circle.hashCode() + " rectangle:" + rectangle.hashCode() + " circle2:" + circle2.hashCode());
    

可以看到circle和circle2的hashCode一致,说明他们指向了同一块内存空间,而rectangle是单独的hashCode。

其实还有一个例子也可以设计成享元模式:黑白棋。这个大家可以自己理解下~

优点:
  • 有共用数据不想多次创建时,可以实现对象共享,减少内存开销。

缺点:
  • 设计复杂,要区分内部状态和外部状态

android中的享元模式:
  • String类:

String s1 = "abc";
String s2 = "abc";

print(s1 == s2)  //这里s1和s2指向同一个引用,打印true
思考:

其实写到这里我有了一个疑问,享元模式是不是就是单例模式+工厂模式?

欢迎大家赐教~

以上是关于享元模式flyweight的主要内容,如果未能解决你的问题,请参考以下文章

设计模式(十三)——享元模式

设计模式---享元模式

设计模式之享元模式与组合模式详解和应用

享元模式

享元模式(Flyweight)

结构型模式 享元模式