软件设计实验13与14:享元模式、代理模式

[实验任务一]:围棋
设计一个围棋软件,在系统中只存在一个白棋对象和一个黑棋对象,但是它们可以在棋盘的不同位置显示多次。

1.提交类图;
2.提交源代码;
3.注意编程规范;
4.要求用简单工厂模式和单例模式实现享元工厂类的设计。

image

`
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周岁,婚介所会提示“对不起,不能早恋!”,并终止业务。
实验要求:

  1. 提交类图;
  2. 提交源代码;
  3. 注意编程规范。

image

`
// 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();
}
}
`

posted @ 2025-11-17 08:41  mwhB  阅读(24)  评论(0)    收藏  举报