比如下五子棋,选手与选手之间通过“棋盘”交互的,而不是彼此之间直接交互。两个选手就是参与通信的角色,而棋盘就是中介者,它要记录选手共用的棋盘。代码如下:
package com.zhangxf.mediator;
import java.util.Scanner;
// 选手类
class Player {
private String name; // 选手名字
private char qiZi; // 选手棋子,用一个字符表示
private QiJu qiJu; // 选手参与的棋局,这个是选手的中介类实例
public Player(String name, char qiZi, QiJu qiJu) {
this.name = name;
this.qiZi = qiZi;
this.qiJu = qiJu;
}
// 选手下棋,什么也没有做,只是将自己当成参数,调用了中介类实例的一个方法
public boolean luoZi() {
return qiJu.setPositionValue(this);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getQiZi() {
return qiZi;
}
public void setQiZi(char qiZi) {
this.qiZi = qiZi;
}
}
// 棋局,中介类,参与选手通过棋局中介交互,相互之间并不直接交互
class QiJu {
private int width; // 棋盘宽度
private int height; // 期盼高度
char[][] qiPan; // 用字符类型的二维数组表示棋盘,如果字符为特殊符号'#'则表示空位
private int[] position = new int[2]; // 当前落子的位置
private Scanner sc = new Scanner(System.in); // 输入流
public QiJu(int width, int height) {
this.width = width;
this.height = height;
qiPan = new char[width][height];
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
qiPan[i][j] = '#';
}
}
}
// 显示当前棋局状态
public void display() {
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
if ((i == position[0]) && (j == position[1])) {
// 如果是刚刚落下的棋子,显示为大写字母,以标识落了位置
System.out.print(Character.toUpperCase(qiPan[i][j]));
} else {
System.out.print(Character.toLowerCase(qiPan[i][j]));
}
if ((j + 1) == width) {
System.out.println("");
} else {
System.out.print(" ");
}
}
}
}
// 中介,选手通过此方法下棋
public boolean setPositionValue(Player p) {
input(p);
if (isFull())
return true;
if (isWinner(p))
return true;
return false;
}
// 在四个方法上判断选手是否获胜
private boolean isWinner(Player p) {
boolean flag = false;
// 水平方向
int ref = position[0];
for (int i = 0; i <= width - 5; i++) {
int step = 0;
for (step = 0; step < 5; step++) {
if (Character.toLowerCase(qiPan[ref][i + step]) != Character.toLowerCase(p.getQiZi())) {
break;
}
}
if (step >= 5) {
flag = true;
System.out.println("chuizhi");
break;
}
}
if (!flag) {
// 垂直方向
ref = position[1];
for (int i = 0; i <= height - 5; i++) {
int step = 0;
for (step = 0; step < 5; step++) {
if (Character.toLowerCase(qiPan[i + step][ref]) != Character.toLowerCase(p.getQiZi())) {
break;
}
}
if (step >= 5) {
flag = true;
System.out.println("shuiping");
break;
}
}
}
if (!flag) {
// 两个斜线方向
}
if (flag == true) {
System.out.println("Finished: Winner is " + p.getName());
}
return flag;
}
// 判断当前棋局是否已经无处落子
private boolean isFull() {
boolean res = true;
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
if (qiPan[i][j] == '#')
res = false;
}
}
if (res) {
System.out.println("Finish:Dogfall");
}
return res;
}
// 处理选手输入
private void input(Player p) {
int x = 0;
int y = 0;
String input = null;
String[] temp = null;
while (true) {
System.out.print(p.getName() + " input:");
input = sc.nextLine();
temp = input.split(" ");
x = Integer.parseInt(temp[0]);
y = Integer.parseInt(temp[1]);
if ((x >= width) || (y >= height)) {
continue;
} else if (qiPan[x][y] != '#') {
continue;
} else {
qiPan[x][y] = Character.toLowerCase(p.getQiZi());
position[0] = x;
position[1] = y;
break;
}
}
display();
}
}
public class Wuziqi {
public static void main(String args[]) {
// 创建棋局
QiJu qiJu = new QiJu(10, 10);
qiJu.display();
// 创建两个选手,并关联棋局
Player black = new Player("Me", 'b', qiJu);
Player white = new Player("Your", 'w', qiJu);
// 开始下棋
System.out.println(black.getName() + "==========" + white.getName());
while (true) {
if (black.luoZi())
break;
if (white.luoZi())
break;
}
}
}
选手类的实现很简单,其主要逻辑是通过调用关联“中介者”的某个方法,并将自己也就是"this"指针传递给中介者“棋盘”。
主要逻辑都在“棋盘”类中实现,因为“棋盘”类连接着两个选手,只有它才知道怎么实现两个选手的交互。