软件设计模式详解
我将按照创建型、结构型和行为型三大类详细讲解23个设计模式,每个模式都包含使用场景、解决问题、优点、缺点以及Java代码示例。
一、创建型模式(5个)
1. 单例模式(Singleton)
使用场景:
- 需要控制资源访问,如数据库连接池
- 配置管理器
- 日志记录器
- 线程池
解决问题:
- 确保一个类只有一个实例
- 提供全局访问点
优点:
- 减少内存开销
- 避免资源多重占用
- 全局访问点便于管理
缺点:
- 违反单一职责原则
- 难以测试
- 可能隐藏不良设计
java
// 双重检查锁实现的单例模式
public class Singleton {
private volatile static Singleton instance;
private Singleton() {
// 私有构造器
}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
// 业务方法
public void showMessage() {
System.out.println("Hello Singleton Pattern!");
}
}
// 使用示例
public class SingletonDemo {
public static void main(String[] args) {
Singleton singleton = Singleton.getInstance();
singleton.showMessage();
}
}
2. 工厂方法模式(Factory Method)
使用场景:
- 创建复杂对象
- 需要根据条件创建不同对象
- 数据库访问层
- 日志记录器
解决问题:
- 对象创建与使用的解耦
- 支持扩展新产品
优点:
- 符合开闭原则
- 客户端代码简洁
- 易于扩展
缺点:
- 增加类的数量
- 增加系统复杂度
java
// 产品接口
interface Product {
void use();
}
// 具体产品A
class ConcreteProductA implements Product {
@Override
public void use() {
System.out.println("Using Product A");
}
}
// 具体产品B
class ConcreteProductB implements Product {
@Override
public void use() {
System.out.println("Using Product B");
}
}
// 工厂接口
interface Factory {
Product createProduct();
}
// 具体工厂A
class ConcreteFactoryA implements Factory {
@Override
public Product createProduct() {
return new ConcreteProductA();
}
}
// 具体工厂B
class ConcreteFactoryB implements Factory {
@Override
public Product createProduct() {
return new ConcreteProductB();
}
}
// 使用示例
public class FactoryMethodDemo {
public static void main(String[] args) {
Factory factory = new ConcreteFactoryA();
Product product = factory.createProduct();
product.use();
factory = new ConcreteFactoryB();
product = factory.createProduct();
product.use();
}
}
3. 抽象工厂模式(Abstract Factory)
使用场景:
- 创建相关产品族
- 跨平台UI组件
- 数据库迁移
解决问题:
- 创建一系列相关或依赖的对象
- 确保产品兼容性
优点:
- 产品族一致性
- 便于交换产品系列
- 符合开闭原则
缺点:
- 增加系统复杂度
- 扩展新产品困难
java
// 抽象产品A
interface Button {
void paint();
}
// 具体产品A1
class WindowsButton implements Button {
@Override
public void paint() {
System.out.println("Rendering Windows style button");
}
}
// 具体产品A2
class MacButton implements Button {
@Override
public void paint() {
System.out.println("Rendering Mac style button");
}
}
// 抽象产品B
interface Checkbox {
void paint();
}
// 具体产品B1
class WindowsCheckbox implements Checkbox {
@Override
public void paint() {
System.out.println("Rendering Windows style checkbox");
}
}
// 具体产品B2
class MacCheckbox implements Checkbox {
@Override
public void paint() {
System.out.println("Rendering Mac style checkbox");
}
}
// 抽象工厂
interface GUIFactory {
Button createButton();
Checkbox createCheckbox();
}
// 具体工厂1
class WindowsFactory implements GUIFactory {
@Override
public Button createButton() {
return new WindowsButton();
}
@Override
public Checkbox createCheckbox() {
return new WindowsCheckbox();
}
}
// 具体工厂2
class MacFactory implements GUIFactory {
@Override
public Button createButton() {
return new MacButton();
}
@Override
public Checkbox createCheckbox() {
return new MacCheckbox();
}
}
// 客户端代码
public class AbstractFactoryDemo {
private Button button;
private Checkbox checkbox;
public AbstractFactoryDemo(GUIFactory factory) {
button = factory.createButton();
checkbox = factory.createCheckbox();
}
public void paint() {
button.paint();
checkbox.paint();
}
public static void main(String[] args) {
// 创建Windows风格界面
GUIFactory windowsFactory = new WindowsFactory();
AbstractFactoryDemo windowsApp = new AbstractFactoryDemo(windowsFactory);
windowsApp.paint();
// 创建Mac风格界面
GUIFactory macFactory = new MacFactory();
AbstractFactoryDemo macApp = new AbstractFactoryDemo(macFactory);
macApp.paint();
}
}
4. 建造者模式(Builder)
使用场景:
- 创建复杂对象
- 需要多种表示的对象
- 参数较多且有默认值
解决问题:
- 分离复杂对象的构建和表示
- 简化客户端创建过程
优点:
- 构建过程可控
- 易于扩展
- 分离构造代码
缺点:
- 增加系统复杂度
- 产品必须有共同点
java
// 产品类
class Computer {
private String CPU;
private String RAM;
private String storage;
private String GPU;
// 私有构造器
private Computer(Builder builder) {
this.CPU = builder.CPU;
this.RAM = builder.RAM;
this.storage = builder.storage;
this.GPU = builder.GPU;
}
@Override
public String toString() {
return "Computer [CPU=" + CPU + ", RAM=" + RAM +
", storage=" + storage + ", GPU=" + GPU + "]";
}
// 建造者类
public static class Builder {
private String CPU;
private String RAM;
private String storage;
private String GPU;
public Builder setCPU(String CPU) {
this.CPU = CPU;
return this;
}
public Builder setRAM(String RAM) {
this.RAM = RAM;
return this;
}
public Builder setStorage(String storage) {
this.storage = storage;
return this;
}
public Builder setGPU(String GPU) {
this.GPU = GPU;
return this;
}
public Computer build() {
return new Computer(this);
}
}
}
// 使用示例
public class BuilderDemo {
public static void main(String[] args) {
// 创建高性能电脑
Computer gamingPC = new Computer.Builder()
.setCPU("Intel i9")
.setRAM("32GB")
.setStorage("1TB SSD")
.setGPU("RTX 3080")
.build();
System.out.println("Gaming PC: " + gamingPC);
// 创建办公电脑
Computer officePC = new Computer.Builder()
.setCPU("Intel i5")
.setRAM("16GB")
.setStorage("512GB SSD")
.build(); // 没有设置GPU
System.out.println("Office PC: " + officePC);
}
}
5. 原型模式(Prototype)
使用场景:
- 对象创建成本较高
- 需要大量相似对象
- 需要保存对象状态
解决问题:
- 减少对象创建开销
- 简化对象创建过程
优点:
- 提高性能
- 简化创建过程
- 动态获取新对象
缺点:
- 深拷贝实现复杂
- 需要为每个类配备克隆方法
java
import java.util.ArrayList;
import java.util.List;
// 原型接口
interface Prototype extends Cloneable {
Prototype clone();
}
// 具体原型类
class ConcretePrototype implements Prototype {
private String name;
private List<String> features;
public ConcretePrototype(String name) {
this.name = name;
this.features = new ArrayList<>();
}
public void addFeature(String feature) {
features.add(feature);
}
@Override
public Prototype clone() {
ConcretePrototype clone = new ConcretePrototype(this.name);
// 深拷贝列表
clone.features = new ArrayList<>(this.features);
return clone;
}
@Override
public String toString() {
return "ConcretePrototype{name='" + name + "', features=" + features + "}";
}
}
// 原型注册表
class PrototypeRegistry {
private static java.util.Map<String, Prototype> prototypes = new java.util.HashMap<>();
static {
ConcretePrototype defaultPrototype = new ConcretePrototype("Default");
defaultPrototype.addFeature("Basic Feature");
prototypes.put("default", defaultPrototype);
}
public static void addPrototype(String key, Prototype prototype) {
prototypes.put(key, prototype);
}
public static Prototype getPrototype(String key) {
Prototype prototype = prototypes.get(key);
return prototype != null ? prototype.clone() : null;
}
}
// 使用示例
public class PrototypeDemo {
public static void main(String[] args) {
// 从注册表获取并克隆原型
Prototype prototype1 = PrototypeRegistry.getPrototype("default");
System.out.println("Prototype 1: " + prototype1);
// 创建新原型并注册
ConcretePrototype customPrototype = new ConcretePrototype("Custom");
customPrototype.addFeature("Advanced Feature 1");
customPrototype.addFeature("Advanced Feature 2");
PrototypeRegistry.addPrototype("custom", customPrototype);
// 克隆自定义原型
Prototype prototype2 = PrototypeRegistry.getPrototype("custom");
System.out.println("Prototype 2: " + prototype2);
// 验证深拷贝
((ConcretePrototype) prototype2).addFeature("New Feature");
System.out.println("Original: " + customPrototype);
System.out.println("Cloned: " + prototype2);
}
}
二、结构型模式(7个)
6. 适配器模式(Adapter)
使用场景:
- 系统需要复用现有类
- 接口不兼容的类需要一起工作
- 旧系统升级
解决问题:
- 接口不兼容问题
- 类的复用
优点:
- 提高类的复用性
- 增加类的透明度
- 灵活性好
缺点:
- 过多使用会使系统混乱
- 增加系统复杂度
java
// 目标接口
interface MediaPlayer {
void play(String audioType, String fileName);
}
// 需要适配的接口
interface AdvancedMediaPlayer {
void playVlc(String fileName);
void playMp4(String fileName);
}
// 具体实现类
class VlcPlayer implements AdvancedMediaPlayer {
@Override
public void playVlc(String fileName) {
System.out.println("Playing vlc file: " + fileName);
}
@Override
public void playMp4(String fileName) {
// 不做任何事
}
}
class Mp4Player implements AdvancedMediaPlayer {
@Override
public void playVlc(String fileName) {
// 不做任何事
}
@Override
public void playMp4(String fileName) {
System.out.println("Playing mp4 file: " + fileName);
}
}
// 适配器类
class MediaAdapter implements MediaPlayer {
private AdvancedMediaPlayer advancedMusicPlayer;
public MediaAdapter(String audioType) {
if (audioType.equalsIgnoreCase("vlc")) {
advancedMusicPlayer = new VlcPlayer();
} else if (audioType.equalsIgnoreCase("mp4")) {
advancedMusicPlayer = new Mp4Player();
}
}
@Override
public void play(String audioType, String fileName) {
if (audioType.equalsIgnoreCase("vlc")) {
advancedMusicPlayer.playVlc(fileName);
} else if (audioType.equalsIgnoreCase("mp4")) {
advancedMusicPlayer.playMp4(fileName);
}
}
}
// 客户端类
class AudioPlayer implements MediaPlayer {
private MediaAdapter mediaAdapter;
@Override
public void play(String audioType, String fileName) {
// 内置支持mp3格式
if (audioType.equalsIgnoreCase("mp3")) {
System.out.println("Playing mp3 file: " + fileName);
}
// 使用适配器支持其他格式
else if (audioType.equalsIgnoreCase("vlc") ||
audioType.equalsIgnoreCase("mp4")) {
mediaAdapter = new MediaAdapter(audioType);
mediaAdapter.play(audioType, fileName);
} else {
System.out.println("Invalid media type: " + audioType);
}
}
}
// 使用示例
public class AdapterDemo {
public static void main(String[] args) {
AudioPlayer audioPlayer = new AudioPlayer();
audioPlayer.play("mp3", "song.mp3");
audioPlayer.play("mp4", "video.mp4");
audioPlayer.play("vlc", "movie.vlc");
audioPlayer.play("avi", "movie.avi");
}
}
7. 桥接模式(Bridge)
使用场景:
- 抽象和实现需要独立变化
- 需要避免永久绑定
- 多个维度变化
解决问题:
- 继承导致的类爆炸问题
- 抽象和实现分离
优点:
- 分离抽象和实现
- 提高系统可扩展性
- 实现细节对客户透明
缺点:
- 增加系统复杂度
- 需要正确识别抽象和实现
java
// 实现化角色
interface Color {
String applyColor();
}
// 具体实现化角色
class Red implements Color {
@Override
public String applyColor() {
return "Red";
}
}
class Blue implements Color {
@Override
public String applyColor() {
return "Blue";
}
}
// 抽象化角色
abstract class Shape {
protected Color color;
public Shape(Color color) {
this.color = color;
}
abstract String draw();
}
// 扩展抽象化角色
class Circle extends Shape {
public Circle(Color color) {
super(color);
}
@Override
String draw() {
return "Circle drawn with color: " + color.applyColor();
}
}
class Square extends Shape {
public Square(Color color) {
super(color);
}
@Override
String draw() {
return "Square drawn with color: " + color.applyColor();
}
}
// 使用示例
public class BridgeDemo {
public static void main(String[] args) {
// 红色圆形
Shape redCircle = new Circle(new Red());
System.out.println(redCircle.draw());
// 蓝色方形
Shape blueSquare = new Square(new Blue());
System.out.println(blueSquare.draw());
// 蓝色圆形
Shape blueCircle = new Circle(new Blue());
System.out.println(blueCircle.draw());
}
}
8. 组合模式(Composite)
使用场景:
- 表示对象的部分-整体层次结构
- 希望客户端忽略组合与单个对象的差异
- 树形菜单
- 文件系统
解决问题:
- 树形结构表示
- 统一处理简单和复杂元素
优点:
- 简化客户端代码
- 容易添加新组件
- 符合开闭原则
缺点:
- 设计较复杂
- 需要限制组件类型
java
import java.util.ArrayList;
import java.util.List;
// 组件接口
interface FileSystemComponent {
void showDetails();
void add(FileSystemComponent component);
void remove(FileSystemComponent component);
}
// 叶子节点
class File implements FileSystemComponent {
private String name;
private int size;
public File(String name, int size) {
this.name = name;
this.size = size;
}
@Override
public void showDetails() {
System.out.println("File: " + name + ", Size: " + size + "KB");
}
@Override
public void add(FileSystemComponent component) {
throw new UnsupportedOperationException("Cannot add to a file");
}
@Override
public void remove(FileSystemComponent component) {
throw new UnsupportedOperationException("Cannot remove from a file");
}
}
// 组合节点
class Directory implements FileSystemComponent {
private String name;
private List<FileSystemComponent> components;
public Directory(String name) {
this.name = name;
this.components = new ArrayList<>();
}
@Override
public void showDetails() {
System.out.println("\nDirectory: " + name);
System.out.println("Contents:");
for (FileSystemComponent component : components) {
component.showDetails();
}
}
@Override
public void add(FileSystemComponent component) {
components.add(component);
}
@Override
public void remove(FileSystemComponent component) {
components.remove(component);
}
}
// 使用示例
public class CompositeDemo {
public static void main(String[] args) {
// 创建文件
FileSystemComponent file1 = new File("Document.txt", 100);
FileSystemComponent file2 = new File("Image.jpg", 2000);
FileSystemComponent file3 = new File("Video.mp4", 50000);
// 创建目录
Directory documents = new Directory("Documents");
Directory media = new Directory("Media");
Directory root = new Directory("Root");
// 构建树形结构
documents.add(file1);
media.add(file2);
media.add(file3);
root.add(documents);
root.add(media);
// 显示结构
root.showDetails();
// 也可以单独显示
System.out.println("\n--- Showing media directory ---");
media.showDetails();
}
}
9. 装饰器模式(Decorator)
使用场景:
- 动态添加职责
- 需要扩展功能但不想使用继承
- I/O流处理
解决问题:
- 扩展对象功能
- 避免子类膨胀
优点:
- 比继承更灵活
- 可以动态添加功能
- 符合开闭原则
缺点:
- 增加系统复杂度
- 多层装饰难以调试
java
// 组件接口
interface Coffee {
double getCost();
String getDescription();
}
// 具体组件
class SimpleCoffee implements Coffee {
@Override
public double getCost() {
return 10.0;
}
@Override
public String getDescription() {
return "Simple coffee";
}
}
// 装饰器基类
abstract class CoffeeDecorator implements Coffee {
protected Coffee decoratedCoffee;
public CoffeeDecorator(Coffee coffee) {
this.decoratedCoffee = coffee;
}
@Override
public double getCost() {
return decoratedCoffee.getCost();
}
@Override
public String getDescription() {
return decoratedCoffee.getDescription();
}
}
// 具体装饰器
class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee coffee) {
super(coffee);
}
@Override
public double getCost() {
return super.getCost() + 2.0;
}
@Override
public String getDescription() {
return super.getDescription() + ", with milk";
}
}
class SugarDecorator extends CoffeeDecorator {
public SugarDecorator(Coffee coffee) {
super(coffee);
}
@Override
public double getCost() {
return super.getCost() + 1.0;
}
@Override
public String getDescription() {
return super.getDescription() + ", with sugar";
}
}
class WhippedCreamDecorator extends CoffeeDecorator {
public WhippedCreamDecorator(Coffee coffee) {
super(coffee);
}
@Override
public double getCost() {
return super.getCost() + 3.0;
}
@Override
public String getDescription() {
return super.getDescription() + ", with whipped cream";
}
}
// 使用示例
public class DecoratorDemo {
public static void main(String[] args) {
// 简单咖啡
Coffee coffee = new SimpleCoffee();
System.out.println("Cost: " + coffee.getCost() +
"; Description: " + coffee.getDescription());
// 加牛奶
coffee = new MilkDecorator(coffee);
System.out.println("Cost: " + coffee.getCost() +
"; Description: " + coffee.getDescription());
// 加糖
coffee = new SugarDecorator(coffee);
System.out.println("Cost: " + coffee.getCost() +
"; Description: " + coffee.getDescription());
// 加奶油
coffee = new WhippedCreamDecorator(coffee);
System.out.println("Cost: " + coffee.getCost() +
"; Description: " + coffee.getDescription());
}
}
10. 外观模式(Facade)
使用场景:
- 复杂子系统需要简单接口
- 分层架构
- 减少系统依赖
解决问题:
- 简化复杂系统接口
- 降低系统耦合度
优点:
- 简化客户端使用
- 减少系统依赖
- 提高安全性
缺点:
- 不符合开闭原则
- 可能成为"上帝对象"
java
// 子系统1
class CPU {
public void freeze() {
System.out.println("CPU freeze");
}
public void jump(long position) {
System.out.println("CPU jump to position: " + position);
}
public void execute() {
System.out.println("CPU execute");
}
}
// 子系统2
class Memory {
public void load(long position, byte[] data) {
System.out.println("Memory load at position: " + position);
}
}
// 子系统3
class HardDrive {
public byte[] read(long lba, int size) {
System.out.println("HardDrive read at LBA: " + lba + ", size: " + size);
return new byte[size];
}
}
// 外观类
class ComputerFacade {
private CPU processor;
private Memory ram;
private HardDrive hd;
public ComputerFacade() {
this.processor = new CPU();
this.ram = new Memory();
this.hd = new HardDrive();
}
public void start() {
System.out.println("Computer starting...");
processor.freeze();
ram.load(BOOT_ADDRESS, hd.read(BOOT_SECTOR, SECTOR_SIZE));
processor.jump(BOOT_ADDRESS);
processor.execute();
System.out.println("Computer started successfully!");
}
private static final long BOOT_ADDRESS = 0x0000;
private static final long BOOT_SECTOR = 0x0007;
private static final int SECTOR_SIZE = 1024;
}
// 使用示例
public class FacadeDemo {
public static void main(String[] args) {
ComputerFacade computer = new ComputerFacade();
computer.start();
// 客户端不需要了解子系统细节
// 只需要调用外观类的简单接口
}
}
11. 享元模式(Flyweight)
使用场景:
- 大量相似对象
- 对象状态可以外部化
- 内存消耗大
- 游戏中的子弹、粒子
解决问题:
- 减少内存使用
- 共享相似对象
优点:
- 减少内存消耗
- 提高性能
缺点:
- 增加系统复杂度
- 外部状态可能影响行为
java
import java.util.HashMap;
import java.util.Map;
// 享元接口
interface Shape {
void draw(int x, int y);
}
// 具体享元类
class Circle implements Shape {
private String color;
private int radius;
public Circle(String color) {
this.color = color;
this.radius = 10; // 默认半径
}
public void setRadius(int radius) {
this.radius = radius;
}
@Override
public void draw(int x, int y) {
System.out.println("Drawing Circle [Color: " + color +
", Radius: " + radius +
", Position: (" + x + ", " + y + ")]");
}
}
// 享元工厂
class ShapeFactory {
private static final Map<String, Shape> circleMap = new HashMap<>();
public static Shape getCircle(String color) {
Circle circle = (Circle) circleMap.get(color);
if (circle == null) {
circle = new Circle(color);
circleMap.put(color, circle);
System.out.println("Creating circle of color: " + color);
}
return circle;
}
public static int getCircleCount() {
return circleMap.size();
}
}
// 使用示例
public class FlyweightDemo {
private static final String[] colors = {"Red", "Green", "Blue", "Yellow", "Black"};
public static void main(String[] args) {
System.out.println("Drawing 20 circles with 5 colors:");
for (int i = 0; i < 20; i++) {
Circle circle = (Circle) ShapeFactory.getCircle(getRandomColor());
circle.setRadius(getRandomRadius());
circle.draw(getRandomX(), getRandomY());
}
System.out.println("\nTotal circles created: " + ShapeFactory.getCircleCount());
}
private static String getRandomColor() {
return colors[(int)(Math.random() * colors.length)];
}
private static int getRandomRadius() {
return (int)(Math.random() * 20) + 5;
}
private static int getRandomX() {
return (int)(Math.random() * 100);
}
private static int getRandomY() {
return (int)(Math.random() * 100);
}
}
12. 代理模式(Proxy)
使用场景:
- 远程代理
- 虚拟代理
- 安全代理
- 智能引用
解决问题:
- 控制对象访问
- 延迟加载
- 访问权限控制
优点:
- 职责清晰
- 高扩展性
- 智能化
缺点:
- 增加系统复杂度
- 可能降低性能
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("Loading image: " + fileName);
}
@Override
public void display() {
System.out.println("Displaying image: " + 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();
}
}
// 虚拟代理示例:延迟加载
class VirtualProxyDemo {
public static void main(String[] args) {
System.out.println("Virtual Proxy Example:");
Image image = new ProxyImage("test_image.jpg");
// 图像不会立即加载
System.out.println("Image object created, but not loaded yet.");
// 第一次显示,图像会加载
System.out.println("First display:");
image.display();
// 第二次显示,图像已加载,直接显示
System.out.println("\nSecond display:");
image.display();
}
}
// 保护代理示例
interface Internet {
void connectTo(String serverHost) throws Exception;
}
class RealInternet implements Internet {
@Override
public void connectTo(String serverHost) {
System.out.println("Connecting to: " + serverHost);
}
}
class ProxyInternet implements Internet {
private Internet internet = new RealInternet();
private static java.util.List<String> bannedSites;
static {
bannedSites = new java.util.ArrayList<>();
bannedSites.add("banned.com");
bannedSites.add("blocked.com");
}
@Override
public void connectTo(String serverHost) throws Exception {
if (bannedSites.contains(serverHost.toLowerCase())) {
throw new Exception("Access Denied to: " + serverHost);
}
internet.connectTo(serverHost);
}
}
// 使用示例
public class ProxyDemo {
public static void main(String[] args) {
System.out.println("\nProtection Proxy Example:");
Internet internet = new ProxyInternet();
try {
internet.connectTo("google.com");
internet.connectTo("banned.com");
} catch (Exception e) {
System.out.println("Exception: " + e.getMessage());
}
}
}
三、行为型模式(11个)
13. 责任链模式(Chain of Responsibility)
使用场景:
- 多个对象处理同一请求
- 审批流程
- 异常处理
- 事件处理
解决问题:
- 请求发送者和接收者解耦
- 动态指定处理者
优点:
- 降低耦合度
- 增加灵活性
- 简化对象连接
缺点:
- 请求可能未处理
- 性能受影响
java
// 处理者接口
abstract class Logger {
public static int INFO = 1;
public static int DEBUG = 2;
public static int ERROR = 3;
protected int level;
protected Logger nextLogger;
public void setNextLogger(Logger nextLogger) {
this.nextLogger = nextLogger;
}
public void logMessage(int level, String message) {
if (this.level <= level) {
write(message);
}
if (nextLogger != null) {
nextLogger.logMessage(level, message);
}
}
abstract protected void write(String message);
}
// 具体处理者
class ConsoleLogger extends Logger {
public ConsoleLogger(int level) {
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("Console Logger: " + message);
}
}
class FileLogger extends Logger {
public FileLogger(int level) {
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("File Logger: " + message);
}
}
class ErrorLogger extends Logger {
public ErrorLogger(int level) {
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("Error Logger: " + message);
}
}
// 使用示例
public class ChainOfResponsibilityDemo {
private static Logger getChainOfLoggers() {
Logger errorLogger = new ErrorLogger(Logger.ERROR);
Logger fileLogger = new FileLogger(Logger.DEBUG);
Logger consoleLogger = new ConsoleLogger(Logger.INFO);
errorLogger.setNextLogger(fileLogger);
fileLogger.setNextLogger(consoleLogger);
return errorLogger;
}
public static void main(String[] args) {
Logger loggerChain = getChainOfLoggers();
System.out.println("Logging INFO level:");
loggerChain.logMessage(Logger.INFO, "This is an information.");
System.out.println("\nLogging DEBUG level:");
loggerChain.logMessage(Logger.DEBUG, "This is a debug level information.");
System.out.println("\nLogging ERROR level:");
loggerChain.logMessage(Logger.ERROR, "This is an error information.");
}
}
14. 命令模式(Command)
使用场景:
- 需要将请求封装为对象
- 支持撤销/重做
- 任务队列
- 事务处理
解决问题:
- 请求发送者和接收者解耦
- 支持命令队列和日志
优点:
- 降低系统耦合度
- 容易扩展新命令
- 支持撤销/重做
缺点:
- 增加系统复杂度
- 可能产生过多具体命令类
java
import java.util.ArrayList;
import java.util.List;
// 命令接口
interface Command {
void execute();
void undo();
}
// 接收者
class Light {
public void on() {
System.out.println("Light is ON");
}
public void off() {
System.out.println("Light is OFF");
}
}
// 具体命令
class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.on();
}
@Override
public void undo() {
light.off();
}
}
class LightOffCommand implements Command {
private Light light;
public LightOffCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.off();
}
@Override
public void undo() {
light.on();
}
}
// 调用者
class RemoteControl {
private Command command;
private List<Command> history = new ArrayList<>();
public void setCommand(Command command) {
this.command = command;
}
public void pressButton() {
command.execute();
history.add(command);
}
public void pressUndo() {
if (!history.isEmpty()) {
Command lastCommand = history.remove(history.size() - 1);
lastCommand.undo();
}
}
}
// 宏命令
class MacroCommand implements Command {
private List<Command> commands = new ArrayList<>();
public void addCommand(Command command) {
commands.add(command);
}
@Override
public void execute() {
for (Command command : commands) {
command.execute();
}
}
@Override
public void undo() {
// 逆序执行撤销
for (int i = commands.size() - 1; i >= 0; i--) {
commands.get(i).undo();
}
}
}
// 使用示例
public class CommandDemo {
public static void main(String[] args) {
// 创建接收者
Light livingRoomLight = new Light();
// 创建命令
Command lightOn = new LightOnCommand(livingRoomLight);
Command lightOff = new LightOffCommand(livingRoomLight);
// 创建调用者
RemoteControl remote = new RemoteControl();
// 测试
System.out.println("Turning light on:");
remote.setCommand(lightOn);
remote.pressButton();
System.out.println("\nUndoing last command:");
remote.pressUndo();
System.out.println("\nTurning light off:");
remote.setCommand(lightOff);
remote.pressButton();
// 宏命令示例
System.out.println("\nMacro Command Example:");
MacroCommand partyMode = new MacroCommand();
partyMode.addCommand(lightOn);
partyMode.addCommand(lightOff);
partyMode.addCommand(lightOn);
remote.setCommand(partyMode);
remote.pressButton();
System.out.println("\nUndoing macro command:");
remote.pressUndo();
}
}
15. 解释器模式(Interpreter)
使用场景:
- 特定类型问题频繁发生
- 简单语法解释器
- 正则表达式
- SQL解析
解决问题:
- 特定领域语言
- 文法表示
优点:
- 容易改变和扩展文法
- 实现文法容易
缺点:
- 执行效率低
- 复杂文法难以维护
java
import java.util.Map;
import java.util.HashMap;
// 表达式接口
interface Expression {
boolean interpret(Map<String, Boolean> context);
}
// 终结符表达式
class Variable implements Expression {
private String name;
public Variable(String name) {
this.name = name;
}
@Override
public boolean interpret(Map<String, Boolean> context) {
return context.getOrDefault(name, false);
}
}
// 非终结符表达式
class AndExpression implements Expression {
private Expression expr1;
private Expression expr2;
public AndExpression(Expression expr1, Expression expr2) {
this.expr1 = expr1;
this.expr2 = expr2;
}
@Override
public boolean interpret(Map<String, Boolean> context) {
return expr1.interpret(context) && expr2.interpret(context);
}
}
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(Map<String, Boolean> context) {
return expr1.interpret(context) || expr2.interpret(context);
}
}
class NotExpression implements Expression {
private Expression expr;
public NotExpression(Expression expr) {
this.expr = expr;
}
@Override
public boolean interpret(Map<String, Boolean> context) {
return !expr.interpret(context);
}
}
// 构建解析树
class ExpressionBuilder {
public static Expression buildExpression(String expression) {
// 简化实现,实际应用中需要完整的语法解析
if (expression.contains("AND")) {
String[] parts = expression.split(" AND ");
return new AndExpression(new Variable(parts[0].trim()),
new Variable(parts[1].trim()));
} else if (expression.contains("OR")) {
String[] parts = expression.split(" OR ");
return new OrExpression(new Variable(parts[0].trim()),
new Variable(parts[1].trim()));
} else if (expression.startsWith("NOT ")) {
return new NotExpression(new Variable(expression.substring(4).trim()));
} else {
return new Variable(expression.trim());
}
}
}
// 使用示例
public class InterpreterDemo {
public static void main(String[] args) {
// 创建上下文
Map<String, Boolean> context = new HashMap<>();
context.put("A", true);
context.put("B", false);
context.put("C", true);
// 构建表达式
Expression expr1 = ExpressionBuilder.buildExpression("A AND B");
Expression expr2 = ExpressionBuilder.buildExpression("A OR B");
Expression expr3 = ExpressionBuilder.buildExpression("NOT C");
Expression expr4 = ExpressionBuilder.buildExpression("A AND B OR C");
// 解释表达式
System.out.println("A AND B = " + expr1.interpret(context));
System.out.println("A OR B = " + expr2.interpret(context));
System.out.println("NOT C = " + expr3.interpret(context));
// 复合表达式
Expression expr5 = new AndExpression(
new Variable("A"),
new OrExpression(new Variable("B"), new Variable("C"))
);
System.out.println("A AND (B OR C) = " + expr5.interpret(context));
}
}
16. 迭代器模式(Iterator)
使用场景:
- 访问聚合对象内容
- 支持多种遍历方式
- 统一遍历接口
解决问题:
- 遍历与聚合分离
- 支持多种遍历
优点:
- 支持多种遍历方式
- 简化聚合类
- 符合单一职责原则
缺点:
- 增加系统复杂度
- 对于简单聚合可能过度设计
java
import java.util.ArrayList;
import java.util.List;
// 迭代器接口
interface Iterator<T> {
boolean hasNext();
T next();
}
// 聚合接口
interface Container<T> {
Iterator<T> getIterator();
}
// 具体聚合类
class NameRepository implements Container<String> {
private String[] names = {"Robert", "John", "Julie", "Lora"};
@Override
public Iterator<String> getIterator() {
return new NameIterator();
}
// 具体迭代器
private class NameIterator implements Iterator<String> {
private int index;
@Override
public boolean hasNext() {
return index < names.length;
}
@Override
public String next() {
if (hasNext()) {
return names[index++];
}
return null;
}
}
}
// 自定义集合类
class CustomCollection<T> implements Container<T> {
private List<T> items = new ArrayList<>();
public void add(T item) {
items.add(item);
}
public void remove(T item) {
items.remove(item);
}
@Override
public Iterator<T> getIterator() {
return new ListIterator();
}
// 正向迭代器
private class ListIterator implements Iterator<T> {
private int index = 0;
@Override
public boolean hasNext() {
return index < items.size();
}
@Override
public T next() {
if (hasNext()) {
return items.get(index++);
}
return null;
}
}
// 反向迭代器
public Iterator<T> getReverseIterator() {
return new ReverseIterator();
}
private class ReverseIterator implements Iterator<T> {
private int index = items.size() - 1;
@Override
public boolean hasNext() {
return index >= 0;
}
@Override
public T next() {
if (hasNext()) {
return items.get(index--);
}
return null;
}
}
}
// 使用示例
public class IteratorDemo {
public static void main(String[] args) {
System.out.println("Name Repository Iterator:");
NameRepository nameRepository = new NameRepository();
Iterator<String> iterator = nameRepository.getIterator();
while (iterator.hasNext()) {
String name = iterator.next();
System.out.println("Name: " + name);
}
System.out.println("\nCustom Collection Iterator:");
CustomCollection<String> collection = new CustomCollection<>();
collection.add("Apple");
collection.add("Banana");
collection.add("Cherry");
collection.add("Date");
System.out.println("Forward iteration:");
Iterator<String> forwardIterator = collection.getIterator();
while (forwardIterator.hasNext()) {
System.out.println(forwardIterator.next());
}
System.out.println("\nReverse iteration:");
Iterator<String> reverseIterator = collection.getReverseIterator();
while (reverseIterator.hasNext()) {
System.out.println(reverseIterator.next());
}
}
}
17. 中介者模式(Mediator)
使用场景:
- 对象间交互复杂
- 聊天室
- 机场调度系统
- MVC控制器
解决问题:
- 减少对象间直接通信
- 集中控制逻辑
优点:
- 降低类间耦合
- 简化对象协议
- 集中控制逻辑
缺点:
- 中介者可能过于复杂
- 可能成为性能瓶颈
java
import java.util.ArrayList;
import java.util.List;
import java.util.Date;
// 中介者接口
interface ChatMediator {
void sendMessage(String msg, User user);
void addUser(User user);
}
// 具体中介者
class ChatMediatorImpl implements ChatMediator {
private List<User> users;
public ChatMediatorImpl() {
this.users = new ArrayList<>();
}
@Override
public void addUser(User user) {
this.users.add(user);
}
@Override
public void sendMessage(String msg, User user) {
for (User u : this.users) {
// 消息不应该发送给发送者自己
if (u != user) {
u.receive(msg);
}
}
}
}
// 抽象同事类
abstract class User {
protected ChatMediator mediator;
protected String name;
public User(ChatMediator mediator, String name) {
this.mediator = mediator;
this.name = name;
}
public abstract void send(String msg);
public abstract void receive(String msg);
}
// 具体同事类
class UserImpl extends User {
public UserImpl(ChatMediator mediator, String name) {
super(mediator, name);
}
@Override
public void send(String msg) {
System.out.println(this.name + " sending message: " + msg);
mediator.sendMessage(msg, this);
}
@Override
public void receive(String msg) {
System.out.println(this.name + " received message: " + msg);
}
}
// 管理员用户
class AdminUser extends User {
public AdminUser(ChatMediator mediator, String name) {
super(mediator, name);
}
@Override
public void send(String msg) {
System.out.println("[Admin] " + this.name + " sending message: " + msg);
mediator.sendMessage("[Admin] " + msg, this);
}
@Override
public void receive(String msg) {
System.out.println("[Admin] " + this.name + " received message: " + msg);
}
public void sendToUser(String msg, User targetUser) {
System.out.println("[Admin " + this.name + " to " + targetUser.name + "]: " + msg);
// 在实际应用中,这里应该有直接发送给特定用户的逻辑
}
}
// 使用示例
public class MediatorDemo {
public static void main(String[] args) {
ChatMediator mediator = new ChatMediatorImpl();
User user1 = new UserImpl(mediator, "Alice");
User user2 = new UserImpl(mediator, "Bob");
User user3 = new UserImpl(mediator, "Charlie");
User admin = new AdminUser(mediator, "Admin");
mediator.addUser(user1);
mediator.addUser(user2);
mediator.addUser(user3);
mediator.addUser(admin);
System.out.println("Chat Room Conversation:");
user1.send("Hi everyone!");
user2.send("Hello Alice!");
admin.send("Welcome to the chat room!");
user3.send("Good to be here!");
}
}
18. 备忘录模式(Memento)
使用场景:
- 需要保存对象状态
- 需要撤销操作
- 游戏存档
- 事务回滚
解决问题:
- 状态保存和恢复
- 封装状态信息
优点:
- 状态恢复机制
- 信息封装
- 简化发起者
缺点:
- 资源消耗大
- 可能暴露实现细节
java
import java.util.ArrayList;
import java.util.List;
// 备忘录类
class Memento {
private final 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;
System.out.println("State set to: " + state);
}
public String getState() {
return state;
}
public Memento saveStateToMemento() {
return new Memento(state);
}
public void getStateFromMemento(Memento memento) {
state = memento.getState();
System.out.println("State restored to: " + state);
}
}
// 管理者类
class CareTaker {
private List<Memento> mementoList = new ArrayList<>();
public void add(Memento state) {
mementoList.add(state);
}
public Memento get(int index) {
return mementoList.get(index);
}
public List<Memento> getAll() {
return new ArrayList<>(mementoList);
}
}
// 文本编辑器示例
class TextEditor {
private String text;
private int cursorPosition;
public void setText(String text) {
this.text = text;
}
public void setCursorPosition(int position) {
this.cursorPosition = position;
}
public EditorMemento save() {
return new EditorMemento(text, cursorPosition);
}
public void restore(EditorMemento memento) {
this.text = memento.getText();
this.cursorPosition = memento.getCursorPosition();
System.out.println("Text Editor restored to: \"" + text +
"\" at position: " + cursorPosition);
}
public void print() {
System.out.println("Text: \"" + text + "\", Cursor at: " + cursorPosition);
}
// 编辑器备忘录
static class EditorMemento {
private final String text;
private final int cursorPosition;
public EditorMemento(String text, int cursorPosition) {
this.text = text;
this.cursorPosition = cursorPosition;
}
public String getText() {
return text;
}
public int getCursorPosition() {
return cursorPosition;
}
}
}
// 使用示例
public class MementoDemo {
public static void main(String[] args) {
System.out.println("=== Basic Memento Example ===");
Originator originator = new Originator();
CareTaker careTaker = new CareTaker();
originator.setState("State #1");
careTaker.add(originator.saveStateToMemento());
originator.setState("State #2");
careTaker.add(originator.saveStateToMemento());
originator.setState("State #3");
System.out.println("Current State: " + originator.getState());
originator.getStateFromMemento(careTaker.get(0));
originator.getStateFromMemento(careTaker.get(1));
System.out.println("\n=== Text Editor Example ===");
TextEditor editor = new TextEditor();
List<TextEditor.EditorMemento> savedStates = new ArrayList<>();
editor.setText("Hello World");
editor.setCursorPosition(5);
savedStates.add(editor.save());
editor.print();
editor.setText("Goodbye World");
editor.setCursorPosition(8);
savedStates.add(editor.save());
editor.print();
editor.setText("Modified Text");
editor.setCursorPosition(10);
editor.print();
System.out.println("\nRestoring to first save:");
editor.restore(savedStates.get(0));
System.out.println("Restoring to second save:");
editor.restore(savedStates.get(1));
}
}
19. 观察者模式(Observer)
使用场景:
- 对象状态变化通知
- 事件驱动系统
- MVC模式
- 消息队列
解决问题:
- 一对多依赖关系
- 对象状态同步
优点:
- 抽象耦合
- 支持广播通信
- 符合开闭原则
缺点:
- 通知顺序不确定
- 可能引起循环引用
java
import java.util.ArrayList;
import java.util.List;
// 观察者接口
interface Observer {
void update(String message);
}
// 主题接口
interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers();
}
// 具体主题
class NewsAgency implements Subject {
private List<Observer> observers = new ArrayList<>();
private String news;
@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(news);
}
}
public void setNews(String news) {
this.news = news;
notifyObservers();
}
}
// 具体观察者
class NewsChannel implements Observer {
private String name;
private String latestNews;
public NewsChannel(String name) {
this.name = name;
}
@Override
public void update(String news) {
this.latestNews = news;
display();
}
public void display() {
System.out.println(name + " received news: " + latestNews);
}
}
// 推拉模型示例
interface StockObserver {
void update(double price, String symbol);
}
class StockMarket implements Subject {
private List<Observer> observers = new ArrayList<>();
private String stockSymbol;
private double stockPrice;
public StockMarket(String symbol, double price) {
this.stockSymbol = symbol;
this.stockPrice = price;
}
public void setPrice(double price) {
this.stockPrice = price;
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(stockSymbol + " price changed to: $" + stockPrice);
}
}
// 拉模型:观察者主动获取数据
public double getStockPrice() {
return stockPrice;
}
public String getStockSymbol() {
return stockSymbol;
}
}
class StockDisplay implements Observer {
private StockMarket market;
public StockDisplay(StockMarket market) {
this.market = market;
market.registerObserver(this);
}
@Override
public void update(String message) {
System.out.println("Stock Update: " + message);
// 可以主动拉取更多数据
System.out.println("Current " + market.getStockSymbol() +
" price: $" + market.getStockPrice());
}
}
// 使用示例
public class ObserverDemo {
public static void main(String[] args) {
System.out.println("=== News Agency Example ===");
NewsAgency agency = new NewsAgency();
NewsChannel channel1 = new NewsChannel("CNN");
NewsChannel channel2 = new NewsChannel("BBC");
NewsChannel channel3 = new NewsChannel("Fox News");
agency.registerObserver(channel1);
agency.registerObserver(channel2);
agency.registerObserver(channel3);
agency.setNews("Breaking News: Observer Pattern is awesome!");
agency.removeObserver(channel2);
System.out.println("\nAfter removing BBC:");
agency.setNews("Update: Design Patterns are useful!");
System.out.println("\n=== Stock Market Example ===");
StockMarket appleStock = new StockMarket("AAPL", 150.0);
StockDisplay display1 = new StockDisplay(appleStock);
appleStock.setPrice(152.5);
appleStock.setPrice(155.0);
}
}
20. 状态模式(State)
使用场景:
- 对象行为随状态改变
- 状态转换复杂
- 条件语句过多
- 工作流引擎
解决问题:
- 状态转换逻辑
- 消除条件语句
优点:
- 状态转换显式化
- 状态类职责单一
- 易于扩展新状态
缺点:
- 增加系统复杂度
- 状态类数量多
java
// 状态接口
interface State {
void handle(Context context);
}
// 具体状态
class StartState implements State {
@Override
public void handle(Context context) {
System.out.println("Player is in start state");
context.setState(this);
}
@Override
public String toString() {
return "Start State";
}
}
class StopState implements State {
@Override
public void handle(Context context) {
System.out.println("Player is in stop state");
context.setState(this);
}
@Override
public String toString() {
return "Stop State";
}
}
class PauseState implements State {
@Override
public void handle(Context context) {
System.out.println("Player is in pause state");
context.setState(this);
}
@Override
public String toString() {
return "Pause State";
}
}
// 上下文
class Context {
private State state;
public Context() {
state = null;
}
public void setState(State state) {
this.state = state;
}
public State getState() {
return state;
}
}
// 交通灯示例
interface TrafficLightState {
void change(TrafficLight light);
void display();
}
class RedLight implements TrafficLightState {
@Override
public void change(TrafficLight light) {
System.out.println("Red light for 60 seconds...");
try {
Thread.sleep(1000); // 模拟等待
} catch (InterruptedException e) {
e.printStackTrace();
}
light.setState(new GreenLight());
}
@Override
public void display() {
System.out.println("[RED LIGHT] - STOP");
}
}
class YellowLight implements TrafficLightState {
@Override
public void change(TrafficLight light) {
System.out.println("Yellow light for 5 seconds...");
try {
Thread.sleep(500); // 模拟等待
} catch (InterruptedException e) {
e.printStackTrace();
}
light.setState(new RedLight());
}
@Override
public void display() {
System.out.println("[YELLOW LIGHT] - CAUTION");
}
}
class GreenLight implements TrafficLightState {
@Override
public void change(TrafficLight light) {
System.out.println("Green light for 55 seconds...");
try {
Thread.sleep(1000); // 模拟等待
} catch (InterruptedException e) {
e.printStackTrace();
}
light.setState(new YellowLight());
}
@Override
public void display() {
System.out.println("[GREEN LIGHT] - GO");
}
}
class TrafficLight {
private TrafficLightState state;
public TrafficLight() {
this.state = new RedLight();
}
public void setState(TrafficLightState state) {
this.state = state;
}
public void change() {
state.change(this);
}
public void display() {
state.display();
}
public void runCycle(int cycles) {
for (int i = 0; i < cycles; i++) {
System.out.println("\nCycle " + (i + 1) + ":");
display();
change();
}
}
}
// 使用示例
public class StateDemo {
public static void main(String[] args) {
System.out.println("=== Media Player State Example ===");
Context context = new Context();
StartState startState = new StartState();
startState.handle(context);
System.out.println("Current state: " + context.getState());
StopState stopState = new StopState();
stopState.handle(context);
System.out.println("Current state: " + context.getState());
System.out.println("\n=== Traffic Light State Example ===");
TrafficLight trafficLight = new TrafficLight();
trafficLight.runCycle(3);
}
}
21. 策略模式(Strategy)
使用场景:
- 多种算法变体
- 需要动态切换算法
- 消除条件语句
- 支付方式选择
解决问题:
- 算法封装和切换
- 消除条件分支
优点:
- 算法可互换
- 扩展性好
- 避免多重条件
缺点:
- 策略类增多
- 客户端需要了解策略
java
import java.util.Arrays;
import java.util.List;
// 策略接口
interface PaymentStrategy {
void pay(int amount);
}
// 具体策略
class CreditCardPayment implements PaymentStrategy {
private String name;
private String cardNumber;
public CreditCardPayment(String name, String cardNumber) {
this.name = name;
this.cardNumber = cardNumber;
}
@Override
public void pay(int amount) {
System.out.println(amount + " paid with credit card");
System.out.println("Cardholder: " + name);
System.out.println("Card number: " + maskCardNumber(cardNumber));
}
private String maskCardNumber(String cardNumber) {
if (cardNumber.length() > 4) {
return "****-****-****-" + cardNumber.substring(cardNumber.length() - 4);
}
return cardNumber;
}
}
class PayPalPayment implements PaymentStrategy {
private String email;
public PayPalPayment(String email) {
this.email = email;
}
@Override
public void pay(int amount) {
System.out.println(amount + " paid using PayPal");
System.out.println("Email: " + email);
}
}
class BitcoinPayment implements PaymentStrategy {
private String walletAddress;
public BitcoinPayment(String walletAddress) {
this.walletAddress = walletAddress;
}
@Override
public void pay(int amount) {
System.out.println(amount + " paid using Bitcoin");
System.out.println("Wallet address: " + walletAddress);
}
}
// 上下文
class ShoppingCart {
private List<String> items;
private PaymentStrategy paymentStrategy;
public ShoppingCart() {
this.items = new java.util.ArrayList<>();
}
public void addItem(String item) {
items.add(item);
}
public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
this.paymentStrategy = paymentStrategy;
}
public void checkout(int amount) {
if (paymentStrategy == null) {
System.out.println("Please select a payment method");
return;
}
System.out.println("Checking out items: " + items);
paymentStrategy.pay(amount);
items.clear();
}
}
// 排序策略示例
interface SortStrategy {
void sort(List<Integer> list);
}
class BubbleSort implements SortStrategy {
@Override
public void sort(List<Integer> list) {
System.out.println("Sorting using Bubble Sort");
// 简化实现
list.sort(Integer::compareTo);
}
}
class QuickSort implements SortStrategy {
@Override
public void sort(List<Integer> list) {
System.out.println("Sorting using Quick Sort");
// 简化实现
list.sort(Integer::compareTo);
}
}
class MergeSort implements SortStrategy {
@Override
public void sort(List<Integer> list) {
System.out.println("Sorting using Merge Sort");
// 简化实现
list.sort(Integer::compareTo);
}
}
class Sorter {
private SortStrategy strategy;
public void setStrategy(SortStrategy strategy) {
this.strategy = strategy;
}
public void sortList(List<Integer> list) {
if (strategy == null) {
throw new IllegalStateException("Sort strategy not set");
}
strategy.sort(list);
System.out.println("Sorted list: " + list);
}
}
// 使用示例
public class StrategyDemo {
public static void main(String[] args) {
System.out.println("=== Payment Strategy Example ===");
ShoppingCart cart = new ShoppingCart();
cart.addItem("Laptop");
cart.addItem("Mouse");
// 使用信用卡支付
cart.setPaymentStrategy(new CreditCardPayment("John Doe", "1234567890123456"));
cart.checkout(1200);
System.out.println("\n=== New Purchase ===");
cart.addItem("Book");
cart.addItem("Pen");
// 切换支付方式
cart.setPaymentStrategy(new PayPalPayment("john.doe@example.com"));
cart.checkout(50);
System.out.println("\n=== Sorting Strategy Example ===");
List<Integer> numbers = Arrays.asList(5, 2, 9, 1, 5, 6);
Sorter sorter = new Sorter();
sorter.setStrategy(new BubbleSort());
sorter.sortList(new java.util.ArrayList<>(numbers));
sorter.setStrategy(new QuickSort());
sorter.sortList(new java.util.ArrayList<>(numbers));
sorter.setStrategy(new MergeSort());
sorter.sortList(new java.util.ArrayList<>(numbers));
}
}
22. 模板方法模式(Template Method)
使用场景:
- 算法框架固定
- 子步骤可变
- 代码复用
- 框架设计
解决问题:
- 算法骨架定义
- 代码复用
优点:
- 代码复用
- 提高扩展性
- 符合开闭原则
缺点:
- 可能违反里氏替换原则
- 增加系统复杂度
java
// 抽象类
abstract class Game {
protected abstract void initialize();
protected abstract void startPlay();
protected abstract void endPlay();
// 模板方法
public final void play() {
// 初始化游戏
initialize();
// 开始游戏
startPlay();
// 结束游戏
endPlay();
}
}
// 具体类
class Cricket extends Game {
@Override
protected void initialize() {
System.out.println("Cricket Game Initialized! Start playing.");
}
@Override
protected void startPlay() {
System.out.println("Cricket Game Started. Enjoy the game!");
}
@Override
protected void endPlay() {
System.out.println("Cricket Game Finished!");
}
}
class Football extends Game {
@Override
protected void initialize() {
System.out.println("Football Game Initialized! Start playing.");
}
@Override
protected void startPlay() {
System.out.println("Football Game Started. Enjoy the game!");
}
@Override
protected void endPlay() {
System.out.println("Football Game Finished!");
}
}
// 数据处理器示例
abstract class DataProcessor {
// 模板方法
public final void process() {
readData();
processData();
writeData();
}
protected abstract void readData();
protected abstract void processData();
protected void writeData() {
System.out.println("Writing processed data...");
}
}
class CSVDataProcessor extends DataProcessor {
@Override
protected void readData() {
System.out.println("Reading data from CSV file...");
}
@Override
protected void processData() {
System.out.println("Processing CSV data...");
}
}
class XMLDataProcessor extends DataProcessor {
@Override
protected void readData() {
System.out.println("Reading data from XML file...");
}
@Override
protected void processData() {
System.out.println("Processing XML data...");
}
@Override
protected void writeData() {
System.out.println("Writing XML data to database...");
}
}
class JSONDataProcessor extends DataProcessor {
@Override
protected void readData() {
System.out.println("Reading data from JSON file...");
}
@Override
protected void processData() {
System.out.println("Processing JSON data...");
}
// 使用默认的writeData实现
}
// 使用钩子方法
abstract class Beverage {
// 模板方法
public final void prepareRecipe() {
boilWater();
brew();
pourInCup();
if (customerWantsCondiments()) {
addCondiments();
}
}
protected abstract void brew();
protected abstract void addCondiments();
protected void boilWater() {
System.out.println("Boiling water");
}
protected void pourInCup() {
System.out.println("Pouring into cup");
}
// 钩子方法 - 子类可以覆盖
protected boolean customerWantsCondiments() {
return true;
}
}
class Coffee extends Beverage {
@Override
protected void brew() {
System.out.println("Dripping coffee through filter");
}
@Override
protected void addCondiments() {
System.out.println("Adding sugar and milk");
}
@Override
protected boolean customerWantsCondiments() {
// 可以询问用户是否需要调料
return true;
}
}
class Tea extends Beverage {
@Override
protected void brew() {
System.out.println("Steeping the tea");
}
@Override
protected void addCondiments() {
System.out.println("Adding lemon");
}
@Override
protected boolean customerWantsCondiments() {
// 茶默认不加调料
return false;
}
}
// 使用示例
public class TemplateMethodDemo {
public static void main(String[] args) {
System.out.println("=== Game Template Example ===");
Game game = new Cricket();
game.play();
System.out.println();
game = new Football();
game.play();
System.out.println("\n=== Data Processor Template Example ===");
DataProcessor processor = new CSVDataProcessor();
processor.process();
System.out.println();
processor = new XMLDataProcessor();
processor.process();
System.out.println();
processor = new JSONDataProcessor();
processor.process();
System.out.println("\n=== Beverage Template with Hook Example ===");
Beverage coffee = new Coffee();
System.out.println("Preparing coffee:");
coffee.prepareRecipe();
System.out.println();
Beverage tea = new Tea();
System.out.println("Preparing tea:");
tea.prepareRecipe();
}
}
23. 访问者模式(Visitor)
使用场景:
- 对象结构稳定
- 需要多种操作
- 数据结构与操作分离
- 编译器语法树
解决问题:
- 添加新操作
- 数据结构和操作解耦
优点:
- 增加新操作容易
- 相关行为集中
- 符合单一职责原则
缺点:
- 增加新元素困难
- 破坏封装性
java
import java.util.ArrayList;
import java.util.List;
// 元素接口
interface ComputerPart {
void accept(ComputerPartVisitor visitor);
}
// 具体元素
class Keyboard implements ComputerPart {
@Override
public void accept(ComputerPartVisitor visitor) {
visitor.visit(this);
}
}
class Monitor implements ComputerPart {
@Override
public void accept(ComputerPartVisitor visitor) {
visitor.visit(this);
}
}
class Mouse implements ComputerPart {
@Override
public void accept(ComputerPartVisitor visitor) {
visitor.visit(this);
}
}
class Computer implements ComputerPart {
private List<ComputerPart> parts;
public Computer() {
parts = new ArrayList<>();
parts.add(new Mouse());
parts.add(new Keyboard());
parts.add(new Monitor());
}
@Override
public void accept(ComputerPartVisitor visitor) {
for (ComputerPart part : parts) {
part.accept(visitor);
}
visitor.visit(this);
}
}
// 访问者接口
interface ComputerPartVisitor {
void visit(Computer computer);
void visit(Mouse mouse);
void visit(Keyboard keyboard);
void visit(Monitor monitor);
}
// 具体访问者
class ComputerPartDisplayVisitor implements ComputerPartVisitor {
@Override
public void visit(Computer computer) {
System.out.println("Displaying Computer");
}
@Override
public void visit(Mouse mouse) {
System.out.println("Displaying Mouse");
}
@Override
public void visit(Keyboard keyboard) {
System.out.println("Displaying Keyboard");
}
@Override
public void visit(Monitor monitor) {
System.out.println("Displaying Monitor");
}
}
class ComputerPartMaintenanceVisitor implements ComputerPartVisitor {
@Override
public void visit(Computer computer) {
System.out.println("Maintaining Computer");
}
@Override
public void visit(Mouse mouse) {
System.out.println("Cleaning Mouse");
}
@Override
public void visit(Keyboard keyboard) {
System.out.println("Cleaning Keyboard");
}
@Override
public void visit(Monitor monitor) {
System.out.println("Cleaning Monitor screen");
}
}
class ComputerPartDiagnosticVisitor implements ComputerPartVisitor {
@Override
public void visit(Computer computer) {
System.out.println("Running diagnostics on Computer");
}
@Override
public void visit(Mouse mouse) {
System.out.println("Testing Mouse connectivity");
}
@Override
public void visit(Keyboard keyboard) {
System.out.println("Testing Keyboard keys");
}
@Override
public void visit(Monitor monitor) {
System.out.println("Testing Monitor display");
}
}
// 表达式示例
interface Expression {
void accept(ExpressionVisitor visitor);
}
class NumberExpression implements Expression {
private int number;
public NumberExpression(int number) {
this.number = number;
}
public int getNumber() {
return number;
}
@Override
public void accept(ExpressionVisitor visitor) {
visitor.visit(this);
}
}
class AdditionExpression implements Expression {
private Expression left;
private Expression right;
public AdditionExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
public Expression getLeft() {
return left;
}
public Expression getRight() {
return right;
}
@Override
public void accept(ExpressionVisitor visitor) {
visitor.visit(this);
}
}
interface ExpressionVisitor {
void visit(NumberExpression number);
void visit(AdditionExpression addition);
}
class ExpressionEvaluator implements ExpressionVisitor {
private int result;
public int getResult() {
return result;
}
@Override
public void visit(NumberExpression number) {
result = number.getNumber();
}
@Override
public void visit(AdditionExpression addition) {
// 递归计算左右表达式
ExpressionEvaluator leftEval = new ExpressionEvaluator();
addition.getLeft().accept(leftEval);
ExpressionEvaluator rightEval = new ExpressionEvaluator();
addition.getRight().accept(rightEval);
result = leftEval.getResult() + rightEval.getResult();
}
}
class ExpressionPrinter implements ExpressionVisitor {
private StringBuilder sb = new StringBuilder();
public String getExpression() {
return sb.toString();
}
@Override
public void visit(NumberExpression number) {
sb.append(number.getNumber());
}
@Override
public void visit(AdditionExpression addition) {
sb.append("(");
addition.getLeft().accept(this);
sb.append(" + ");
addition.getRight().accept(this);
sb.append(")");
}
}
// 使用示例
public class VisitorDemo {
public static void main(String[] args) {
System.out.println("=== Computer Parts Visitor Example ===");
ComputerPart computer = new Computer();
System.out.println("1. Display Visitor:");
computer.accept(new ComputerPartDisplayVisitor());
System.out.println("\n2. Maintenance Visitor:");
computer.accept(new ComputerPartMaintenanceVisitor());
System.out.println("\n3. Diagnostic Visitor:");
computer.accept(new ComputerPartDiagnosticVisitor());
System.out.println("\n=== Expression Visitor Example ===");
// 创建表达式: (5 + 3) + 2
Expression expression = new AdditionExpression(
new AdditionExpression(
new NumberExpression(5),
new NumberExpression(3)
),
new NumberExpression(2)
);
// 求值访问者
ExpressionEvaluator evaluator = new ExpressionEvaluator();
expression.accept(evaluator);
System.out.println("Result: " + evaluator.getResult());
// 打印访问者
ExpressionPrinter printer = new ExpressionPrinter();
expression.accept(printer);
System.out.println("Expression: " + printer.getExpression());
}
}
总结
设计模式是解决特定问题的可复用方案,每种模式都有其适用场景和优缺点:
创建型模式重点:
- 单例:全局唯一实例
- 工厂:对象创建解耦
- 建造者:复杂对象构建
- 原型:对象克隆
结构型模式重点:
- 适配器:接口转换
- 装饰器:动态添加功能
- 代理:控制访问
- 组合:树形结构
行为型模式重点:
- 观察者:一对多依赖
- 策略:算法切换
- 模板方法:算法框架
- 状态:状态驱动行为
选择原则:
- 理解问题本质:先分析问题,再选择模式
- 保持简单:不要过度设计
- 考虑变化:识别可能变化的部分
- 组合使用:模式可以组合使用
实际应用建议:
- 从简单实现开始,需要时再重构
- 优先使用组合而非继承
- 保持代码可读性和可维护性
- 理解模式思想比机械套用更重要
这些模式是经验的总结,掌握它们能帮助设计出更灵活、可维护的软件系统。在实际开发中,应根据具体需求灵活选择和调整模式实现。