外观模式是一种结构型设计模式,它为一组复杂的类提供了一个简单的接口(也就是外观类),以便客户端可以通过这个接口访问这些类的功能,从而隐藏了这些类的复杂性,简化了客户端的使用。
在这个游戏场景中,我们使用了外观模式的示例代码,即GameFacade类充当一个外观类。客户端只需像操作GameFacade类一样调用setHero()和setWeapon()方法来选择英雄和武器,而不需要直接与英雄和武器类打交道。GameFacade类的startGame()方法内部使用了HeroFactory和WeaponFactory抽象工厂类创建具体的英雄和武器对象,完成英雄和武器的选择过程。
外观模式可以将复杂的类和系统内部复杂性与客户端分离,提高代码的易用性、可维护性和可扩展性。但是,外观模式也有一定的局限性,会降低代码的灵活性和可复用性。
public class Ashe implements Hero { // 具体产品类-寒冰
@Override
public void selectHero() {
System.out.println("Freeze!"); // 输出“冻结!”
}
}
public class AsheFactory implements HeroFactory { // 具体工厂类-寒冰工厂
@Override
public Hero createHero() {
return new Ashe(); // 创建一个寒冰英雄实例
}
}
// 具体产品类-弓箭
public class Bow implements Weapon {
@Override
public void selectWeapon() {
System.out.println("You have selected a bow."); // 输出“你已选择弓箭。”
}
}
// 具体武器工厂类-弓箭工厂
public class BowFactory implements WeaponFactory {
@Override
public Weapon createWeapon() {
return new Bow(); // 创建一个弓箭实例
}
}
public class Garen implements Hero { // 具体产品类-盖伦
@Override
public void selectHero() {
System.out.println("For Demacia!"); // 输出“为了德玛西亚!”
}
}
public class GarenFactory implements HeroFactory { // 具体工厂类-盖伦工厂
@Override
public Hero createHero() {
return new Garen(); // 创建一个盖伦英雄实例
}
}
// 具体产品类-大剑
public class GreatSword implements Weapon {
@Override
public void selectWeapon() {
System.out.println("You have selected a great sword."); // 输出“你已选择大剑。”
}
}
// 具体武器工厂类-大剑工厂
public class GreatSwordFactory implements WeaponFactory {
@Override
public Weapon createWeapon() {
return new GreatSword(); // 创建一个大剑实例
}
}
public interface Hero { // 抽象产品类-英雄
void selectHero(); // 选择英雄
}
public interface HeroFactory { // 抽象工厂类-英雄工厂
Hero createHero(); // 创建英雄
}
// 抽象产品类-武器
public interface Weapon {
void selectWeapon(); // 选择武器
}
// 抽象武器工厂接口
public interface WeaponFactory {
Weapon createWeapon(); // 创建武器
}
public class GameFacade {
private HeroFactory heroFactory;
private WeaponFactory weaponFactory;
public GameFacade() {
this.heroFactory = new GarenFactory(); // 默认英雄为盖伦
this.weaponFactory = new GreatSwordFactory(); // 默认武器为大剑
}
public void setHero(String heroName) {
if (heroName.equals("盖伦")) {
this.heroFactory = new GarenFactory(); // 如果英雄名称是“盖伦”,则创建一个盖伦英雄实例
} else if (heroName.equals("寒冰")) {
this.heroFactory = new AsheFactory(); // 如果英雄名称是“寒冰”,则创建一个寒冰英雄实例
} else {
throw new IllegalArgumentException("无法识别的英雄名称!"); // 如果英雄名称不是“盖伦”或“寒冰”,则抛出异常
}
}
public void setWeapon(String weaponName) {
if (weaponName.equals("大剑")) {
this.weaponFactory = new GreatSwordFactory(); // 如果武器名称是“大剑”,则创建一个大剑实例
} else if (weaponName.equals("弓箭")) {
this.weaponFactory = new BowFactory(); // 如果武器名称是“弓箭”,则创建一个弓箭实例
} else {
throw new IllegalArgumentException("无法识别的武器名称!"); // 如果武器名称不是“大剑”或“弓箭”,则抛出异常
}
}
public void startGame() {
Hero hero = heroFactory.createHero(); // 创建一个英雄实例
Weapon weapon = weaponFactory.createWeapon(); // 创建一个武器实例
hero.selectHero(); // 选择英雄
weapon.selectWeapon(); // 选择武器
}
}
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Main {
public static void main(String[] args) {
final Logger logger = Logger.getLogger(Main.class.getName()); // 创建一个Logger实例
Scanner scanner = new Scanner(System.in); // 创建一个Scanner实例
GameFacade game = new GameFacade(); // 创建一个GameFacade实例
try {
String heroName; // 定义一个英雄名称的字符串变量
String weaponName; // 定义一个武器名称的字符串变量
System.out.println("请输入英雄名称(盖伦/寒冰):"); // 输出提示信息
heroName = scanner.nextLine(); // 获取用户输入的英雄名称
game.setHero(heroName); // 设置英雄
System.out.println("请输入武器名称(大剑/弓箭):"); // 输出提示信息
weaponName = scanner.nextLine(); // 获取用户输入的武器名称
game.setWeapon(weaponName); // 设置武器
game.startGame(); // 开始游戏
} catch (Exception e) {
logger.log(Level.SEVERE, e.getMessage()); // 输出日志信息
System.out.println("程序出现异常,无法选择英雄和武器!"); // 输出提示信息
} finally {
scanner.close(); // 关闭Scanner实例
}
}
}