23种设计模式之享元模式(Flyweight Pattern)

享元模式概念

享元模式(Flyweight Pattern)是一种结构型设计模式,旨在减少对象的数量,以节省内存空间和提高性能。它通过共享相同或相似状态的多个对象来减少对象的数量。享元模式通常用于大量创建细粒度对象的场景。

享元模式使用场景

在享元模式中,我们创建一个工厂类(Flyweight Factory),该工厂类对外提供获取享元对象的方法。享元对象包含两部分属性:内部状态(Intrinsic State)和外部状态(Extrinsic State)。内部状态指不随外界环境改变而改变的共享部分,外部状态指随着环境的改变而改变的部分。

当客户端需要一个享元对象时,它向工厂类请求一个对象,工厂类会首先查询对象池中是否已经有该对象的实例。如果有,就直接返回对象池中的实例;如果没有,则创建一个新的实例并将其放入对象池中,同时返回给客户端。

享元模式优缺点

享元模式的优点在于,它可以大大减少系统中对象的数量,从而提高系统的性能和内存利用率。它也可以使得代码更加简洁,易于维护和扩展。

但是,享元模式也有一些缺点,在某些情况下,它可能会牺牲部分内存以换取性能的提升。同时,由于享元对象通常是不可变的对象,因此可能会对系统中的某些业务逻辑造成影响。

享元模式代码案例

下面以一个具体例子,比如制作黑白棋游戏来进一步说明:

对于黑白棋这个游戏来说,我们需要大量的棋子对象,如果为每一个棋子都单独创建一个对象,那么系统的性能和内存开销都会非常大。而使用享元模式,我们可以将一些相同的棋子对象共享起来,只需要保存其内部和外部状态区分即可。例如,黑方和白方用不同颜色的棋子,但同一颜色的棋子之间是可以互相替换的。

定义棋子类Piece

public interface Piece {
    void put(int x, int y);
}

public class BlackPiece implements Piece {
    @Override
    public void put(int x, int y) {
        System.out.println("在坐标 (" + x + ", " + y + ") 放置了一个黑棋子");
    }
}

public class WhitePiece implements Piece {
    @Override
    public void put(int x, int y) {
        System.out.println("在坐标 (" + x + ", " + y + ") 放置了一个白棋子");
    }
}

以上代码实现了两个具体的棋子类:BlackPiece 和 WhitePiece。它们都实现了 Piece 接口,并重写了其中的 put() 方法,用于在指定坐标放棋子。

实现享元工厂类PieceFactory

import java.util.HashMap;
import java.util.Map;

public class PieceFactory {
    private final Map<String, Piece> map = new HashMap<>();

    public Piece getPiece(String color) {
        Piece piece = map.get(color);

        if (piece == null) {
            switch (color) {
                case "black":
                    piece = new BlackPiece();
                    break;
                case "white":
                    piece = new WhitePiece();
                    break;
                default:
                    throw new IllegalArgumentException("Unsupported color: " + color);
            }
            map.put(color, piece);
        }

        return piece;
    }
}

以上代码实现了一个操作棋子对象的共享工厂PieceFactory,其中使用了HashMap来保存已经创建过的棋子对象。直接调用getPiece()方法即可根据颜色获取相应的棋子对象。如果该颜色的棋子对象不存在,则创建一个新的棋子对象并存入map中,否则直接从map中获取棋子对象。

在客户端中使用享元模式

public class Client {
    public static void main(String[] args) {
        PieceFactory factory = new PieceFactory();
        Piece black1 = factory.getPiece("black");
        black1.put(1, 1);
        Piece black2 = factory.getPiece("black");
        black2.put(2, 2);
        Piece white1 = factory.getPiece("white");
        white1.put(3, 3);
        Piece white2 = factory.getPiece("white");
        white2.put(4, 4);
    }
}

在上面的代码中,我们可以看到一个完整的享元模式实现。在客户端中,我们只需要获取工厂类中提供的共享对象即可,通过调用 put() 方法来为棋子设置坐标。

通过以上例子,我们可以看出享元模式的优点:它大幅度减少内存占用并提高了系统性能,对于类似的大量重复对象的场景非常友好

好了,本篇文章就先分享到这里了,后续将会继续介绍23种设计模式之其他模式,感谢大佬认真读完支持咯~

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYbld98a' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片