Java 设计模式

171 阅读7分钟

单例模式 (Singleton Pattern)

单例模式的几种实现方式

1. 饿汉式(线程安全,类加载时就初始化)

public class EagerSingleton {
    // 类加载时就创建实例
    private static final EagerSingleton instance = new EagerSingleton();
    
    // 私有构造器
    private EagerSingleton() {}
    
    // 全局访问点
    public static EagerSingleton getInstance() {
        return instance;
    }
    
    // 其他方法
    public void showMessage() {
        System.out.println("Hello from EagerSingleton!");
    }
}

优点:实现简单,线程安全
缺点:即使不使用也会创建实例,可能造成资源浪费

2. 懒汉式(线程不安全)

public class LazySingleton {
    private static LazySingleton instance;
    
    private LazySingleton() {}
    
    public static LazySingleton getInstance() {
        if (instance == null) {
            instance = new LazySingleton();
        }
        return instance;
    }
}

问题:多线程环境下可能创建多个实例

3. 同步方法懒汉式(线程安全但效率低)

public class SynchronizedSingleton {
    private static SynchronizedSingleton instance;
    
    private SynchronizedSingleton() {}
    
    // 方法同步,效率低
    public static synchronized SynchronizedSingleton getInstance() {
        if (instance == null) {
            instance = new SynchronizedSingleton();
        }
        return instance;
    }
}

缺点:每次获取实例都要同步,性能较差

4. 双重检查锁定(推荐方式)

public class DoubleCheckedSingleton {
    // volatile 确保多线程环境下的可见性和有序性
    private static volatile DoubleCheckedSingleton instance;
    
    private DoubleCheckedSingleton() {}
    
    public static DoubleCheckedSingleton getInstance() {
        // 第一次检查,避免不必要的同步
        if (instance == null) {
            synchronized (DoubleCheckedSingleton.class) {
                // 第二次检查,确保只有一个实例被创建
                if (instance == null) {
                    instance = new DoubleCheckedSingleton();
                }
            }
        }
        return instance;
    }
}

优点:线程安全,性能好
注意:必须使用 volatile 关键字

5. 静态内部类实现(推荐方式)

public class InnerClassSingleton {
    private InnerClassSingleton() {}
    
    // 静态内部类在第一次使用时才会加载
    private static class SingletonHolder {
        private static final InnerClassSingleton INSTANCE = new InnerClassSingleton();
    }
    
    public static InnerClassSingleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
}

优点:线程安全,延迟加载,实现简单

6. 枚举实现(最佳实践)

public enum EnumSingleton {
    INSTANCE;
    
    public void doSomething() {
        System.out.println("Enum Singleton is working");
    }
}

优点:线程安全,防止反序列化重新创建对象,防止反射攻击

单例模式的实际应用场景

  1. 数据库连接池
public class DatabaseConnectionPool {
    private static DatabaseConnectionPool instance;
    private List<Connection> connections;
    
    private DatabaseConnectionPool() {
        // 初始化连接池
        connections = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            connections.add(createConnection());
        }
    }
    
    public static synchronized DatabaseConnectionPool getInstance() {
        if (instance == null) {
            instance = new DatabaseConnectionPool();
        }
        return instance;
    }
    
    public Connection getConnection() {
        // 从池中获取连接
    }
    
    public void releaseConnection(Connection conn) {
        // 释放连接回池中
    }
    
    private Connection createConnection() {
        // 创建新连接
    }
}
  1. 配置管理器
public class ConfigManager {
    private static ConfigManager instance;
    private Properties config;
    
    private ConfigManager() {
        config = new Properties();
        try {
            config.load(new FileInputStream("config.properties"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    public static synchronized ConfigManager getInstance() {
        if (instance == null) {
            instance = new ConfigManager();
        }
        return instance;
    }
    
    public String getConfigValue(String key) {
        return config.getProperty(key);
    }
}

工厂模式

简单工厂模式

public class PizzaFactory {
    public Pizza createPizza(String type) {
        Pizza pizza = null;
        
        if (type.equals("cheese")) {
            pizza = new CheesePizza();
        } else if (type.equals("pepperoni")) {
            pizza = new PepperoniPizza();
        } else if (type.equals("veggie")) {
            pizza = new VeggiePizza();
        }
        
        return pizza;
    }
}

// 使用
PizzaFactory factory = new PizzaFactory();
Pizza pizza = factory.createPizza("cheese");
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();

工厂方法模式

public abstract class PizzaStore {
    public Pizza orderPizza(String type) {
        Pizza pizza = createPizza(type);
        
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
        
        return pizza;
    }
    
    // 工厂方法,由子类实现
    protected abstract Pizza createPizza(String type);
}

public class NYPizzaStore extends PizzaStore {
    protected Pizza createPizza(String type) {
        if (type.equals("cheese")) {
            return new NYStyleCheesePizza();
        } else if (type.equals("pepperoni")) {
            return new NYStylePepperoniPizza();
        }
        return null;
    }
}

public class ChicagoPizzaStore extends PizzaStore {
    protected Pizza createPizza(String type) {
        if (type.equals("cheese")) {
            return new ChicagoStyleCheesePizza();
        } else if (type.equals("pepperoni")) {
            return new ChicagoStylePepperoniPizza();
        }
        return null;
    }
}

抽象工厂模式

public interface PizzaIngredientFactory {
    Dough createDough();
    Sauce createSauce();
    Cheese createCheese();
    Veggies[] createVeggies();
    Pepperoni createPepperoni();
    Clams createClam();
}

public class NYPizzaIngredientFactory implements PizzaIngredientFactory {
    public Dough createDough() {
        return new ThinCrustDough();
    }
    
    public Sauce createSauce() {
        return new MarinaraSauce();
    }
    
    public Cheese createCheese() {
        return new ReggianoCheese();
    }
    
    public Veggies[] createVeggies() {
        Veggies veggies[] = { new Garlic(), new Onion(), new Mushroom() };
        return veggies;
    }
    
    public Pepperoni createPepperoni() {
        return new SlicedPepperoni();
    }
    
    public Clams createClam() {
        return new FreshClams();
    }
}

public class CheesePizza extends Pizza {
    PizzaIngredientFactory ingredientFactory;
    
    public CheesePizza(PizzaIngredientFactory ingredientFactory) {
        this.ingredientFactory = ingredientFactory;
    }
    
    void prepare() {
        System.out.println("Preparing " + name);
        dough = ingredientFactory.createDough();
        sauce = ingredientFactory.createSauce();
        cheese = ingredientFactory.createCheese();
    }
}

观察者模式

Java内置观察者实现

import java.util.Observable;
import java.util.Observer;

// 被观察者
class WeatherData extends Observable {
    private float temperature;
    private float humidity;
    private float pressure;
    
    public void measurementsChanged() {
        setChanged();  // 标记状态已改变
        notifyObservers();  // 通知观察者
    }
    
    public void setMeasurements(float temperature, float humidity, float pressure) {
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
        measurementsChanged();
    }
    
    public float getTemperature() {
        return temperature;
    }
    
    public float getHumidity() {
        return humidity;
    }
    
    public float getPressure() {
        return pressure;
    }
}

// 观察者
class CurrentConditionsDisplay implements Observer {
    private Observable observable;
    private float temperature;
    private float humidity;
    
    public CurrentConditionsDisplay(Observable observable) {
        this.observable = observable;
        observable.addObserver(this);
    }
    
    public void update(Observable obs, Object arg) {
        if (obs instanceof WeatherData) {
            WeatherData weatherData = (WeatherData)obs;
            this.temperature = weatherData.getTemperature();
            this.humidity = weatherData.getHumidity();
            display();
        }
    }
    
    public void display() {
        System.out.println("Current conditions: " + temperature 
            + "F degrees and " + humidity + "% humidity");
    }
}

// 使用
WeatherData weatherData = new WeatherData();
CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData);

weatherData.setMeasurements(80, 65, 30.4f);
weatherData.setMeasurements(82, 70, 29.2f);

自定义观察者模式(更灵活)

// 主题接口
interface Subject {
    void registerObserver(Observer o);
    void removeObserver(Observer o);
    void notifyObservers();
}

// 观察者接口
interface Observer {
    void update(float temp, float humidity, float pressure);
}

// 显示接口
interface DisplayElement {
    void display();
}

// 具体主题
class WeatherData implements Subject {
    private List<Observer> observers;
    private float temperature;
    private float humidity;
    private float pressure;
    
    public WeatherData() {
        observers = new ArrayList<>();
    }
    
    public void registerObserver(Observer o) {
        observers.add(o);
    }
    
    public void removeObserver(Observer o) {
        int i = observers.indexOf(o);
        if (i >= 0) {
            observers.remove(i);
        }
    }
    
    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(temperature, humidity, pressure);
        }
    }
    
    public void measurementsChanged() {
        notifyObservers();
    }
    
    public void setMeasurements(float temperature, float humidity, float pressure) {
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
        measurementsChanged();
    }
}

// 具体观察者
class CurrentConditionsDisplay implements Observer, DisplayElement {
    private float temperature;
    private float humidity;
    private Subject weatherData;
    
    public CurrentConditionsDisplay(Subject weatherData) {
        this.weatherData = weatherData;
        weatherData.registerObserver(this);
    }
    
    public void update(float temperature, float humidity, float pressure) {
        this.temperature = temperature;
        this.humidity = humidity;
        display();
    }
    
    public void display() {
        System.out.println("Current conditions: " + temperature 
            + "F degrees and " + humidity + "% humidity");
    }
}

装饰器模式

Java I/O 中的装饰器模式

// 抽象组件
public abstract class InputStream {
    public abstract int read() throws IOException;
    // 其他方法...
}

// 具体组件
public class FileInputStream extends InputStream {
    public FileInputStream(String name) throws FileNotFoundException {
        // 实现
    }
    
    public int read() throws IOException {
        // 实现
    }
}

// 抽象装饰器
public class FilterInputStream extends InputStream {
    protected InputStream in;
    
    protected FilterInputStream(InputStream in) {
        this.in = in;
    }
    
    public int read() throws IOException {
        return in.read();
    }
}

// 具体装饰器
public class BufferedInputStream extends FilterInputStream {
    public BufferedInputStream(InputStream in) {
        super(in);
    }
    
    public int read() throws IOException {
        // 添加缓冲功能
    }
}

// 使用
InputStream in = new BufferedInputStream(
                    new FileInputStream("test.txt"));

自定义装饰器示例

// 饮料抽象类
public abstract class Beverage {
    String description = "Unknown Beverage";
    
    public String getDescription() {
        return description;
    }
    
    public abstract double cost();
}

// 调料装饰器抽象类
public abstract class CondimentDecorator extends Beverage {
    public abstract String getDescription();
}

// 具体饮料
public class Espresso extends Beverage {
    public Espresso() {
        description = "Espresso";
    }
    
    public double cost() {
        return 1.99;
    }
}

// 具体调料
public class Mocha extends CondimentDecorator {
    Beverage beverage;
    
    public Mocha(Beverage beverage) {
        this.beverage = beverage;
    }
    
    public String getDescription() {
        return beverage.getDescription() + ", Mocha";
    }
    
    public double cost() {
        return 0.20 + beverage.cost();
    }
}

// 使用
Beverage beverage = new Espresso();
System.out.println(beverage.getDescription() + " $" + beverage.cost());

Beverage beverage2 = new DarkRoast();
beverage2 = new Mocha(beverage2);
beverage2 = new Mocha(beverage2);
beverage2 = new Whip(beverage2);
System.out.println(beverage2.getDescription() + " $" + beverage2.cost());

策略模式

支付策略示例

// 策略接口
interface PaymentStrategy {
    void pay(int amount);
}

// 具体策略
class CreditCardStrategy implements PaymentStrategy {
    private String name;
    private String cardNumber;
    private String cvv;
    private String dateOfExpiry;
    
    public CreditCardStrategy(String name, String cardNumber, String cvv, String dateOfExpiry) {
        this.name = name;
        this.cardNumber = cardNumber;
        this.cvv = cvv;
        this.dateOfExpiry = dateOfExpiry;
    }
    
    @Override
    public void pay(int amount) {
        System.out.println(amount + " paid with credit/debit card");
    }
}

class PayPalStrategy implements PaymentStrategy {
    private String email;
    private String password;
    
    public PayPalStrategy(String email, String password) {
        this.email = email;
        this.password = password;
    }
    
    @Override
    public void pay(int amount) {
        System.out.println(amount + " paid using PayPal");
    }
}

// 上下文
class ShoppingCart {
    private List<Item> items;
    
    public ShoppingCart() {
        this.items = new ArrayList<>();
    }
    
    public void addItem(Item item) {
        this.items.add(item);
    }
    
    public void removeItem(Item item) {
        this.items.remove(item);
    }
    
    public int calculateTotal() {
        int sum = 0;
        for (Item item : items) {
            sum += item.getPrice();
        }
        return sum;
    }
    
    public void pay(PaymentStrategy paymentMethod) {
        int amount = calculateTotal();
        paymentMethod.pay(amount);
    }
}

// 使用
ShoppingCart cart = new ShoppingCart();
cart.addItem(new Item("1234", 10));
cart.addItem(new Item("5678", 40));

// 使用信用卡支付
cart.pay(new CreditCardStrategy("John Doe", "1234567890123456", "123", "12/25"));

// 使用PayPal支付
cart.pay(new PayPalStrategy("john@example.com", "password"));

Java Comparator 中的策略模式

// 策略接口
public interface Comparator<T> {
    int compare(T o1, T o2);
    // 其他默认方法...
}

// 具体策略
class AgeComparator implements Comparator<Person> {
    public int compare(Person p1, Person p2) {
        return Integer.compare(p1.getAge(), p2.getAge());
    }
}

class NameComparator implements Comparator<Person> {
    public int compare(Person p1, Person p2) {
        return p1.getName().compareTo(p2.getName());
    }
}

// 上下文
Collections.sort(List<T> list, Comparator<? super T> c);

// 使用
List<Person> people = new ArrayList<>();
// 添加人员...

// 按年龄排序
Collections.sort(people, new AgeComparator());

// 按姓名排序
Collections.sort(people, new NameComparator());

// 使用Lambda表达式作为策略
Collections.sort(people, (p1, p2) -> p1.getName().compareTo(p2.getName()));

建造者模式

复杂对象构建示例

public class Computer {
    // 必需参数
    private String HDD;
    private String RAM;
    
    // 可选参数
    private boolean isGraphicsCardEnabled;
    private boolean isBluetoothEnabled;
    
    private Computer(ComputerBuilder builder) {
        this.HDD = builder.HDD;
        this.RAM = builder.RAM;
        this.isGraphicsCardEnabled = builder.isGraphicsCardEnabled;
        this.isBluetoothEnabled = builder.isBluetoothEnabled;
    }
    
    // Getter方法
    
    // 建造者类
    public static class ComputerBuilder {
        // 必需参数
        private String HDD;
        private String RAM;
        
        // 可选参数 - 初始化为默认值
        private boolean isGraphicsCardEnabled = false;
        private boolean isBluetoothEnabled = false;
        
        public ComputerBuilder(String HDD, String RAM) {
            this.HDD = HDD;
            this.RAM = RAM;
        }
        
        public ComputerBuilder setGraphicsCardEnabled(boolean isGraphicsCardEnabled) {
            this.isGraphicsCardEnabled = isGraphicsCardEnabled;
            return this;
        }
        
        public ComputerBuilder setBluetoothEnabled(boolean isBluetoothEnabled) {
            this.isBluetoothEnabled = isBluetoothEnabled;
            return this;
        }
        
        public Computer build() {
            return new Computer(this);
        }
    }
}

// 使用
Computer computer = new Computer.ComputerBuilder("500GB", "8GB")
                .setBluetoothEnabled(true)
                .setGraphicsCardEnabled(true)
                .build();

StringBuilder 和 StringBuffer

Java中的StringBuilder和StringBuffer实际上是简化版的建造者模式:

StringBuilder builder = new StringBuilder();
builder.append("Hello");
builder.append(" ");
builder.append("World");
String result = builder.toString();

链式调用示例

public class NutritionFacts {
    private final int servingSize;
    private final int servings;
    private final int calories;
    private final int fat;
    private final int sodium;
    private final int carbohydrate;
    
    public static class Builder {
        // 必需参数
        private final int servingSize;
        private final int servings;
        
        // 可选参数 - 初始化为默认值
        private int calories = 0;
        private int fat = 0;
        private int sodium = 0;
        private int carbohydrate = 0;
        
        public Builder(int servingSize, int servings) {
            this.servingSize = servingSize;
            this.servings = servings;
        }
        
        public Builder calories(int val) {
            calories = val;
            return this;
        }
        
        public Builder fat(int val) {
            fat = val;
            return this;
        }
        
        public Builder sodium(int val) {
            sodium = val;
            return this;
        }
        
        public Builder carbohydrate(int val) {
            carbohydrate = val;
            return this;
        }
        
        public NutritionFacts build() {
            return new NutritionFacts(this);
        }
    }
    
    private NutritionFacts(Builder builder) {
        servingSize = builder.servingSize;
        servings = builder.servings;
        calories = builder.calories;
        fat = builder.fat;
        sodium = builder.sodium;
        carbohydrate = builder.carbohydrate;
    }
}

// 使用
NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8)
    .calories(100)
    .sodium(35)
    .carbohydrate(27)
    .build();

总结

设计模式是解决特定问题的经验总结,理解它们的适用场景比记住实现更重要。在实际开发中:

  1. 单例模式:确保全局唯一实例,注意线程安全和性能
  2. 工厂模式:封装对象创建过程,降低耦合
  3. 观察者模式:实现对象间的一对多依赖关系
  4. 装饰器模式:动态扩展对象功能,避免类爆炸
  5. 策略模式:封装算法,使它们可以互相替换
  6. 建造者模式:分步构建复杂对象,提高可读性