创建型
工厂模式
定义一个工厂接口,让子类去决定具体创建哪种产品
产品接口A+具体产品实现产品接口A
抽象类工厂B,里面的抽象方法是创建产品+具体工厂继承工厂B,创建产品的方法里按照想要创建的产品来new对象
客户端使用 工厂B=具体工厂,工厂B.创建产品,产品.具体方法。
也就是直接用工厂就能创建出不同的产品,只需要直接new的时候是new哪个具体工厂就行
解耦客户端和具体产品
易于扩展新产品
java
// 产品接口
interface Product {
void use();
}
// 具体产品
class ConcreteProductA implements Product {
public void use() { System.out.println("使用产品A"); }
}
class ConcreteProductB implements Product {
public void use() { System.out.println("使用产品B"); }
}
// 工厂接口
abstract class Factory {
abstract Product createProduct();
}
// 具体工厂
class FactoryA extends Factory {
Product createProduct() { return new ConcreteProductA(); }
}
class FactoryB extends Factory {
Product createProduct() { return new ConcreteProductB(); }
}
// 客户端
public class Client {
public static void main(String[] args) {
Factory factory = new FactoryA();
Product product = factory.createProduct();
product.use(); // 输出:使用产品A
}
}
、
抽象工厂
和工厂差不多,只是上面是一个产品,这里是一族产品。通过抽象工厂接口动态创建同一产品族的一整套产品。
注意工厂,在工厂方法中用的抽象类,在抽象工厂中用的接口。因为单个产品可以实现一些默认方法,抽象工厂更灵活直接用接口定义需要实现哪些方法。
java
interface Button { void click(); }
interface TextField { void display(); }
// 具体产品族:Windows
class WinButton implements Button { public void click() { System.out.println("Windows 按钮点击"); } }
class WinTextField implements TextField { public void display() { System.out.println("Windows 文本框显示"); } }
// 具体产品族:Mac
class MacButton implements Button { public void click() { System.out.println("Mac 按钮点击"); } }
class MacTextField implements TextField { public void display() { System.out.println("Mac 文本框显示"); } }
// 抽象工厂
interface GUIFactory {
Button createButton();
TextField createTextField();
}
// 具体工厂
class WinFactory implements GUIFactory {
public Button createButton() { return new WinButton(); }
public TextField createTextField() { return new WinTextField(); }
}
class MacFactory implements GUIFactory {
public Button createButton() { return new MacButton(); }
public TextField createTextField() { return new MacTextField(); }
}
// 客户端
public class Client {
public static void main(String[] args) {
GUIFactory factory = new WinFactory(); // 可以换成 MacFactory
Button btn = factory.createButton();
TextField tf = factory.createTextField();
btn.click();
tf.display();
}
}
生成器
客户端 → 调用 Director
Director → 按顺序调用 Builder 各个构建方法(Director = 流程封装者,可选,不是必须)
Builder → 构建每个部件
Builder → 返回最终 Product
客户端 → 得到完整产品,无需关心内部步骤
java
class Product {
private String partA;
private String partB;
public void setPartA(String partA) { this.partA = partA; }
public void setPartB(String partB) { this.partB = partB; }
public void show() { System.out.println("PartA: "+partA+", PartB: "+partB); }
}
// 抽象生成器
abstract class Builder {
abstract void buildPartA();
abstract void buildPartB();
abstract Product getResult();
}
// 具体生成器
class ConcreteBuilder extends Builder {
private Product product = new Product();
void buildPartA() { product.setPartA("组件A"); }
void buildPartB() { product.setPartB("组件B"); }
Product getResult() { return product; }
}
// 指挥者
class Director {
private Builder builder;
public Director(Builder builder) { this.builder = builder; }
public Product construct() {
builder.buildPartA();
builder.buildPartB();
return builder.getResult();
}
}
// 客户端
public class Client {
public static void main(String[] args) {
Builder builder = new ConcreteBuilder();
Director director = new Director(builder);
Product product = director.construct();
product.show(); // 输出 PartA: 组件A, PartB: 组件B
}
}
原型
通过复制已有的对象来创建新对象,而不是通过 new 去实例化。
java
interface Prototype extends Cloneable {
Prototype clone();
}
// 具体原型
class ConcretePrototype implements Prototype {
private String field;
public ConcretePrototype(String field) { this.field = field; }
public void setField(String field) { this.field = field; }
public String getField() { return field; }
@Override
public Prototype clone() {
try {
return (ConcretePrototype) super.clone(); // 浅拷贝
} catch (CloneNotSupportedException e) {
return null;
}
}
}
// 客户端
public class Client {
public static void main(String[] args) {
ConcretePrototype prototype = new ConcretePrototype("原型对象");
ConcretePrototype copy = (ConcretePrototype) prototype.clone();
copy.setField("克隆对象");
System.out.println(prototype.getField()); // 输出:原型对象
System.out.println(copy.getField()); // 输出:克隆对象
}
}
单例
保证一个类只有一个实例,并提供全局访问点
java
class Singleton {
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;
}
}
java
class Singleton {
private Singleton() {}
private static class Holder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return Holder.INSTANCE;
}
}
结构型
适配器
Target(目标接口)
- 客户端期待的接口
Adaptee(适配者)
- 已有的接口或类,需要适配
Adapter(适配器)
- 将 Adaptee 转换为 Target 接口
- 客户端通过 Adapter 调用 Adaptee
将一个类的接口转换成客户端期望的接口,使原本因接口不兼容而无法一起工作的类能够协同工作。
java
interface MediaPlayer { // Target
void play(String audioType, String fileName);
}
class Mp3Player implements MediaPlayer { // 已有类,直接支持 mp3
public void play(String audioType, String fileName) {
if(audioType.equalsIgnoreCase("mp3")) {
System.out.println("播放 mp3 文件:" + fileName);
}
}
}
// 适配者:支持 vlc 格式
class VlcPlayer {
public void playVlc(String fileName) {
System.out.println("播放 vlc 文件:" + fileName);
}
}
// 适配器:把 VlcPlayer 适配成 MediaPlayer
class MediaAdapter implements MediaPlayer {
private VlcPlayer vlcPlayer;
public MediaAdapter(String audioType) {
if(audioType.equalsIgnoreCase("vlc")) {
vlcPlayer = new VlcPlayer();
}
}
public void play(String audioType, String fileName) {
if(audioType.equalsIgnoreCase("vlc")) {
vlcPlayer.playVlc(fileName);
}
}
}
// 客户端
public class AudioPlayer implements MediaPlayer {
MediaAdapter mediaAdapter;
public void play(String audioType, String fileName) {
if(audioType.equalsIgnoreCase("mp3")) {
System.out.println("播放 mp3 文件:" + fileName);
} else if(audioType.equalsIgnoreCase("vlc")) {
mediaAdapter = new MediaAdapter(audioType);
mediaAdapter.play(audioType, fileName);
} else {
System.out.println("格式不支持:" + audioType);
}
}
}
桥接器
- 问题来源**
假设你要设计一个绘图系统,有两类变化维度:
- 形状(Shape):圆形、方形、三角形......
- 颜色/绘制方式(DrawAPI):红色、绿色、蓝色、虚线、实线......
如果你用传统继承:
- 你可能会写
RedCircle、GreenCircle、RedSquare、GreenSquare...... - 这样类数量 会爆炸(形状 × 绘制方式 = 很多类)
- 桥接模式的目的**
桥接模式就是 解耦两个变化维度:
- 抽象部分(Shape):定义形状
- 实现部分(DrawAPI):定义颜色或绘制方式
- 桥接:Shape 持有 DrawAPI 的引用,通过它去绘制
这样就可以自由组合:
- 圆形 + 红色
- 圆形 + 绿色
- 方形 + 红色
- 方形 + 绿色
而不需要为每种组合写一个类。
桥接模式 = 把"抽象"和"实现"分开,让两边独立扩展,自由组合
-
抽象(Shape)和实现(DrawAPI)都可以独立增加新类
-
不用继承堆出大量子类
-
抽象 = "形状工厂"
-
实现 = "画笔类型"
-
桥接 = "工厂拿着画笔去画"
-
好处:你可以随便换工厂或画笔组合,不用写新类
💡 一句话理解:
桥接模式就是 解决两个变化维度的组合问题,让它们独立扩展,不爆炸类。
java
// 实现部分接口:绘制方式
interface DrawAPI {
void draw(String shapeName, int x, int y);
}
// 具体实现1:红色绘制
class RedDraw implements DrawAPI {
public void draw(String shapeName, int x, int y) {
System.out.println("用红色画 " + shapeName + " 在 (" + x + "," + y + ")");
}
}
// 具体实现2:绿色绘制
class GreenDraw implements DrawAPI {
public void draw(String shapeName, int x, int y) {
System.out.println("用绿色画 " + shapeName + " 在 (" + x + "," + y + ")");
}
}
// 抽象部分:形状
abstract class Shape {
protected DrawAPI drawAPI; // 桥接
protected String name;
public Shape(String name, DrawAPI drawAPI) {
this.name = name;
this.drawAPI = drawAPI;
}
abstract void draw(int x, int y);
}
// 扩展抽象类1:圆形
class Circle extends Shape {
public Circle(DrawAPI drawAPI) {
super("圆形", drawAPI);
}
public void draw(int x, int y) {
drawAPI.draw(name, x, y);
}
}
// 扩展抽象类2:方形
class Square extends Shape {
public Square(DrawAPI drawAPI) {
super("方形", drawAPI);
}
public void draw(int x, int y) {
drawAPI.draw(name, x, y);
}
}
// 客户端演示
public class Client {
public static void main(String[] args) {
// 红色圆形
Shape redCircle = new Circle(new RedDraw());
redCircle.draw(10, 20);
// 绿色圆形
Shape greenCircle = new Circle(new GreenDraw());
greenCircle.draw(15, 25);
// 红色方形
Shape redSquare = new Square(new RedDraw());
redSquare.draw(5, 5);
// 绿色方形
Shape greenSquare = new Square(new GreenDraw());
greenSquare.draw(12, 8);
}
}
组合
组合模式 = 把单个对象和组合对象用同一个接口表示 ,让客户端 一致地处理单个对象和组合对象。
优点:
- 客户端操作统一
- 支持树形结构递归
- 易扩展新类型
java
import java.util.*;
// 组件接口
interface Component {
void showName();
}
// 叶子节点:文件
class FileLeaf implements Component {
private String name;
public FileLeaf(String name) { this.name = name; }
public void showName() {
System.out.println("文件: " + name);
}
}
// 组合节点:文件夹
class FolderComposite implements Component {
private String name;
private List<Component> children = new ArrayList<>();
public FolderComposite(String name) { this.name = name; }
public void add(Component c) { children.add(c); }
public void remove(Component c) { children.remove(c); }
public void showName() {
System.out.println("文件夹: " + name);
for(Component c : children) {
c.showName(); // 递归调用
}
}
}
// 客户端
public class Client {
public static void main(String[] args) {
Component file1 = new FileLeaf("file1.txt");
Component file2 = new FileLeaf("file2.txt");
FolderComposite folder1 = new FolderComposite("folder1");
folder1.add(file1);
folder1.add(file2);
Component file3 = new FileLeaf("file3.txt");
FolderComposite root = new FolderComposite("root");
root.add(folder1);
root.add(file3);
root.showName();
}
}
装饰器
装饰模式 = 动态给对象添加功能,而不改原类
Component(组件接口) = 原始对象的接口(咖啡、饮品)
ConcreteComponent(具体组件) = 原始对象(SimpleCoffee)
Decorator(装饰类) = 持有 Component 引用,扩展功能
ConcreteDecorator(具体装饰) = 牛奶、糖、巧克力等
java
interface Coffee { // Component
double cost();
String getDescription();
}
// ConcreteComponent
class SimpleCoffee implements Coffee {
public double cost() { return 5; }
public String getDescription() { return "简单咖啡"; }
}
// Decorator
abstract class CoffeeDecorator implements Coffee {
protected Coffee coffee;
public CoffeeDecorator(Coffee coffee) { this.coffee = coffee; }
}
// ConcreteDecorator 1:加牛奶
class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee coffee) { super(coffee); }
public double cost() { return coffee.cost() + 2; }
public String getDescription() { return coffee.getDescription() + " + 牛奶"; }
}
// ConcreteDecorator 2:加糖
class SugarDecorator extends CoffeeDecorator {
public SugarDecorator(Coffee coffee) { super(coffee); }
public double cost() { return coffee.cost() + 1; }
public String getDescription() { return coffee.getDescription() + " + 糖"; }
}
// 客户端
public class Client {
public static void main(String[] args) {
Coffee coffee = new SimpleCoffee();
System.out.println(coffee.getDescription() + " ¥" + coffee.cost());
coffee = new MilkDecorator(coffee);
coffee = new SugarDecorator(coffee);
System.out.println(coffee.getDescription() + " ¥" + coffee.cost());
}
}
外观
- 核心问题**
假设你在做 家庭影院系统:
- 有多个子系统:DVD 播放器、音响、投影仪、灯光、空调......
- 客户端想"看电影"
- 如果客户端自己一个个去调用每个子系统的开关方法,太复杂
问题:客户端不想关心这么多细节,只想一个简单接口操作整个系统
- 外观模式的目的**
提供一个 统一的高层接口 ,让客户端 简单操作复杂子系统,降低耦合。
核心思想:
- Facade(外观类) = 提供简单接口
- Subsystem(子系统) = 具体复杂系统
- 客户端只和 Facade 交互,不直接操作子系统
java
class DVDPlayer {
public void on() { System.out.println("DVD 打开"); }
public void play(String movie) { System.out.println("播放电影:" + movie); }
public void off() { System.out.println("DVD 关闭"); }
}
class Projector {
public void on() { System.out.println("投影仪打开"); }
public void off() { System.out.println("投影仪关闭"); }
}
class SoundSystem {
public void on() { System.out.println("音响打开"); }
public void off() { System.out.println("音响关闭"); }
}
// 外观类
class HomeTheaterFacade {
private DVDPlayer dvd;
private Projector projector;
private SoundSystem sound;
public HomeTheaterFacade(DVDPlayer dvd, Projector projector, SoundSystem sound) {
this.dvd = dvd;
this.projector = projector;
this.sound = sound;
}
public void watchMovie(String movie) {
System.out.println("准备看电影...");
dvd.on();
dvd.play(movie);
projector.on();
sound.on();
}
public void endMovie() {
System.out.println("结束电影...");
dvd.off();
projector.off();
sound.off();
}
}
// 客户端
public class Client {
public static void main(String[] args) {
DVDPlayer dvd = new DVDPlayer();
Projector projector = new Projector();
SoundSystem sound = new SoundSystem();
HomeTheaterFacade theater = new HomeTheaterFacade(dvd, projector, sound);
theater.watchMovie("阿凡达");
System.out.println("----电影结束----");
theater.endMovie();
}
}
享元
共享对象,避免重复创建 ,把可共享部分和不可共享部分分离。
核心思想:
- Intrinsic state(内部状态,可共享):对象的共享部分,比如字符"a"的字体、形状
- Extrinsic state(外部状态,不可共享):对象的上下文,比如位置、颜色
- 享元工厂:统一管理共享对象,避免重复创建
java
import java.util.*;
// 抽象享元
interface Glyph {
void display(int x, int y); // 外部状态:位置
}
// 具体享元
class CharacterGlyph implements Glyph {
private char character; // 内部状态:字符本身
public CharacterGlyph(char character) {
this.character = character;
}
public void display(int x, int y) {
System.out.println("显示字符 '" + character + "' 在 (" + x + "," + y + ")");
}
}
// 享元工厂
class GlyphFactory {
private Map<Character, Glyph> pool = new HashMap<>();
public Glyph getCharacter(char c) {
if(!pool.containsKey(c)) {
pool.put(c, new CharacterGlyph(c));
}
return pool.get(c);
}
}
// 客户端
public class Client {
public static void main(String[] args) {
GlyphFactory factory = new GlyphFactory();
// 文本 "HELLO"
int x = 0;
for(char c : "HELLO".toCharArray()) {
Glyph glyph = factory.getCharacter(c);
glyph.display(x, 0); // 位置不同,字符对象共享
x += 1;
}
}
}
代理
代理模式 = 在真实对象前后加"代理",增加控制逻辑
java
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("从磁盘加载图片:" + filename);
}
public void display() {
System.out.println("显示图片:" + filename);
}
}
// 代理
class ProxyImage implements Image {
private RealImage realImage;
private String filename;
public ProxyImage(String filename) {
this.filename = filename;
}
public void display() {
if(realImage == null) { // 延迟加载
realImage = new RealImage(filename);
}
System.out.println("代理操作前逻辑");
realImage.display(); // 调用真实对象
System.out.println("代理操作后逻辑");
}
}
// 客户端
public class Client {
public static void main(String[] args) {
Image image = new ProxyImage("test.jpg");
// 第一次显示,真实对象才会被创建
image.display();
System.out.println("---第二次显示---");
// 第二次显示,不需要重新加载
image.display();
}
}
行为型
责任链
让多个对象都有机会处理请求,将请求沿着链传递,直到有对象处理它。
核心思想:
- Handler(处理者接口) = 定义处理请求方法和链的引用
- ConcreteHandler(具体处理者) = 实现处理逻辑,决定是否处理或传给下一个
- Client(客户端) = 只发起请求,不关心谁处理
请假审批
日志处理(debug/info/error 按级别处理)
事件处理(GUI 事件冒泡)
系统请求过滤(安全过滤器链
java
abstract class Handler {
protected Handler next; // 链上的下一个处理者
public void setNext(Handler next) {
this.next = next;
}
public abstract void handleRequest(int days);
}
// 具体处理者1:班主任
class ClassTeacher extends Handler {
public void handleRequest(int days) {
if(days <= 2) {
System.out.println("班主任批准请假 " + days + " 天");
} else if(next != null) {
next.handleRequest(days); // 转交下一个
}
}
}
// 具体处理者2:系主任
class DepartmentHead extends Handler {
public void handleRequest(int days) {
if(days <= 5) {
System.out.println("系主任批准请假 " + days + " 天");
} else if(next != null) {
next.handleRequest(days);
}
}
}
// 具体处理者3:校长
class Principal extends Handler {
public void handleRequest(int days) {
System.out.println("校长批准请假 " + days + " 天");
}
}
// 客户端
public class Client {
public static void main(String[] args) {
Handler classTeacher = new ClassTeacher();
Handler deptHead = new DepartmentHead();
Handler principal = new Principal();
// 设置责任链
classTeacher.setNext(deptHead);
deptHead.setNext(principal);
// 发起请求
int leaveDays1 = 1;
classTeacher.handleRequest(leaveDays1); // 由班主任处理
int leaveDays2 = 4;
classTeacher.handleRequest(leaveDays2); // 班主任不处理,传给系主任
int leaveDays3 = 10;
classTeacher.handleRequest(leaveDays3); // 最终由校长处理
}
}
命令
把"请求"抽象成对象,让调用者(Invoker)不用关心请求细节,提高系统灵活性和可扩展性.遥控器(Invoker)可以动态控制 任意设备
java
// 命令接口
interface Command {
void execute();
}
// 接收者1:灯
class Light {
public void on() { System.out.println("灯打开"); }
public void off() { System.out.println("灯关闭"); }
}
// 接收者2:空调
class AirCondition {
public void on() { System.out.println("空调打开"); }
public void off() { System.out.println("空调关闭"); }
}
// 具体命令1:开灯
class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) { this.light = light; }
public void execute() { light.on(); }
}
// 具体命令2:关灯
class LightOffCommand implements Command {
private Light light;
public LightOffCommand(Light light) { this.light = light; }
public void execute() { light.off(); }
}
// 具体命令3:开空调
class ACOnCommand implements Command {
private AirCondition ac;
public ACOnCommand(AirCondition ac) { this.ac = ac; }
public void execute() { ac.on(); }
}
// 具体命令4:关空调
class ACOffCommand implements Command {
private AirCondition ac;
public ACOffCommand(AirCondition ac) { this.ac = ac; }
public void execute() { ac.off(); }
}
// 调用者:遥控器
class RemoteControl {
private Command slot;
public void setCommand(Command command) { slot = command; }
public void pressButton() { slot.execute(); }
}
// 客户端
public class Client {
public static void main(String[] args) {
Light light = new Light();
AirCondition ac = new AirCondition();
Command lightOn = new LightOnCommand(light);
Command lightOff = new LightOffCommand(light);
Command acOn = new ACOnCommand(ac);
Command acOff = new ACOffCommand(ac);
RemoteControl remote = new RemoteControl();
// 开灯
remote.setCommand(lightOn);
remote.pressButton();
// 关灯
remote.setCommand(lightOff);
remote.pressButton();
// 开空调
remote.setCommand(acOn);
remote.pressButton();
// 关空调
remote.setCommand(acOff);
remote.pressButton();
}
}
迭代器
提供一种 顺序访问集合元素的方式,而不暴露集合内部结构。
Iterator(迭代器接口) = 提供访问元素的方法(hasNext()、next())
ConcreteIterator(具体迭代器) = 实现遍历逻辑
Aggregate(聚合接口) = 提供创建迭代器方法
ConcreteAggregate(具体聚合) = 实现集合存储和迭代器创建
java
import java.util.*;
// 迭代器接口
interface Iterator<E> {
boolean hasNext();
E next();
}
// 聚合接口
interface Aggregate<E> {
Iterator<E> createIterator();
}
// 具体聚合:书架
class BookShelf implements Aggregate<String> {
private List<String> books = new ArrayList<>();
public void addBook(String book) {
books.add(book);
}
public Iterator<String> createIterator() {
return new BookShelfIterator(books);
}
}
// 具体迭代器
class BookShelfIterator implements Iterator<String> {
private List<String> books;
private int index = 0;
public BookShelfIterator(List<String> books) {
this.books = books;
}
public boolean hasNext() {
return index < books.size();
}
public String next() {
return books.get(index++);
}
}
// 客户端
public class Client {
public static void main(String[] args) {
BookShelf shelf = new BookShelf();
shelf.addBook("Java 编程思想");
shelf.addBook("Effective Java");
shelf.addBook("算法导论");
Iterator<String> iterator = shelf.createIterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
中介者
中介者模式 = 对象之间不直接通信,通过中介者协调
java
import java.util.*;
// 中介者接口
interface Mediator {
void sendMessage(String message, Colleague colleague);
}
// 同事抽象类
abstract class Colleague {
protected Mediator mediator;
public Colleague(Mediator mediator) { this.mediator = mediator; }
public abstract void receive(String message);
}
// 具体中介者
class ConcreteMediator implements Mediator {
private List<Colleague> colleagues = new ArrayList<>();
public void addColleague(Colleague colleague) {
colleagues.add(colleague);
}
public void sendMessage(String message, Colleague sender) {
for(Colleague c : colleagues) {
if(c != sender) { // 不给自己发
c.receive(message);
}
}
}
}
// 具体同事1
class User extends Colleague {
private String name;
public User(Mediator mediator, String name) { super(mediator); this.name = name; }
public void send(String message) {
System.out.println(name + " 发送消息: " + message);
mediator.sendMessage(message, this);
}
public void receive(String message) {
System.out.println(name + " 收到消息: " + message);
}
}
// 客户端
public class Client {
public static void main(String[] args) {
ConcreteMediator chatRoom = new ConcreteMediator();
User u1 = new User(chatRoom, "Alice");
User u2 = new User(chatRoom, "Bob");
User u3 = new User(chatRoom, "Charlie");
chatRoom.addColleague(u1);
chatRoom.addColleague(u2);
chatRoom.addColleague(u3);
u1.send("Hello, everyone!");
u2.send("Hi, Alice!");
}
}
备忘录
备忘录模式 = 保存对象状态 → 方便撤销/恢复 → 不破坏封装
Originator(发起人) = 拥有内部状态,并能创建/恢复备忘录
Memento(备忘录) = 存储发起人的内部状态
Caretaker(管理者) = 管理备忘录,不修改内容,只保存和提供恢复
java
import java.util.*;
// 发起人
class Editor {
private String content;
public void setContent(String content) { this.content = content; }
public String getContent() { return content; }
// 创建备忘录
public Memento save() {
return new Memento(content);
}
// 恢复备忘录
public void restore(Memento memento) {
this.content = memento.getContent();
}
}
// 备忘录
class Memento {
private final String content;
public Memento(String content) { this.content = content; }
public String getContent() { return content; }
}
// 管理者
class Caretaker {
private Stack<Memento> history = new Stack<>();
public void save(Memento memento) { history.push(memento); }
public Memento undo() { return history.pop(); }
}
// 客户端
public class Client {
public static void main(String[] args) {
Editor editor = new Editor();
Caretaker caretaker = new Caretaker();
editor.setContent("Hello");
caretaker.save(editor.save());
editor.setContent("Hello, World");
caretaker.save(editor.save());
editor.setContent("Hello, World!!!");
System.out.println("当前内容:" + editor.getContent());
editor.restore(caretaker.undo());
System.out.println("撤销一次:" + editor.getContent());
editor.restore(caretaker.undo());
System.out.println("撤销两次:" + editor.getContent());
}
}
观察者
定义对象间的一种一对多依赖关系,让一个对象状态变化时,所有依赖它的对象都会收到通知并自动更新
Subject(主题/被观察者) = 保存观察者列表,状态变化时通知它们
Observer(观察者) = 定义接收更新的方法
ConcreteObserver(具体观察者) = 实现更新逻辑
java
import java.util.*;
// 观察者接口
interface Observer {
void update(String message);
}
// 主题接口
interface Subject {
void attach(Observer o); // 添加观察者
void detach(Observer o); // 移除观察者
void notifyObservers(); // 通知所有观察者
}
// 具体主题
class WeatherStation implements Subject {
private List<Observer> observers = new ArrayList<>();
private String weather;
public void setWeather(String weather) {
this.weather = weather;
notifyObservers(); // 天气变化,通知观察者
}
public void attach(Observer o) { observers.add(o); }
public void detach(Observer o) { observers.remove(o); }
public void notifyObservers() {
for(Observer o : observers) {
o.update(weather);
}
}
}
// 具体观察者1
class PhoneDisplay implements Observer {
private String name;
public PhoneDisplay(String name) { this.name = name; }
public void update(String message) {
System.out.println(name + " 手机显示天气: " + message);
}
}
// 具体观察者2
class WindowDisplay implements Observer {
private String name;
public WindowDisplay(String name) { this.name = name; }
public void update(String message) {
System.out.println(name + " 窗口显示天气: " + message);
}
}
// 客户端
public class Client {
public static void main(String[] args) {
WeatherStation station = new WeatherStation();
Observer phone = new PhoneDisplay("Alice");
Observer window = new WindowDisplay("Bob");
station.attach(phone);
station.attach(window);
station.setWeather("晴天");
station.setWeather("下雨");
}
}
状态
- State(状态接口) = 定义不同状态下的行为
- ConcreteState(具体状态) = 实现状态对应行为
- Context(环境类) = 持有当前状态,根据状态调用对应行为
允许对象在内部状态改变时改变它的行为
播放器根据当前状态自动选择行为,不用在按钮里写一堆 if/else 判断
java
interface State {
void pressPlay(MusicPlayer player);
void pressPause(MusicPlayer player);
void pressStop(MusicPlayer player);
}
// 播放状态
class PlayingState implements State {
public void pressPlay(MusicPlayer player) {
System.out.println("已经在播放中");
}
public void pressPause(MusicPlayer player) {
System.out.println("暂停播放");
player.setState(new PausedState());
}
public void pressStop(MusicPlayer player) {
System.out.println("停止播放");
player.setState(new StoppedState());
}
}
// 暂停状态
class PausedState implements State {
public void pressPlay(MusicPlayer player) {
System.out.println("恢复播放");
player.setState(new PlayingState());
}
public void pressPause(MusicPlayer player) {
System.out.println("已经暂停");
}
public void pressStop(MusicPlayer player) {
System.out.println("停止播放");
player.setState(new StoppedState());
}
}
// 停止状态
class StoppedState implements State {
public void pressPlay(MusicPlayer player) {
System.out.println("开始播放");
player.setState(new PlayingState());
}
public void pressPause(MusicPlayer player) {
System.out.println("停止状态不能暂停");
}
public void pressStop(MusicPlayer player) {
System.out.println("已经停止");
}
}
// 环境类
class MusicPlayer {
private State state;
public MusicPlayer() {
state = new StoppedState(); // 初始状态
}
public void setState(State state) { this.state = state; }
public void pressPlay() { state.pressPlay(this); }
public void pressPause() { state.pressPause(this); }
public void pressStop() { state.pressStop(this); }
}
// 客户端
public class Client {
public static void main(String[] args) {
MusicPlayer player = new MusicPlayer();
player.pressPlay(); // 开始播放
player.pressPause(); // 暂停播放
player.pressPlay(); // 恢复播放
player.pressStop(); // 停止播放
player.pressPause(); // 停止状态不能暂停
}
}
策略
Strategy(策略接口) = 定义算法/行为接口
ConcreteStrategy(具体策略) = 实现不同算法/行为
Context(环境类) = 持有策略对象,通过它调用对应行为
策略模式 = 把变化的算法封装起来 → 客户端可动态选择
java
interface PaymentStrategy {
void pay(double amount);
}
// 具体策略1:支付宝
class Alipay implements PaymentStrategy {
public void pay(double amount) {
System.out.println("使用支付宝支付:" + amount + " 元");
}
}
// 具体策略2:微信
class WechatPay implements PaymentStrategy {
public void pay(double amount) {
System.out.println("使用微信支付:" + amount + " 元");
}
}
// 具体策略3:银行卡
class BankCardPay implements PaymentStrategy {
public void pay(double amount) {
System.out.println("使用银行卡支付:" + amount + " 元");
}
}
// 环境类
class PaymentContext {
private PaymentStrategy strategy;
public PaymentContext(PaymentStrategy strategy) {
this.strategy = strategy;
}
public void setStrategy(PaymentStrategy strategy) { this.strategy = strategy; }
public void pay(double amount) { strategy.pay(amount); }
}
// 客户端
public class Client {
public static void main(String[] args) {
PaymentContext context = new PaymentContext(new Alipay());
context.pay(100); // 支付宝支付 100 元
context.setStrategy(new WechatPay());
context.pay(200); // 微信支付 200 元
context.setStrategy(new BankCardPay());
context.pay(300); // 银行卡支付 300 元
}
}
模板方法
模板方法模式 = 固定算法骨架,允许子类定制具体步骤
java
abstract class Beverage {
// 模板方法(固定流程)
public final void prepare() {
boilWater();
brew();
pourInCup();
addCondiments();
}
private void boilWater() {
System.out.println("烧水");
}
protected abstract void brew(); // 冲泡
private void pourInCup() {
System.out.println("倒入杯中");
}
protected abstract void addCondiments(); // 加调料
}
// 具体子类:咖啡
class Coffee extends Beverage {
protected void brew() {
System.out.println("用热水冲泡咖啡");
}
protected void addCondiments() {
System.out.println("加糖和牛奶");
}
}
// 具体子类:茶
class Tea extends Beverage {
protected void brew() {
System.out.println("用热水浸泡茶叶");
}
protected void addCondiments() {
System.out.println("加柠檬");
}
}
// 客户端
public class Client {
public static void main(String[] args) {
Beverage coffee = new Coffee();
coffee.prepare();
System.out.println("----------");
Beverage tea = new Tea();
tea.prepare();
}
}
访问者
将作用于对象结构上的操作封装到独立访问者类中,使得在不修改对象的前提下可以定义新的操作
核心思想:
- Visitor(访问者接口) = 定义访问不同类型元素的方法
- ConcreteVisitor(具体访问者) = 实现具体操作
- Element(元素接口) = 接受访问者
- ConcreteElement(具体元素) = 实现接受访问者方法
- ObjectStructure(对象结构) = 管理一组元素,允许访问者访问
java
import java.util.*;
// 元素接口
interface Employee {
void accept(Visitor visitor);
}
// 具体元素1:程序员
class Programmer implements Employee {
private String name;
private int hours;
public Programmer(String name, int hours) { this.name = name; this.hours = hours; }
public String getName() { return name; }
public int getHours() { return hours; }
public void accept(Visitor visitor) { visitor.visit(this); }
}
// 具体元素2:经理
class Manager implements Employee {
private String name;
private int teamSize;
public Manager(String name, int teamSize) { this.name = name; this.teamSize = teamSize; }
public String getName() { return name; }
public int getTeamSize() { return teamSize; }
public void accept(Visitor visitor) { visitor.visit(this); }
}
// 访问者接口
interface Visitor {
void visit(Programmer programmer);
void visit(Manager manager);
}
// 具体访问者:计算工资
class SalaryVisitor implements Visitor {
public void visit(Programmer programmer) {
System.out.println(programmer.getName() + " 工资:" + programmer.getHours() * 100 + " 元");
}
public void visit(Manager manager) {
System.out.println(manager.getName() + " 工资:" + (manager.getTeamSize() * 500 + 3000) + " 元");
}
}
// 对象结构
class Company {
private List<Employee> employees = new ArrayList<>();
public void addEmployee(Employee e) { employees.add(e); }
public void accept(Visitor visitor) {
for(Employee e : employees) e.accept(visitor);
}
}
// 客户端
public class Client {
public static void main(String[] args) {
Company company = new Company();
company.addEmployee(new Programmer("Alice", 160));
company.addEmployee(new Manager("Bob", 5));
SalaryVisitor salaryVisitor = new SalaryVisitor();
company.accept(salaryVisitor);
}
}