Groovy设计模式:23种经典模式的Groovy实现
1. 设计模式与Groovy语言特性
1.1 为何选择Groovy实现设计模式
Groovy作为基于JVM的动态语言,为设计模式实现提供了独特优势:
- 闭包(Closure):简化策略模式、命令模式等行为型模式的实现
- 元编程(Metaprogramming):通过
@Canonical、@TupleConstructor等注解减少创建型模式的样板代码 - DSL支持:使构建者模式(Builder)实现更加自然
- 操作符重载:增强外观模式、装饰器模式的API友好性
- 集合API:内置的集合操作简化迭代器模式实现
1.2 设计模式分类概览
2. 创建型设计模式
2.1 单例模式(Singleton Pattern)
Groovy通过元编程特性实现线程安全的单例:
class SingletonLogger {
private static SingletonLogger instance
private SingletonLogger() {} // 私有构造函数
static synchronized SingletonLogger getInstance() {
if (!instance) {
instance = new SingletonLogger()
}
instance
}
void log(String message) {
println "[${new Date()}] $message"
}
}
// 使用方式
def logger = SingletonLogger.instance
logger.log("应用启动")
2.2 工厂方法模式(Factory Method Pattern)
interface Document {
String getContent()
}
class TextDocument implements Document {
String content
TextDocument(String content) {
this.content = content
}
String getContent() { content }
}
class SpreadsheetDocument implements Document {
String content
SpreadsheetDocument(String content) {
this.content = content
}
String getContent() { content }
}
abstract class DocumentFactory {
abstract Document createDocument(String content)
// 工厂方法模式中的模板方法
Document openDocument(String content) {
def doc = createDocument(content)
println "文档已创建: ${doc.getClass().simpleName}"
doc
}
}
class TextDocumentFactory extends DocumentFactory {
Document createDocument(String content) {
new TextDocument(content)
}
}
class SpreadsheetDocumentFactory extends DocumentFactory {
Document createDocument(String content) {
new SpreadsheetDocument(content)
}
}
// 使用示例
def textFactory = new TextDocumentFactory()
def textDoc = textFactory.openDocument("Hello Groovy")
def sheetFactory = new SpreadsheetDocumentFactory()
def sheetDoc = sheetFactory.openDocument("A1=10, B1=20")
2.3 构建者模式(Builder Pattern)
利用Groovy的DSL特性实现优雅的构建者:
class HTMLBuilder {
private String result = ""
def html(Closure closure) {
result += "<html>"
closure.resolveStrategy = Closure.DELEGATE_FIRST
closure.delegate = this
closure()
result += "</html>"
}
def body(Closure closure) {
result += "<body>"
closure.resolveStrategy = Closure.DELEGATE_FIRST
closure.delegate = this
closure()
result += "</body>"
}
def p(String text) {
result += "<p>$text</p>"
}
String toString() { result }
}
// 使用DSL风格构建HTML
def html = new HTMLBuilder()
html.html {
body {
p "Groovy构建者模式示例"
p "使用闭包实现优雅的DSL"
}
}
println html.toString()
3. 结构型设计模式
3.1 装饰器模式(Decorator Pattern)
interface Coffee {
String getDescription()
double getCost()
}
class SimpleCoffee implements Coffee {
String getDescription() { "简单咖啡" }
double getCost() { 10.0 }
}
abstract class CoffeeDecorator implements Coffee {
protected Coffee coffee
CoffeeDecorator(Coffee coffee) {
this.coffee = coffee
}
}
class MilkDecorator extends CoffeeDecorator {
MilkDecorator(Coffee coffee) { super(coffee) }
String getDescription() { "${coffee.description} + 牛奶" }
double getCost() { coffee.cost + 3.0 }
}
class SugarDecorator extends CoffeeDecorator {
SugarDecorator(Coffee coffee) { super(coffee) }
String getDescription() { "${coffee.description} + 糖" }
double getCost() { coffee.cost + 1.0 }
}
// 使用示例
def coffee = new SimpleCoffee()
println "${coffee.description} ¥${coffee.cost}"
coffee = new MilkDecorator(coffee)
println "${coffee.description} ¥${coffee.cost}"
coffee = new SugarDecorator(coffee)
println "${coffee.description} ¥${coffee.cost}"
3.2 适配器模式(Adapter Pattern)
// 遗留系统接口
interface LegacyPaymentSystem {
void processPayment(double amount, String currency)
}
class OldPaymentGateway implements LegacyPaymentSystem {
void processPayment(double amount, String currency) {
println "旧系统处理支付: $amount $currency"
}
}
// 新系统接口
interface ModernPaymentAPI {
void makePayment(BigDecimal amount, String currencyCode)
String getTransactionId()
}
// 适配器实现
class PaymentAdapter implements ModernPaymentAPI {
private LegacyPaymentSystem legacySystem
private String transactionId
PaymentAdapter(LegacyPaymentSystem legacySystem) {
this.legacySystem = legacySystem
this.transactionId = "TXN-${System.currentTimeMillis()}"
}
void makePayment(BigDecimal amount, String currencyCode) {
legacySystem.processPayment(amount.doubleValue(), currencyCode)
}
String getTransactionId() { transactionId }
}
// 使用示例
def legacySystem = new OldPaymentGateway()
def paymentAPI = new PaymentAdapter(legacySystem)
paymentAPI.makePayment(new BigDecimal("99.99"), "CNY")
println "交易ID: ${paymentAPI.transactionId}"
3.3 代理模式(Proxy Pattern)
interface Image {
void display()
}
class RealImage implements Image {
private String filename
RealImage(String filename) {
this.filename = filename
loadFromDisk()
}
private void loadFromDisk() {
println "从磁盘加载图片: $filename"
}
void display() {
println "显示图片: $filename"
}
}
class ProxyImage implements Image {
private RealImage realImage
private String filename
ProxyImage(String filename) {
this.filename = filename
}
void display() {
if (!realImage) {
realImage = new RealImage(filename) // 延迟加载
}
realImage.display()
}
}
// 使用示例
Image image = new ProxyImage("large_image.jpg")
println "第一次显示(应该加载图片):"
image.display()
println "\n第二次显示(不应再次加载):"
image.display()
4. 行为型设计模式
4.1 策略模式(Strategy Pattern)
interface SortStrategy {
List sort(List list)
}
class BubbleSortStrategy implements SortStrategy {
List sort(List list) {
def sorted = new ArrayList(list)
for (i in 0..<sorted.size()) {
for (j in 0..<sorted.size()-i-1) {
if (sorted[j] > sorted[j+1]) {
sorted.swap(j, j+1)
}
}
}
sorted
}
}
class QuickSortStrategy implements SortStrategy {
List sort(List list) {
if (list.size() <= 1) return list
def pivot = list[list.size().intdiv(2)]
def left = list.findAll { it < pivot }
def middle = list.findAll { it == pivot }
def right = list.findAll { it > pivot }
sort(left) + middle + sort(right)
}
}
class Sorter {
private SortStrategy strategy
Sorter(SortStrategy strategy) {
this.strategy = strategy
}
void setStrategy(SortStrategy strategy) {
this.strategy = strategy
}
List sort(List list) {
strategy.sort(list)
}
}
// 使用示例
def numbers = [3, 1, 4, 1, 5, 9, 2, 6]
def sorter = new Sorter(new BubbleSortStrategy())
println "冒泡排序结果: ${sorter.sort(numbers)}"
sorter.setStrategy(new QuickSortStrategy())
println "快速排序结果: ${sorter.sort(numbers)}"
4.2 观察者模式(Observer Pattern)
interface Observer {
void update(String message)
}
interface Subject {
void addObserver(Observer observer)
void removeObserver(Observer observer)
void notifyObservers(String message)
}
class NewsAgency implements Subject {
private List<Observer> observers = []
void addObserver(Observer observer) {
observers.add(observer)
}
void removeObserver(Observer observer) {
observers.remove(observer)
}
void notifyObservers(String message) {
observers.each { it.update(message) }
}
void publishNews(String news) {
println "发布新闻: $news"
notifyObservers(news)
}
}
class Newspaper implements Observer {
private String name
Newspaper(String name) {
this.name = name
}
void update(String message) {
println "$name 收到新闻: $message"
}
}
// 使用示例
def agency = new NewsAgency()
def chinaDaily = new Newspaper("中国日报")
def economist = new Newspaper("财经周刊")
agency.addObserver(chinaDaily)
agency.addObserver(economist)
agency.publishNews("Groovy设计模式教程发布")
4.3 命令模式(Command Pattern)
interface Command {
void execute()
void undo()
}
class Light {
void turnOn() { println "灯已打开" }
void turnOff() { println "灯已关闭" }
}
class TurnOnCommand implements Command {
private Light light
TurnOnCommand(Light light) {
this.light = light
}
void execute() { light.turnOn() }
void undo() { light.turnOff() }
}
class TurnOffCommand implements Command {
private Light light
TurnOffCommand(Light light) {
this.light = light
}
void execute() { light.turnOff() }
void undo() { light.turnOn() }
}
class RemoteControl {
private Command command
void setCommand(Command command) {
this.command = command
}
void pressButton() {
command.execute()
}
void pressUndo() {
command.undo()
}
}
// 使用示例
def light = new Light()
def remote = new RemoteControl()
remote.setCommand(new TurnOnCommand(light))
remote.pressButton() // 开灯
remote.setCommand(new TurnOffCommand(light))
remote.pressButton() // 关灯
remote.pressUndo() // 撤销(开灯)
5. 设计模式应用场景与选择指南
5.1 设计模式选择决策树
5.2 Groovy设计模式最佳实践
- 优先使用Groovy特性:利用闭包简化策略模式,使用DSL优化构建者模式
- 减少样板代码:通过
@TupleConstructor注解简化工厂模式实现 - 元编程应用:使用
ExpandoMetaClass实现动态装饰器 - 不可变设计:结合
@Immutable注解实现线程安全的单例模式 - 测试友好:利用接口和依赖注入提高模式实现的可测试性
6. 完整设计模式实现代码
6.1 单例模式线程安全实现
@Singleton(lazy = true)
class ThreadSafeSingleton {
// 私有构造函数由@Singleton注解自动生成
void doSomething() {
println "线程安全的单例实例: ${this.hashCode()}"
}
}
// 使用方式
def instance1 = ThreadSafeSingleton.instance
def instance2 = ThreadSafeSingleton.instance
println "实例1哈希: ${instance1.hashCode()}"
println "实例2哈希: ${instance2.hashCode()}"
println "实例是否相同: ${instance1 == instance2}"
6.2 抽象工厂模式
interface Button {
void render()
}
interface TextField {
void render()
}
// Windows风格组件
class WindowsButton implements Button {
void render() { println "渲染Windows按钮" }
}
class WindowsTextField implements TextField {
void render() { println "渲染Windows文本框" }
}
// Mac风格组件
class MacButton implements Button {
void render() { println "渲染Mac按钮" }
}
class MacTextField implements TextField {
void render() { println "渲染Mac文本框" }
}
// 抽象工厂接口
interface UIFactory {
Button createButton()
TextField createTextField()
}
class WindowsUIFactory implements UIFactory {
Button createButton() { new WindowsButton() }
TextField createTextField() { new WindowsTextField() }
}
class MacUIFactory implements UIFactory {
Button createButton() { new MacButton() }
TextField createTextField() { new MacTextField() }
}
// 应用程序
class Application {
private UIFactory factory
Application(UIFactory factory) {
this.factory = factory
}
void createUI() {
def button = factory.createButton()
def textField = factory.createTextField()
button.render()
textField.render()
}
}
// 使用示例
def os = System.getProperty("os.name").toLowerCase()
def factory = os.contains("win") ? new WindowsUIFactory() : new MacUIFactory()
def app = new Application(factory)
app.createUI()
7. 总结与扩展学习
Groovy为设计模式实现提供了丰富的语言特性,使经典设计模式的实现更加简洁优雅。本文介绍了9种常用设计模式的Groovy实现,涵盖创建型、结构型和行为型三大类别。
7.1 未覆盖的设计模式实现指南
对于剩余14种设计模式,建议参考以下实现策略:
- 模板方法模式:使用抽象类和Groovy闭包结合实现
- 迭代器模式:利用Groovy集合的
iterator()方法和闭包迭代 - 状态模式:结合Groovy的
@Canonical和枚举实现状态转换 - 访问者模式:利用Groovy的双重分派特性简化实现
- 中介者模式:使用Groovy的事件总线机制实现组件解耦
7.2 进一步学习资源
- Groovy官方文档中的设计模式章节
- 《Groovy in Action》中的高级设计模式实现
- Apache Groovy GitHub仓库中的示例代码
- Groovy社区贡献的设计模式DSL库
通过掌握这些设计模式的Groovy实现,开发者可以编写更加优雅、灵活和可维护的代码,充分发挥Groovy语言的动态特性和简洁语法优势。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



