设计模式(结构型模式)享元模式

目录

    • 一、简介
    • 二、享元模式
      • 2.1、棋子类
      • 2.2、棋子工厂类
      • 2.3、棋子类
    • 三、优点与缺点

一、简介

  享元模式是一种结构型设计模式,旨在通过共享对象来最大程度地减少内存使用和提高性能。它主要用于减少创建对象的数量,节省内存和提高性能。

  该模式通过共享相似对象之间的公共部分来减少内存占用。当需要创建大量相似对象时,通过重用已存在的相似对象,而不是每次都新建一个对象来节省内存。这个被共享的对象称为享元(Flyweight),包含了对象的共享状态和非共享状态。共享状态是可以被多个对象共享的部分,而非共享状态是对象独有的部分。

  通过分离内部状态(不变且可共享)和外部状态(变化且不可共享),享元模式允许在运行时共享许多细粒度对象,从而提高系统的性能和效率。典型的例子是文本编辑器中的字符对象,大量的字符对象在外观上是相似的,例如,大写字母 “A” 的字形和颜色通常是相同的,所以可以使用享元模式来共享这些共同的特性,从而节省内存。

二、享元模式

  当涉及中国象棋时,可以使用享元模式来模拟棋子。每个棋子(如将、车、马等)都有自己的共享属性(例如颜色、类型),而位置是每个棋子独有的非共享属性。

2.1、棋子类

  首先,定义棋子类 ChessPiece:

// 棋子类
public class ChessPiece {
    private String type; // 共享属性 - 棋子类型
    private String color; // 共享属性 - 棋子颜色
    private int x, y; // 非共享属性 - 棋子位置

    public ChessPiece(String color, String type) {
        this.type = type;
        this.color = color;
        this.x = 0; // 默认位置
        this.y = 0;
    }

    public void setPosition(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public void display() {
        System.out.println("象棋: " + color + " " + type + " 的位置 (" + x + ", " + y + ")");
    }
}

2.2、棋子工厂类

  然后,创建一个工厂类 ChessPieceFactory 来管理棋子的共享:

// 棋子工厂类
public class ChessPieceFactory {
    private static final Map<String, ChessPiece> pieces = new HashMap<>();

    public static ChessPiece getChessPiece(String color, String type) {
        String key = color + "_" + type;
        if (!pieces.containsKey(key)) {
            pieces.put(key, new ChessPiece(color, type));
        }
        return pieces.get(key);
    }
}

2.3、棋子类

  接下来,使用示例:

public class FlyweightChessDemo {

    public static void main(String[] args) {
        ChessPiece piece1 = ChessPieceFactory.getChessPiece("红", "炮");
        piece1.setPosition(0, 3);
        piece1.display();

        ChessPiece piece2 = ChessPieceFactory.getChessPiece("红", "车");
        piece2.setPosition(1, 3);
        piece2.display();

        ChessPiece piece3 = ChessPieceFactory.getChessPiece("黑", "马");
        piece3.setPosition(0, 6);
        piece3.display();

        ChessPiece piece4 = ChessPieceFactory.getChessPiece("黑", "卒");
        piece4.setPosition(3, 5);
        piece4.display();
    }
}

运行结果:

象棋: 红 炮 的位置 (0, 3)
象棋: 红 车 的位置 (1, 3)
象棋: 黑 马 的位置 (0, 6)
象棋: 黑 卒 的位置 (3, 5)

  在这个例子中,ChessPieceFactory 管理着共享的棋子对象。当需要创建棋子时,首先检查该类型和颜色的棋子是否已经存在,如果存在则直接返回已存在的棋子对象,否则创建新的棋子对象。这样可以实现共享相同类型和颜色的棋子,减少了棋子对象的创建数量,节省了内存空间。

三、优点与缺点

  享元模式的优点和缺点如下所示:

优点:

  • 减少内存消耗: 通过共享相似对象的公共部分来减少内存消耗。对于大量相似对象,可以显著减少所需内存。
  • 提高性能: 通过重用已存在的享元对象,避免了频繁创建和销毁对象,从而提高了系统的性能和效率。
  • 降低系统复杂度: 享元模式将对象的状态分为内部状态和外部状态,使得系统更加简单和易于管理。

缺点:

  • 可能引入复杂性: 实现享元模式需要对对象的内部状态和外部状态进行分离,可能会引入额外的复杂性,使得代码变得复杂难懂。
  • 限制共享对象的可变性: 由于共享的对象通常具有不可变性,因此共享对象的修改可能会影响到其他对象,需要慎重考虑对象的可变性。
  • 可能降低单个对象的独立性: 对象的部分状态变为共享状态,可能降低单个对象的独立性,需要根据实际情况进行权衡。

  综上所述,享元模式在合适的场景下能够显著减少内存消耗和提高性能,但需要注意在设计和实现时平衡可维护性和复杂性,避免引入过多的共享状态以及可能导致的对象状态不一致问题。

你可能感兴趣的:(设计模式,设计模式,享元模式)