Java 设计模式详解
·
设计模式是软件设计中常见问题的典型解决方案,是经验丰富的开发人员在长期实践中总结出来的最佳实践。
#设计模式分类
1. 创建型模式 (5种)
2. 结构型模式 (7种)
3. 行为型模式 (11种)
创建型模式
1. 单例模式 (Singleton)
确保一个类只有一个实例,并提供全局访问点
java
// 懒汉式(线程安全)
public class Singleton {
private static volatile Singleton instance;
private Singleton() {
// 防止反射创建实例
if (instance != null) {
throw new RuntimeException("Use getInstance() method to get the single instance.");
}
}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
// 枚举实现(推荐)
public enum EnumSingleton {
INSTANCE;
public void doSomething() {
System.out.println("Doing something...");
}
}
// 静态内部类实现
public class StaticSingleton {
private StaticSingleton() {}
private static class SingletonHolder {
private static final StaticSingleton INSTANCE = new StaticSingleton();
}
public static StaticSingleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
2. 工厂方法模式 (Factory Method)
定义一个创建对象的接口,但让子类决定实例化哪个类
java
// 产品接口
public interface Product {
void use();
}
// 具体产品
public class ConcreteProductA implements Product {
@Override
public void use() {
System.out.println("Using Product A");
}
}
public class ConcreteProductB implements Product {
@Override
public void use() {
System.out.println("Using Product B");
}
}
// 创建者抽象类
public abstract class Creator {
public abstract Product createProduct();
public void someOperation() {
Product product = createProduct();
product.use();
}
}
// 具体创建者
public class ConcreteCreatorA extends Creator {
@Override
public Product createProduct() {
return new ConcreteProductA();
}
}
public class ConcreteCreatorB extends Creator {
@Override
public Product createProduct() {
return new ConcreteProductB();
}
}
接口定义抽象方法。
实现抽象接口的类实现了具体的方法。
抽象类定义了如何调用抽象接口。
实现抽象类的类实现了抽象类中方法的具体实现。
1.接口定义抽象方法←←2.实体类实现抽象方法
↑\ ↑
↑ \ ↑
↑ \ ↑
↑ \ ↑
↑ \ ↑
3.抽象类调用←←←←4.具体实现类创建和使用实体类的对象。
#返回对象是接口 返回对象是接口类型
3. 抽象工厂模式 (Abstract Factory)
提供一个接口,用于创建相关或依赖对象的家族,而不需要指定具体类
java
// 抽象产品族
public interface Button {
void render();
}
public interface Checkbox {
void paint();
}
// 具体产品 - Windows系列
public class WindowsButton implements Button {
@Override
public void render() {
System.out.println("Rendering Windows style button");
}
}
public class WindowsCheckbox implements Checkbox {
@Override
public void paint() {
System.out.println("Painting Windows style checkbox");
}
}
// 具体产品 - Mac系列
public class MacButton implements Button {
@Override
public void render() {
System.out.println("Rendering Mac style button");
}
}
public class MacCheckbox implements Checkbox {
@Override
public void paint() {
System.out.println("Painting Mac style checkbox");
}
}
// 抽象工厂
public interface GUIFactory {
Button createButton();
Checkbox createCheckbox();
}
// 具体工厂
public class WindowsFactory implements GUIFactory {
@Override
public Button createButton() {
return new WindowsButton();
}
@Override
public Checkbox createCheckbox() {
return new WindowsCheckbox();
}
}
public class MacFactory implements GUIFactory {
@Override
public Button createButton() {
return new MacButton();
}
@Override
public Checkbox createCheckbox() {
return new MacCheckbox();
}
}
4.建造者模式 (Builder)
将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示
java
public class Computer {
private final String CPU;
private final String RAM;
private final String storage;
private final String graphicsCard;
private Computer(Builder builder) {
this.CPU = builder.CPU;
this.RAM = builder.RAM;
this.storage = builder.storage;
this.graphicsCard = builder.graphicsCard;
}
public static class Builder {
private String CPU;
private String RAM;
private String storage;
private String graphicsCard;
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 setGraphicsCard(String graphicsCard) {
this.graphicsCard = graphicsCard;
return this;
}
public Computer build() {
return new Computer(this);
}
}
// 使用方法
public static void main(String[] args) {
Computer computer = new Computer.Builder()
.setCPU("Intel i7")
.setRAM("16GB")
.setStorage("1TB SSD")
.setGraphicsCard("NVIDIA RTX 3080")
.build();
}
}
5. 原型模式 (Prototype)
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象
java
public 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;
}
}
public class Rectangle extends Shape {
public Rectangle() {
type = "Rectangle";
}
@Override
public void draw() {
System.out.println("Drawing Rectangle");
}
}
public class Circle extends Shape {
public Circle() {
type = "Circle";
}
@Override
public void draw() {
System.out.println("Drawing Circle");
}
}
// 原型管理器
public 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();
}
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);
}
}
结构型模式
6. 适配器模式 (Adapter)
将一个类的接口转换成客户希望的另外一个接口
java
// 目标接口
public interface MediaPlayer {
void play(String audioType, String fileName);
}
// 被适配的类
public class AdvancedMediaPlayer {
public void playVlc(String fileName) {
System.out.println("Playing vlc file: " + fileName);
}
public void playMp4(String fileName) {
System.out.println("Playing mp4 file: " + fileName);
}
}
// 适配器
public class MediaAdapter implements MediaPlayer {
private AdvancedMediaPlayer advancedMusicPlayer;
public MediaAdapter(String audioType) {
if (audioType.equalsIgnoreCase("vlc")) {
advancedMusicPlayer = new AdvancedMediaPlayer();
} else if (audioType.equalsIgnoreCase("mp4")) {
advancedMusicPlayer = new AdvancedMediaPlayer();
}
}
@Override
public void play(String audioType, String fileName) {
if (audioType.equalsIgnoreCase("vlc")) {
advancedMusicPlayer.playVlc(fileName);
} else if (audioType.equalsIgnoreCase("mp4")) {
advancedMusicPlayer.playMp4(fileName);
}
}
}
7. 装饰器模式 (Decorator)
动态地给一个对象添加一些额外的职责
java
// 组件接口
public interface Coffee {
double getCost();
String getDescription();
}
// 具体组件
public class SimpleCoffee implements Coffee {
@Override
public double getCost() {
return 1.0;
}
@Override
public String getDescription() {
return "Simple coffee";
}
}
// 装饰器抽象类
public 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();
}
}
// 具体装饰器
public class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee coffee) {
super(coffee);
}
@Override
public double getCost() {
return super.getCost() + 0.5;
}
@Override
public String getDescription() {
return super.getDescription() + ", with milk";
}
}
public class SugarDecorator extends CoffeeDecorator {
public SugarDecorator(Coffee coffee) {
super(coffee);
}
@Override
public double getCost() {
return super.getCost() + 0.2;
}
@Override
public String getDescription() {
return super.getDescription() + ", with sugar";
}
}
// 使用
public class DecoratorDemo {
public static void main(String[] args) {
Coffee coffee = new SimpleCoffee();
coffee = new MilkDecorator(coffee);
coffee = new SugarDecorator(coffee);
System.out.println(coffee.getDescription() + " costs $" + coffee.getCost());
}
}
8. 代理模式 (Proxy)
为其他对象提供一种代理以控制对这个对象的访问
java
// 主题接口
public interface Image {
void display();
}
// 真实主题
public class RealImage implements Image {
private String fileName;
public RealImage(String fileName) {
this.fileName = fileName;
loadFromDisk();
}
private void loadFromDisk() {
System.out.println("Loading " + fileName);
}
@Override
public void display() {
System.out.println("Displaying " + fileName);
}
}
// 代理
public 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();
}
}
9. 外观模式 (Facade)
为子系统中的一组接口提供一个一致的界面
java
// 子系统类
public class CPU {
public void start() {
System.out.println("CPU started");
}
}
public class Memory {
public void load() {
System.out.println("Memory loaded");
}
}
public class HardDrive {
public void read() {
System.out.println("HardDrive read");
}
}
// 外观类
public class ComputerFacade {
private CPU cpu;
private Memory memory;
private HardDrive hardDrive;
public ComputerFacade() {
this.cpu = new CPU();
this.memory = new Memory();
this.hardDrive = new HardDrive();
}
public void start() {
cpu.start();
memory.load();
hardDrive.read();
System.out.println("Computer started successfully");
}
}
10. 组合模式 (Composite)
将对象组合成树形结构以表示"部分-整体"的层次结构
java
// 组件接口
public interface Employee {
void showDetails();
void add(Employee employee);
void remove(Employee employee);
}
// 叶子节点
public 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 showDetails() {
System.out.println("Developer: " + name + ", Position: " + position);
}
@Override
public void add(Employee employee) {
// 叶子节点没有子节点
}
@Override
public void remove(Employee employee) {
// 叶子节点没有子节点
}
}
// 复合节点
public class Manager implements Employee {
private String name;
private String position;
private List<Employee> subordinates;
public Manager(String name, String position) {
this.name = name;
this.position = position;
this.subordinates = new ArrayList<>();
}
@Override
public void showDetails() {
System.out.println("Manager: " + name + ", Position: " + position);
System.out.println("Subordinates:");
for (Employee employee : subordinates) {
employee.showDetails();
}
}
@Override
public void add(Employee employee) {
subordinates.add(employee);
}
@Override
public void remove(Employee employee) {
subordinates.remove(employee);
}
}
#行为型模式
11. 观察者模式 (Observer)
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新
java
// 观察者接口
public interface Observer {
void update(String message);
}
// 主题接口
public interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers();
}
// 具体主题
public class NewsAgency implements Subject {
private List<Observer> observers;
private String news;
public NewsAgency() {
observers = new ArrayList<>();
}
@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();
}
}
// 具体观察者
public class NewsChannel implements Observer {
private String news;
@Override
public void update(String news) {
this.news = news;
display();
}
public void display() {
System.out.println("Breaking News: " + news);
}
}
12. 策略模式 (Strategy)
定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换
java
// 策略接口
public interface PaymentStrategy {
void pay(int amount);
}
// 具体策略
public class CreditCardPayment implements PaymentStrategy {
private String cardNumber;
public CreditCardPayment(String cardNumber) {
this.cardNumber = cardNumber;
}
@Override
public void pay(int amount) {
System.out.println("Paid " + amount + " using Credit Card: " + cardNumber);
}
}
public class PayPalPayment implements PaymentStrategy {
private String email;
public PayPalPayment(String email) {
this.email = email;
}
@Override
public void pay(int amount) {
System.out.println("Paid " + amount + " using PayPal: " + email);
}
}
// 上下文
public class ShoppingCart {
private List<String> items;
private PaymentStrategy paymentStrategy;
public ShoppingCart() {
items = new ArrayList<>();
}
public void addItem(String item) {
items.add(item);
}
public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
this.paymentStrategy = paymentStrategy;
}
public void checkout(int amount) {
paymentStrategy.pay(amount);
}
}
13.模板方法模式 (Template Method)
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中
java
public abstract class Game {
// 模板方法
public final void play() {
initialize();
startPlay();
endPlay();
}
abstract void initialize();
abstract void startPlay();
abstract void endPlay();
}
public class Cricket extends Game {
@Override
void initialize() {
System.out.println("Cricket Game Initialized");
}
@Override
void startPlay() {
System.out.println("Cricket Game Started");
}
@Override
void endPlay() {
System.out.println("Cricket Game Finished");
}
}
public class Football extends Game {
@Override
void initialize() {
System.out.println("Football Game Initialized");
}
@Override
void startPlay() {
System.out.println("Football Game Started");
}
@Override
void endPlay() {
System.out.println("Football Game Finished");
}
}
14. 责任链模式 (Chain of Responsibility)
避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,
并且沿着这条链传递请求,直到有对象处理它为止。
java
// 处理器接口
public 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);
}
// 具体处理器
public class ConsoleLogger extends Logger {
public ConsoleLogger(int level) {
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("Standard Console::Logger: " + message);
}
}
public class ErrorLogger extends Logger {
public ErrorLogger(int level) {
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("Error Console::Logger: " + message);
}
}
public class FileLogger extends Logger {
public FileLogger(int level) {
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("File::Logger: " + message);
}
}
#设计模式选择指南
场景 |推荐模式
需要全局唯一实例 |单例模式
创建复杂对象 |建造者模式
需要创建对象家族 |抽象工厂模式
需要扩展对象功能 |装饰器模式
需要为其他对象提供代理 |代理模式
需要处理不同算法 |策略模式
需要一对多依赖关系 |观察者模式
需要定义算法骨架 |模板方法模式
需要处理多种请求 |责任链模式
#总结
设计模式是解决特定问题的经验总结,合理使用可以:
提高代码的可重用性
提高代码的可读性
保证代码的可靠性
使代码更容易被他人理解
但也要避免过度设计,根据实际需求选择合适的模式。
更多推荐


所有评论(0)