Java 设计模式大揭秘:23 种模式全解析
📚 设计模式分类
Java 设计模式分为三大类,就像美食界的"中餐、西餐、日料",各有特色:
一、创建型模式(5 种):解决"生孩子"的问题
1. 单例模式(Singleton)
比喻:就像国家总统,一个国家只能有一个总统,所有部门都找同一个人办事。
应用场景:日志管理器、数据库连接池、配置中心(一个系统里只需要一个实例)。
代码示例:
// 枚举单例(最推荐的方式,线程安全,防止反射攻击)
public enum Singleton {
INSTANCE;
public String getConfig() {
return "配置信息";
}
}
// 使用
Singleton instance = Singleton.INSTANCE;
System.out.println(instance.getConfig()); // 输出:配置信息
为什么好:避免资源浪费,防止多个实例导致冲突,代码简洁。
2. 工厂方法模式(Factory Method)
比喻:就像点外卖,你只需要说"我要一份披萨",不用关心是哪家店做的。
应用场景:对象创建逻辑复杂,需要解耦创建和使用。
代码示例:
// 产品接口
interface Car {
void drive();
}
// 具体产品
class SUV implements Car {
public void drive() {
System.out.println("越野车行驶");
}
}
// 工厂类
class CarFactory {
public Car createCar(String type) {
if ("SUV".equals(type)) {
return new SUV();
}
return null;
}
}
// 使用
Car myCar = new CarFactory().createCar("SUV");
myCar.drive(); // 输出:越野车行驶
3. 抽象工厂模式(Abstract Factory)
比喻:就像苹果生态,iPhone 和 AirPods 一起卖,小米手机和耳机一起卖。
应用场景:需要创建相关产品家族。
代码示例:
interface Phone {
void call();
}
interface Earphone {
void play();
}
// 苹果产品家族
class iPhone implements Phone {
public void call() {
System.out.println("iPhone打电话");
}
}
class AirPods implements Earphone {
public void play() {
System.out.println("AirPods播放音乐");
}
}
// 工厂接口
interface TechFactory {
Phone createPhone();
Earphone createEarphone();
}
// 苹果工厂
class AppleFactory implements TechFactory {
public Phone createPhone() {
return new iPhone();
}
public Earphone createEarphone() {
return new AirPods();
}
}
// 使用
TechFactory appleFactory = new AppleFactory();
Phone phone = appleFactory.createPhone();
Earphone earphone = appleFactory.createEarphone();
phone.call(); // iPhone打电话
earphone.play(); // AirPods播放音乐
4. 建造者模式(Builder)
比喻:就像点咖啡,你告诉店员"要大杯、热的、加奶、不加糖",店员按照你的要求制作。
应用场景:对象创建过程复杂,参数多且有依赖关系。
代码示例:
class Coffee {
private int size;
private boolean hot;
private boolean milk;
private boolean sugar;
private Coffee(Builder builder) {
this.size = builder.size;
this.hot = builder.hot;
this.milk = builder.milk;
this.sugar = builder.sugar;
}
public static class Builder {
private int size;
private boolean hot = true;
private boolean milk;
private boolean sugar;
public Builder size(int size) {
this.size = size;
return this;
}
public Builder hot(boolean hot) {
this.hot = hot;
return this;
}
public Builder milk(boolean milk) {
this.milk = milk;
return this;
}
public Builder sugar(boolean sugar) {
this.sugar = sugar;
return this;
}
public Coffee build() {
return new Coffee(this);
}
}
@Override
public String toString() {
return "Coffee{" +
"size=" + size +
", hot=" + hot +
", milk=" + milk +
", sugar=" + sugar +
'}';
}
}
// 使用
Coffee coffee = new Coffee.Builder()
.size(300)
.hot(false)
.milk(true)
.sugar(false)
.build();
System.out.println(coffee); // Coffee{size=300, hot=false, milk=true, sugar=false}
5. 原型模式(Prototype)
比喻:就像复印机,你只需要一张纸,就可以快速复制出多份相同内容。
应用场景:创建对象成本高,需要快速复制已有对象。
代码示例:
class Shape implements Cloneable {
private String type;
public Shape(String type) {
this.type = type;
}
public String getType() {
return type;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
// 使用
Shape circle = new Shape("Circle");
Shape clonedCircle = (Shape) circle.clone();
System.out.println(clonedCircle.getType()); // Circle
二、结构型模式(7 种):解决"如何组合"的问题
6. 适配器模式(Adapter)
比喻:就像手机充电器的转接头,把不同接口的充电口转换成通用的。
应用场景:将不兼容的接口转换成兼容的接口。
代码示例:
// 目标接口
interface MediaPlayer {
void play(String audioType, String fileName);
}
// 适配者
class AdvancedMediaPlayer {
public void playVlc(String fileName) {
System.out.println("Playing vlc file. Name: " + fileName);
}
public void playMp4(String fileName) {
System.out.println("Playing mp4 file. Name: " + fileName);
}
}
// 适配器
class MediaAdapter implements MediaPlayer {
private AdvancedMediaPlayer advancedMediaPlayer;
public MediaAdapter(String audioType) {
if ("vlc".equalsIgnoreCase(audioType)) {
advancedMediaPlayer = new AdvancedMediaPlayer();
} else if ("mp4".equalsIgnoreCase(audioType)) {
advancedMediaPlayer = new AdvancedMediaPlayer();
}
}
@Override
public void play(String audioType, String fileName) {
if ("vlc".equalsIgnoreCase(audioType)) {
advancedMediaPlayer.playVlc(fileName);
} else if ("mp4".equalsIgnoreCase(audioType)) {
advancedMediaPlayer.playMp4(fileName);
}
}
}
// 使用
MediaPlayer mediaPlayer = new MediaAdapter("vlc");
mediaPlayer.play("vlc", "movie.vlc"); // Playing vlc file. Name: movie.vlc
7. 装饰模式(Decorator)
比喻:就像披萨,基础披萨是核心,加芝士、火腿、蘑菇都是装饰。
应用场景:动态地给对象添加职责,不使用继承。
代码示例:
// 组件接口
interface Coffee {
String getDescription();
double cost();
}
// 具体组件
class SimpleCoffee implements Coffee {
@Override
public String getDescription() {
return "Simple Coffee";
}
@Override
public double cost() {
return 1.0;
}
}
// 装饰器
abstract class CoffeeDecorator implements Coffee {
protected Coffee coffee;
public CoffeeDecorator(Coffee coffee) {
this.coffee = coffee;
}
@Override
public String getDescription() {
return coffee.getDescription();
}
@Override
public double cost() {
return coffee.cost();
}
}
// 具体装饰器
class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee coffee) {
super(coffee);
}
@Override
public String getDescription() {
return super.getDescription() + ", Milk";
}
@Override
public double cost() {
return super.cost() + 0.5;
}
}
// 使用
Coffee coffee = new SimpleCoffee();
coffee = new MilkDecorator(coffee);
System.out.println(coffee.getDescription()); // Simple Coffee, Milk
System.out.println(coffee.cost()); // 1.5
8. 外观模式(Facade)
比喻:就像手机 APP,你不需要知道手机内部怎么运作,只需要点几个按钮。
应用场景:为复杂的子系统提供一个统一的接口。
代码示例:
// 子系统
class CPU {
public void start() {
System.out.println("CPU is starting...");
}
}
class Memory {
public void load() {
System.out.println("Memory is loading...");
}
}
class HardDrive {
public void read() {
System.out.println("Hard drive is reading...");
}
}
// 外观
class ComputerFacade {
private CPU cpu;
private Memory memory;
private HardDrive hardDrive;
public ComputerFacade() {
this.cpu = new CPU();
this.memory = new Memory();
this.hardDrive = new HardDrive();
}
public void start() {
cpu.start();
memory.load();
hardDrive.read();
System.out.println("Computer started successfully!");
}
}
// 使用
ComputerFacade computer = new ComputerFacade();
computer.start();
// 输出:
// CPU is starting...
// Memory is loading...
// Hard drive is reading...
// Computer started successfully!
9. 代理模式(Proxy)
比喻:就像经纪人,你不需要直接和明星接触,通过经纪人就能安排见面。
应用场景:控制对对象的访问,如权限控制、延迟加载。
代码示例:
// 接口
interface Image {
void display();
}
// 真实对象
class RealImage implements Image {
private String fileName;
public RealImage(String fileName) {
this.fileName = fileName;
loadFromDisk();
}
private void loadFromDisk() {
System.out.println("Loading " + fileName);
}
@Override
public void display() {
System.out.println("Displaying " + fileName);
}
}
// 代理
class ProxyImage implements Image {
private RealImage realImage;
private String fileName;
public ProxyImage(String fileName) {
this.fileName = fileName;
}
@Override
public void display() {
if (realImage == null) {
realImage = new RealImage(fileName);
}
realImage.display();
}
}
// 使用
Image image = new ProxyImage("test.jpg");
image.display(); // Loading test.jpg, Displaying test.jpg
image.display(); // Displaying test.jpg (不再加载,直接显示)
10. 桥接模式(Bridge)
比喻:就像手机和 SIM 卡,手机(抽象)和 SIM 卡(实现)可以分离。
应用场景:将抽象部分与其实现部分分离,使它们可以独立变化。
代码示例:
// 实现类接口
interface Implementor {
void operationImpl();
}
// 具体实现
class ConcreteImplementorA implements Implementor {
@Override
public void operationImpl() {
System.out.println("ConcreteImplementorA operation");
}
}
class ConcreteImplementorB implements Implementor {
@Override
public void operationImpl() {
System.out.println("ConcreteImplementorB operation");
}
}
// 抽象类
abstract class Abstraction {
protected Implementor implementor;
public Abstraction(Implementor implementor) {
this.implementor = implementor;
}
public abstract void operation();
}
// 扩展抽象类
class RefinedAbstraction extends Abstraction {
public RefinedAbstraction(Implementor implementor) {
super(implementor);
}
@Override
public void operation() {
System.out.println("RefinedAbstraction operation");
implementor.operationImpl();
}
}
// 使用
Implementor implementorA = new ConcreteImplementorA();
Abstraction abstraction = new RefinedAbstraction(implementorA);
abstraction.operation();
// 输出:
// RefinedAbstraction operation
// ConcreteImplementorA operation
11. 组合模式(Composite)
比喻:就像一棵树,有根节点、分支节点和叶子节点,但可以统一处理。
应用场景:表示对象的"整体-部分"层次结构。
代码示例:
// 组件
abstract class Component {
protected String name;
public Component(String name) {
this.name = name;
}
public abstract void add(Component component);
public abstract void remove(Component component);
public abstract void display(int depth);
}
// 叶子节点
class Leaf extends Component {
public Leaf(String name) {
super(name);
}
@Override
public void add(Component component) {
System.out.println("Cannot add to a leaf");
}
@Override
public void remove(Component component) {
System.out.println("Cannot remove from a leaf");
}
@Override
public void display(int depth) {
System.out.println("-".repeat(depth) + name);
}
}
// 组合节点
class Composite extends Component {
private List<Component> children = new ArrayList<>();
public Composite(String name) {
super(name);
}
@Override
public void add(Component component) {
children.add(component);
}
@Override
public void remove(Component component) {
children.remove(component);
}
@Override
public void display(int depth) {
System.out.println("-".repeat(depth) + name);
for (Component child : children) {
child.display(depth + 2);
}
}
}
// 使用
Component root = new Composite("Root");
Component branch1 = new Composite("Branch1");
Component leaf1 = new Leaf("Leaf1");
Component leaf2 = new Leaf("Leaf2");
branch1.add(leaf1);
branch1.add(leaf2);
root.add(branch1);
root.display(0);
// 输出:
// Root
// Branch1
// Leaf1
// Leaf2
12. 享元模式(Flyweight)
比喻:就像图书馆的书籍,很多读者看同一本书,但不需要为每个人复制一本。
应用场景:共享大量细粒度对象,减少内存占用。
代码示例:
// 享元
interface Flyweight {
void operation(String extrinsicState);
}
// 具体享元
class ConcreteFlyweight implements Flyweight {
private String intrinsicState;
public ConcreteFlyweight(String intrinsicState) {
this.intrinsicState = intrinsicState;
}
@Override
public void operation(String extrinsicState) {
System.out.println("Intrinsic: " + intrinsicState + ", Extrinsic: " + extrinsicState);
}
}
// 享元工厂
class FlyweightFactory {
private Map<String, Flyweight> flyweights = new HashMap<>();
public Flyweight getFlyweight(String intrinsicState) {
if (!flyweights.containsKey(intrinsicState)) {
flyweights.put(intrinsicState, new ConcreteFlyweight(intrinsicState));
}
return flyweights.get(intrinsicState);
}
}
// 使用
FlyweightFactory factory = new FlyweightFactory();
Flyweight flyweight1 = factory.getFlyweight("A");
Flyweight flyweight2 = factory.getFlyweight("B");
Flyweight flyweight3 = factory.getFlyweight("A");
flyweight1.operation("X"); // Intrinsic: A, Extrinsic: X
flyweight2.operation("Y"); // Intrinsic: B, Extrinsic: Y
flyweight3.operation("Z"); // Intrinsic: A, Extrinsic: Z
三、行为型模式(11 种):解决"如何交互"的问题
13. 责任链模式(Chain of Responsibility)
比喻:就像公司审批流程,小问题找部门经理,大问题找总监,最终找 CEO。
应用场景:多个对象可以处理请求,但具体哪个对象处理未知。
代码示例:
// 处理者接口
abstract class Handler {
protected Handler successor;
public void setSuccessor(Handler successor) {
this.successor = successor;
}
public abstract void handleRequest(String request);
}
// 具体处理者
class Manager extends Handler {
@Override
public void handleRequest(String request) {
if ("salary".equals(request)) {
System.out.println("Manager handles salary request");
} else if (successor != null) {
successor.handleRequest(request);
}
}
}
class Director extends Handler {
@Override
public void handleRequest(String request) {
if ("project".equals(request)) {
System.out.println("Director handles project request");
} else if (successor != null) {
successor.handleRequest(request);
}
}
}
// 使用
Handler manager = new Manager();
Handler director = new Director();
manager.setSuccessor(director);
manager.handleRequest("salary"); // Manager handles salary request
manager.handleRequest("project"); // Director handles project request
14. 命令模式(Command)
比喻:就像点餐,你点菜(命令)给服务员(调用者),服务员传给厨师(接收者)。
应用场景:将请求封装为对象,实现解耦。
代码示例:
// 命令接口
interface Command {
void execute();
}
// 接收者
class Light {
public void turnOn() {
System.out.println("Light is on");
}
public void turnOff() {
System.out.println("Light is off");
}
}
// 具体命令
class TurnOnLightCommand implements Command {
private Light light;
public TurnOnLightCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.turnOn();
}
}
class TurnOffLightCommand implements Command {
private Light light;
public TurnOffLightCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.turnOff();
}
}
// 调用者
class RemoteControl {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void pressButton() {
command.execute();
}
}
// 使用
Light light = new Light();
Command turnOn = new TurnOnLightCommand(light);
Command turnOff = new TurnOffLightCommand(light);
RemoteControl remote = new RemoteControl();
remote.setCommand(turnOn);
remote.pressButton(); // Light is on
remote.setCommand(turnOff);
remote.pressButton(); // Light is off
15. 解析器模式(Interpreter)
比喻:就像语言翻译,把自然语言转换成计算机能理解的指令。
应用场景:定义语言的文法,并解释该语言的句子。
代码示例:
// 表达式接口
interface Expression {
boolean interpret(String context);
}
// 终结符表达式
class TerminalExpression implements Expression {
private String data;
public TerminalExpression(String data) {
this.data = data;
}
@Override
public boolean interpret(String context) {
return context.contains(data);
}
}
// 非终结符表达式
class OrExpression implements Expression {
private Expression expr1;
private Expression expr2;
public OrExpression(Expression expr1, Expression expr2) {
this.expr1 = expr1;
this.expr2 = expr2;
}
@Override
public boolean interpret(String context) {
return expr1.interpret(context) || expr2.interpret(context);
}
}
// 使用
Expression isMale = new TerminalExpression("Male");
Expression isMarried = new TerminalExpression("Married");
Expression expression = new OrExpression(isMale, isMarried);
System.out.println(expression.interpret("Male")); // true
System.out.println(expression.interpret("Married")); // true
System.out.println(expression.interpret("Single")); // false
16. 迭代器模式(Iterator)
比喻:就像翻书,你不需要知道书的内部结构,只需要按顺序一页页翻。
应用场景:提供一种方法顺序访问一个聚合对象的各个元素。
代码示例:
// 迭代器接口
interface Iterator {
boolean hasNext();
Object next();
}
// 聚合
interface Aggregate {
Iterator createIterator();
}
// 具体迭代器
class BookShelfIterator implements Iterator {
private BookShelf bookShelf;
private int index;
public BookShelfIterator(BookShelf bookShelf) {
this.bookShelf = bookShelf;
this.index = 0;
}
@Override
public boolean hasNext() {
return index < bookShelf.getSize();
}
@Override
public Object next() {
Book book = bookShelf.getBook(index);
index++;
return book;
}
}
// 具体聚合
class BookShelf implements Aggregate {
private List<Book> books = new ArrayList<>();
public void addBook(Book book) {
books.add(book);
}
public Book getBook(int index) {
return books.get(index);
}
public int getSize() {
return books.size();
}
@Override
public Iterator createIterator() {
return new BookShelfIterator(this);
}
}
// 使用
BookShelf bookShelf = new BookShelf();
bookShelf.addBook(new Book("Book1"));
bookShelf.addBook(new Book("Book2"));
bookShelf.addBook(new Book("Book3"));
Iterator iterator = bookShelf.createIterator();
while (iterator.hasNext()) {
System.out.println(iterator.next()); // Book1, Book2, Book3
}
17. 中介者模式(Mediator)
比喻:就像微信群,大家不需要直接互相联系,只需要通过群主(中介者)沟通。
应用场景:用一个中介对象来封装一系列对象之间的交互。
代码示例:
// 中介者
interface Mediator {
void send(String message, Colleague colleague);
}
// 同事
abstract class Colleague {
protected Mediator mediator;
public Colleague(Mediator mediator) {
this.mediator = mediator;
}
public abstract void receive(String message);
}
// 具体同事
class ConcreteColleague1 extends Colleague {
public ConcreteColleague1(Mediator mediator) {
super(mediator);
}
@Override
public void receive(String message) {
System.out.println("Colleague1 received: " + message);
}
public void send(String message) {
mediator.send(message, this);
}
}
class ConcreteColleague2 extends Colleague {
public ConcreteColleague2(Mediator mediator) {
super(mediator);
}
@Override
public void receive(String message) {
System.out.println("Colleague2 received: " + message);
}
public void send(String message) {
mediator.send(message, this);
}
}
// 具体中介者
class ConcreteMediator implements Mediator {
private ConcreteColleague1 colleague1;
private ConcreteColleague2 colleague2;
public void setColleague1(ConcreteColleague1 colleague1) {
this.colleague1 = colleague1;
}
public void setColleague2(ConcreteColleague2 colleague2) {
this.colleague2 = colleague2;
}
@Override
public void send(String message, Colleague colleague) {
if (colleague == colleague1) {
colleague2.receive(message);
} else {
colleague1.receive(message);
}
}
}
// 使用
ConcreteMediator mediator = new ConcreteMediator();
ConcreteColleague1 colleague1 = new ConcreteColleague1(mediator);
ConcreteColleague2 colleague2 = new ConcreteColleague2(mediator);
mediator.setColleague1(colleague1);
mediator.setColleague2(colleague2);
colleague1.send("Hello from Colleague1"); // Colleague2 received: Hello from Colleague1
colleague2.send("Hello from Colleague2"); // Colleague1 received: Hello from Colleague2
18. 备忘录模式(Memento)
比喻:就像游戏存档,你可以随时保存状态,需要时恢复。
应用场景:在不破坏封装性的前提下,捕获并外部化对象的内部状态。
代码示例:
// 备忘录
class Memento {
private String state;
public Memento(String state) {
this.state = state;
}
public String getState() {
return state;
}
}
// 发起者
class Originator {
private String state;
public void setState(String state) {
this.state = state;
}
public String getState() {
return state;
}
public Memento saveStateToMemento() {
return new Memento(state);
}
public void getStateFromMemento(Memento memento) {
state = memento.getState();
}
}
// 管理者
class CareTaker {
private List<Memento> mementoList = new ArrayList<>();
public void addMemento(Memento memento) {
mementoList.add(memento);
}
public Memento getMemento(int index) {
return mementoList.get(index);
}
}
// 使用
Originator originator = new Originator();
CareTaker careTaker = new CareTaker();
originator.setState("State1");
careTaker.addMemento(originator.saveStateToMemento());
originator.setState("State2");
careTaker.addMemento(originator.saveStateToMemento());
originator.setState("State3");
System.out.println("Current State: " + originator.getState()); // State3
originator.getStateFromMemento(careTaker.getMemento(0));
System.out.println("Restored State: " + originator.getState()); // State1
19. 观察者模式(Observer)
比喻:就像天气预报,你订阅了天气,天气变化时会收到通知。
应用场景:当对象间存在一对多的依赖关系时。
代码示例:
// 观察者
interface Observer {
void update(String message);
}
// 主题
interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers();
}
// 具体主题
class WeatherData implements Subject {
private List<Observer> observers = new ArrayList<>();
private float temperature;
public void setTemperature(float temperature) {
this.temperature = temperature;
notifyObservers();
}
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update("Temperature: " + temperature);
}
}
}
// 具体观察者
class TemperatureDisplay implements Observer {
@Override
public void update(String message) {
System.out.println("TemperatureDisplay: " + message);
}
}
class WeatherStation {
public static void main(String[] args) {
WeatherData weatherData = new WeatherData();
Observer display = new TemperatureDisplay();
weatherData.registerObserver(display);
weatherData.setTemperature(25.5f); // TemperatureDisplay: Temperature: 25.5
}
}
20. 状态模式(State)
比喻:就像手机状态,待机、通话、游戏,不同状态下功能不同。
应用场景:对象的行为依赖于它的状态,并且可以运行时改变状态。
代码示例:
// 状态接口
interface State {
void handleRequest();
}
// 具体状态
class ConcreteStateA implements State {
@Override
public void handleRequest() {
System.out.println("ConcreteStateA handles request");
}
}
class ConcreteStateB implements State {
@Override
public void handleRequest() {
System.out.println("ConcreteStateB handles request");
}
}
// 上下文
class Context {
private State state;
public Context(State state) {
this.state = state;
}
public void setState(State state) {
this.state = state;
}
public void request() {
state.handleRequest();
}
}
// 使用
Context context = new Context(new ConcreteStateA());
context.request(); // ConcreteStateA handles request
context.setState(new ConcreteStateB());
context.request(); // ConcreteStateB handles request
21. 策略模式(Strategy)
比喻:就像外卖选择配送方式,雨天用电动车,晴天用自行车,晚高峰用摩托。
应用场景:定义一系列算法,把它们封装起来,并且使它们可以相互替换。
代码示例:
// 策略接口
interface Strategy {
void execute();
}
// 具体策略
class ConcreteStrategyA implements Strategy {
@Override
public void execute() {
System.out.println("Executing strategy A");
}
}
class ConcreteStrategyB implements Strategy {
@Override
public void execute() {
System.out.println("Executing strategy B");
}
}
// 上下文
class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
public void executeStrategy() {
strategy.execute();
}
}
// 使用
Context context = new Context(new ConcreteStrategyA());
context.executeStrategy(); // Executing strategy A
context.setStrategy(new ConcreteStrategyB());
context.executeStrategy(); // Executing strategy B
22. 模板方法模式(Template Method)
比喻:就像做咖啡的流程:烧水 → 加咖啡粉 → 冲泡 → 搅拌,子类只改"加奶还是糖"。
应用场景:定义一个算法的框架,允许子类在不改变结构的情况下重写步骤。
代码示例:
// 抽象类
abstract class CaffeineBeverage {
final void prepareRecipe() {
boilWater();
brew();
pourInCup();
addCondiments();
}
abstract void brew();
abstract void addCondiments();
void boilWater() {
System.out.println("Boiling water");
}
void pourInCup() {
System.out.println("Pouring into cup");
}
}
// 具体实现
class Tea extends CaffeineBeverage {
@Override
void brew() {
System.out.println("Steeping the tea");
}
@Override
void addCondiments() {
System.out.println("Adding lemon");
}
}
class Coffee extends CaffeineBeverage {
@Override
void brew() {
System.out.println("Dripping coffee through filter");
}
@Override
void addCondiments() {
System.out.println("Adding sugar and milk");
}
}
// 使用
CaffeineBeverage tea = new Tea();
tea.prepareRecipe();
// 输出:
// Boiling water
// Steeping the tea
// Pouring into cup
// Adding lemon
CaffeineBeverage coffee = new Coffee();
coffee.prepareRecipe();
// 输出:
// Boiling water
// Dripping coffee through filter
// Pouring into cup
// Adding sugar and milk
23. 访问者模式(Visitor)
比喻:就像医院体检,一队医生(访问者)轮流检查你身体每个器官。
应用场景:对一个对象结构中的元素进行操作,不改变元素的类。
代码示例:
// 访问者接口
interface Visitor {
void visit(Animal animal);
void visit(Plant plant);
}
// 具体访问者
class ZooKeeper implements Visitor {
@Override
public void visit(Animal animal) {
System.out.println("ZooKeeper feeding " + animal.getName());
}
@Override
public void visit(Plant plant) {
System.out.println("ZooKeeper watering " + plant.getName());
}
}
// 元素接口
interface Element {
void accept(Visitor visitor);
}
// 具体元素
class Animal implements Element {
private String name;
public Animal(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
class Plant implements Element {
private String name;
public Plant(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
// 使用
Element animal = new Animal("Lion");
Element plant = new Plant("Tree");
Visitor zooKeeper = new ZooKeeper();
animal.accept(zooKeeper); // ZooKeeper feeding Lion
plant.accept(zooKeeper); // ZooKeeper watering Tree
💡 为什么学习设计模式?
设计模式不是"必须用"的魔法,而是"知道时能用"的工具。就像你不会每顿饭都用刀叉,但知道怎么用才能吃得更好。
"设计模式不是目的,而是手段;不是为了用而用,而是为了更好地解决问题。"