设计模式重构

53 浏览
4 试用
0 购买
Aug 26, 2025更新

帮助分析现有代码并结合设计模式进行优化改造

示例1

是的,你可以通过应用单例模式来确保 `Logger` 类只有一个实例。单例模式的核心是在代码运行期间,确保只创建一个实例,并且每次访问该类时都返回相同的实例,从而提高代码一致性。

### 实现思路

1. **控制实例化**: 使用类变量 `__instance` 作为存储单例实例的地方,确保第一次实例化后,后续调用都返回该实例。
2. **隐藏构造方法**: 通过在构造方法中添加逻辑,防止直接通过 `__init__` 创建新对象。
3. **提供访问入口**: 提供一个类方法(例如 `get_instance`)作为全局访问点,来返回单例实例。

这种结构还能很好地避免多个 `Logger` 实例之间的状态不一致问题。

---

### 重构后的代码

以下是基于单例模式重构后的代码实现:

```python
class Logger:
    # 类变量,用于存储单例实例
    __instance = None

    # 重写 __new__ 方法来控制实例的创建
    def __new__(cls, *args, **kwargs):
        if cls.__instance is None:  # 如果尚未创建实例
            cls.__instance = super().__new__(cls)  # 创建新实例
            cls.__instance.log = []  # 初始化实例的属性
        return cls.__instance  # 返回单例实例

# 使用这个单例类
logger1 = Logger()
logger2 = Logger()

# 测试单例行为:共享同一个 log 列表
logger1.log.append('Log 1')
print(logger2.log)  # 输出:['Log 1']

# 确认是同一个实例
print(logger1 is logger2)  # 输出:True
```

---

### 代码详细说明

1. **单例逻辑的关键实现**:
    - `__new__` 方法:在 Python 中 `__new__` 是控制实例创建的特殊方法,在 `__init__` 之前调用。
    - `cls.__instance`: 一个类变量,用来存储单例实例。只有在 `__instance` 为空时才会创建新的实例。

2. **日志的共享性**:
    - `logger1.log` 和 `logger2.log` 是同一个引用,因为它们共享同一个实例。
    - 修改日志的内容会对所有引用产生影响。

3. **实例唯一性**:
    - `logger1 is logger2` 验证了在内存中这两个变量是同一个实例。

---

### 替代实现(懒加载单例)

如果你希望实例只在第一次需要时被创建,可以用懒加载实现:

```python
class Logger:
    __instance = None

    def __new__(cls, *args, **kwargs):
        if cls.__instance is None:
            cls.__instance = super().__new__(cls)
            cls.__instance.log = []
        return cls.__instance

# 示例用法
logger1 = Logger()
logger1.log.append('Log 1')

logger2 = Logger()
print(logger2.log)  # 输出:['Log 1']
print(logger1 is logger2)  # 输出:True
```

这个版本不会在类加载时立即创建实例,但效果本质上是一样的。

---

### 重构后的优点

1. **避免误创建多个实例**:
   通过 `__new__` 方法强制所有调用返回同一个实例。
   
2. **全局一致性**:
   不管从哪里访问,日志记录器的状态始终一致。

3. **高可维护性**:
   使用类方法后可以方便扩展日志记录功能而无需担心实例管理问题。

希望这个方案满足你的需求,有问题随时沟通!

示例2

是的,可以通过“工厂模式”来实现模块化管理对象的创建,这样可以将对象实例化逻辑与客户端代码解耦,增强代码的可扩展性和灵活性。当需要新增动物类型时,只需更新工厂类的逻辑,而不需要修改已有的客户代码。

以下是重构代码的实现思路和步骤:

---

### **实现思路**
1. **创建抽象工厂类或接口**:
   定义一个接口或抽象类用于生成`Animal`对象。

2. **实现具体工厂类**:
   创建一个具体的工厂类,根据需求提供创建不同类型`Animal`对象的逻辑。

3. **在客户端代码中使用工厂代替直接实例化**:
   把调用`new Dog()`或`new Cat()`替换为通过工厂的创建方法。例如,`AnimalFactory.create("Cat")`。

4. **利于扩展**:
   增加新的动物类型时,只需在工厂中增加新的创建逻辑,无需改动其他代码。

---

### **重构后的代码**

```java
// Step 1: 动物基类
public abstract class Animal {
    public abstract void speak(); // 抽象 speak 方法
}

// Step 2: 具体动物类实现
public class Dog extends Animal {
    @Override
    public void speak() {
        System.out.println("Woof");
    }
}

public class Cat extends Animal {
    @Override
    public void speak() {
        System.out.println("Meow");
    }
}

// Step 3: 工厂类接口(可选)
public interface AnimalFactory {
    Animal createAnimal(String animalType); // 工厂提供创建方法
}

// Step 4: 具体工厂实现
public class SimpleAnimalFactory implements AnimalFactory {
    @Override
    public Animal createAnimal(String animalType) {
        switch (animalType.toLowerCase()) {
            case "dog":
                return new Dog();
            case "cat":
                return new Cat();
            default:
                throw new IllegalArgumentException("Unknown animal type: " + animalType);
        }
    }
}

// Step 5: 使用工厂创建对象(客户端代码)
public class Main {
    public static void main(String[] args) {
        // 创建工厂
        AnimalFactory factory = new SimpleAnimalFactory();

        // 创建动物实例
        Animal dog = factory.createAnimal("dog");
        Animal cat = factory.createAnimal("cat");

        // 调用 speak 方法
        dog.speak(); // 输出: Woof
        cat.speak(); // 输出: Meow
    }
}
```

---

### **详细解读与优化**:

1. **解耦创建逻辑**:
   - 通过`SimpleAnimalFactory`类封装对象创建逻辑,客户端代码无需关心具体类名(如`Dog`或`Cat`)。
   - 客户端只需传递类型信息(如字符串`"dog"`、`"cat"`),无需直接使用构造函数,这样的代码更加灵活。

2. **增强可扩展性**:
   - 增加新动物类型时,比如新增`Bird`类,只需扩展工厂的`createAnimal`方法:
     ```java
     case "bird":
        return new Bird();
     ```
   - 客户端代码无需修改,符合**开放封闭原则(OCP)**。

3. **增加自定义异常处理**(可选):
   - 对未知动物类型,建议抛出一个自定义异常用于更清晰的错误处理:
     ```java
     public class AnimalNotFoundException extends RuntimeException {
         public AnimalNotFoundException(String message) {
             super(message);
         }
     }
     ```

4. **考虑使用更复杂的工厂模式**:
   - 这里的`SimpleAnimalFactory`属于“简单工厂”。对于更复杂的场景,可以使用**工厂方法模式**或者**抽象工厂模式**。
   - 工厂方法模式可以在每个具体的动物子类中定义自己的工厂方法,用于实现更细粒度的控制。

---

### **总结**
通过使用简单工厂模式,您可以有效地避免在客户端代码中硬编码具体的构造函数调用,降低代码的耦合度,提升代码的模块化、可扩展性及可维护性。随着应用程序中动物种类的扩展,只需修改工厂类,而无需直接修改客户端代码,最大程度地符合设计模式的目标。

示例3

是的,通过应用“观察者模式”,你的代码几乎已经实现了观察者模式的核心设计理念。它允许定义对象间的“一对多”依赖关系,使得当一个对象更改其状态时,所有依赖它的对象都会收到通知。这种模式可以有效减少耦合,提高代码的可扩展性和可维护性。

### 审查当前代码
当前的代码片段已经包含了观察者模式的基本实现,具有以下特点:
1. `Observer` 接口代表观察者,这里包含了 `Update(data string)` 方法,观察者在被通知时执行此方法。
2. `Subject` 类(或结构体)管理一组观察者,当状态变化(通过调用 `NotifyObservers`)时,它通知所有注册的观察者。

该实现已经很好,但可以进一步细化和增强灵活性,提升代码的可读性、扩展性和使用体验。

---

### 建议的优化
我们可以在以下几个方面进行代码重构和改进:
1. **Liskov Substitution Principle (LSP)** - 确保 `Observer` 接口和实现具备更通用的扩展能力。
2. **解耦的增强**:
   - 允许 `Subject` 动态添加和移除观察者,不局限于只调用 `AddObserver`。
   - 对于 `Update` 方法,可以定义更通用的数据类型(而不是固定 `string`)。
3. **事件扩展能力**:
   - 增强对事件的区分,不仅支持简单通知数据,还支持区分不同的事件类型或事件源。
4. **日志和调试**:
   - 定义日志机制,便于观察者操作的执行跟踪。

---

### 重构后的实现
以下是一个更健壮且更可扩展的 “观察者模式” 的改进版本:

```go
package main

import (
    "fmt"
)

// Observer 定义观察者接口
type Observer interface {
    Update(event string, data interface{}) // 方法更通用,支持不同事件类型和数据
}

// Subject 定义主题结构体
type Subject struct {
    observers map[string][]Observer // 按照事件类型分组管理观察者
}

// NewSubject 创建Subject实例
func NewSubject() *Subject {
    return &Subject{
        observers: make(map[string][]Observer),
    }
}

// RegisterObserver 注册观察者到指定事件类型
func (s *Subject) RegisterObserver(event string, o Observer) {
    s.observers[event] = append(s.observers[event], o)
}

// RemoveObserver 从指定事件类型移除观察者
func (s *Subject) RemoveObserver(event string, o Observer) {
    observers := s.observers[event]
    for i, observer := range observers {
        if observer == o {
            // 从 slice 中移除
            s.observers[event] = append(observers[:i], observers[i+1:]...)
            return
        }
    }
}

// NotifyObservers 通知特定事件类型的观察者
func (s *Subject) NotifyObservers(event string, data interface{}) {
    observers := s.observers[event]
    for _, observer := range observers {
        observer.Update(event, data) // 通知观察者
    }
}

// 示例观察者实现
type ConcreteObserver struct {
    name string
}

func (co *ConcreteObserver) Update(event string, data interface{}) {
    fmt.Printf("Observer %s received event '%s' with data: %v\n", co.name, event, data)
}

func main() {
    // 创建主题
    subject := NewSubject()

    // 创建两个观察者
    observer1 := &ConcreteObserver{name: "Observer1"}
    observer2 := &ConcreteObserver{name: "Observer2"}

    // 订阅事件
    subject.RegisterObserver("event1", observer1)
    subject.RegisterObserver("event1", observer2)
    subject.RegisterObserver("event2", observer2)

    // 触发事件1
    subject.NotifyObservers("event1", "Hello Event 1")
    // 触发事件2
    subject.NotifyObservers("event2", "Hello Event 2")

    // 移除一个观察者
    subject.RemoveObserver("event1", observer1)

    // 再次触发事件1
    subject.NotifyObservers("event1", "Hello Event 1 Again")
}
```

---

### 重构后的功能增强点说明
1. **多事件类型支持**:
   - 原始实现对事件的区分能力较弱,重构后采用 `map[string][]Observer` 将观察者按照事件类型分组。这种方式允许支持细粒度的事件管理,同时能够轻松扩展新类型事件。
2. **更灵活的数据载荷支持**:
   - 将 `Update(data string)` 方法参数改为 `Update(event string, data interface{})`,使得通知机制不限于特定的数据类型,为各种业务场景提供了更广泛的适用性。
3. **动态添加/移除观察者**:
   - 提供了 `RegisterObserver` 和 `RemoveObserver` 接口,让调用者可以动态地为特定事件添加或移除观察者。
4. **单一职责和分层设计**:
   - 引入了 `NewSubject` 构造函数初始化 `Subject`,让 `Subject` 的职责更加单一。
   - 日志打印的功能封装在具体的观察者实现中,与核心逻辑分离。
5. **代码可读性与可维护性提升**:
   - 将方法和结构体抽象为更高层的“事件—观察”设计范式,从而更容易被团队成员理解和扩展。

---

### 使用场景
这种增强后的观察者模式更适合复杂的事件处理场景,例如:
1. 消息总线机制:多个模块监听某些类型的消息,如日志处理、事件链路追踪等。
2. UI事件系统:UI控件响应用户操作,如按钮点击、表单提交等。
3. 实时通知系统:基于订阅机制的更新推送,例如社交媒体、新闻动态更新等。

通过上述改进,与团队成员共享设计理念和代码,能够提升代码重用率、易维护性和业务扩展性。

适用用户

初级开发者

借助提示词学习设计模式的实际应用方法,并提升代码质量与编程能力。

资深程序员

优化现有代码结构,解决复杂问题,快速打磨高质量代码。

技术团队负责人

为团队制定一致的代码重构规范,提升整体代码维护性与减少技术债务。

项目技术顾问

借助设计模式,为客户项目提供更具价值的代码改造方案和技术建议。

编程教育工作者

通过案例演示设计模式如何应用于实际代码,为学员提供生动的教学资源。

解决的问题

帮助软件开发者结合设计模式优化现有代码,提高代码的可读性、可维护性与复用性,以及提升系统整体质量。

特征总结

智能分析代码片段,快速识别潜在问题并提供优化建议。
支持多种主流编程语言的代码审查,为开发者提供高适配性解决方案。
结合经典设计模式,实现代码结构优化,提升可维护性与可读性。
针对具体开发目标,定制化重构思路,满足业务需求与技术目标的双重要求。
自动生成优化后代码片段,帮助开发者直接应用,提高开发效率。
标注需要修改的关键部分,让代码优化过程更清晰、更直观。
加速技术决策,为复杂项目提供设计模式参考与实践指导。
帮助团队协作,创建更规范、更易维护的代码库。

如何使用购买的提示词模板

1. 直接在外部 Chat 应用中使用

将模板生成的提示词复制粘贴到您常用的 Chat 应用(如 ChatGPT、Claude 等),即可直接对话使用,无需额外开发。适合个人快速体验和轻量使用场景。

2. 发布为 API 接口调用

把提示词模板转化为 API,您的程序可任意修改模板参数,通过接口直接调用,轻松实现自动化与批量处理。适合开发者集成与业务系统嵌入。

3. 在 MCP Client 中配置使用

在 MCP client 中配置对应的 server 地址,让您的 AI 应用自动调用提示词模板。适合高级用户和团队协作,让提示词在不同 AI 工具间无缝衔接。

10积分 20积分
立减 50%
限时优惠还剩 00:00:00

您购买后可以获得什么

获得完整提示词模板
- 共 102 tokens
- 4 个可调节参数
{ 编程语言 } { 代码片段 } { 设计模式名称 } { 目标需求 }
自动加入"我的提示词库"
- 获得提示词优化器支持
- 版本化管理支持
获得社区共享的应用案例
限时免费

不要错过!

免费获取高级提示词-优惠即将到期

17
:
23
小时
:
59
分钟
:
59
摄影
免费 原价:20 限时
试用