Java享元模式

Java享元模式详解

介绍

享元模式是一种结构型设计模式,它通过共享相同对象来降低内存使用和对象创建的开销。

在Java中,享元模式通常用于管理大量的相似对象,以减少内存开销和提高性能。具体来说,享元模式使用工厂类来创建对象并在内部维护一个池(Pool),以便在需要时可以重复使用已经创建的对象,而不是每次都创建新的对象。

实现

在Java中,享元模式需要实现以下几个组件:

  • 享元工厂(Flyweight Factory):负责创建并管理享元对象,通常使用单例模式实现。
  • 抽象享元(Flyweight):定义享元对象的接口,包含所有可共享对象的方法。
  • 具体享元(Concrete Flyweight):实现抽象享元的接口,包含内部状态和可共享状态。
  • 非共享享元(Unshared Flyweight):不可以共享的享元对象。
  • 客户端(Client):请求享元工厂使用享元对象。

下面给出一个简单的Java代码示例来说明享元模式的实现方法。

首先定义抽象享元接口:

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

接着定义享元工厂:

import java.util.HashMap;

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);
    }
}

运行客户端代码,可以看到输出结果:

Creating circle of color : Black
Circle: Draw() [Color : Black, x : 1, y :69, radius :100
Creating circle of color : White
Circle: Draw() [Color : White, x : 94, y :97, radius :100
Creating circle of color : Green
Circle: Draw() [Color : Green, x : 67, y :42, radius :100
Creating circle of color : Blue
Circle: Draw() [Color : Blue, x : 4, y :77, radius :100
Creating circle of color : Red
Circle: Draw() [Color : Red, x : 28, y :18, radius :100
Circle: Draw() [Color : Black, x : 60, y :30, radius :100
Circle: Draw() [Color : White, x : 92, y :53, radius :100
Circle: Draw() [Color : Green, x : 11, y :78, radius :100
Circle: Draw() [Color : Blue, x : 96, y :14, radius :100
Circle: Draw() [Color : Red, x : 5, y :83, radius :100
Circle: Draw() [Color : Black, x : 2, y :66, radius :100
Circle: Draw() [Color : White, x : 63, y :74, radius :100
Circle: Draw() [Color : Green, x : 94, y :44, radius :100
Circle: Draw() [Color : Blue, x : 24, y :14, radius :100
Circle: Draw() [Color : Red, x : 25, y :67, radius :100
Circle: Draw() [Color : Black, x : 28, y :89, radius :100
Circle: Draw() [Color : White, x : 82, y :64, radius :100
Circle: Draw() [Color : Green, x : 3, y :57, radius :100
Circle: Draw() [Color : Blue, x : 89, y :60, radius :100
Circle: Draw() [Color : Red, x : 56, y :31, radius :100

可以看到,当多次请求相同颜色的圆形时,工厂只会创建一次圆形对象,并将其缓存到池中,下次请求时直接返回已有的对象,避免了重复创建对象的开销,提高了性能。

优缺点

优点:

  • 减少内存使用和对象创建的开销,提高性能。
  • 可以共享相同对象,避免了重复创建对象的开销。
  • 提高代码复用性。
  • 提高系统的可扩展性。

缺点:

  • 代码的逻辑复杂度增加,可能会对可读性和可维护性造成影响。适用场景
  • 享元模式适用于以下情况:

  • 系统中有大量相似的对象需要创建
  • 创建对象时大量使用内存资源
  • 对象的状态可以被共享,但其它部分必须独立
  • 对象的状态不会被改变

适用场景

享元模式适用于以下情况:

  • 系统中有大量相似的对象需要创建
  • 创建对象时大量使用内存资源
  • 对象的状态可以被共享,但其它部分必须独立
  • 对象的状态不会被改变

总结

享元模式是一种非常实用的设计模式,可以大幅降低系统开销,在处理需要大量相似对象时特别有用。在实际开发中,我们应该优先考虑使用享元模式来处理这种情况。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值