文章
Java 23种设计模式
一、创建型模式 (5种)
1. 单例模式 (Singleton)
意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
/**
* 单例模式 - 懒汉式(线程安全)
*/
public class Singleton {
// 使用volatile保证可见性和禁止指令重排序
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;
}
// 其他方法
public void showMessage() {
System.out.println("Hello, I am a Singleton!");
}
}
// 使用示例
public class SingletonDemo {
public static void main(String[] args) {
// 获取单例对象
Singleton singleton = Singleton.getInstance();
// 调用方法
singleton.showMessage();
// 再次获取实例,验证是否为同一个对象
Singleton anotherSingleton = Singleton.getInstance();
System.out.println("Is same instance? " + (singleton == anotherSingleton));
}
}
2. 工厂方法模式 (Factory Method)
意图:定义一个用于创建对象的接口,让子类决定实例化哪一个类。
/**
* 产品接口
*/
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 - 生产产品A
*/
class ConcreteFactoryA implements Factory {
@Override
public Product createProduct() {
return new ConcreteProductA();
}
}
/**
* 具体工厂B - 生产产品B
*/
class ConcreteFactoryB implements Factory {
@Override
public Product createProduct() {
return new ConcreteProductB();
}
}
// 使用示例
public class FactoryMethodDemo {
public static void main(String[] args) {
// 创建工厂A
Factory factoryA = new ConcreteFactoryA();
// 使用工厂A创建产品
Product productA = factoryA.createProduct();
productA.use();
// 创建工厂B
Factory factoryB = new ConcreteFactoryB();
// 使用工厂B创建产品
Product productB = factoryB.createProduct();
productB.use();
}
}
3. 抽象工厂模式 (Abstract Factory)
意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
/**
* 抽象产品A
*/
interface AbstractProductA {
void use();
}
/**
* 抽象产品B
*/
interface AbstractProductB {
void eat();
}
/**
* 具体产品A1
*/
class ProductA1 implements AbstractProductA {
@Override
public void use() {
System.out.println("Using Product A1");
}
}
/**
* 具体产品A2
*/
class ProductA2 implements AbstractProductA {
@Override
public void use() {
System.out.println("Using Product A2");
}
}
/**
* 具体产品B1
*/
class ProductB1 implements AbstractProductB {
@Override
public void eat() {
System.out.println("Eating Product B1");
}
}
/**
* 具体产品B2
*/
class ProductB2 implements AbstractProductB {
@Override
public void eat() {
System.out.println("Eating Product B2");
}
}
/**
* 抽象工厂
*/
interface AbstractFactory {
AbstractProductA createProductA();
AbstractProductB createProductB();
}
/**
* 具体工厂1 - 生产A1和B1产品
*/
class ConcreteFactory1 implements AbstractFactory {
@Override
public AbstractProductA createProductA() {
return new ProductA1();
}
@Override
public AbstractProductB createProductB() {
return new ProductB1();
}
}
/**
* 具体工厂2 - 生产A2和B2产品
*/
class ConcreteFactory2 implements AbstractFactory {
@Override
public AbstractProductA createProductA() {
return new ProductA2();
}
@Override
public AbstractProductB createProductB() {
return new ProductB2();
}
}
// 使用示例
public class AbstractFactoryDemo {
public static void main(String[] args) {
// 创建工厂1
AbstractFactory factory1 = new ConcreteFactory1();
// 使用工厂1创建产品A和B
AbstractProductA productA1 = factory1.createProductA();
AbstractProductB productB1 = factory1.createProductB();
productA1.use();
productB1.eat();
// 创建工厂2
AbstractFactory factory2 = new ConcreteFactory2();
// 使用工厂2创建产品A和B
AbstractProductA productA2 = factory2.createProductA();
AbstractProductB productB2 = factory2.createProductB();
productA2.use();
productB2.eat();
}
}
4. 建造者模式 (Builder)
意图:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
/**
* 产品类 - 电脑
*/
class Computer {
private String cpu;
private String ram;
private String storage;
private String gpu;
public void setCpu(String cpu) {
this.cpu = cpu;
}
public void setRam(String ram) {
this.ram = ram;
}
public void setStorage(String storage) {
this.storage = storage;
}
public void setGpu(String gpu) {
this.gpu = gpu;
}
@Override
public String toString() {
return "Computer{" +
"cpu='" + cpu + '\'' +
", ram='" + ram + '\'' +
", storage='" + storage + '\'' +
", gpu='" + gpu + '\'' +
'}';
}
}
/**
* 抽象建造者
*/
interface ComputerBuilder {
void buildCpu();
void buildRam();
void buildStorage();
void buildGpu();
Computer getResult();
}
/**
* 具体建造者 - 游戏电脑
*/
class GamingComputerBuilder implements ComputerBuilder {
private Computer computer = new Computer();
@Override
public void buildCpu() {
computer.setCpu("Intel i9");
}
@Override
public void buildRam() {
computer.setRam("32GB DDR4");
}
@Override
public void buildStorage() {
computer.setStorage("1TB SSD + 2TB HDD");
}
@Override
public void buildGpu() {
computer.setGpu("NVIDIA RTX 3080");
}
@Override
public Computer getResult() {
return computer;
}
}
/**
* 具体建造者 - 办公电脑
*/
class OfficeComputerBuilder implements ComputerBuilder {
private Computer computer = new Computer();
@Override
public void buildCpu() {
computer.setCpu("Intel i5");
}
@Override
public void buildRam() {
computer.setRam("16GB DDR4");
}
@Override
public void buildStorage() {
computer.setStorage("512GB SSD");
}
@Override
public void buildGpu() {
computer.setGpu("Integrated Graphics");
}
@Override
public Computer getResult() {
return computer;
}
}
/**
* 指挥者
*/
class ComputerDirector {
public Computer construct(ComputerBuilder builder) {
builder.buildCpu();
builder.buildRam();
builder.buildStorage();
builder.buildGpu();
return builder.getResult();
}
}
// 使用示例
public class BuilderDemo {
public static void main(String[] args) {
ComputerDirector director = new ComputerDirector();
// 构建游戏电脑
ComputerBuilder gamingBuilder = new GamingComputerBuilder();
Computer gamingComputer = director.construct(gamingBuilder);
System.out.println("Gaming Computer: " + gamingComputer);
// 构建办公电脑
ComputerBuilder officeBuilder = new OfficeComputerBuilder();
Computer officeComputer = director.construct(officeBuilder);
System.out.println("Office Computer: " + officeComputer);
}
}
5. 原型模式 (Prototype)
意图:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
import java.util.HashMap;
import java.util.Map;
/**
* 抽象原型类
*/
abstract class Shape implements Cloneable {
private String id;
protected String type;
abstract void draw();
public String getType() {
return type;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Override
public Object clone() {
Object clone = null;
try {
clone = super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return clone;
}
}
/**
* 具体原型类 - 矩形
*/
class Rectangle extends Shape {
public Rectangle() {
type = "Rectangle";
}
@Override
public void draw() {
System.out.println("Inside Rectangle::draw() method.");
}
}
/**
* 具体原型类 - 圆形
*/
class Circle extends Shape {
public Circle() {
type = "Circle";
}
@Override
public void draw() {
System.out.println("Inside Circle::draw() method.");
}
}
/**
* 原型管理器
*/
class ShapeCache {
private static Map<String, Shape> shapeMap = new HashMap<>();
public static Shape getShape(String shapeId) {
Shape cachedShape = shapeMap.get(shapeId);
return (Shape) cachedShape.clone();
}
// 对每种形状都运行数据库查询,并创建该形状
// shapeMap.put(shapeKey, shape);
// 例如,我们要添加三种形状
public static void loadCache() {
Circle circle = new Circle();
circle.setId("1");
shapeMap.put(circle.getId(), circle);
Rectangle rectangle = new Rectangle();
rectangle.setId("2");
shapeMap.put(rectangle.getId(), rectangle);
}
}
// 使用示例
public class PrototypeDemo {
public static void main(String[] args) {
ShapeCache.loadCache();
Shape clonedShape1 = ShapeCache.getShape("1");
System.out.println("Shape : " + clonedShape1.getType());
clonedShape1.draw();
Shape clonedShape2 = ShapeCache.getShape("2");
System.out.println("Shape : " + clonedShape2.getType());
clonedShape2.draw();
// 验证是否为不同对象
System.out.println("Are shapes same? " + (clonedShape1 == clonedShape2));
}
}
二、结构型模式 (7种)
6. 适配器模式 (Adapter)
意图:将一个类的接口转换成客户希望的另外一个接口。
/**
* 目标接口 - 客户期望的接口
*/
interface MediaPlayer {
void play(String audioType, String fileName);
}
/**
* 适配者接口 - 已存在的接口
*/
interface AdvancedMediaPlayer {
void playVlc(String fileName);
void playMp4(String fileName);
}
/**
* 具体适配者 - VLC播放器
*/
class VlcPlayer implements AdvancedMediaPlayer {
@Override
public void playVlc(String fileName) {
System.out.println("Playing vlc file. Name: " + fileName);
}
@Override
public void playMp4(String fileName) {
// 什么也不做
}
}
/**
* 具体适配者 - MP4播放器
*/
class Mp4Player implements AdvancedMediaPlayer {
@Override
public void playVlc(String fileName) {
// 什么也不做
}
@Override
public void playMp4(String fileName) {
System.out.println("Playing mp4 file. Name: " + 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. Name: " + fileName);
}
// mediaAdapter 提供了播放其他文件格式的支持
else if (audioType.equalsIgnoreCase("vlc")
|| audioType.equalsIgnoreCase("mp4")) {
mediaAdapter = new MediaAdapter(audioType);
mediaAdapter.play(audioType, fileName);
} else {
System.out.println("Invalid media. " + audioType + " format not supported");
}
}
}
// 使用示例
public class AdapterDemo {
public static void main(String[] args) {
AudioPlayer audioPlayer = new AudioPlayer();
audioPlayer.play("mp3", "beyond the horizon.mp3");
audioPlayer.play("mp4", "alone.mp4");
audioPlayer.play("vlc", "far far away.vlc");
audioPlayer.play("avi", "mind me.avi");
}
}
7. 桥接模式 (Bridge)
意图:将抽象部分与它的实现部分分离,使它们都可以独立地变化。
/**
* 实现部分接口
*/
interface DrawAPI {
void drawCircle(int radius, int x, int y);
}
/**
* 具体实现A
*/
class RedCircle implements DrawAPI {
@Override
public void drawCircle(int radius, int x, int y) {
System.out.println("Drawing Circle[ color: red, radius: "
+ radius + ", x: " + x + ", y: " + y + "]");
}
}
/**
* 具体实现B
*/
class GreenCircle implements DrawAPI {
@Override
public void drawCircle(int radius, int x, int y) {
System.out.println("Drawing Circle[ color: green, radius: "
+ radius + ", x: " + x + ", y: " + y + "]");
}
}
/**
* 抽象部分
*/
abstract class Shape {
protected DrawAPI drawAPI;
protected Shape(DrawAPI drawAPI) {
this.drawAPI = drawAPI;
}
public abstract void draw();
}
/**
* 扩展抽象部分 - 圆形
*/
class Circle extends Shape {
private int x, y, radius;
public Circle(int x, int y, int radius, DrawAPI drawAPI) {
super(drawAPI);
this.x = x;
this.y = y;
this.radius = radius;
}
@Override
public void draw() {
drawAPI.drawCircle(radius, x, y);
}
}
// 使用示例
public class BridgeDemo {
public static void main(String[] args) {
Shape redCircle = new Circle(100, 100, 10, new RedCircle());
Shape greenCircle = new Circle(200, 200, 20, new GreenCircle());
redCircle.draw();
greenCircle.draw();
}
}
8. 组合模式 (Composite)
意图:将对象组合成树形结构以表示"部分-整体"的层次结构。
import java.util.ArrayList;
import java.util.List;
/**
* 组件接口
*/
interface Employee {
void showEmployeeDetails();
}
/**
* 叶子节点 - 开发人员
*/
class Developer implements Employee {
private String name;
private String position;
public Developer(String name, String position) {
this.name = name;
this.position = position;
}
@Override
public void showEmployeeDetails() {
System.out.println("Developer: " + name + ", Position: " + position);
}
}
/**
* 叶子节点 - 经理
*/
class Manager implements Employee {
private String name;
private String position;
public Manager(String name, String position) {
this.name = name;
this.position = position;
}
@Override
public void showEmployeeDetails() {
System.out.println("Manager: " + name + ", Position: " + position);
}
}
/**
* 组合类 - 部门
*/
class Department implements Employee {
private String name;
private List<Employee> employees = new ArrayList<>();
public Department(String name) {
this.name = name;
}
public void addEmployee(Employee employee) {
employees.add(employee);
}
public void removeEmployee(Employee employee) {
employees.remove(employee);
}
@Override
public void showEmployeeDetails() {
System.out.println("Department: " + name);
for (Employee employee : employees) {
employee.showEmployeeDetails();
}
}
}
// 使用示例
public class CompositeDemo {
public static void main(String[] args) {
Employee dev1 = new Developer("John", "Senior Developer");
Employee dev2 = new Developer("David", "Junior Developer");
Department engineering = new Department("Engineering");
engineering.addEmployee(dev1);
engineering.addEmployee(dev2);
Employee man1 = new Manager("Mike", "Engineering Manager");
Employee man2 = new Manager("Sophia", "HR Manager");
Department hr = new Department("Human Resources");
hr.addEmployee(man2);
Department company = new Department("Company");
company.addEmployee(man1);
company.addEmployee(engineering);
company.addEmployee(hr);
company.showEmployeeDetails();
}
}
9. 装饰器模式 (Decorator)
意图:动态地给一个对象添加一些额外的职责。
/**
* 组件接口
*/
interface Car {
void assemble();
}
/**
* 具体组件
*/
class BasicCar implements Car {
@Override
public void assemble() {
System.out.print("Basic Car.");
}
}
/**
* 装饰器抽象类
*/
abstract class CarDecorator implements Car {
protected Car car;
public CarDecorator(Car car) {
this.car = car;
}
@Override
public void assemble() {
car.assemble();
}
}
/**
* 具体装饰器 - 运动型
*/
class SportsCar extends CarDecorator {
public SportsCar(Car car) {
super(car);
}
@Override
public void assemble() {
super.assemble();
System.out.print(" Adding features of Sports Car.");
}
}
/**
* 具体装饰器 - 豪华型
*/
class LuxuryCar extends CarDecorator {
public LuxuryCar(Car car) {
super(car);
}
@Override
public void assemble() {
super.assemble();
System.out.print(" Adding features of Luxury Car.");
}
}
// 使用示例
public class DecoratorDemo {
public static void main(String[] args) {
Car sportsCar = new SportsCar(new BasicCar());
sportsCar.assemble();
System.out.println("\n");
Car sportsLuxuryCar = new SportsCar(new LuxuryCar(new BasicCar()));
sportsLuxuryCar.assemble();
}
}
10. 外观模式 (Facade)
意图:为子系统中的一组接口提供一个一致的界面。
/**
* 子系统A
*/
class CPU {
public void freeze() {
System.out.println("CPU freeze");
}
public void jump(long position) {
System.out.println("CPU jump to " + position);
}
public void execute() {
System.out.println("CPU execute");
}
}
/**
* 子系统B
*/
class Memory {
public void load(long position, byte[] data) {
System.out.println("Memory load at " + position);
}
}
/**
* 子系统C
*/
class HardDrive {
public byte[] read(long lba, int size) {
System.out.println("HardDrive read " + size + " bytes from " + lba);
return new byte[size];
}
}
/**
* 外观类
*/
class ComputerFacade {
private static final long BOOT_ADDRESS = 0x00000000;
private static final long BOOT_SECTOR = 0x00000000;
private static final int SECTOR_SIZE = 512;
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() {
processor.freeze();
ram.load(BOOT_ADDRESS, hd.read(BOOT_SECTOR, SECTOR_SIZE));
processor.jump(BOOT_ADDRESS);
processor.execute();
}
}
// 使用示例
public class FacadeDemo {
public static void main(String[] args) {
ComputerFacade computer = new ComputerFacade();
computer.start();
}
}
11. 享元模式 (Flyweight)
意图:运用共享技术有效地支持大量细粒度的对象。
import java.util.HashMap;
/**
* 享元接口
*/
interface Shape {
void draw();
}
/**
* 具体享元类
*/
class Circle implements Shape {
private String color;
private int x;
private int y;
private int radius;
public Circle(String color) {
this.color = color;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public void setRadius(int radius) {
this.radius = radius;
}
@Override
public void draw() {
System.out.println("Circle: Draw() [Color : " + color
+ ", x : " + x + ", y :" + y + ", radius :" + radius);
}
}
/**
* 享元工厂
*/
class ShapeFactory {
private static final HashMap<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 class FlyweightDemo {
private static final String[] colors = {"Red", "Green", "Blue", "White", "Black"};
public static void main(String[] args) {
for (int i = 0; i < 20; ++i) {
Circle circle = (Circle) ShapeFactory.getCircle(getRandomColor());
circle.setX(getRandomX());
circle.setY(getRandomY());
circle.setRadius(100);
circle.draw();
}
}
private static String getRandomColor() {
return colors[(int)(Math.random() * colors.length)];
}
private static int getRandomX() {
return (int)(Math.random() * 100);
}
private static int getRandomY() {
return (int)(Math.random() * 100);
}
}
12. 代理模式 (Proxy)
意图:为其他对象提供一种代理以控制对这个对象的访问。
/**
* 接口
*/
interface Image {
void display();
}
/**
* 真实对象
*/
class RealImage implements Image {
private String fileName;
public RealImage(String fileName) {
this.fileName = fileName;
loadFromDisk(fileName);
}
@Override
public void display() {
System.out.println("Displaying " + fileName);
}
private void loadFromDisk(String fileName) {
System.out.println("Loading " + 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();
}
}
// 使用示例
public class ProxyDemo {
public static void main(String[] args) {
Image image = new ProxyImage("test_10mb.jpg");
// 图像将从磁盘加载
image.display();
System.out.println("");
// 图像不需要从磁盘加载
image.display();
}
}
三、行为型模式 (11种)
13. 责任链模式 (Chain of Responsibility)
意图:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。
/**
* 抽象处理器
*/
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("Standard Console::Logger: " + message);
}
}
/**
* 具体处理器 - 错误日志
*/
class ErrorLogger extends Logger {
public ErrorLogger(int level) {
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("Error 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);
}
}
// 使用示例
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();
loggerChain.logMessage(Logger.INFO, "This is an information.");
System.out.println();
loggerChain.logMessage(Logger.DEBUG, "This is a debug level information.");
System.out.println();
loggerChain.logMessage(Logger.ERROR, "This is an error information.");
}
}
14. 命令模式 (Command)
意图:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化。
/**
* 命令接口
*/
interface Order {
void execute();
}
/**
* 请求类
*/
class Stock {
private String name = "ABC";
private int quantity = 10;
public void buy() {
System.out.println("Stock [ Name: " + name + ", Quantity: "
+ quantity + " ] bought");
}
public void sell() {
System.out.println("Stock [ Name: " + name + ", Quantity: "
+ quantity + " ] sold");
}
}
/**
* 具体命令 - 买入
*/
class BuyStock implements Order {
private Stock abcStock;
public BuyStock(Stock abcStock) {
this.abcStock = abcStock;
}
@Override
public void execute() {
abcStock.buy();
}
}
/**
* 具体命令 - 卖出
*/
class SellStock implements Order {
private Stock abcStock;
public SellStock(Stock abcStock) {
this.abcStock = abcStock;
}
@Override
public void execute() {
abcStock.sell();
}
}
/**
* 调用者
*/
class Broker {
private List<Order> orderList = new ArrayList<>();
public void takeOrder(Order order) {
orderList.add(order);
}
public void placeOrders() {
for (Order order : orderList) {
order.execute();
}
orderList.clear();
}
}
// 使用示例
public class CommandDemo {
public static void main(String[] args) {
Stock abcStock = new Stock();
BuyStock buyStockOrder = new BuyStock(abcStock);
SellStock sellStockOrder = new SellStock(abcStock);
Broker broker = new Broker();
broker.takeOrder(buyStockOrder);
broker.takeOrder(sellStockOrder);
broker.placeOrders();
}
}
15. 解释器模式 (Interpreter)
意图:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
import java.util.Stack;
/**
* 表达式接口
*/
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);
}
}
/**
* 与表达式
*/
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(String context) {
return expr1.interpret(context) && expr2.interpret(context);
}
}
// 使用示例
public class InterpreterDemo {
// 规则:Robert 和 John 是男性
public static Expression getMaleExpression() {
Expression robert = new TerminalExpression("Robert");
Expression john = new TerminalExpression("John");
return new OrExpression(robert, john);
}
// 规则:Julie 是一个已婚的女性
public static Expression getMarriedWomanExpression() {
Expression julie = new TerminalExpression("Julie");
Expression married = new TerminalExpression("Married");
return new AndExpression(julie, married);
}
public static void main(String[] args) {
Expression isMale = getMaleExpression();
Expression isMarriedWoman = getMarriedWomanExpression();
System.out.println("John is male? " + isMale.interpret("John"));
System.out.println("Julie is a married woman? "
+ isMarriedWoman.interpret("Married Julie"));
}
}
16. 迭代器模式 (Iterator)
意图:提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示。
/**
* 迭代器接口
*/
interface Iterator {
boolean hasNext();
Object next();
}
/**
* 容器接口
*/
interface Container {
Iterator getIterator();
}
/**
* 具体容器
*/
class NameRepository implements Container {
public String[] names = {"Robert", "John", "Julie", "Lora"};
@Override
public Iterator getIterator() {
return new NameIterator();
}
/**
* 具体迭代器
*/
private class NameIterator implements Iterator {
int index;
@Override
public boolean hasNext() {
return index < names.length;
}
@Override
public Object next() {
if (this.hasNext()) {
return names[index++];
}
return null;
}
}
}
// 使用示例
public class IteratorDemo {
public static void main(String[] args) {
NameRepository namesRepository = new NameRepository();
for (Iterator iter = namesRepository.getIterator(); iter.hasNext();) {
String name = (String) iter.next();
System.out.println("Name : " + name);
}
}
}
17. 中介者模式 (Mediator)
意图:用一个中介对象来封装一系列的对象交互。
import java.util.Date;
/**
* 中介者接口
*/
interface ChatRoom {
void showMessage(User user, String message);
}
/**
* 具体中介者
*/
class ChatRoomImpl implements ChatRoom {
@Override
public void showMessage(User user, String message) {
System.out.println(new Date().toString() + " [" + user.getName() + "] : " + message);
}
}
/**
* 同事类
*/
class User {
private String name;
private ChatRoom chatRoom;
public User(String name, ChatRoom chatRoom) {
this.name = name;
this.chatRoom = chatRoom;
}
public String getName() {
return name;
}
public void sendMessage(String message) {
chatRoom.showMessage(this, message);
}
}
// 使用示例
public class MediatorDemo {
public static void main(String[] args) {
ChatRoom chatRoom = new ChatRoomImpl();
User john = new User("John", chatRoom);
User jane = new User("Jane", chatRoom);
john.sendMessage("Hi there!");
jane.sendMessage("Hey!");
}
}
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 add(Memento state) {
mementoList.add(state);
}
public Memento get(int index) {
return mementoList.get(index);
}
}
// 使用示例
public class MementoDemo {
public static void main(String[] args) {
Originator originator = new Originator();
CareTaker careTaker = new CareTaker();
originator.setState("State #1");
originator.setState("State #2");
careTaker.add(originator.saveStateToMemento());
originator.setState("State #3");
careTaker.add(originator.saveStateToMemento());
originator.setState("State #4");
System.out.println("Current State: " + originator.getState());
originator.getStateFromMemento(careTaker.get(0));
System.out.println("First saved State: " + originator.getState());
originator.getStateFromMemento(careTaker.get(1));
System.out.println("Second saved State: " + originator.getState());
}
}
19. 观察者模式 (Observer)
意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
import java.util.ArrayList;
import java.util.List;
/**
* 主题接口
*/
interface Subject {
void registerObserver(Observer o);
void removeObserver(Observer o);
void notifyObservers();
}
/**
* 具体主题
*/
class ConcreteSubject implements Subject {
private List<Observer> observers = new ArrayList<>();
private int state;
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
notifyObservers();
}
@Override
public void registerObserver(Observer o) {
observers.add(o);
}
@Override
public void removeObserver(Observer o) {
observers.remove(o);
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update();
}
}
}
/**
* 观察者接口
*/
interface Observer {
void update();
}
/**
* 具体观察者A
*/
class ConcreteObserverA implements Observer {
private ConcreteSubject subject;
public ConcreteObserverA(ConcreteSubject subject) {
this.subject = subject;
subject.registerObserver(this);
}
@Override
public void update() {
System.out.println("ConcreteObserverA: Subject's state changed to "
+ subject.getState());
}
}
/**
* 具体观察者B
*/
class ConcreteObserverB implements Observer {
private ConcreteSubject subject;
public ConcreteObserverB(ConcreteSubject subject) {
this.subject = subject;
subject.registerObserver(this);
}
@Override
public void update() {
System.out.println("ConcreteObserverB: Subject's state changed to "
+ subject.getState());
}
}
// 使用示例
public class ObserverDemo {
public static void main(String[] args) {
ConcreteSubject subject = new ConcreteSubject();
new ConcreteObserverA(subject);
new ConcreteObserverB(subject);
subject.setState(1);
subject.setState(2);
}
}
20. 状态模式 (State)
意图:允许一个对象在其内部状态改变时改变它的行为。
/**
* 状态接口
*/
interface State {
void doAction(Context context);
}
/**
* 具体状态 - 开始状态
*/
class StartState implements State {
@Override
public void doAction(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 doAction(Context context) {
System.out.println("Player is in stop state");
context.setState(this);
}
@Override
public String toString() {
return "Stop State";
}
}
/**
* 上下文类
*/
class Context {
private State state;
public Context() {
state = null;
}
public void setState(State state) {
this.state = state;
}
public State getState() {
return state;
}
}
// 使用示例
public class StateDemo {
public static void main(String[] args) {
Context context = new Context();
StartState startState = new StartState();
startState.doAction(context);
System.out.println(context.getState().toString());
StopState stopState = new StopState();
stopState.doAction(context);
System.out.println(context.getState().toString());
}
}
21. 策略模式 (Strategy)
意图:定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。
/**
* 策略接口
*/
interface Strategy {
int doOperation(int num1, int num2);
}
/**
* 具体策略 - 加法
*/
class OperationAdd implements Strategy {
@Override
public int doOperation(int num1, int num2) {
return num1 + num2;
}
}
/**
* 具体策略 - 减法
*/
class OperationSubtract implements Strategy {
@Override
public int doOperation(int num1, int num2) {
return num1 - num2;
}
}
/**
* 具体策略 - 乘法
*/
class OperationMultiply implements Strategy {
@Override
public int doOperation(int num1, int num2) {
return num1 * num2;
}
}
/**
* 上下文类
*/
class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public int executeStrategy(int num1, int num2) {
return strategy.doOperation(num1, num2);
}
}
// 使用示例
public class StrategyDemo {
public static void main(String[] args) {
Context context = new Context(new OperationAdd());
System.out.println("10 + 5 = " + context.executeStrategy(10, 5));
context = new Context(new OperationSubtract());
System.out.println("10 - 5 = " + context.executeStrategy(10, 5));
context = new Context(new OperationMultiply());
System.out.println("10 * 5 = " + context.executeStrategy(10, 5));
}
}
22. 模板方法模式 (Template Method)
意图:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。
/**
* 抽象类 - 定义模板方法
*/
abstract class Game {
abstract void initialize();
abstract void startPlay();
abstract void endPlay();
// 模板方法
public final void play() {
// 初始化游戏
initialize();
// 开始游戏
startPlay();
// 结束游戏
endPlay();
}
}
/**
* 具体子类 - 足球游戏
*/
class Football extends Game {
@Override
void initialize() {
System.out.println("Football Game Initialized! Start playing.");
}
@Override
void startPlay() {
System.out.println("Football Game Started. Enjoy the game!");
}
@Override
void endPlay() {
System.out.println("Football Game Finished!");
}
}
/**
* 具体子类 - 篮球游戏
*/
class Basketball extends Game {
@Override
void initialize() {
System.out.println("Basketball Game Initialized! Start playing.");
}
@Override
void startPlay() {
System.out.println("Basketball Game Started. Enjoy the game!");
}
@Override
void endPlay() {
System.out.println("Basketball Game Finished!");
}
}
// 使用示例
public class TemplateMethodDemo {
public static void main(String[] args) {
Game game = new Football();
game.play();
System.out.println();
game = new Basketball();
game.play();
}
}
23. 访问者模式 (Visitor)
意图:表示一个作用于某对象结构中的各元素的操作。
/**
* 元素接口
*/
interface ComputerPart {
void accept(ComputerPartVisitor computerPartVisitor);
}
/**
* 具体元素 - 键盘
*/
class Keyboard implements ComputerPart {
@Override
public void accept(ComputerPartVisitor computerPartVisitor) {
computerPartVisitor.visit(this);
}
}
/**
* 具体元素 - 显示器
*/
class Monitor implements ComputerPart {
@Override
public void accept(ComputerPartVisitor computerPartVisitor) {
computerPartVisitor.visit(this);
}
}
/**
* 具体元素 - 鼠标
*/
class Mouse implements ComputerPart {
@Override
public void accept(ComputerPartVisitor computerPartVisitor) {
computerPartVisitor.visit(this);
}
}
/**
* 具体元素 - 计算机
*/
class Computer implements ComputerPart {
ComputerPart[] parts;
public Computer() {
parts = new ComputerPart[] {new Mouse(), new Keyboard(), new Monitor()};
}
@Override
public void accept(ComputerPartVisitor computerPartVisitor) {
for (ComputerPart part : parts) {
part.accept(computerPartVisitor);
}
computerPartVisitor.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.");
}
}
// 使用示例
public class VisitorDemo {
public static void main(String[] args) {
ComputerPart computer = new Computer();
computer.accept(new ComputerPartDisplayVisitor());
}
}
总结
这23种设计模式可以分为三大类:
- 创建型模式:关注对象的创建过程
- 单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式
- 结构型模式:关注类和对象的组合
- 适配器模式、桥接模式、组合模式、装饰器模式、外观模式、享元模式、代理模式
- 行为型模式:关注对象之间的交互
- 责任链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式、访问者模式
每种设计模式都有其特定的应用场景,理解这些模式可以帮助我们编写更加灵活、可维护和可扩展的代码。在实际开发中,应根据具体问题选择合适的模式,而不是为了使用模式而使用模式。