使用享元模式设计一个围棋软件,在系统中只存在一个白棋对象和一个黑棋对象,但是它们可以在棋盘的不同位置显示多次。

类图:
image

代码:
import java.awt.Point;

// 棋子接口(享元接口)
interface ChessPiece {
// 获取棋子颜色
String getColor();
// 显示棋子(传入外在状态:位置)
void display(Point position);
}

// 黑棋实现类(单例)
class BlackChessPiece implements ChessPiece {

// 单例实例
private static BlackChessPiece instance;

// 私有构造器(防止外部实例化)
private BlackChessPiece() {}

// 静态方法获取单例
public static synchronized BlackChessPiece getInstance() {
if (instance == null) {
instance = new BlackChessPiece();
}
return instance;
}

@Override
public String getColor() {
return "黑色";
}

@Override
public void display(Point position) {
System.out.println("在位置 (" + position.x + "," + position.y + ") 显示" + getColor() + "棋子");
}
}

// 白棋实现类(单例)
class WhiteChessPiece implements ChessPiece {
// 单例实例
private static WhiteChessPiece instance;

// 私有构造器(防止外部实例化)
private WhiteChessPiece() {}

// 静态方法获取单例
public static synchronized WhiteChessPiece getInstance() {
if (instance == null) {
instance = new WhiteChessPiece();
}
return instance;
}

@Override
public String getColor() {
return "白色";
}

@Override
public void display(Point position) {
System.out.println("在位置 (" + position.x + "," + position.y + ") 显示" + getColor() + "棋子");
}
}

// 棋子工厂类(简单工厂模式 + 享元工厂)
class ChessPieceFactory {
// 根据颜色获取棋子实例(享元)
public static ChessPiece getChessPiece(String color) {
if ("黑色".equals(color)) {
return BlackChessPiece.getInstance(); // 返回黑棋单例
} else if ("白色".equals(color)) {
return WhiteChessPiece.getInstance(); // 返回白棋单例
} else {
throw new IllegalArgumentException("无效的棋子颜色");
}
}
}

// 测试类
public class GoChessGame {
public static void main(String[] args) {
// 从工厂获取棋子(实际是单例)
ChessPiece black1 = ChessPieceFactory.getChessPiece("黑色");
ChessPiece black2 = ChessPieceFactory.getChessPiece("黑色");
ChessPiece white1 = ChessPieceFactory.getChessPiece("白色");
ChessPiece white2 = ChessPieceFactory.getChessPiece("白色");

// 验证单例(同一颜色的棋子是同一个实例)
System.out.println("black1与black2是否为同一实例:" + (black1 == black2)); // true
System.out.println("white1与white2是否为同一实例:" + (white1 == white2)); // true

// 在不同位置显示棋子(传入外在状态)
black1.display(new Point(3, 3));
black2.display(new Point(5, 5)); // 复用黑棋实例,显示在新位置
white1.display(new Point(4, 4));
white2.display(new Point(6, 6)); // 复用白棋实例,显示在新位置
}
}

posted on 2025-11-20 08:18  -MARIO  阅读(7)  评论(0)    收藏  举报