前言
还在为设计模式面试抓瞎?这篇直接给你划重点!涵盖创建型、结构型、行为型三大类共 20 道高频题,从单例模式线程安全实现,到工厂、代理、观察者等核心模式的原理、场景、区别全拆解。

一、创建型设计模式
1. 什么是单例模式?请实现一个线程安全的单例模式。
单例模式确保一个类仅有一个实例,并提供一个全局访问点。线程安全的单例需避免多线程同时创建实例,常见实现方式有饿汉式、懒汉式(双重检查锁定)、静态内部类等。其中,双重检查锁定通过两次判断实例是否为空,并使用synchronized
同步示例,既保证线程安全又提高效率。
示例:
java
public class Singleton {
// volatile防止指令重排序,确保instance初始化完成后再被访问
private static volatile Singleton instance;
// 私有构造方法,防止外部实例化
private Singleton() {}
// 全局访问点
public static Singleton getInstance() {
// 第一次检查,避免频繁进入同步块
if (instance == null) {
// 同步代码块,保证多线程安全
synchronized (Singleton.class) {
// 第二次检查,防止多个线程同时通过第一次检查后创建多个实例
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
2. 工厂模式有哪几种?简单工厂模式与工厂方法模式的区别是什么?
工厂模式分为简单工厂模式、工厂方法模式、抽象工厂模式。
- 简单工厂模式:由一个工厂类根据传入的参数决定创建哪种产品实例,违背"开闭原则"(新增产品需修改工厂类)。
- 工厂方法模式:定义一个创建产品的接口,由子类决定具体创建哪种产品,每个产品对应一个工厂子类,符合"开闭原则"(新增产品只需新增工厂子类)。
示例:
java
// 产品接口
interface Product { void produce(); }
// 具体产品A
class ProductA implements Product { public void produce() { System.out.println("生产A"); } }
// 具体产品B
class ProductB implements Product { public void produce() { System.out.println("生产B"); } }
// 简单工厂
class SimpleFactory {
public static Product createProduct(String type) {
if ("A".equals(type)) return new ProductA();
else if ("B".equals(type)) return new ProductB();
else throw new IllegalArgumentException("无效类型");
}
}
java
// 产品接口(同上)
interface Product { void produce(); }
// 具体产品A、B(同上)
// 工厂接口
interface Factory { Product createProduct(); }
// 产品A的工厂
class FactoryA implements Factory { public Product createProduct() { return new ProductA(); } }
// 产品B的工厂
class FactoryB implements Factory { public Product createProduct() { return new ProductB(); } }
3. 抽象工厂模式的适用场景是什么?请举例说明。
抽象工厂模式提供一个接口,用于创建一系列相关或相互依赖的对象,而无需指定具体类。适用于产品族(多个相关产品组成的集合)的创建,当需要保证产品间的兼容性时使用。
例如,电脑厂商需同时生产CPU和主板,不同品牌(如Intel、AMD)的CPU和主板需配套使用,抽象工厂可确保创建的CPU和主板属于同一品牌。
示例:
java
// 产品接口:CPU
interface CPU { void calculate(); }
// 产品接口:主板
interface Mainboard { void installCPU(); }
// 具体产品:Intel CPU
class IntelCPU implements CPU { public void calculate() { System.out.println("Intel CPU计算"); } }
// 具体产品:Intel主板
class IntelMainboard implements Mainboard { public void installCPU() { System.out.println("安装Intel CPU"); } }
// 具体产品:AMD CPU
class AmdCPU implements CPU { public void calculate() { System.out.println("AMD CPU计算"); } }
// 具体产品:AMD主板
class AmdMainboard implements Mainboard { public void installCPU() { System.out.println("安装AMD CPU"); } }
// 抽象工厂接口
interface ComputerFactory {
CPU createCPU();
Mainboard createMainboard();
}
// Intel工厂(生产Intel产品族)
class IntelFactory implements ComputerFactory {
public CPU createCPU() { return new IntelCPU(); }
public Mainboard createMainboard() { return new IntelMainboard(); }
}
// AMD工厂(生产AMD产品族)
class AmdFactory implements ComputerFactory {
public CPU createCPU() { return new AmdCPU(); }
public Mainboard createMainboard() { return new AmdMainboard(); }
}
4. 建造者模式与工厂模式的区别是什么?
- 工厂模式专注于"创建什么",主要用于创建单一产品,隐藏产品的创建过程,客户端只需知道产品类型即可。
- 建造者模式专注于"如何创建",用于创建复杂对象(由多个部分组成),通过分步构建并组装各部分,客户端可控制构建过程,且能灵活改变产品的内部结构。
例如,工厂模式可直接创建"电脑",而建造者模式可分步构建"电脑的CPU、内存、硬盘"并组装成电脑。
示例:
java
// 产品:电脑
class Computer {
private String cpu;
private String memory;
// 省略getter、setter和toString
}
// 建造者接口
interface ComputerBuilder {
void buildCPU();
void buildMemory();
Computer getResult();
}
// 具体建造者:游戏电脑
class GameComputerBuilder implements ComputerBuilder {
private Computer computer = new Computer();
public void buildCPU() { computer.setCpu("高性能CPU"); }
public void buildMemory() { computer.setMemory("32G内存"); }
public Computer getResult() { return computer; }
}
// 指挥者:控制构建流程
class Director {
public Computer construct(ComputerBuilder builder) {
builder.buildCPU();
builder.buildMemory();
return builder.getResult();
}
}
5. 原型模式的核心是什么?深拷贝与浅拷贝的区别?
原型模式通过复制现有实例(原型)来创建新实例,核心是clone()
方法,避免重复初始化对象,提高创建效率。
- 浅拷贝:仅复制对象本身及基本类型字段,引用类型字段仍指向原对象的引用(修改拷贝对象的引用字段会影响原对象)。
- 深拷贝:复制对象本身及所有引用类型字段(递归拷贝),原对象与拷贝对象完全独立(修改互不影响)。
示例:
java
import java.io.*;
// 实现Cloneable接口(浅拷贝)
class Prototype implements Cloneable, Serializable {
private String name;
private ReferenceType ref; // 引用类型字段
// 浅拷贝
@Override
protected Prototype clone() throws CloneNotSupportedException {
return (Prototype) super.clone();
}
// 深拷贝(通过序列化实现)
public Prototype deepClone() throws IOException, ClassNotFoundException {
// 序列化
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
// 反序列化
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return (Prototype) ois.readObject();
}
}
class ReferenceType implements Serializable {
private int value;
// 省略getter、setter
}
二、结构型设计模式
6. 适配器模式有哪两种实现方式?请举例说明类适配器。
适配器模式将一个类的接口转换成客户端期望的另一个接口,使不兼容的类可以一起工作。分为类适配器(通过继承实现)和对象适配器(通过组合实现)。类适配器通过继承适配者类并实现目标接口,缺点是受单继承限制;对象适配器通过持有适配者实例实现,更灵活。
示例(类适配器):
java
// 目标接口(客户端期望的接口)
interface Target { void request(); }
// 适配者(需要被适配的类)
class Adaptee {
public void specificRequest() { System.out.println("适配者的特殊请求"); }
}
// 类适配器(继承Adaptee,实现Target)
class ClassAdapter extends Adaptee implements Target {
public void request() {
// 调用适配者的方法,适配成目标接口
specificRequest();
}
}
7. 装饰器模式的作用是什么?与继承相比有何优势?
装饰器模式动态地给对象添加额外职责,不改变其原有结构。优势在于:
- 比继承更灵活:可动态组合多个装饰器,而继承是静态的,且可能导致类爆炸(每增加一个功能需新增子类)。
- 遵循"开闭原则":新增功能只需新增装饰器类,无需修改原有代码。
例如,给咖啡加牛奶、加糖,可通过MilkDecorator
、SugarDecorator
动态装饰Coffee
对象。
示例:
java
// 抽象组件:咖啡
abstract class Coffee {
abstract String getDescription();
abstract double cost();
}
// 具体组件:黑咖啡
class BlackCoffee extends Coffee {
public String getDescription() { return "黑咖啡"; }
public double cost() { return 10; }
}
// 装饰器抽象类(继承Coffee,持有Coffee实例)
abstract class CoffeeDecorator extends Coffee {
protected Coffee coffee;
public CoffeeDecorator(Coffee coffee) { this.coffee = coffee; }
}
// 具体装饰器:牛奶
class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee coffee) { super(coffee); }
public String getDescription() { return coffee.getDescription() + "+牛奶"; }
public double cost() { return coffee.cost() + 3; }
}
// 具体装饰器:糖
class SugarDecorator extends CoffeeDecorator {
public SugarDecorator(Coffee coffee) { super(coffee); }
public String getDescription() { return coffee.getDescription() + "+糖"; }
public double cost() { return coffee.cost() + 2; }
}
// 使用:黑咖啡+牛奶+糖
public class Test {
public static void main(String[] args) {
Coffee coffee = new BlackCoffee();
coffee = new MilkDecorator(coffee);
coffee = new SugarDecorator(coffee);
System.out.println(coffee.getDescription() + ",价格:" + coffee.cost());
}
}
8. 代理模式有哪几种?静态代理与动态代理的区别?
代理模式为对象提供一个代理,控制对原对象的访问。分为静态代理、动态代理(JDK动态代理、CGLIB动态代理)。
- 静态代理:代理类在编译期生成,与目标类实现同一接口,缺点是每代理一个类需手动编写代理类,复用性差。
- 动态代理:代理类在运行期动态生成,无需手动编写,JDK动态代理基于接口(目标类需实现接口),CGLIB基于继承(目标类可无接口)。
示例:
java
// 接口
interface UserService { void save(); }
// 目标类
class UserServiceImpl implements UserService { public void save() { System.out.println("保存用户"); } }
// 静态代理类
class UserServiceProxy implements UserService {
private UserService target;
public UserServiceProxy(UserService target) { this.target = target; }
public void save() {
System.out.println("前置日志"); // 增强
target.save();
System.out.println("后置日志"); // 增强
}
}
java
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
// InvocationHandler实现类
class LogHandler implements InvocationHandler {
private Object target;
public LogHandler(Object target) { this.target = target; }
// 动态生成代理方法
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("前置日志");
Object result = method.invoke(target, args);
System.out.println("后置日志");
return result;
}
}
// 使用
public class Test {
public static void main(String[] args) {
UserService target = new UserServiceImpl();
// 生成代理对象
UserService proxy = (UserService) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new LogHandler(target)
);
proxy.save();
}
}
9. 外观模式(Facade)的作用是什么?请举例说明。
外观模式为子系统中的一组接口提供一个统一的高层接口,简化客户端与子系统的交互。例如,电脑启动需依次启动CPU、内存、硬盘等子系统,外观模式可提供一个ComputerFacade
类,封装这些子系统的启动逻辑,客户端只需调用start()
即可。
示例:
java
// 子系统1:CPU
class CPU { public void start() { System.out.println("CPU启动"); } }
// 子系统2:内存
class Memory { public void start() { System.out.println("内存启动"); } }
// 外观类
class ComputerFacade {
private CPU cpu;
private Memory memory;
public ComputerFacade() {
cpu = new CPU();
memory = new Memory();
}
// 统一接口
public void start() {
cpu.start();
memory.start();
System.out.println("电脑启动完成");
}
}
// 客户端
public class Test {
public static void main(String[] args) {
ComputerFacade computer = new ComputerFacade();
computer.start(); // 无需直接操作子系统
}
}
10. 组合模式(Composite)的适用场景是什么?
组合模式将对象组合成树形结构,使客户端对单个对象和组合对象(容器)的使用具有一致性。适用于处理层次结构(如文件系统:文件和文件夹,文件夹可包含文件或子文件夹),客户端可统一操作"文件"和"文件夹"。
示例:
java
import java.util.ArrayList;
import java.util.List;
// 抽象组件
abstract class Component {
protected String name;
public Component(String name) { this.name = name; }
abstract void add(Component c); // 新增子组件(容器实现,叶子不实现)
abstract void remove(Component c); // 删除子组件
abstract void display(int depth); // 显示层级
}
// 叶子节点:文件
class File extends Component {
public File(String name) { super(name); }
public void add(Component c) { throw new UnsupportedOperationException(); }
public void remove(Component c) { throw new UnsupportedOperationException(); }
public void display(int depth) {
System.out.println("-".repeat(depth) + name);
}
}
// 容器节点:文件夹
class Folder extends Component {
private List<Component> children = new ArrayList<>();
public Folder(String name) { super(name); }
public void add(Component c) { children.add(c); }
public void remove(Component c) { children.remove(c); }
public void display(int depth) {
System.out.println("-".repeat(depth) + name);
// 递归显示子组件
for (Component child : children) {
child.display(depth + 2);
}
}
}
三、行为型设计模式
11. 观察者模式的核心是什么?请实现一个简单的观察者模式。
观察者模式定义对象间的一对多依赖关系,当一个对象(主题)状态改变时,所有依赖它的对象(观察者)会自动收到通知并更新。核心是解耦主题和观察者,主题只需维护观察者列表,无需知道具体观察者类型。例如,天气预报系统中,多个显示器(观察者)订阅天气数据(主题),数据更新时所有显示器同步刷新。
示例:
java
import java.util.ArrayList;
import java.util.List;
// 主题接口
interface Subject {
void registerObserver(Observer o); // 注册观察者
void removeObserver(Observer o); // 移除观察者
void notifyObservers(); // 通知所有观察者
}
// 观察者接口
interface Observer {
void update(float temperature); // 接收更新
}
// 具体主题:天气数据
class WeatherData implements Subject {
private List<Observer> observers;
private float temperature;
public WeatherData() { observers = new ArrayList<>(); }
public void registerObserver(Observer o) { observers.add(o); }
public void removeObserver(Observer o) { observers.remove(o); }
public void notifyObservers() {
for (Observer o : observers) {
o.update(temperature);
}
}
// 数据更新时通知观察者
public void setTemperature(float temperature) {
this.temperature = temperature;
notifyObservers();
}
}
// 具体观察者:显示器
class Display implements Observer {
private float temperature;
public void update(float temperature) {
this.temperature = temperature;
display();
}
private void display() {
System.out.println("当前温度:" + temperature + "℃");
}
}
12. 策略模式与状态模式的区别是什么?
- 策略模式:定义一系列算法,封装每个算法并使它们可互换,客户端可根据需要选择算法,算法的切换由客户端主动控制。例如,购物车的折扣策略(满减、打折)可通过策略模式动态切换。
- 状态模式:封装对象的状态及其对应的行为,状态的切换由对象内部条件自动触发,客户端无需知道状态细节。例如,订单的状态(待支付→已支付→已发货)转换由订单内部逻辑控制。
核心区别:策略模式是"客户端选算法",状态模式是"对象内部状态驱动行为"。
示例:
java
// 策略接口
interface DiscountStrategy { double calculate(double price); }
// 具体策略:满减
class FullReduction implements DiscountStrategy {
public double calculate(double price) { return price > 100 ? price - 20 : price; }
}
// 上下文:购物车
class ShoppingCart {
private DiscountStrategy strategy;
public void setStrategy(DiscountStrategy strategy) { this.strategy = strategy; }
public double checkout(double price) { return strategy.calculate(price); }
}
java
// 状态接口
interface OrderState { void handle(Order order); }
// 具体状态:待支付
class PendingState implements OrderState {
public void handle(Order order) {
System.out.println("订单待支付");
order.setState(new PaidState()); // 状态转换
}
}
// 具体状态:已支付(其他状态省略)
class PaidState implements OrderState {
public void handle(Order order) { System.out.println("订单已支付"); }
}
// 上下文:订单
class Order {
private OrderState state;
public Order() { state = new PendingState(); }
public void setState(OrderState state) { this.state = state; }
public void process() { state.handle(this); }
}
13. 模板方法模式的核心思想是什么?请举例说明。
模板方法模式在抽象类中定义一个算法的骨架(模板方法),将算法的某些步骤延迟到子类中实现,使子类在不改变算法结构的情况下重定义特定步骤。核心是"抽象父类定义流程,子类实现细节",例如,泡茶和泡咖啡的流程(烧水→加原料→冲泡→倒出)相同,但原料不同,可通过模板方法模式实现。
示例:
java
// 抽象类:定义模板方法
abstract class Beverage {
// 模板方法(算法骨架,用final修饰防止子类修改)
public final void make() {
boilWater();
addIngredients(); // 抽象方法,子类实现
brew(); // 抽象方法,子类实现
pourInCup();
}
private void boilWater() { System.out.println("烧水"); }
private void pourInCup() { System.out.println("倒入杯子"); }
protected abstract void addIngredients();
protected abstract void brew();
}
// 具体子类:咖啡
class Coffee extends Beverage {
protected void addIngredients() { System.out.println("加咖啡粉"); }
protected void brew() { System.out.println("冲泡咖啡"); }
}
// 具体子类:茶
class Tea extends Beverage {
protected void addIngredients() { System.out.println("加茶叶"); }
protected void brew() { System.out.println("冲泡茶叶"); }
}
14. 迭代器模式的作用是什么?为什么说它支持对集合的多种遍历方式?
迭代器模式提供一种方法顺序访问聚合对象中的元素,而无需暴露其内部结构。通过定义迭代器接口(hasNext()
、next()
),聚合对象可提供多个不同的迭代器实现,支持多种遍历方式(如正序、倒序)。例如,对列表既可按索引正序遍历,也可按元素值倒序遍历,客户端只需使用迭代器接口,无需关心聚合对象的具体结构。
示例:
java
// 迭代器接口
interface Iterator {
boolean hasNext();
Object next();
}
// 聚合接口
interface Aggregate {
Iterator createIterator();
}
// 具体聚合:列表
class MyList implements Aggregate {
private String[] items;
private int size;
public MyList() { items = new String[10]; }
public void add(String item) { items[size++] = item; }
public String get(int index) { return items[index]; }
public int getSize() { return size; }
// 创建正序迭代器
public Iterator createIterator() { return new NormalIterator(this); }
// 正序迭代器
private class NormalIterator implements Iterator {
private MyList list;
private int index;
public NormalIterator(MyList list) { this.list = list; index = 0; }
public boolean hasNext() { return index < list.getSize(); }
public Object next() { return list.get(index++); }
}
// 可新增倒序迭代器(略)
}
15. 命令模式的核心是什么?请实现一个简单的命令模式。
命令模式将请求封装为对象(命令),使客户端可参数化不同的请求、队列请求或记录请求日志,支持撤销操作。核心是"命令对象",它封装了接收者和要执行的动作,客户端通过调用命令对象的execute()
方法触发请求,而非直接调用接收者。例如,遥控器(客户端)通过命令对象控制灯光(接收者)的开/关。
示例:
java
// 命令接口
interface Command {
void execute();
void undo(); // 撤销
}
// 接收者:灯光
class Light {
public void on() { System.out.println("灯开"); }
public void off() { System.out.println("灯关"); }
}
// 具体命令:开灯
class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) { this.light = light; }
public void execute() { light.on(); }
public void undo() { light.off(); }
}
// 调用者:遥控器
class RemoteControl {
private Command command;
public void setCommand(Command command) { this.command = command; }
public void pressButton() { command.execute(); }
public void pressUndoButton() { command.undo(); }
}
16. 责任链模式的适用场景是什么?请举例说明。
责任链模式为请求创建一个接收者对象的链,每个接收者都包含对下一个接收者的引用,请求沿链传递,直到被某个接收者处理。适用于处理具有多个可能处理者的请求,且不确定具体处理者(如审批流程:请假1天→组长审批,3天→经理审批,7天→总监审批)。
示例:
java
// 抽象处理者
abstract class Approver {
protected Approver nextApprover; // 下一个处理者
public Approver(Approver next) { this.nextApprover = next; }
public abstract void approve(int days);
}
// 具体处理者:组长(处理1天以内)
class GroupLeader extends Approver {
public GroupLeader(Approver next) { super(next); }
public void approve(int days) {
if (days <= 1) {
System.out.println("组长批准请假" + days + "天");
} else {
nextApprover.approve(days); // 传递给下一个处理者
}
}
}
// 具体处理者:经理(处理3天以内,其他处理者略)
class Manager extends Approver {
public Manager(Approver next) { super(next); }
public void approve(int days) {
if (days <= 3) {
System.out.println("经理批准请假" + days + "天");
} else {
nextApprover.approve(days);
}
}
}
17. 中介者模式的作用是什么?它如何减少对象间的耦合?
中介者模式定义一个中介对象,封装一系列对象的交互,使对象间无需直接通信,而是通过中介者间接交互,从而减少对象间的耦合。例如,聊天室中,用户(同事对象)发送消息无需直接发给其他用户,而是通过聊天室(中介者)转发,用户只需与中介者交互,无需知道其他用户的存在。
示例:
java
// 中介者接口
interface Mediator {
void sendMessage(String msg, Colleague colleague);
}
// 同事接口
abstract class Colleague {
protected Mediator mediator;
public Colleague(Mediator mediator) { this.mediator = mediator; }
public abstract void receive(String msg);
public void send(String msg) { mediator.sendMessage(msg, this); }
}
// 具体同事:用户A
class UserA extends Colleague {
public UserA(Mediator mediator) { super(mediator); }
public void receive(String msg) { System.out.println("UserA收到:" + msg); }
}
// 具体同事:用户B
class UserB extends Colleague {
public UserB(Mediator mediator) { super(mediator); }
public void receive(String msg) { System.out.println("UserB收到:" + msg); }
}
// 具体中介者:聊天室
class ChatRoom implements Mediator {
private UserA userA;
private UserB userB;
public void setUserA(UserA userA) { this.userA = userA; }
public void setUserB(UserB userB) { this.userB = userB; }
public void sendMessage(String msg, Colleague colleague) {
if (colleague == userA) {
userB.receive(msg); // 转发给UserB
} else {
userA.receive(msg); // 转发给UserA
}
}
}
18. 访问者模式的核心是什么?适用于什么场景?
访问者模式将数据结构与数据操作分离,定义一个访问者接口,包含对每种元素的操作方法,元素类提供accept()
方法接收访问者,使新增操作无需修改元素类。适用于数据结构稳定(元素类型固定)但操作多变的场景,例如,电商系统中,商品(元素)的类型固定(食品、电器),但需新增"计算税费""计算折扣"等操作。
示例:
java
// 访问者接口(定义对所有元素的操作)
interface Visitor {
void visit(Food food);
void visit(Electronics electronics);
}
// 具体访问者:计算价格
class PriceVisitor implements Visitor {
public void visit(Food food) { System.out.println("食品价格:" + food.getPrice()); }
public void visit(Electronics electronics) { System.out.println("电器价格:" + electronics.getPrice()); }
}
// 元素接口
interface Element {
void accept(Visitor visitor);
}
// 具体元素:食品
class Food implements Element {
private double price;
public Food(double price) { this.price = price; }
public double getPrice() { return price; }
public void accept(Visitor visitor) { visitor.visit(this); } // 接收访问者
}
// 具体元素:电器
class Electronics implements Element {
/* 实现类似Food */
private double price;
public Electronics(double price) { this.price = price; }
public double getPrice() { return price; }
public void accept(Visitor visitor) { visitor.visit(this); } // 接收访问者
}
19. 备忘录模式的作用是什么?请实现一个简单的备忘录模式。
备忘录模式在不破坏封装的前提下,捕获对象的内部状态并保存,以便后续恢复该状态。适用于需要保存和恢复状态的场景(如游戏存档、编辑器撤销功能)。核心角色:原发器(Originator,创建并保存状态)、备忘录(Memento,存储状态)、负责人(Caretaker,管理备忘录)。
示例:
java
// 备忘录:存储状态
class Memento {
private String state;
public Memento(String state) { this.state = state; }
public String getState() { return state; }
}
// 原发器:游戏角色
class GameRole {
private String state; // 状态:位置、血量等
public void setState(String state) { this.state = state; }
// 创建备忘录
public Memento saveState() { return new Memento(state); }
// 恢复状态
public void restoreState(Memento memento) { this.state = memento.getState(); }
}
// 负责人:管理备忘录(存档)
class Caretaker {
private Memento memento;
public void setMemento(Memento memento) { this.memento = memento; }
public Memento getMemento() { return memento; }
}
20. 解释器模式的核心思想是什么?适用于什么场景?
解释器模式定义一个语言的语法规则,并构建一个解释器来解释该语言中的句子。核心是将语法规则抽象为表达式类,通过组合表达式来解析复杂语句。适用于简单语法的场景(如数学表达式解析、正则表达式解析),但语法复杂时会导致类爆炸,不推荐使用。
示例(解析简单加法表达式):
java
// 抽象表达式
interface Expression {
int interpret();
}
// 终结符表达式:数字
class NumberExpression implements Expression {
private int num;
public NumberExpression(int num) { this.num = num; }
public int interpret() { return num; }
}
// 非终结符表达式:加法
class AddExpression implements Expression {
private Expression left;
private Expression right;
public AddExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
public int interpret() { return left.interpret() + right.interpret(); }
}
// 使用:解析"1+2"
public class Test {
public static void main(String[] args) {
Expression expr = new AddExpression(new NumberExpression(1), new NumberExpression(2));
System.out.println(expr.interpret()); // 输出3
}
}
写在最后
都看到这了,给个一键三连吧,点赞 、关注 、收藏、您的支持是我坚持创作最大的动力~~~