单例模式(Singleton)
单例模式确保一个类只有一个实例,并提供一个全局访问点。这在你需要控制实例数量来节省资源时非常有用,比如数据库连接或文件系统的访问。
实际例子:想象你的银行应用只应该有一个连接到银行数据库的对象,这样可以避免因为多个连接而引起的潜在冲突。
public class DatabaseConnector {
private static DatabaseConnector instance = new DatabaseConnector();
private DatabaseConnector() {
// 私有构造函数以防止外部直接创建实例
}
public static DatabaseConnector getInstance() {
return instance;
}
public void connect() {
// 连接到数据库的代码
}
}
使用单例模式时,你只能通过DatabaseConnector.getInstance()来获取数据库连接对象。
工厂方法模式(Factory Method)
工厂方法模式提供一个创建对象的接口,让子类决定实例化哪一个类。这使一个类的实例化延迟到其子类。
实际例子:在处理不同类型的支付方式时,比如信用卡支付、电子钱包支付等,你可以使用工厂方法来决定实例化哪一个支付类,而不是直接实例化。
public abstract class PaymentProcessorFactory {
public abstract PaymentProcessor createPaymentProcessor();
}
public class CreditCardProcessorFactory extends PaymentProcessorFactory {
@Override
public PaymentProcessor createPaymentProcessor() {
return new CreditCardProcessor();
}
}
public class ElectronicWalletProcessorFactory extends PaymentProcessorFactory {
@Override
public PaymentProcessor createPaymentProcessor() {
return new ElectronicWalletProcessor();
}
}
// 假设这是一个支付处理器的接口
public interface PaymentProcessor {
void processPayment(double amount);
}
// 信用卡支付处理器
public class CreditCardProcessor implements PaymentProcessor {
@Override
public void processPayment(double amount) {
// 处理信用卡支付
}
}
// 电子钱包支付处理器
public class ElectronicWalletProcessor implements PaymentProcessor {
@Override
public void processPayment(double amount) {
// 处理电子钱包支付
}
}
使用工厂方法时,客户端代码可以不用指定具体的支付处理器类型就能创建处理器。
抽象工厂模式(Abstract Factory)
抽象工厂模式提供一个创建一系列相关或依赖对象的接口,而无需指定它们具体的类。
实际例子:假设你开发了一个数据仪表板,它可以显示来自不同数据源的图表(例如,SQL数据库、NoSQL数据库或文件)。使用抽象工厂,可以创建一个兼容所有数据源的接口,而无需担心每个数据源的具体实现。
// 抽象工厂接口
public interface DataConnectionFactory {
SQLConnection createSQLConnection();
NoSQLConnection createNoSQLConnection();
}
// 具体工厂实现
public class ProductionDataConnectionFactory implements DataConnectionFactory {
@Override
public SQLConnection createSQLConnection() {
return new MySQLConnection();
}
@Override
public NoSQLConnection createNoSQLConnection() {
return new MongoDBConnection();
}
}
// 数据库连接接口
public interface SQLConnection {
void executeSQL(String query);
}
public interface NoSQLConnection {
void executeNoSQL(String query);
}
// 数据库连接实现
public class MySQLConnection implements SQLConnection {
@Override
public void executeSQL(String query) {
// 执行MySQL查询
}
}
public class MongoDBConnection implements NoSQLConnection {
@Override
public void executeNoSQL(String query) {
// 执行MongoDB查询
}
}
抽象工厂允许客户端代码在运行时创建特定的数据库连接,而不必知道具体的类。
建造者模式(Builder)
建造者模式将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
实际例子:考虑创建一个复杂的查询报告,其中包含多个可选部分,如标题、摘要、图表、结果分析等。使用建造者模式可以帮助你逐步构建这个报告,并且在最后得到一个包含所选部分的完整对象。
public class Report {
private String title;
private String summary;
private String charts;
private String analysis;
public static class Builder {
private String title;
private String summary;
private String charts;
private String analysis;
public Builder setTitle(String title) {
this.title = title;
return this;
}
public Builder setSummary(String summary) {
this.summary = summary;
return this;
}
public Builder setCharts(String charts) {
this.charts = charts;
return this;
}
public Builder setAnalysis(String analysis) {
this.analysis = analysis;
return this;
}
public Report build() {
return new Report(this);
}
}
private Report(Builder builder) {
this.title = builder.title;
this.summary = builder.summary;
this.charts = builder.charts;
this.analysis = builder.analysis;
}
}
// 使用方式
Report report = new Report.Builder()
.setTitle("Annual Financial Report")
.setSummary("Summary of the year")
.setCharts("Charts related to finances")
.setAnalysis("In-depth financial analysis")
.build();
建造者模式提供了一种链式调用的方法来构建复杂对象。
观察者模式(Observer)
观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,所有依赖于它的对象都会得到通知并自动更新。
实际例子:在股票交易系统中,如果某只股票的价格改变,所有订阅了这只股票价格更新的投资者都应该被通知。你可以将投资者作为“观察者”注册到股票对象,一旦股票价格有变化,所有的投资者都会收到更新。
import java.util.ArrayList;
import java.util.List;
// 被观察的股票类
public class Stock {
private List<StockObserver> observers = new ArrayList<>();
private double price;
public void addObserver(StockObserver observer) {
observers.add(observer);
}
public void setPrice(double price) {
this.price = price;
notifyObservers();
}
private void notifyObservers() {
for (StockObserver observer : observers) {
observer.update(price);
}
}
}
// 观察者接口
public interface StockObserver {
void update(double price);
}
// 具体的观察者
public class Investor implements StockObserver {
private String name;
public Investor(String name) {
this.name = name;
}
@Override
public void update(double price) {
System.out.println(name + " noticed stock price changed to: " + price);
}
}
// 使用方式
Stock appleStock = new Stock();
Investor investor1 = new Investor("Alice");
Investor investor2 = new Investor("Bob");
appleStock.addObserver(investor1);
appleStock.addObserver(investor2);
appleStock.setPrice(123.45); // Alice and Bob will be notified
这里的Stock类有一个价格属性,当价格变化时,所有注册的StockObserver(比如Investor)都会被通知。
装饰器模式(Decorator)
装饰器模式允许向对象添加新的功能,而不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有类的一个包装。
// 组件接口
public interface Text {
String getContent();
}
// 具体组件
public class PlainText implements Text {
private String content;
public PlainText(String content) {
this.content = content;
}
@Override
public String getContent() {
return content;
}
}
// 装饰器抽象类
public abstract class TextDecorator implements Text {
protected Text text;
public TextDecorator(Text text) {
this.text = text;
}
}
// 具体装饰器
public class BoldDecorator extends TextDecorator {
public BoldDecorator(Text text) {
super(text);
}
@Override
public String getContent() {
return "<b>" + text.getContent() + "</b>";
}
}
public class ItalicDecorator extends TextDecorator {
public ItalicDecorator(Text text) {
super(text);
}
@Override
public String getContent() {
return "<i>" + text.getContent() + "</i>";
}
}
// 使用方式
Text myText = new PlainText("Hello, World!");
myText = new BoldDecorator(myText);
myText = new ItalicDecorator(myText);
System.out.println(myText.getContent()); // 输出: <i><b>Hello, World!</b></i>
在这个例子中,PlainText 类通过BoldDecorator 和 ItalicDecorator 被装饰,不需要修改原有类的情况下增加了新的功能。
这些示例演示了设计模式在实际编码中的应用,但请记住,在实际的软件开发中,实现这些模式可能需要更多的考虑,包括线程安全、异常处理、资源管理等方面。