软件设计实验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  茆伟昊  阅读(2)  评论(0)    收藏  举报