1. 单例模式(Singleton Pattern)
原理
确保一个类只有一个实例,并提供全局访问点。核心是通过私有构造器和静态方法控制实例化。
应用场景
- 配置管理类
- 数据库连接池
- 日志记录器
代码实例1:日志管理器(懒汉式,线程安全)
场景:在一个电商系统中,需要一个全局日志管理器记录操作日志。
java">public class Logger {
// volatile确保多线程环境下可见性
private static volatile Logger instance;
private Logger() {
// 防止反射破坏单例
if (instance != null) {
throw new RuntimeException("Use getInstance() method to get the single instance.");
}
}
public static Logger getInstance() {
if (instance == null) {
synchronized (Logger.class) {
if (instance == null) {
instance = new Logger();
}
}
}
return instance;
}
public void log(String message) {
System.out.println("Log: " + message);
}
}
// 使用
public class OrderService {
public void createOrder() {
Logger logger = Logger.getInstance();
logger.log("Order created at " + System.currentTimeMillis());
}
}
说明:双重检查锁(Double-Checked Locking)确保线程安全,适用于延迟加载。
代码实例2:配置管理(饿汉式)
场景:读取应用的全局配置(如API密钥)。
java">public class ConfigManager {
// 类加载时即创建实例
private static final ConfigManager INSTANCE = new ConfigManager();
private final String apiKey;
private ConfigManager() {
this.apiKey = "12345-ABCDE"; // 模拟从文件加载
}
public static ConfigManager getInstance() {
return INSTANCE;
}
public String getApiKey() {
return apiKey;
}
}
// 使用
public class PaymentService {
public void processPayment() {
ConfigManager config = ConfigManager.getInstance();
System.out.println("Using API Key: " + config.getApiKey());
}
}
说明:饿汉式在类加载时初始化,简单但不支持延迟加载。
注意事项
- 线程安全:懒汉式需加锁,饿汉式天然安全。
- 序列化/反射破坏:需额外处理(如上例中的构造器检查)。
2. 工厂方法模式(Factory Method Pattern)
原理
定义一个创建对象的接口,由子类决定实例化哪个类,推迟实例化到子类。
应用场景
- 创建不同类型的日志记录器
- 动态生成数据库连接
代码实例1:日志工厂
场景:支持文件日志和数据库日志。
java">public interface Logger {
void log(String message);
}
public class FileLogger implements Logger {
@Override
public void log(String message) {
System.out.println("File Log: " + message);
}
}
public class DatabaseLogger implements Logger {
@Override
public void log(String message) {
System.out.println("DB Log: " + message);
}
}
public abstract class LoggerFactory {
public abstract Logger createLogger();
public void writeLog(String message) {
Logger logger = createLogger();
logger.log(message);
}
}
public class FileLoggerFactory extends LoggerFactory {
@Override
public Logger createLogger() {
return new FileLogger();
}
}
// 使用
public class Client {
public static void main(String[] args) {
LoggerFactory factory = new FileLoggerFactory();
factory.writeLog("Order processed");
}
}
代码实例2:数据库连接工厂
场景:支持MySQL和PostgreSQL连接。
java">public interface DatabaseConnection {
void connect();
}
public class MySQLConnection implements DatabaseConnection {
@Override
public void connect() {
System.out.println("Connected to MySQL");
}
}
public class PostgreSQLConnection implements DatabaseConnection {
@Override
public void connect() {
System.out.println("Connected to PostgreSQL");
}
}
public abstract class ConnectionFactory {
public abstract DatabaseConnection createConnection();
}
public class MySQLConnectionFactory extends ConnectionFactory {
@Override
public DatabaseConnection createConnection() {
return new MySQLConnection();
}
}
// 使用
public class DataService {
public void queryData(ConnectionFactory factory) {
DatabaseConnection conn = factory.createConnection();
conn.connect();
}
}
注意事项
- 扩展性强,但工厂类增多可能导致复杂度上升。
- 可结合Spring的依赖注入简化实现。
3. 建造者模式(Builder Pattern)
原理
将复杂对象的构建过程与其表示分离,逐步构建。
应用场景
- 创建复杂配置对象
- 构造HTTP请求
代码实例1:订单对象构建
场景:电商系统中构造订单。
java">public class Order {
private final String orderId;
private final String customerName;
private final double amount;
private Order(Builder builder) {
this.orderId = builder.orderId;
this.customerName = builder.customerName;
this.amount = builder.amount;
}
public static class Builder {
private String orderId;
private String customerName;
private double amount;
public Builder orderId(String orderId) {
this.orderId = orderId;
return this;
}
public Builder customerName(String customerName) {
this.customerName = customerName;
return this;
}
public Builder amount(double amount) {
this.amount = amount;
return this;
}
public Order build() {
return new Order(this);
}
}
}
// 使用
public class OrderService {
public Order createOrder() {
return new Order.Builder()
.orderId("ORD001")
.customerName("Alice")
.amount(100.0)
.build();
}
}
代码实例2:HTTP请求构建
场景:构造HTTP请求参数。
java">public class HttpRequest {
private final String url;
private final String method;
private final String body;
private HttpRequest(Builder builder) {
this.url = builder.url;
this.method = builder.method;
this.body = builder.body;
}
public static class Builder {
private String url;
private String method = "GET";
private String body;
public Builder url(String url) {
this.url = url;
return this;
}
public Builder method(String method) {
this.method = method;
return this;
}
public Builder body(String body) {
this.body = body;
return this;
}
public HttpRequest build() {
return new HttpRequest(this);
}
}
}
// 使用
public class ApiClient {
public HttpRequest sendRequest() {
return new HttpRequest.Builder()
.url("https://api.example.com")
.method("POST")
.body("{'data': 'test'}")
.build();
}
}
注意事项
- 适合复杂对象,避免过多构造函数参数。
- 可结合Lombok的
@Builder
简化代码。
4. 装饰者模式(Decorator Pattern)
原理
动态为对象添加职责,不修改原有类。
应用场景
- 日志增强
- 数据流处理
代码实例1:咖啡订单装饰
场景:咖啡店系统中添加额外配料。
java">public interface Coffee {
double cost();
String description();
}
public class SimpleCoffee implements Coffee {
@Override
public double cost() {
return 5.0;
}
@Override
public String description() {
return "Simple Coffee";
}
}
public abstract class CoffeeDecorator implements Coffee {
protected Coffee coffee;
public CoffeeDecorator(Coffee coffee) {
this.coffee = coffee;
}
}
public class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee coffee) {
super(coffee);
}
@Override
public double cost() {
return coffee.cost() + 1.5;
}
@Override
public String description() {
return coffee.description() + ", Milk";
}
}
// 使用
public class CoffeeShop {
public static void main(String[] args) {
Coffee coffee = new MilkDecorator(new SimpleCoffee());
System.out.println(coffee.description() + " costs " + coffee.cost());
}
}
代码实例2:日志装饰
场景:为日志添加时间戳。
java">public interface Logger {
void log(String message);
}
public class BasicLogger implements Logger {
@Override
public void log(String message) {
System.out.println(message);
}
}
public abstract class LoggerDecorator implements Logger {
protected Logger logger;
public LoggerDecorator(Logger logger) {
this.logger = logger;
}
}
public class TimestampLogger extends LoggerDecorator {
public TimestampLogger(Logger logger) {
super(logger);
}
@Override
public void log(String message) {
logger.log(System.currentTimeMillis() + " - " + message);
}
}
// 使用
public class App {
public static void main(String[] args) {
Logger logger = new TimestampLogger(new BasicLogger());
logger.log("Order processed");
}
}
注意事项
- 灵活性高,但可能增加类数量。
- Spring AOP本质上也类似装饰者模式。
5. 代理模式(Proxy Pattern)
原理
为对象提供代理,控制访问或增强功能。
应用场景
- 权限控制
- 延迟加载
代码实例1:权限代理
场景:限制用户访问敏感操作。
java">public interface UserService {
void deleteUser(String userId);
}
public class UserServiceImpl implements UserService {
@Override
public void deleteUser(String userId) {
System.out.println("User " + userId + " deleted");
}
}
public class UserServiceProxy implements UserService {
private UserService target;
private String role;
public UserServiceProxy(UserService target, String role) {
this.target = target;
this.role = role;
}
@Override
public void deleteUser(String userId) {
if ("admin".equals(role)) {
target.deleteUser(userId);
} else {
System.out.println("Permission denied");
}
}
}
// 使用
public class Main {
public static void main(String[] args) {
UserService service = new UserServiceProxy(new UserServiceImpl(), "user");
service.deleteUser("001");
}
}
代码实例2:延迟加载代理
场景:延迟加载大文件。
java">public interface FileLoader {
void load();
}
public class RealFileLoader implements FileLoader {
private String fileName;
public RealFileLoader(String fileName) {
this.fileName = fileName;
}
@Override
public void load() {
System.out.println("Loading file: " + fileName);
}
}
public class LazyFileLoaderProxy implements FileLoader {
private RealFileLoader realLoader;
private String fileName;
public LazyFileLoaderProxy(String fileName) {
this.fileName = fileName;
}
@Override
public void load() {
if (realLoader == null) {
realLoader = new RealFileLoader(fileName);
}
realLoader.load();
}
}
// 使用
public class FileSystem {
public static void main(String[] args) {
FileLoader loader = new LazyFileLoaderProxy("largeFile.txt");
loader.load(); // 仅在需要时加载
}
}
注意事项
- 动态代理(如
java.lang.reflect.Proxy
)更灵活。 - Spring AOP大量使用代理模式。
6. 观察者模式(Observer Pattern)
原理
定义一对多依赖,主体状态变化时通知观察者。
应用场景
- 事件监听
- 库存变化通知
代码实例1:库存通知
场景:库存不足时通知采购部门。
java">import java.util.ArrayList;
import java.util.List;
public interface Observer {
void update(String message);
}
public class Stock {
private List<Observer> observers = new ArrayList<>();
private int quantity;
public void addObserver(Observer observer) {
observers.add(observer);
}
public void setQuantity(int quantity) {
this.quantity = quantity;
if (quantity < 10) {
notifyObservers("Stock low: " + quantity);
}
}
private void notifyObservers(String message) {
for (Observer observer : observers) {
observer.update(message);
}
}
}
public class PurchasingDept implements Observer {
@Override
public void update(String message) {
System.out.println("Purchasing: " + message);
}
}
// 使用
public class Warehouse {
public static void main(String[] args) {
Stock stock = new Stock();
stock.addObserver(new PurchasingDept());
stock.setQuantity(5);
}
}
代码实例2:订单状态通知
场景:订单状态变化时通知用户。
java">import java.util.ArrayList;
import java.util.List;
public interface OrderObserver {
void onOrderUpdate(String orderId, String status);
}
public class Order {
private List<OrderObserver> observers = new ArrayList<>();
private String orderId;
private String status;
public Order(String orderId) {
this.orderId = orderId;
}
public void addObserver(OrderObserver observer) {
observers.add(observer);
}
public void setStatus(String status) {
this.status = status;
notifyObservers();
}
private void notifyObservers() {
for (OrderObserver observer : observers) {
observer.onOrderUpdate(orderId, status);
}
}
}
public class Customer implements OrderObserver {
@Override
public void onOrderUpdate(String orderId, String status) {
System.out.println("Customer notified: Order " + orderId + " is " + status);
}
}
// 使用
public class OrderService {
public static void main(String[] args) {
Order order = new Order("ORD001");
order.addObserver(new Customer());
order.setStatus("Shipped");
}
}
注意事项
- Java提供了
Observable
和Observer
(已过时),推荐自定义或用java.util.EventListener
。 - Spring的
ApplicationEvent
是观察者模式的典型应用。
7. 策略模式(Strategy Pattern)
原理
定义一系列算法,动态选择使用。
应用场景
- 支付方式选择
- 折扣计算
代码实例1:支付策略
场景:电商系统中的支付方式。
java">public interface PaymentStrategy {
void pay(double amount);
}
public class AlipayStrategy implements PaymentStrategy {
@Override
public void pay(double amount) {
System.out.println("Paid " + amount + " via Alipay");
}
}
public class CreditCardStrategy implements PaymentStrategy {
@Override
public void pay(double amount) {
System.out.println("Paid " + amount + " via Credit Card");
}
}
public class PaymentContext {
private PaymentStrategy strategy;
public void setStrategy(PaymentStrategy strategy) {
this.strategy = strategy;
}
public void executePayment(double amount) {
strategy.pay(amount);
}
}
// 使用
public class CheckoutService {
public void checkout(double amount, String paymentType) {
PaymentContext context = new PaymentContext();
if ("alipay".equals(paymentType)) {
context.setStrategy(new AlipayStrategy());
} else {
context.setStrategy(new CreditCardStrategy());
}
context.executePayment(amount);
}
}
代码实例2:折扣策略
场景:促销活动中计算折扣。
java">public interface DiscountStrategy {
double applyDiscount(double price);
}
public class NoDiscountStrategy implements DiscountStrategy {
@Override
public double applyDiscount(double price) {
return price;
}
}
public class HolidayDiscountStrategy implements DiscountStrategy {
@Override
public double applyDiscount(double price) {
return price * 0.8; // 20% off
}
}
public class ShoppingCart {
private DiscountStrategy discountStrategy;
public void setDiscountStrategy(DiscountStrategy discountStrategy) {
this.discountStrategy = discountStrategy;
}
public double calculateTotal(double price) {
return discountStrategy.applyDiscount(price);
}
}
// 使用
public class Main {
public static void main(String[] args) {
ShoppingCart cart = new ShoppingCart();
cart.setDiscountStrategy(new HolidayDiscountStrategy());
System.out.println("Total: " + cart.calculateTotal(100));
}
}
注意事项
- 可结合Spring的
@Conditional
动态注入策略。 - 避免策略类过多导致维护困难。
8. 迭代器模式(Iterator Pattern)
原理
提供一种顺序访问集合元素的方法,隐藏底层实现。
应用场景
- 遍历自定义集合
- 数据分页
代码实例1:商品列表迭代
场景:遍历电商商品列表。
java">import java.util.ArrayList;
import java.util.Iterator;
public class ProductList {
private ArrayList<String> products = new ArrayList<>();
public void addProduct(String product) {
products.add(product);
}
public Iterator<String> iterator() {
return products.iterator();
}
}
// 使用
public class Store {
public static void main(String[] args) {
ProductList list = new ProductList();
list.addProduct("Phone");
list.addProduct("Laptop");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
代码实例2:订单分页迭代
场景:分页遍历订单。
java">import java.util.ArrayList;
import java.util.Iterator;
public class OrderRepository {
private ArrayList<String> orders = new ArrayList<>();
public OrderRepository() {
orders.add("ORD001");
orders.add("ORD002");
orders.add("ORD003");
}
public Iterator<String> getPageIterator(int pageSize) {
return new OrderIterator(pageSize);
}
private class OrderIterator implements Iterator<String> {
private int index = 0;
private int pageSize;
public OrderIterator(int pageSize) {
this.pageSize = pageSize;
}
@Override
public boolean hasNext() {
return index < orders.size() && index < pageSize;
}
@Override
public String next() {
return orders.get(index++);
}
}
}
// 使用
public class OrderService {
public static void main(String[] args) {
OrderRepository repo = new OrderRepository();
Iterator<String> iterator = repo.getPageIterator(2);
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
注意事项
- Java集合框架已内置
Iterator
,自定义时注意兼容性。 - 可结合
for-each
语法简化使用。
9. 模板方法模式(Template Method Pattern)
原理
定义算法骨架,子类实现具体步骤。
应用场景
- 数据处理流程
- 报表生成
代码实例1:数据导入模板
场景:导入不同格式的数据。
java">public abstract class DataImporter {
// 模板方法
public void importData() {
connect();
String data = readData();
processData(data);
disconnect();
}
protected void connect() {
System.out.println("Connected to source");
}
protected abstract String readData();
protected abstract void processData(String data);
protected void disconnect() {
System.out.println("Disconnected");
}
}
public class CsvImporter extends DataImporter {
@Override
protected String readData() {
return "CSV data";
}
@Override
protected void processData(String data) {
System.out.println("Processing " + data);
}
}
// 使用
public class Main {
public static void main(String[] args) {
DataImporter importer = new CsvImporter();
importer.importData();
}
}
代码实例2:报表生成模板
场景:生成不同格式的销售报表。
java">public abstract class ReportGenerator {
public void generateReport() {
fetchData();
formatData();
saveReport();
}
protected void fetchData() {
System.out.println("Fetching sales data");
}
protected abstract void formatData();
protected abstract void saveReport();
}
public class PdfReportGenerator extends ReportGenerator {
@Override
protected void formatData() {
System.out.println("Formatting as PDF");
}
@Override
protected void saveReport() {
System.out.println("Saving as PDF file");
}
}
// 使用
public class ReportService {
public static void main(String[] args) {
ReportGenerator generator = new PdfReportGenerator();
generator.generateReport();
}
}
注意事项
- 确保抽象方法职责清晰。
- Spring的
JdbcTemplate
是典型模板方法应用。
10. 外观模式(Facade Pattern)
原理
为子系统提供统一接口,简化调用。
应用场景
- 封装第三方API
- 简化复杂业务逻辑
代码实例1:支付外观
场景:封装支付子系统。
java">public class PaymentGateway {
public void charge(double amount) {
System.out.println("Charging " + amount);
}
}
public class FraudCheck {
public boolean isFraudulent(double amount) {
return amount > 1000;
}
}
public class PaymentFacade {
private PaymentGateway gateway = new PaymentGateway();
private FraudCheck fraudCheck = new FraudCheck();
public void processPayment(double amount) {
if (!fraudCheck.isFraudulent(amount)) {
gateway.charge(amount);
System.out.println("Payment processed");
} else {
System.out.println("Payment blocked due to fraud");
}
}
}
// 使用
public class CheckoutService {
public static void main(String[] args) {
PaymentFacade facade = new PaymentFacade();
facade.processPayment(500);
}
}
代码实例2:订单处理外观
场景:简化订单创建流程。
java">public class InventoryService {
public void reserveStock(String productId) {
System.out.println("Reserved stock for " + productId);
}
}
public class ShippingService {
public void scheduleShipping(String orderId) {
System.out.println("Scheduled shipping for " + orderId);
}
}
public class OrderFacade {
private InventoryService inventory = new InventoryService();
private ShippingService shipping = new ShippingService();
public void createOrder(String orderId, String productId) {
inventory.reserveStock(productId);
shipping.scheduleShipping(orderId);
System.out.println("Order " + orderId + " created");
}
}
// 使用
public class Main {
public static void main(String[] args) {
OrderFacade facade = new OrderFacade();
facade.createOrder("ORD001", "PROD001");
}
}
注意事项
- 避免外观类过于复杂,变成“上帝类”。
- Spring的
Service
层常扮演外观角色。