设计模式与UML关系深度解析 如何用UML图精准表达设计模式精髓 解决软件架构设计难题

引言:设计模式与UML的完美结合
在软件工程领域,设计模式(Design Patterns)和统一建模语言(UML)是两大核心工具,它们共同构成了现代软件架构设计的基石。设计模式提供了经过验证的、可复用的解决方案来解决常见的软件设计问题,而UML则是一种标准化的图形化语言,用于可视化、描述和文档化软件系统的结构和行为。将两者结合使用,可以帮助架构师和开发者更清晰地表达设计意图,避免常见的设计陷阱,并有效解决复杂的架构难题。
本文将深入探讨设计模式与UML之间的内在联系,详细解析如何使用UML图精准表达设计模式的精髓,并通过实际案例展示如何应用这些知识解决软件架构设计中的难题。我们将从基础概念入手,逐步深入到高级应用,涵盖创建型、结构型和行为型设计模式的UML表达方式,并提供完整的代码示例和UML图描述,帮助读者全面掌握这一关键技能。
第一部分:设计模式与UML基础概念
设计模式概述
设计模式是软件开发中反复出现的问题的可复用解决方案。它们不是可以直接转换为代码的特定设计,而是描述了一种在特定上下文中解决问题的通用模板。设计模式通常分为三大类:
创建型模式
:关注对象的创建机制,帮助系统独立于对象的创建、组合和表示方式。包括工厂方法、抽象工厂、单例、建造者和原型模式。
结构型模式
:关注对象和类的组合,形成更大的结构。包括适配器、桥接、组合、装饰器、外观、享元和代理模式。
行为型模式
:关注对象之间的职责分配和通信。包括责任链、命令、解释器、迭代器、中介者、备忘录、观察者、状态、策略、模板方法和访问者模式。
UML简介
统一建模语言(UML)是一种标准化的建模语言,用于软件系统的可视化描述。UML提供了一套丰富的图表类型,用于不同的建模目的:
结构图
:展示系统的静态结构,包括类图、对象图、组件图、部署图和包图。
行为图
:展示系统的动态行为,包括用例图、活动图、状态机图和顺序图。
在表达设计模式时,
类图
是最常用的UML图类型,因为它能清晰地展示类之间的静态关系(如继承、关联、依赖和实现)。此外,
顺序图
和
协作图
也常用于展示设计模式中对象之间的交互流程。
设计模式与UML的关系
设计模式本质上是描述类和对象之间关系的模板,而UML正是表达这些关系的理想工具。UML的类图可以精确地表示设计模式中的参与者(类)、它们之间的关系以及协作方式。通过UML图,我们可以:
可视化设计模式的结构
:清晰地看到模式中各个类的职责和关系。
文档化设计决策
:为团队提供易于理解的设计文档。
沟通设计意图
:帮助团队成员快速理解复杂的架构设计。
验证设计正确性
:通过图形化的方式检查设计是否符合模式规范。
第二部分:使用UML表达创建型设计模式
1. 工厂方法模式(Factory Method)
模式精髓
:定义一个用于创建对象的接口,但让子类决定实例化哪个类。工厂方法使一个类的实例化延迟到其子类。
UML类图表达
:
+—————-+ +——————+
| Product | | Creator |
|—————-| |——————|
| +operation() | | +factoryMethod() |
+—————-+ | +operation() |
^ +——————+
| ^
| |
+—————-+ +——————+
| ConcreteProduct| | ConcreteCreator |
|—————-| |——————|
| +operation() | | +factoryMethod() |
+—————-+ +——————+
详细解释
:
Product
:定义工厂方法创建的对象的接口。
ConcreteProduct
:实现Product接口的具体产品类。
Creator
:声明工厂方法,返回一个Product类型的对象。Creator也可以定义一个工厂方法的默认实现。
ConcreteCreator
:重写工厂方法以返回ConcreteProduct实例。
代码示例
:
// Product接口
interface Document {
void open();
void save();
}

// ConcreteProduct
class PDFDocument implements Document {
@Override
public void open() {
System.out.println(“Opening PDF document”);
}

@Override
public void save() {
System.out.println(“Saving PDF document”);
}
}

class WordDocument implements Document {
@Override
public void open() {
System.out.println(“Opening Word document”);
}

@Override
public void save() {
System.out.println(“Saving Word document”);
}
}

// Creator抽象类
abstract class DocumentCreator {
// 工厂方法
public abstract Document createDocument();

// 其他操作,使用工厂方法
public void newDocument() {
Document doc = createDocument();
doc.open();
doc.save();
}
}

// ConcreteCreator
class PDFDocumentCreator extends DocumentCreator {
@Override
public Document createDocument() {
return new PDFDocument();
}
}

class WordDocumentCreator extends DocumentCreator {
@Override
public Document createDocument() {
return new WordDocument();
}
}

// 使用示例
public class FactoryMethodDemo {
public static void main(String[] args) {
DocumentCreator pdfCreator = new PDFDocumentCreator();
Document pdfDoc = pdfCreator.createDocument();
pdfDoc.open();
pdfDoc.save();

DocumentCreator wordCreator = new WordDocumentCreator();
Document wordDoc = wordCreator.createDocument();
wordDoc.open();
wordDoc.save();
}
}
UML顺序图表达
:
Client -> pdfCreator: createDocument()
pdfCreator -> PDFDocument: new PDFDocument()
PDFDocument –> pdfCreator: return PDFDocument
pdfCreator –> Client: return Document
Client -> Document: open()
Client -> Document: save()
2. 抽象工厂模式(Abstract Factory)
模式精髓
:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
UML类图表达
:
+——————+ +——————+
| AbstractFactory | | AbstractProductA |
|——————| |——————|
| +createProductA()| | +operation() |
| +createProductB()| +——————+
+——————+ ^
^ |
| |
+——————+ +——————+
| ConcreteFactory1 | | ConcreteProductA1|
|——————| |——————|
| +createProductA()| | +operation() |
| +createProductB()| +——————+
+——————+ ^
^ |
| |
+——————+ +——————+
| ConcreteFactory2 | | ConcreteProductA2|
|——————| |——————|
| +createProductA()| | +operation() |
| +createProductB()| +——————+
+——————+
详细解释
:
AbstractFactory
:声明创建抽象产品对象的操作接口。
ConcreteFactory
:实现创建具体产品对象的操作。
AbstractProduct
:为一类产品对象声明一个接口。
ConcreteProduct
:定义一个具体工厂创建的具体产品对象。
代码示例
:
// 抽象产品A
interface Button {
void render();
}

// 抽象产品B
interface Checkbox {
void check();
}

// 具体产品A1
class WindowsButton implements Button {
@Override
public void render() {
System.out.println(“Render Windows style button”);
}
}

// 具体产品A2
class MacButton implements Button {
@Override
public void render() {
System.out.println(“Render Mac style button”);
}
}

// 具体产品B1
class WindowsCheckbox implements Checkbox {
@Override
public void check() {
System.out.println(“Check Windows style checkbox”);
}
}

// 具体产品B2
class MacCheckbox implements Checkbox {
@Override
public void check() {
System.out.println(“Check Mac style checkbox”);
}
}

// 抽象工厂
interface GUIFactory {
Button createButton();
Checkbox createCheckbox();
}

// 具体工厂1
class WindowsFactory implements GUIFactory {
@Override
public Button createButton() {
return new WindowsButton();
}

@Override
public Checkbox createCheckbox() {
return new WindowsCheckbox();
}
}

// 具体工厂2
class MacFactory implements GUIFactory {
@Override
public Button createButton() {
return new MacButton();
}

@Override
public Checkbox createCheckbox() {
return new MacCheckbox();
}
}

// 使用示例
public class AbstractFactoryDemo {
private Button button;
private Checkbox checkbox;

public AbstractFactoryDemo(GUIFactory factory) {
button = factory.createButton();
checkbox = factory.createCheckbox();
}

public void paint() {
button.render();
checkbox.check();
}

public static void main(String[] args) {
GUIFactory windowsFactory = new WindowsFactory();
AbstractFactoryDemo windowsApp = new AbstractFactoryDemo(windowsFactory);
windowsApp.paint();

GUIFactory macFactory = new MacFactory();
AbstractFactoryDemo macApp = new AbstractFactoryDemo(macFactory);
macApp.paint();
}
}
3. 单例模式(Singleton)
模式精髓
:确保一个类只有一个实例,并提供一个全局访问点。
UML类图表达
:
+—————-+
| Singleton |
|—————-|
| -instance:Singleton|
|—————-|
| +getInstance() |
| +operation() |
+—————-+
详细解释
:
私有构造函数
:防止外部直接实例化。
静态实例
:保存唯一的实例。
静态工厂方法
:提供全局访问点。
代码示例
:
public class Singleton {
// 静态实例,使用volatile保证可见性
private static volatile Singleton instance;

// 私有构造函数
private Singleton() {
// 防止反射破坏单例
if (instance != null) {
throw new IllegalStateException(“Cannot create new instance of a singleton class”);
}
}

// 静态工厂方法(线程安全)
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}

// 业务方法
public void operation() {
System.out.println(“Singleton operation”);
}

// 防止反序列化破坏单例
protected Object readResolve() {
return getInstance();
}
}

// 使用示例
public class SingletonDemo {
public static void main(String[] args) {
Singleton singleton1 = Singleton.getInstance();
Singleton singleton2 = Singleton.getInstance();

System.out.println(singleton1 == singleton2); // true

singleton1.operation();
singleton2.operation();
}
}
第三部分:使用UML表达结构型设计模式
1. 适配器模式(Adapter)
模式精髓
:将一个类的接口转换成客户希望的另一个接口。适配器让原本接口不兼容的类可以一起工作。
UML类图表达
:
+—————-+ +—————-+
| Target | | Adaptee |
|—————-| |—————-|
| +request() | | +specificRequest() |
+—————-+ +—————-+
^ ^
| |
+————————-+
|
+—————-+
| Adapter |
|—————-|
| +request() |
+—————-+
详细解释
:
Target
:客户期待的接口。
Adaptee
:需要被适配的现有接口。
Adapter
:实现Target接口并持有Adaptee实例,将请求转发给Adaptee。
代码示例
:
// 目标接口
interface MediaPlayer {
void play(String audioType, String fileName);
}

// 不兼容的接口
interface AdvancedMediaPlayer {
void playVLC(String fileName);
void playMP4(String fileName);
}

// 具体的高级播放器
class VLCPlayer implements AdvancedMediaPlayer {
@Override
public void playVLC(String fileName) {
System.out.println(“Playing vlc file: ” + fileName);
}

@Override
public void playMP4(String fileName) {
// 不支持
}
}

class MP4Player implements AdvancedMediaPlayer {
@Override
public void playVLC(String fileName) {
// 不支持
}

@Override
public void playMP4(String fileName) {
System.out.println(“Playing mp4 file: ” + fileName);
}
}

// 适配器
class MediaAdapter implements MediaPlayer {
private AdvancedMediaPlayer advancedMediaPlayer;

public MediaAdapter(String audioType) {
if (audioType.equalsIgnoreCase(“vlc”)) {
advancedMediaPlayer = new VLCPlayer();
} else if (audioType.equalsIgnoreCase(“mp4”)) {
advancedMediaPlayer = new MP4Player();
}
}

@Override
public void play(String audioType, String fileName) {
if (audioType.equalsIgnoreCase(“vlc”)) {
advancedMediaPlayer.playVLC(fileName);
} else if (audioType.equalsIgnoreCase(“mp4”)) {
advancedMediaPlayer.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: ” + fileName);
}
// 使用适配器支持其他格式
else if (audioType.equalsIgnoreCase(“vlc”) || audioType.equalsIgnoreCase(“mp4”)) {
mediaAdapter = new MediaAdapter(audioType);
mediaAdapter.play(audioType, fileName);
} else {
System.out.println(“Invalid media type: ” + audioType);
}
}
}

// 使用示例
public class AdapterDemo {
public static void main(String[] args) {
AudioPlayer audioPlayer = new AudioPlayer();

audioPlayer.play(“mp3”, “song.mp3”);
audioPlayer.play(“mp4”, “movie.mp4”);
audioPlayer.play(“vlc”, “video.vlc”);
audioPlayer.play(“avi”, “movie.avi”);
}
}
2. 装饰器模式(Decorator)
模式精髓
:动态地给一个对象添加一些额外的职责。就扩展功能而言,它比生成子类更为灵活。
UML类图表达
:
+—————-+
| Component |
|—————-|
| +operation() |
+—————-+
^
|
+—————-+ +—————-+
| ConcreteComponent| | Decorator |
|—————-| |—————-|
| +operation() | | -component:Component|
+—————-+ | +operation() |
+—————-+
^
|
+—————-+
| ConcreteDecorator|
|—————-|
| +operation() |
+—————-+
详细解释
:
Component
:定义一个对象接口,可以给这些对象动态地添加职责。
ConcreteComponent
:定义一个具体的对象,可以给这个对象添加职责。
Decorator
:持有一个Component对象的实例,并定义一个与Component接口一致的接口。
ConcreteDecorator
:向组件添加具体的职责。
代码示例
:
// 抽象组件
interface Coffee {
double getCost();
String getDescription();
}

// 具体组件
class SimpleCoffee implements Coffee {
@Override
public double getCost() {
return 1.0;
}

@Override
public String getDescription() {
return “Simple coffee”;
}
}

// 装饰器基类
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();
}
}

// 具体装饰器
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() + “, Milk”;
}
}

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() + “, Sugar”;
}
}

class WhippedCreamDecorator extends CoffeeDecorator {
public WhippedCreamDecorator(Coffee coffee) {
super(coffee);
}

@Override
public double getCost() {
return super.getCost() + 0.7;
}

@Override
public String getDescription() {
return super.getDescription() + “, Whipped Cream”;
}
}

// 使用示例
public class DecoratorDemo {
public static void main(String[] args) {
// 简单咖啡
Coffee coffee = new SimpleCoffee();
System.out.println(coffee.getDescription() + ” $” + coffee.getCost());

// 加牛奶
coffee = new MilkDecorator(coffee);
System.out.println(coffee.getDescription() + ” $” + coffee.getCost());

// 加糖
coffee = new SugarDecorator(coffee);
System.out.println(coffee.getDescription() + ” $” + coffee.getCost());

// 加鲜奶油
coffee = new WhippedCreamDecorator(coffee);
System.out.println(coffee.getDescription() + ” $” + coffee.getCost());
}
}
第四部分:使用UML表达行为型设计模式
1. 观察者模式(Observer)
模式精髓
:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
UML类图表达
:
+—————-+ +—————-+
| Subject | | Observer |
|—————-| |—————-|
| +attach(Observer) | | +update() |
| +detach(Observer) | +—————-+
| +notify() | ^
+—————-+ |
^ |
| |
+—————-+ +—————-+
| ConcreteSubject| | ConcreteObserver|
|—————-| |—————-|
| +getState() | | +update() |
| +setState() | +—————-+
+—————-+
详细解释
:
Subject
:目标对象,维护一个观察者列表,提供添加、删除和通知观察者的方法。
Observer
:观察者接口,定义更新方法。
ConcreteSubject
:具体目标,存储状态,状态改变时通知所有观察者。
ConcreteObserver
:具体观察者,实现更新方法,维持一个对ConcreteSubject的引用。
代码示例
:
import java.util.ArrayList;
import java.util.List;

// 观察者接口
interface Observer {
void update(String message);
}

// 目标接口
interface Subject {
void attach(Observer observer);
void detach(Observer observer);
void notifyObservers();
}

// 具体目标
class NewsAgency implements Subject {
private List observers = new ArrayList<>();
private String news;

@Override
public void attach(Observer observer) {
observers.add(observer);
}

@Override
public void detach(Observer observer) {
observers.remove(observer);
}

@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(news);
}
}

public void setNews(String news) {
this.news = news;
System.out.println(“News Agency: ” + news);
notifyObservers();
}
}

// 具体观察者
class NewsChannel implements Observer {
private String name;

public NewsChannel(String name) {
this.name = name;
}

@Override
public void update(String message) {
System.out.println(name + ” received: ” + message);
}
}

// 使用示例
public class ObserverDemo {
public static void main(String[] args) {
NewsAgency agency = new NewsAgency();

Observer channel1 = new NewsChannel(“CNN”);
Observer channel2 = new NewsChannel(“BBC”);
Observer channel3 = new NewsChannel(“Fox News”);

agency.attach(channel1);
agency.attach(channel2);
agency.attach(channel3);

agency.setNews(“Breaking News: Design Patterns are awesome!”);

agency.detach(channel2);

agency.setNews(“Update: UML makes patterns clearer!”);
}
}
UML顺序图表达
:
Client -> NewsAgency: setNews(“News”)
NewsAgency -> NewsAgency: notifyObservers()
loop for each observer
NewsAgency -> NewsChannel: update(“News”)
NewsChannel –> NewsAgency: return
end
2. 策略模式(Strategy)
模式精髓
:定义一系列算法,将每个算法封装起来,并使它们可以互换。策略模式让算法的变化独立于使用它的客户。
UML类图表达
:
+—————-+ +—————-+
| Context | | Strategy |
|—————-| |—————-|
| -strategy:Strategy| | +algorithm() |
| +setStrategy() | +—————-+
| +executeStrategy()| ^
+—————-+ |
^ |
| |
+—————-+ +—————-+
| ConcreteStrategyA| | ConcreteStrategyB|
|—————-| |—————-|
| +algorithm() | | +algorithm() |
+—————-+ +—————-+
详细解释
:
Strategy
:策略接口,定义所有支持的算法的公共接口。
ConcreteStrategy
:具体策略,实现Strategy接口,提供具体的算法实现。
Context
:上下文,用一个ConcreteStrategy对象来配置,维护一个Strategy对象的引用,可以定义一个接口来让Strategy访问它的数据。
代码示例
:
// 策略接口
interface PaymentStrategy {
void pay(double amount);
}

// 具体策略:信用卡支付
class CreditCardPayment implements PaymentStrategy {
private String cardNumber;
private String name;

public CreditCardPayment(String cardNumber, String name) {
this.cardNumber = cardNumber;
this.name = name;
}

@Override
public void pay(double amount) {
System.out.println(“Paid $” + amount + ” using Credit Card: ” + cardNumber + ” (” + name + “)”);
}
}

// 具体策略:PayPal支付
class PayPalPayment implements PaymentStrategy {
private String email;

public PayPalPayment(String email) {
this.email = email;
}

@Override
public void pay(double amount) {
System.out.println(“Paid $” + amount + ” using PayPal: ” + email);
}
}

// 具体策略:比特币支付
class BitcoinPayment implements PaymentStrategy {
private String walletAddress;

public BitcoinPayment(String walletAddress) {
this.walletAddress = walletAddress;
}

@Override
public void pay(double amount) {
System.out.println(“Paid $” + amount + ” using Bitcoin: ” + walletAddress);
}
}

// 上下文
class PaymentContext {
private PaymentStrategy strategy;

public void setStrategy(PaymentStrategy strategy) {
this.strategy = strategy;
}

public void executePayment(double amount) {
if (strategy == null) {
throw new IllegalStateException(“Payment strategy not set”);
}
strategy.pay(amount);
}
}

// 使用示例
public class StrategyDemo {
public static void main(String[] args) {
PaymentContext context = new PaymentContext();

// 使用信用卡支付
context.setStrategy(new CreditCardPayment(“1234-5678-9012-3456”, “John Doe”));
context.executePayment(100.00);

// 使用PayPal支付
context.setStrategy(new PayPalPayment(“john.doe@example.com”));
context.executePayment(50.00);

// 使用比特币支付
context.setStrategy(new BitcoinPayment(“1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa”));
context.executePayment(200.00);
}
}
第五部分:综合案例 – 使用设计模式和UML解决软件架构难题
案例背景:电商系统订单处理架构
假设我们正在设计一个大型电商系统的订单处理模块,面临以下挑战:
需要支持多种支付方式(信用卡、PayPal、支付宝、微信支付)
需要支持多种配送方式(快递、自提、同城配送)
需要支持多种订单类型(普通订单、预售订单、团购订单)
系统需要易于扩展,以便未来添加新的支付方式、配送方式或订单类型
需要保证订单处理流程的一致性和可维护性
架构设计:组合使用多种设计模式
1. 使用抽象工厂模式创建订单处理组件
首先,我们使用抽象工厂模式来创建支付处理器、配送处理器和订单处理器。
UML类图
:
+————————+
| OrderProcessingFactory |
|————————|
| +createPaymentProcessor()|
| +createDeliveryProcessor()|
| +createOrderProcessor()|
+————————+
^
|
+————————+
| StandardOrderFactory |
|————————|
| +createPaymentProcessor()|
| +createDeliveryProcessor()|
| +createOrderProcessor()|
+————————+
2. 使用策略模式处理支付和配送
UML类图
:
+—————-+ +—————-+
| PaymentContext | | PaymentStrategy|
|—————-| |—————-|
| -strategy | | +pay() |
| +setStrategy() | +—————-+
| +executePay() | ^
+—————-+ |
^ |
| |
+—————-+ +—————-+
| DeliveryContext| | DeliveryStrategy|
|—————-| |—————-|
| -strategy | | +deliver() |
| +setStrategy() | +—————-+
| +executeDeliver()| ^
+—————-+ |
^ |
| |
+—————-+ +—————-+
| OrderProcessor | | OrderStrategy |
|—————-| |—————-|
| -paymentCtx | | +process() |
| -deliveryCtx | +—————-+
| +processOrder()| ^
+—————-+ |
|
+—————-+
| StandardOrder |
|—————-|
| +process() |
+—————-+
3. 使用观察者模式实现订单状态通知
UML类图
:
+—————-+ +—————-+
| OrderSubject | | OrderObserver |
|—————-| |—————-|
| +attach() | | +update() |
| +detach() | +—————-+
| +notify() | ^
+—————-+ |
^ |
| |
+—————-+ +—————-+
| Order | | CustomerObserver|
|—————-| |—————-|
| +setState() | | +update() |
| +getState() | +—————-+
+—————-+ ^
|
+—————-+
| AdminObserver |
|—————-|
| +update() |
+—————-+
完整代码实现
import java.util.ArrayList;
import java.util.List;

// ==================== 抽象工厂模式 ====================

// 抽象工厂接口
interface OrderProcessingFactory {
PaymentStrategy createPaymentProcessor();
DeliveryStrategy createDeliveryProcessor();
OrderStrategy createOrderProcessor();
}

// 标准订单工厂
class StandardOrderFactory implements OrderProcessingFactory {
@Override
public PaymentStrategy createPaymentProcessor() {
return new CreditCardPayment();
}

@Override
public DeliveryStrategy createDeliveryProcessor() {
return new ExpressDelivery();
}

@Override
public OrderStrategy createOrderProcessor() {
return new StandardOrder();
}
}

// 预售订单工厂
class PreOrderFactory implements OrderProcessingFactory {
@Override
public PaymentStrategy createPaymentProcessor() {
return new DepositPayment();
}

@Override
public DeliveryStrategy createDeliveryProcessor() {
return new ScheduledDelivery();
}

@Override
public OrderStrategy createOrderProcessor() {
return new PreOrder();
}
}

// ==================== 策略模式 ====================

// 支付策略接口
interface PaymentStrategy {
void pay(double amount);
}

// 信用卡支付
class CreditCardPayment implements PaymentStrategy {
@Override
public void pay(double amount) {
System.out.println(“Processing credit card payment: $” + amount);
}
}

// PayPal支付
class PayPalPayment implements PaymentStrategy {
@Override
public void pay(double amount) {
System.out.println(“Processing PayPal payment: $” + amount);
}
}

// 支付宝支付
class AlipayPayment implements PaymentStrategy {
@Override
public void pay(double amount) {
System.out.println(“Processing Alipay payment: $” + amount);
}
}

// 定金支付(用于预售)
class DepositPayment implements PaymentStrategy {
@Override
public void pay(double amount) {
double deposit = amount * 0.3; // 30%定金
System.out.println(“Processing deposit payment: $” + deposit + ” (30% of $” + amount + “)”);
}
}

// 配送策略接口
interface DeliveryStrategy {
void deliver(String address);
}

// 快递配送
class ExpressDelivery implements DeliveryStrategy {
@Override
public void deliver(String address) {
System.out.println(“Delivering to: ” + address + ” via Express Courier”);
}
}

// 同城配送
class LocalDelivery implements DeliveryStrategy {
@Override
public void deliver(String address) {
System.out.println(“Delivering to: ” + address + ” via Local Courier”);
}
}

// 自提
class SelfPickup implements DeliveryStrategy {
@Override
public void deliver(String address) {
System.out.println(“Order ready for pickup at: ” + address);
}
}

// 预售配送
class ScheduledDelivery implements DeliveryStrategy {
@Override
public void deliver(String address) {
System.out.println(“Scheduled delivery to: ” + address + ” on release date”);
}
}

// 订单处理策略接口
interface OrderStrategy {
void process(Order order);
}

// 标准订单处理
class StandardOrder implements OrderStrategy {
@Override
public void process(Order order) {
System.out.println(“Processing standard order #” + order.getOrderId());
order.getPaymentStrategy().pay(order.getTotalAmount());
order.getDeliveryStrategy().deliver(order.getShippingAddress());
order.setState(“PROCESSED”);
}
}

// 预售订单处理
class PreOrder implements OrderStrategy {
@Override
public void process(Order order) {
System.out.println(“Processing pre-order #” + order.getOrderId());
order.getPaymentStrategy().pay(order.getTotalAmount());
System.out.println(“Pre-order placed in queue. Will ship on release date.”);
order.setState(“PRE_ORDERED”);
}
}

// 团购订单处理
class GroupBuyOrder implements OrderStrategy {
@Override
public void process(Order order) {
System.out.println(“Processing group buy order #” + order.getOrderId());
System.out.println(“Checking group buy threshold…”);
order.getPaymentStrategy().pay(order.getTotalAmount());
order.getDeliveryStrategy().deliver(order.getShippingAddress());
order.setState(“GROUP_BUY_PROCESSED”);
}
}

// ==================== 观察者模式 ====================

// 观察者接口
interface OrderObserver {
void update(Order order, String message);
}

// 客户观察者
class CustomerObserver implements OrderObserver {
private String customerEmail;

public CustomerObserver(String customerEmail) {
this.customerEmail = customerEmail;
}

@Override
public void update(Order order, String message) {
System.out.println(“Email to ” + customerEmail + “: Order #” + order.getOrderId() + ” – ” + message);
}
}

// 管理员观察者
class AdminObserver implements OrderObserver {
@Override
public void update(Order order, String message) {
System.out.println(“Admin Alert: Order #” + order.getOrderId() + ” – ” + message);
}
}

// 库存观察者
class InventoryObserver implements OrderObserver {
@Override
public void update(Order order, String message) {
if (message.contains(“PROCESSED”) || message.contains(“PRE_ORDERED”)) {
System.out.println(“Inventory System: Deducting stock for order #” + order.getOrderId());
}
}
}

// ==================== 订单类(上下文) ====================

class Order {
private String orderId;
private double totalAmount;
private String shippingAddress;
private String state;

private PaymentStrategy paymentStrategy;
private DeliveryStrategy deliveryStrategy;
private OrderStrategy orderStrategy;

private List observers = new ArrayList<>();

public Order(String orderId, double totalAmount, String shippingAddress) {
this.orderId = orderId;
this.totalAmount = totalAmount;
this.shippingAddress = shippingAddress;
this.state = “CREATED”;
}

// 设置策略
public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
this.paymentStrategy = paymentStrategy;
}

public void setDeliveryStrategy(DeliveryStrategy deliveryStrategy) {
this.deliveryStrategy = deliveryStrategy;
}

public void setOrderStrategy(OrderStrategy orderStrategy) {
this.orderStrategy = orderStrategy;
}

// 获取策略
public PaymentStrategy getPaymentStrategy() {
return paymentStrategy;
}

public DeliveryStrategy getDeliveryStrategy() {
return deliveryStrategy;
}

public OrderStrategy getOrderStrategy() {
return orderStrategy;
}

// 状态管理
public void setState(String state) {
String oldState = this.state;
this.state = state;
notifyObservers(“State changed from ” + oldState + ” to ” + state);
}

public String getState() {
return state;
}

// 观察者管理
public void attach(OrderObserver observer) {
observers.add(observer);
}

public void detach(OrderObserver observer) {
observers.remove(observer);
}

private void notifyObservers(String message) {
for (OrderObserver observer : observers) {
observer.update(this, message);
}
}

// 业务方法
public void process() {
if (orderStrategy == null) {
throw new IllegalStateException(“Order strategy not set”);
}
orderStrategy.process(this);
}

// Getters
public String getOrderId() { return orderId; }
public double getTotalAmount() { return totalAmount; }
public String getShippingAddress() { return shippingAddress; }
}

// ==================== 订单处理上下文 ====================

class OrderProcessingContext {
private Order order;
private OrderProcessingFactory factory;

public OrderProcessingContext(String orderId, double amount, String address, OrderProcessingFactory factory) {
this.order = new Order(orderId, amount, address);
this.factory = factory;
setupOrder();
}

private void setupOrder() {
// 使用工厂创建策略
order.setPaymentStrategy(factory.createPaymentProcessor());
order.setDeliveryStrategy(factory.createDeliveryProcessor());
order.setOrderStrategy(factory.createOrderProcessor());

// 添加观察者
order.attach(new CustomerObserver(“customer@example.com”));
order.attach(new AdminObserver());
order.attach(new InventoryObserver());
}

public void processOrder() {
System.out.println(“\n=== Processing Order: ” + order.getOrderId() + ” ===”);
order.process();
}

public void changePaymentStrategy(PaymentStrategy newStrategy) {
order.setPaymentStrategy(newStrategy);
System.out.println(“Payment strategy changed for order: ” + order.getOrderId());
}

public void changeDeliveryStrategy(DeliveryStrategy newStrategy) {
order.setDeliveryStrategy(newStrategy);
System.out.println(“Delivery strategy changed for order: ” + order.getOrderId());
}
}

// ==================== 使用示例 ====================

public class ECommerceArchitectureDemo {
public static void main(String[] args) {
// 场景1:标准订单处理
OrderProcessingContext standardOrder = new OrderProcessingContext(
“ORD-001”, 150.00, “123 Main St, New York”,
new StandardOrderFactory()
);
standardOrder.processOrder();

// 场景2:预售订单处理
OrderProcessingContext preOrder = new OrderProcessingContext(
“PRE-001”, 200.00, “456 Oak Ave, Los Angeles”,
new PreOrderFactory()
);
preOrder.processOrder();

// 场景3:动态更改支付方式
OrderProcessingContext flexibleOrder = new OrderProcessingContext(
“ORD-002”, 300.00, “789 Pine Rd, Chicago”,
new StandardOrderFactory()
);
// 更改支付方式为支付宝
flexibleOrder.changePaymentStrategy(new AlipayPayment());
// 更改配送方式为自提
flexibleOrder.changeDeliveryStrategy(new SelfPickup());
flexibleOrder.processOrder();

// 场景4:模拟复杂业务流程
System.out.println(“\n=== Complex Order Processing ===”);
Order complexOrder = new Order(“COMPLEX-001”, 500.00, “100 Business Blvd, Seattle”);

// 动态组合策略
complexOrder.setPaymentStrategy(new PayPalPayment());
complexOrder.setDeliveryStrategy(new LocalDelivery());
complexOrder.setOrderStrategy(new GroupBuyOrder());

// 添加多个观察者
complexOrder.attach(new CustomerObserver(“vip@example.com”));
complexOrder.attach(new AdminObserver());
complexOrder.attach(new InventoryObserver());

// 处理订单
complexOrder.process();
}
}
UML系统架构图
+———————-+
| OrderProcessing |
| System |
+———————-+
| |
| +—————-+ |
| | OrderContext | |
| |—————-| |
| | -order: Order | |
| | -factory: Factory| |
| | +process() | |
| +—————-+ |
| | |
| v |
| +—————-+ |
| | Order | |
| |—————-| |
| | -state | |
| | -strategies | |
| | -observers | |
| | +process() | |
| +—————-+ |
| | |
| +——–+——–+ |
| | | |
| v v |
|+—————+ +—————+ |
| PaymentContext | | DeliveryContext| |
|—————| |—————| |
| -strategy | | -strategy | |
| +pay() | | +deliver() | |
+—————+ +—————+ |
| |
v v |
+————+ +————+ |
| Payment | | Delivery | |
| Strategy | | Strategy | |
| Interface | | Interface | |
+————+ +————+ |
| |
v v |
+————+ +————+ |
| Concrete | | Concrete | |
| Strategies | | Strategies | |
+————+ +————+ |
| |
+———————-+
|
v
+———————-+
| Observer Pattern |
+———————-+
| OrderSubject |
| +attach/detach/notify|
+———————-+
|
v
+———————-+
| Observers List |
+———————-+
| CustomerObserver |
| AdminObserver |
| InventoryObserver |
+———————-+
第六部分:最佳实践与常见陷阱
1. 何时使用设计模式
应该使用设计模式的情况
:
问题反复出现,且解决方案经过验证
需要提高代码的可维护性和可扩展性
团队需要共同的设计语言
需要重构现有代码以提高质量
不应该使用设计模式的情况
:
为了使用模式而使用模式(过度设计)
简单问题用复杂模式解决
团队不理解模式,导致误用
性能关键路径,模式可能引入开销
2. UML图设计的最佳实践
保持简洁
:
只展示关键的类和关系,避免过度细节
使用有意义的类名和关系名
对于复杂系统,使用包图分层
一致性
:
保持命名约定一致
使用标准的UML符号
在整个系统中保持相同的抽象层次
文档化
:
为每个模式添加注释说明其目的
在UML图中添加关键约束和不变量
记录模式选择的原因
3. 常见陷阱与解决方案
陷阱1:过度使用设计模式
问题
:简单代码变得复杂
解决方案
:遵循YAGNI原则(You Aren’t Gonna Need It),只在真正需要时使用模式
陷阱2:模式误用
问题
:选择了错误的模式解决错误的问题
解决方案
:深入理解模式意图和适用场景,进行代码审查
陷阱3:UML图过于复杂
问题
:难以理解和维护
解决方案
:分层绘制,使用多个UML图,保持每个图的焦点单一
陷阱4:忽略模式的权衡
问题
:引入模式带来预期之外的复杂性
解决方案
:评估模式的利弊,考虑性能、学习曲线和维护成本
第七部分:高级主题 – 模式组合与架构风格
1. 模式组合策略
设计模式很少单独使用,通常会组合使用以解决更复杂的问题:
创建型 + 结构型
:
抽象工厂 + 建造者:创建复杂对象的多个变体
工厂方法 + 装饰器:动态创建装饰对象
结构型 + 行为型
:
组合 + 访问者:处理树形结构的复杂操作
代理 + 观察者:实现远程事件通知
行为型 + 行为型
:
策略 + 模板方法:算法框架与具体实现分离
命令 + 备忘录:实现可撤销操作
2. 架构风格中的模式应用
分层架构
:
使用工厂方法创建各层组件
使用适配器模式隔离层间依赖
使用观察者模式实现层间通信
微服务架构
:
使用代理模式实现服务网关
使用命令模式处理异步消息
使用策略模式实现服务发现
事件驱动架构
:
使用观察者模式实现事件发布/订阅
使用命令模式封装事件处理
使用责任链模式处理事件管道
结论
设计模式与UML是现代软件架构设计中不可或缺的工具。通过UML图,我们可以精确地表达设计模式的结构和行为,使复杂的架构设计变得清晰易懂。本文深入探讨了如何使用UML表达各种设计模式,并通过一个完整的电商系统案例展示了如何组合使用多种模式解决实际的架构难题。
关键要点总结:
理解模式本质
:每个模式解决特定类型的问题,理解其意图是正确应用的前提
UML是沟通工具
:UML图的价值在于清晰传达设计意图,而非追求完美的图形
模式组合的力量
:实际系统中很少使用单一模式,组合使用才能发挥最大价值
权衡与选择
:没有银弹,需要根据具体场景权衡模式的利弊
持续演进
:架构设计是持续的过程,模式和UML图需要随需求变化而演进
通过掌握设计模式与UML的结合使用,开发者和架构师能够:
更快地识别和解决设计问题
创建更灵活、可维护的系统
与团队成员更有效地沟通设计决策
构建能够应对未来变化的架构
记住,设计模式和UML都是工具,真正的目标是创建高质量的软件系统。在实践中不断学习和反思,才能真正掌握这些强大的技术。