Appearance
外观模式
定义
外观模式(Facade Pattern)定义了一个高层接口,这个接口使得子系统更易于使用。外观模式通过提供一个统一的接口,隐藏了子系统的复杂性,使得客户端可以更简单地与系统交互。
适用场景
- 当系统中有多个复杂的子系统时,可以使用外观模式来提供一个简单的接口,使得客户端可以更简单地与系统交互。
- 当系统需要对外提供一个统一的接口,而内部子系统复杂多变时,可以使用外观模式来隐藏子系统的复杂性。
优点
- 简化了客户端与子系统的交互,使得客户端可以更简单地与系统交互。
- 隐藏了子系统的复杂性,使得系统更易于维护和扩展。
- 提高了系统的可扩展性,可以在不修改外观类的情况下,增加新的子系统。
缺点
- 增加了类的数量,可能会使系统变得复杂。
- 如果子系统发生变化,可能需要修改外观类,这可能会影响到客户端的代码。
代码示例
这里写一个游戏内有多个模块:副本、拍卖行、PK场,玩家进入游戏大厅,可以进入不同模块。
副本
java
public class DungeonSystem {
private boolean running;
public void play() {
running = true;
System.out.println("使用副本模块,下副本战斗...");
}
public void stop() {
if (running) {
running = false;
System.out.println("副本战斗结束,返回游戏大厅");
}
}
}
拍卖行
java
public class AuctionHouse {
private boolean running;
public void play() {
running = true;
System.out.println("拍卖行参与拍卖...");
}
public void stop() {
if (running) {
// 执行一些停止操作
running = false;
System.out.println("退出拍卖行,返回游戏大厅");
}
}
}
PK场
java
public class FightSystem {
private boolean running;
public void play() {
running = true;
System.out.println("PK场战斗中...");
}
public void stop() {
if (running) {
running = false;
System.out.println("停止PK,返回游戏大厅");
}
}
}
游戏大厅
java
public class GameLobby {
private AuctionHouse auctionHouse;
private DungeonSystem dungeonSystem;
private FightSystem fightSystem;
public GameLobby() {
auctionHouse = new AuctionHouse();
dungeonSystem = new DungeonSystem();
fightSystem = new FightSystem();
}
public void pk() {
auctionHouse.stop();
dungeonSystem.stop();
fightSystem.play();
}
public void dungeon() {
auctionHouse.stop();
fightSystem.stop();
dungeonSystem.play();
}
public void auction() {
dungeonSystem.stop();
fightSystem.stop();
auctionHouse.play();
}
public synchronized void play() {
Random random = new Random();
int i = random.nextInt(3);
switch (i) {
case 0:
auction();
break;
case 1:
pk();
break;
case 2:
default:
// 默认玩法
dungeon();
break;
}
}
}
使用
java
public class Client {
public static void main(String[] args) {
GameLobby gameLobby = new GameLobby();
gameLobby.pk();
gameLobby.auction();
gameLobby.dungeon();
// 玩10秒钟
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
ScheduledFuture<?> future = executorService.scheduleAtFixedRate(gameLobby::play, 0, 200, TimeUnit.MILLISECONDS);
// 10秒后结束
executorService.schedule(() -> future.cancel(false), 10, TimeUnit.SECONDS);
// 10秒后中止线程池
executorService.schedule(executorService::shutdown, 15, TimeUnit.SECONDS);
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
运行结果
txt
PK场战斗中...
停止PK,返回游戏大厅
拍卖行参与拍卖...
退出拍卖行,返回游戏大厅
使用副本模块,下副本战斗...
副本战斗结束,返回游戏大厅
拍卖行参与拍卖...
退出拍卖行,返回游戏大厅
PK场战斗中...
停止PK,返回游戏大厅
使用副本模块,下副本战斗...
使用副本模块,下副本战斗...
使用副本模块,下副本战斗...
副本战斗结束,返回游戏大厅
拍卖行参与拍卖...
退出拍卖行,返回游戏大厅
PK场战斗中...
PK场战斗中...
PK场战斗中...
PK场战斗中...
停止PK,返回游戏大厅
使用副本模块,下副本战斗...
使用副本模块,下副本战斗...
副本战斗结束,返回游戏大厅
PK场战斗中...
停止PK,返回游戏大厅
拍卖行参与拍卖...
退出拍卖行,返回游戏大厅
PK场战斗中...
停止PK,返回游戏大厅
拍卖行参与拍卖...
拍卖行参与拍卖...
退出拍卖行,返回游戏大厅
PK场战斗中...
停止PK,返回游戏大厅
拍卖行参与拍卖...
退出拍卖行,返回游戏大厅
PK场战斗中...
停止PK,返回游戏大厅
拍卖行参与拍卖...
退出拍卖行,返回游戏大厅
使用副本模块,下副本战斗...
副本战斗结束,返回游戏大厅
PK场战斗中...
停止PK,返回游戏大厅
拍卖行参与拍卖...
退出拍卖行,返回游戏大厅
使用副本模块,下副本战斗...
使用副本模块,下副本战斗...
副本战斗结束,返回游戏大厅
PK场战斗中...
停止PK,返回游戏大厅
拍卖行参与拍卖...
拍卖行参与拍卖...
退出拍卖行,返回游戏大厅
使用副本模块,下副本战斗...
副本战斗结束,返回游戏大厅
拍卖行参与拍卖...
拍卖行参与拍卖...
退出拍卖行,返回游戏大厅
PK场战斗中...
停止PK,返回游戏大厅
拍卖行参与拍卖...
退出拍卖行,返回游戏大厅
使用副本模块,下副本战斗...
副本战斗结束,返回游戏大厅
PK场战斗中...
停止PK,返回游戏大厅
拍卖行参与拍卖...
拍卖行参与拍卖...
退出拍卖行,返回游戏大厅
使用副本模块,下副本战斗...
副本战斗结束,返回游戏大厅
PK场战斗中...
停止PK,返回游戏大厅
拍卖行参与拍卖...
拍卖行参与拍卖...
拍卖行参与拍卖...
拍卖行参与拍卖...
拍卖行参与拍卖...
退出拍卖行,返回游戏大厅
使用副本模块,下副本战斗...
使用副本模块,下副本战斗...
副本战斗结束,返回游戏大厅
拍卖行参与拍卖...
退出拍卖行,返回游戏大厅
PK场战斗中...
停止PK,返回游戏大厅
使用副本模块,下副本战斗...
使用副本模块,下副本战斗...