软件设计实验13与14:享元模式、代理模式
[实验任务一]:围棋
设计一个围棋软件,在系统中只存在一个白棋对象和一个黑棋对象,但是它们可以在棋盘的不同位置显示多次。
1.提交类图;
2.提交源代码;
3.注意编程规范;
4.要求用简单工厂模式和单例模式实现享元工厂类的设计。

`
import java.util.*;
/**
-
围棋游戏(享元模式单文件实现)
-
使用内部类将所有组件封装在一个类中
*/
public class GoGame {// ========== 1. 外部状态类 ==========
public static class Position {
private final int x, y;
public Position(int x, int y) { this.x = x; this.y = y; }
public int getX() { return x; }
public int getY() { return y; }
@Override
public String toString() { return "(" + x + "," + y + ")"; }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Position)) return false;
Position p = (Position) o;
return x == p.x && y == p.y;
}
@Override
public int hashCode() {
return Objects.hash(x, y);
}
}// ========== 2. 抽象享元类 ==========
public abstract static class ChessPiece {
protected String color;
protected ChessPiece(String color) { this.color = color; }
public abstract void display(Position pos);
public String getColor() { return color; }
}// ========== 3. 具体享元类 ==========
public static class WhitePiece extends ChessPiece {
public WhitePiece() { super("白色"); }
@Override
public void display(Position pos) {
System.out.println("在" + pos + "放置" + color + "棋");
}
}public static class BlackPiece extends ChessPiece {
public BlackPiece() { super("黑色"); }
@Override
public void display(Position pos) {
System.out.println("在" + pos + "放置" + color + "棋");
}
}// ========== 4. 享元工厂 ==========
public static class ChessPieceFactory {
private static final Map<String, ChessPiece> pieces = new HashMap<>();public static synchronized ChessPiece getPiece(String color) { if (!pieces.containsKey(color)) { if ("黑色".equals(color)) { pieces.put(color, new BlackPiece()); } else if ("白色".equals(color)) { pieces.put(color, new WhitePiece()); } else { throw new IllegalArgumentException("无效颜色: " + color); } System.out.println("创建新的" + color + "棋子对象"); } return pieces.get(color); } public static int getPieceCount() { return pieces.size(); }}
// ========== 5. 客户端类 ==========
public static class GoBoard {
private final Map<Position, ChessPiece> board = new HashMap<>();public void placePiece(String color, int x, int y) { ChessPiece piece = ChessPieceFactory.getPiece(color); Position pos = new Position(x, y); board.put(pos, piece); piece.display(pos); } public void displayBoard() { System.out.println("\n--- 棋盘状态 ---"); board.forEach((pos, piece) -> System.out.println(piece.getColor() + "棋位于" + pos)); System.out.println("共享对象数: " + ChessPieceFactory.getPieceCount()); System.out.println("棋盘棋子数: " + board.size()); }}
// ========== 测试方法 ==========
public static void main(String[] args) {
System.out.println("===== 享元模式测试 =====\n");
GoBoard board = new GoBoard();// 放置棋子 board.placePiece("黑色", 3, 3); board.placePiece("白色", 3, 4); board.placePiece("黑色", 4, 4); board.placePiece("白色", 4, 3); board.placePiece("黑色", 5, 5); board.placePiece("白色", 5, 6); // 显示结果 board.displayBoard(); // 验证共享 System.out.println("\n--- 对象共享验证 ---"); System.out.println("黑棋对象数量: 1"); System.out.println("白棋对象数量: 1");}
}
`
实验14:代理模式
本次实验属于模仿型实验,通过本次实验学生将掌握以下内容:
1、理解代理模式的动机,掌握该模式的结构;
2、能够利用代理模式解决实际问题。
[实验任务一]:婚介所
婚介所其实就是找对象的一个代理,请仿照我们的课堂例子“论坛权限控制代理”完成这个实际问题,其中如果年纪小于18周岁,婚介所会提示“对不起,不能早恋!”,并终止业务。
实验要求:
- 提交类图;
- 提交源代码;
- 注意编程规范。

`
// MarriageService.java
// 婚姻服务接口
interface MarriageService {
void findPartner();
}
// RealCustomer.java
// 真实客户类
class RealCustomer implements MarriageService {
private String name;
private int age;
public RealCustomer(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public void findPartner() {
System.out.println(name + "正在寻找合适的伴侣...");
}
// Getter 方法
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
// MarriageAgencyProxy.java
// 婚介所代理类
class MarriageAgencyProxy implements MarriageService {
private MarriageService customer;
public MarriageAgencyProxy(MarriageService customer) {
this.customer = customer;
}
@Override
public void findPartner() {
if (checkAge()) {
System.out.println("婚介所开始为您服务...");
customer.findPartner();
System.out.println("婚介所服务完成!");
} else {
System.out.println("对不起,不能早恋!");
}
}
private boolean checkAge() {
// 检查年龄是否满18岁
if (customer instanceof RealCustomer) {
RealCustomer realCustomer = (RealCustomer) customer;
return realCustomer.getAge() >= 18;
}
return false;
}
}
// Client.java
// 客户端测试类
public class ProxyPatternDemo {
public static void main(String[] args) {
// 测试案例1:成年人使用婚介所服务
System.out.println("=== 案例1:成年人 ===");
MarriageService adult = new RealCustomer("张三", 25);
MarriageService agency1 = new MarriageAgencyProxy(adult);
agency1.findPartner();
System.out.println("\n=== 案例2:未成年人 ===");
// 测试案例2:未成年人使用婚介所服务
MarriageService minor = new RealCustomer("李四", 16);
MarriageService agency2 = new MarriageAgencyProxy(minor);
agency2.findPartner();
System.out.println("\n=== 案例3:边界测试 ===");
// 测试案例3:刚好18岁
MarriageService justAdult = new RealCustomer("王五", 18);
MarriageService agency3 = new MarriageAgencyProxy(justAdult);
agency3.findPartner();
}
}
`
浙公网安备 33010602011771号