第3章:识别代码中的设计问题与重构策略

第三章:识别代码中的设计问题与重构策略

在软件开发的长期演进过程中,代码库会逐渐积累各种设计问题,这些问题通常被称为"代码坏味道"。识别这些坏味道是重构的第一步,也是保持代码健康的关键。本章将详细分析22种常见的代码坏味道,为每种坏味道提供具体的商业项目实例,并展示如何在C++、C#和Java三种语言中识别和解决这些问题。

3.1 重复代码的识别与消除

重复代码是软件开发中最常见的问题之一。当相同的代码结构出现在多个地方时,任何修改都需要在多个位置进行,这不仅增加了工作量,也容易引入不一致性。

商业场景:电子商务系统的折扣计算

假设我们正在开发一个电子商务系统,其中折扣计算逻辑在多个地方重复出现。

C++ 示例:重复的折扣逻辑
#include <iostream>
#include <string>
#include <vector>

class ShoppingCart
{
private:
    std::vector<std::pair<std::string, double>> items;
    
public:
    void addItem(const std::string& productName, double price)
    {
        items.push_back(std::make_pair(productName, price));
    }
    
    // 重复的折扣计算逻辑 - 版本1
    double calculateVIPDiscount()
    {
        double total = 0.0;
        for (const auto& item : items)
        {
            total += item.second;
        }
        
        // VIP折扣逻辑
        double discount = 0.0;
        if (total > 1000.0)
        {
            discount = total * 0.2; // 20%折扣
        }
        else if (total > 500.0)
        {
            discount = total * 0.1; // 10%折扣
        }
        else
        {
            discount = total * 0.05; // 5%折扣
        }
        
        return total - discount;
    }
    
    // 重复的折扣计算逻辑 - 版本2
    double calculateSeasonalDiscount(const std::string& season)
    {
        double total = 0.0;
        for (const auto& item : items)
        {
            total += item.second;
        }
        
        // 季节性折扣逻辑(与VIP折扣逻辑相似)
        double discount = 0.0;
        if (total > 1000.0)
        {
            if (season == "Christmas")
            {
                discount = total * 0.25; // 25%折扣
            }
            else
            {
                discount = total * 0.2; // 20%折扣
            }
        }
        else if (total > 500.0)
        {
            discount = total * 0.1; // 10%折扣
        }
        else
        {
            discount = total * 0.05; // 5%折扣
        }
        
        return total - discount;
    }
};

// 重构后:提取公共逻辑
class DiscountCalculator
{
public:
    static double calculateBaseDiscount(double totalAmount)
    {
        if (totalAmount > 1000.0)
        {
            return 0.2; // 20%基础折扣率
        }
        else if (totalAmount > 500.0)
        {
            return 0.1; // 10%基础折扣率
        }
        else
        {
            return 0.05; // 5%基础折扣率
        }
    }
    
    static double calculateVIPDiscount(double totalAmount)
    {
        double baseRate = calculateBaseDiscount(totalAmount);
        return totalAmount * baseRate;
    }
    
    static double calculateSeasonalDiscount(double totalAmount, const std::string& season)
    {
        double baseRate = calculateBaseDiscount(totalAmount);
        
        // 季节性调整
        if (season == "Christmas" && totalAmount > 1000.0)
        {
            baseRate += 0.05; // 额外5%折扣
        }
        
        return totalAmount * baseRate;
    }
};

class RefactoredShoppingCart
{
private:
    std::vector<std::pair<std::string, double>> items;
    
    double calculateTotal()
    {
        double total = 0.0;
        for (const auto& item : items)
        {
            total += item.second;
        }
        return total;
    }
    
public:
    void addItem(const std::string& productName, double price)
    {
        items.push_back(std::make_pair(productName, price));
    }
    
    double calculateVIPDiscount()
    {
        double total = calculateTotal();
        double discount = DiscountCalculator::calculateVIPDiscount(total);
        return total - discount;
    }
    
    double calculateSeasonalDiscount(const std::string& season)
    {
        double total = calculateTotal();
        double discount = DiscountCalculator::calculateSeasonalDiscount(total, season);
        return total - discount;
    }
};

int main()
{
    // 使用重构前的代码
    ShoppingCart cart;
    cart.addItem("Laptop", 999.99);
    cart.addItem("Mouse", 49.99);
    
    std::cout << "VIP Discount Price: $" << cart.calculateVIPDiscount() << std::endl;
    std::cout << "Christmas Discount Price: $" << cart.calculateSeasonalDiscount("Christmas") << std::endl;
    
    // 使用重构后的代码
    RefactoredShoppingCart refactoredCart;
    refactoredCart.addItem("Laptop", 999.99);
    refactoredCart.addItem("Mouse", 49.99);
    
    std::cout << "\nRefactored VIP Discount Price: $" << refactoredCart.calculateVIPDiscount() << std::endl;
    std::cout << "Refactored Christmas Discount Price: $" << refactoredCart.calculateSeasonalDiscount("Christmas") << std::endl;
    
    return 0;
}
C# 示例:重复的验证逻辑
using System;
using System.Collections.Generic;

namespace ECommerceSystem
{
    // 重复代码示例:多个地方有相似的验证逻辑
    public class UserRegistrationService
    {
        public bool RegisterUser(string username, string email, string password)
        {
            // 用户名验证逻辑(在多个地方重复)
            if (string.IsNullOrEmpty(username))
            {
                throw new ArgumentException("Username cannot be empty");
            }
            if (username.Length < 3)
            {
                throw new ArgumentException("Username must be at least 3 characters");
            }
            if (username.Length > 50)
            {
                throw new ArgumentException("Username cannot exceed 50 characters");
            }
            
            // 邮箱验证逻辑(在多个地方重复)
            if (string.IsNullOrEmpty(email))
            {
                throw new ArgumentException("Email cannot be empty");
            }
            if (!email.Contains("@"))
            {
                throw new ArgumentException("Email must contain @ symbol");
            }
            if (email.Length > 100)
            {
                throw new ArgumentException("Email cannot exceed 100 characters");
            }
            
            // 密码验证逻辑(在多个地方重复)
            if (string.IsNullOrEmpty(password))
            {
                throw new ArgumentException("Password cannot be empty");
            }
            if (password.Length < 8)
            {
                throw new ArgumentException("Password must be at least 8 characters");
            }
            
            // 注册逻辑...
            return true;
        }
        
        public bool UpdateUserProfile(string userId, string newUsername, string newEmail)
        {
            // 重复的用户名验证逻辑
            if (string.IsNullOrEmpty(newUsername))
            {
                throw new ArgumentException("Username cannot be empty");
            }
            if (newUsername.Length < 3)
            {
                throw new ArgumentException("Username must be at least 3 characters");
            }
            if (newUsername.Length > 50)
            {
                throw new ArgumentException("Username cannot exceed 50 characters");
            }
            
            // 重复的邮箱验证逻辑
            if (string.IsNullOrEmpty(newEmail))
            {
                throw new ArgumentException("Email cannot be empty");
            }
            if (!newEmail.Contains("@"))
            {
                throw new ArgumentException("Email must contain @ symbol");
            }
            if (newEmail.Length > 100)
            {
                throw new ArgumentException("Email cannot exceed 100 characters");
            }
            
            // 更新逻辑...
            return true;
        }
    }
    
    // 重构后:提取验证逻辑到专用类
    public static class ValidationHelper
    {
        public static void ValidateUsername(string username)
        {
            if (string.IsNullOrEmpty(username))
            {
                throw new ArgumentException("Username cannot be empty");
            }
            if (username.Length < 3)
            {
                throw new ArgumentException("Username must be at least 3 characters");
            }
            if (username.Length > 50)
            {
                throw new ArgumentException("Username cannot exceed 50 characters");
            }
        }
        
        public static void ValidateEmail(string email)
        {
            if (string.IsNullOrEmpty(email))
            {
                throw new ArgumentException("Email cannot be empty");
            }
            if (!email.Contains("@"))
            {
                throw new ArgumentException("Email must contain @ symbol");
            }
            if (email.Length > 100)
            {
                throw new ArgumentException("Email cannot exceed 100 characters");
            }
        }
        
        public static void ValidatePassword(string password)
        {
            if (string.IsNullOrEmpty(password))
            {
                throw new ArgumentException("Password cannot be empty");
            }
            if (password.Length < 8)
            {
                throw new ArgumentException("Password must be at least 8 characters");
            }
        }
    }
    
    public class RefactoredUserRegistrationService
    {
        public bool RegisterUser(string username, string email, string password)
        {
            ValidationHelper.ValidateUsername(username);
            ValidationHelper.ValidateEmail(email);
            ValidationHelper.ValidatePassword(password);
            
            // 注册逻辑...
            return true;
        }
        
        public bool UpdateUserProfile(string userId, string newUsername, string newEmail)
        {
            ValidationHelper.ValidateUsername(newUsername);
            ValidationHelper.ValidateEmail(newEmail);
            
            // 更新逻辑...
            return true;
        }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                UserRegistrationService service = new UserRegistrationService();
                service.RegisterUser("john123", "john@example.com", "password123");
                Console.WriteLine("User registered successfully");
                
                RefactoredUserRegistrationService refactoredService = new RefactoredUserRegistrationService();
                refactoredService.RegisterUser("jane456", "jane@example.com", "password456");
                Console.WriteLine("User registered successfully (refactored)");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error: {ex.Message}");
            }
        }
    }
}

3.2 过长函数的识别与重构

过长函数通常包含太多职责,难以理解、测试和维护。一个函数应该只做一件事情,并且做好它。

商业场景:订单处理系统

Java 示例:复杂的订单处理函数
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

// 过长函数示例
class OrderProcessor {
    
    public void processOrder(Order order) {
        // 验证订单
        if (order == null) {
            System.out.println("Order is null");
            return;
        }
        
        if (order.getItems() == null || order.getItems().isEmpty()) {
            System.out.println("Order has no items");
            return;
        }
        
        // 验证库存
        for (OrderItem item : order.getItems()) {
            Product product = item.getProduct();
            if (product.getStockQuantity() < item.getQuantity()) {
                System.out.println("Insufficient stock for product: " + product.getName());
                return;
            }
        }
        
        // 计算价格
        double subtotal = 0;
        for (OrderItem item : order.getItems()) {
            subtotal += item.getProduct().getPrice() * item.getQuantity();
        }
        
        // 计算税金
        double taxRate = 0.08; // 8%税率
        double tax = subtotal * taxRate;
        
        // 计算运费
        double shippingCost = calculateShippingCost(order);
        
        // 应用折扣
        double discount = 0;
        if (order.getCustomer().isPremiumMember()) {
            discount = subtotal * 0.1; // 10%折扣
        }
        
        // 计算总额
        double total = subtotal + tax + shippingCost - discount;
        
        // 更新库存
        for (OrderItem item : order.getItems()) {
            Product product = item.getProduct();
            product.setStockQuantity(product.getStockQuantity() - item.getQuantity());
        }
        
        // 处理支付
        boolean paymentSuccess = processPayment(order.getCustomer(), total);
        if (!paymentSuccess) {
            System.out.println("Payment failed");
            return;
        }
        
        // 生成发票
        generateInvoice(order, subtotal, tax, shippingCost, discount, total);
        
        // 发送确认邮件
        sendConfirmationEmail(order.getCustomer(), order);
        
        // 更新订单状态
        order.setStatus("Completed");
        order.setProcessedDate(new Date());
        
        // 记录订单到数据库
        saveOrderToDatabase(order);
        
        System.out.println("Order processed successfully");
    }
    
    private double calculateShippingCost(Order order) {
        // 简化实现
        return 10.0;
    }
    
    private boolean processPayment(Customer customer, double amount) {
        // 简化实现
        return true;
    }
    
    private void generateInvoice(Order order, double subtotal, double tax, 
                                 double shipping, double discount, double total) {
        System.out.println("Generating invoice for order: " + order.getId());
    }
    
    private void sendConfirmationEmail(Customer customer, Order order) {
        System.out.println("Sending confirmation email to: " + customer.getEmail());
    }
    
    private void saveOrderToDatabase(Order order) {
        System.out.println("Saving order to database: " + order.getId());
    }
}

// 重构后:将长函数分解为多个小函数
class RefactoredOrderProcessor {
    
    private final InventoryManager inventoryManager;
    private final PaymentProcessor paymentProcessor;
    private final NotificationService notificationService;
    private final OrderRepository orderRepository;
    
    public RefactoredOrderProcessor() {
        this.inventoryManager = new InventoryManager();
        this.paymentProcessor = new PaymentProcessor();
        this.notificationService = new NotificationService();
        this.orderRepository = new OrderRepository();
    }
    
    public void processOrder(Order order) {
        if (!validateOrder(order)) {
            return;
        }
        
        if (!inventoryManager.checkStockAvailability(order)) {
            return;
        }
        
        OrderCalculationResult calculation = calculateOrderAmounts(order);
        
        if (!paymentProcessor.processPayment(order.getCustomer(), calculation.getTotal())) {
            return;
        }
        
        inventoryManager.updateStock(order);
        
        generateInvoice(order, calculation);
        
        notificationService.sendOrderConfirmation(order.getCustomer(), order);
        
        completeOrder(order);
        
        orderRepository.save(order);
        
        System.out.println("Order processed successfully");
    }
    
    private boolean validateOrder(Order order) {
        if (order == null) {
            System.out.println("Order is null");
            return false;
        }
        
        if (order.getItems() == null || order.getItems().isEmpty()) {
            System.out.println("Order has no items");
            return false;
        }
        
        return true;
    }
    
    private OrderCalculationResult calculateOrderAmounts(Order order) {
        double subtotal = calculateSubtotal(order);
        double tax = calculateTax(subtotal);
        double shippingCost = calculateShippingCost(order);
        double discount = calculateDiscount(order, subtotal);
        double total = subtotal + tax + shippingCost - discount;
        
        return new OrderCalculationResult(subtotal, tax, shippingCost, discount, total);
    }
    
    private double calculateSubtotal(Order order) {
        double subtotal = 0;
        for (OrderItem item : order.getItems()) {
            subtotal += item.getProduct().getPrice() * item.getQuantity();
        }
        return subtotal;
    }
    
    private double calculateTax(double subtotal) {
        double taxRate = 0.08;
        return subtotal * taxRate;
    }
    
    private double calculateShippingCost(Order order) {
        // 简化实现
        return 10.0;
    }
    
    private double calculateDiscount(Order order, double subtotal) {
        if (order.getCustomer().isPremiumMember()) {
            return subtotal * 0.1;
        }
        return 0;
    }
    
    private void generateInvoice(Order order, OrderCalculationResult calculation) {
        System.out.println("Generating invoice for order: " + order.getId());
        System.out.println("Subtotal: $" + calculation.getSubtotal());
        System.out.println("Tax: $" + calculation.getTax());
        System.out.println("Shipping: $" + calculation.getShippingCost());
        System.out.println("Discount: $" + calculation.getDiscount());
        System.out.println("Total: $" + calculation.getTotal());
    }
    
    private void completeOrder(Order order) {
        order.setStatus("Completed");
        order.setProcessedDate(new Date());
    }
}

// 辅助类
class OrderCalculationResult {
    private double subtotal;
    private double tax;
    private double shippingCost;
    private double discount;
    private double total;
    
    public OrderCalculationResult(double subtotal, double tax, double shippingCost, 
                                  double discount, double total) {
        this.subtotal = subtotal;
        this.tax = tax;
        this.shippingCost = shippingCost;
        this.discount = discount;
        this.total = total;
    }
    
    public double getSubtotal() { return subtotal; }
    public double getTax() { return tax; }
    public double getShippingCost() { return shippingCost; }
    public double getDiscount() { return discount; }
    public double getTotal() { return total; }
}

// 其他服务类(简化)
class InventoryManager {
    public boolean checkStockAvailability(Order order) {
        for (OrderItem item : order.getItems()) {
            Product product = item.getProduct();
            if (product.getStockQuantity() < item.getQuantity()) {
                System.out.println("Insufficient stock for product: " + product.getName());
                return false;
            }
        }
        return true;
    }
    
    public void updateStock(Order order) {
        for (OrderItem item : order.getItems()) {
            Product product = item.getProduct();
            product.setStockQuantity(product.getStockQuantity() - item.getQuantity());
        }
    }
}

class PaymentProcessor {
    public boolean processPayment(Customer customer, double amount) {
        // 简化实现
        return true;
    }
}

class NotificationService {
    public void sendOrderConfirmation(Customer customer, Order order) {
        System.out.println("Sending confirmation email to: " + customer.getEmail());
    }
}

class OrderRepository {
    public void save(Order order) {
        System.out.println("Saving order to database: " + order.getId());
    }
}

// 数据模型类
class Order {
    private String id;
    private Customer customer;
    private List<OrderItem> items;
    private String status;
    private Date processedDate;
    
    public Order(String id, Customer customer) {
        this.id = id;
        this.customer = customer;
        this.items = new ArrayList<>();
    }
    
    public void addItem(Product product, int quantity) {
        items.add(new OrderItem(product, quantity));
    }
    
    // Getter和Setter方法
    public String getId() { return id; }
    public Customer getCustomer() { return customer; }
    public List<OrderItem> getItems() { return items; }
    public String getStatus() { return status; }
    public void setStatus(String status) { this.status = status; }
    public Date getProcessedDate() { return processedDate; }
    public void setProcessedDate(Date processedDate) { this.processedDate = processedDate; }
}

class OrderItem {
    private Product product;
    private int quantity;
    
    public OrderItem(Product product, int quantity) {
        this.product = product;
        this.quantity = quantity;
    }
    
    public Product getProduct() { return product; }
    public int getQuantity() { return quantity; }
}

class Product {
    private String name;
    private double price;
    private int stockQuantity;
    
    public Product(String name, double price, int stockQuantity) {
        this.name = name;
        this.price = price;
        this.stockQuantity = stockQuantity;
    }
    
    public String getName() { return name; }
    public double getPrice() { return price; }
    public int getStockQuantity() { return stockQuantity; }
    public void setStockQuantity(int stockQuantity) { this.stockQuantity = stockQuantity; }
}

class Customer {
    private String email;
    private boolean premiumMember;
    
    public Customer(String email, boolean premiumMember) {
        this.email = email;
        this.premiumMember = premiumMember;
    }
    
    public String getEmail() { return email; }
    public boolean isPremiumMember() { return premiumMember; }
}

public class Main {
    public static void main(String[] args) {
        // 创建测试数据
        Customer customer = new Customer("john@example.com", true);
        Order order = new Order("ORD001", customer);
        
        Product laptop = new Product("Laptop", 999.99, 10);
        Product mouse = new Product("Mouse", 49.99, 50);
        
        order.addItem(laptop, 1);
        order.addItem(mouse, 2);
        
        // 使用重构前的处理器
        OrderProcessor processor = new OrderProcessor();
        System.out.println("Processing order with original processor:");
        processor.processOrder(order);
        
        System.out.println("\n---\n");
        
        // 使用重构后的处理器
        RefactoredOrderProcessor refactoredProcessor = new RefactoredOrderProcessor();
        System.out.println("Processing order with refactored processor:");
        refactoredProcessor.processOrder(order);
    }
}

3.3 过大类的识别与重构

当一个类试图做太多事情时,它会变得难以理解和维护。过大的类通常有太多的字段和方法,违反了单一职责原则。

商业场景:客户关系管理系统

C++ 示例:包含太多职责的Customer类
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <memory>

// 过大的类示例:Customer类承担了太多职责
class Customer
{
private:
    // 个人信息
    std::string id;
    std::string name;
    std::string email;
    std::string phone;
    std::string address;
    std::string city;
    std::string state;
    std::string zipCode;
    std::string country;
    
    // 账户信息
    std::string accountNumber;
    double accountBalance;
    std::string accountType;
    std::string currency;
    
    // 订单历史
    std::vector<std::string> orderIds;
    std::map<std::string, double> orderAmounts;
    
    // 支付信息
    std::vector<std::string> paymentMethods;
    std::map<std::string, std::string> paymentDetails;
    
    // 服务历史
    std::vector<std::string> serviceTickets;
    std::map<std::string, std::string> serviceHistory;
    
    // 偏好设置
    std::map<std::string, std::string> preferences;
    std::vector<std::string> favoriteProducts;
    
public:
    Customer(const std::string& customerId, const std::string& customerName)
        : id(customerId), name(customerName), accountBalance(0.0) {}
    
    // 个人信息相关方法
    void updatePersonalInfo(const std::string& newEmail, const std::string& newPhone,
                           const std::string& newAddress, const std::string& newCity,
                           const std::string& newState, const std::string& newZip,
                           const std::string& newCountry)
    {
        email = newEmail;
        phone = newPhone;
        address = newAddress;
        city = newCity;
        state = newState;
        zipCode = newZip;
        country = newCountry;
    }
    
    std::string getFullAddress() const
    {
        return address + ", " + city + ", " + state + " " + zipCode + ", " + country;
    }
    
    // 账户相关方法
    void createAccount(const std::string& accNumber, const std::string& accType,
                      const std::string& curr)
    {
        accountNumber = accNumber;
        accountType = accType;
        currency = curr;
    }
    
    void deposit(double amount)
    {
        accountBalance += amount;
    }
    
    bool withdraw(double amount)
    {
        if (amount <= accountBalance)
        {
            accountBalance -= amount;
            return true;
        }
        return false;
    }
    
    double getAccountBalance() const
    {
        return accountBalance;
    }
    
    // 订单相关方法
    void addOrder(const std::string& orderId, double amount)
    {
        orderIds.push_back(orderId);
        orderAmounts[orderId] = amount;
    }
    
    double getTotalSpent() const
    {
        double total = 0.0;
        for (const auto& pair : orderAmounts)
        {
            total += pair.second;
        }
        return total;
    }
    
    // 支付相关方法
    void addPaymentMethod(const std::string& method, const std::string& details)
    {
        paymentMethods.push_back(method);
        paymentDetails[method] = details;
    }
    
    // 服务相关方法
    void createServiceTicket(const std::string& ticketId, const std::string& description)
    {
        serviceTickets.push_back(ticketId);
        serviceHistory[ticketId] = description;
    }
    
    // 偏好相关方法
    void setPreference(const std::string& key, const std::string& value)
    {
        preferences[key] = value;
    }
    
    void addFavoriteProduct(const std::string& productId)
    {
        favoriteProducts.push_back(productId);
    }
    
    // 太多其他方法...
    // 这个类已经变得太大,承担了太多职责
};

// 重构后:将大类分解为多个小类
class PersonalInfo
{
private:
    std::string id;
    std::string name;
    std::string email;
    std::string phone;
    std::string address;
    std::string city;
    std::string state;
    std::string zipCode;
    std::string country;
    
public:
    PersonalInfo(const std::string& customerId, const std::string& customerName)
        : id(customerId), name(customerName) {}
    
    void updateInfo(const std::string& newEmail, const std::string& newPhone,
                   const std::string& newAddress, const std::string& newCity,
                   const std::string& newState, const std::string& newZip,
                   const std::string& newCountry)
    {
        email = newEmail;
        phone = newPhone;
        address = newAddress;
        city = newCity;
        state = newState;
        zipCode = newZip;
        country = newCountry;
    }
    
    std::string getFullAddress() const
    {
        return address + ", " + city + ", " + state + " " + zipCode + ", " + country;
    }
    
    std::string getId() const { return id; }
    std::string getName() const { return name; }
    std::string getEmail() const { return email; }
    std::string getPhone() const { return phone; }
};

class CustomerAccount
{
private:
    std::string accountNumber;
    double balance;
    std::string accountType;
    std::string currency;
    
public:
    CustomerAccount(const std::string& accNumber, const std::string& accType,
                   const std::string& curr)
        : accountNumber(accNumber), balance(0.0), accountType(accType), currency(curr) {}
    
    void deposit(double amount)
    {
        balance += amount;
    }
    
    bool withdraw(double amount)
    {
        if (amount <= balance)
        {
            balance -= amount;
            return true;
        }
        return false;
    }
    
    double getBalance() const
    {
        return balance;
    }
    
    std::string getAccountNumber() const { return accountNumber; }
    std::string getAccountType() const { return accountType; }
};

class OrderHistory
{
private:
    std::vector<std::string> orderIds;
    std::map<std::string, double> orderAmounts;
    
public:
    void addOrder(const std::string& orderId, double amount)
    {
        orderIds.push_back(orderId);
        orderAmounts[orderId] = amount;
    }
    
    double getTotalSpent() const
    {
        double total = 0.0;
        for (const auto& pair : orderAmounts)
        {
            total += pair.second;
        }
        return total;
    }
    
    int getOrderCount() const
    {
        return orderIds.size();
    }
    
    const std::vector<std::string>& getOrderIds() const
    {
        return orderIds;
    }
};

class PaymentManager
{
private:
    std::vector<std::string> paymentMethods;
    std::map<std::string, std::string> paymentDetails;
    
public:
    void addPaymentMethod(const std::string& method, const std::string& details)
    {
        paymentMethods.push_back(method);
        paymentDetails[method] = details;
    }
    
    bool hasPaymentMethod(const std::string& method) const
    {
        for (const auto& m : paymentMethods)
        {
            if (m == method)
            {
                return true;
            }
        }
        return false;
    }
    
    std::string getPaymentDetails(const std::string& method) const
    {
        auto it = paymentDetails.find(method);
        if (it != paymentDetails.end())
        {
            return it->second;
        }
        return "";
    }
};

class CustomerPreferences
{
private:
    std::map<std::string, std::string> preferences;
    std::vector<std::string> favoriteProducts;
    
public:
    void setPreference(const std::string& key, const std::string& value)
    {
        preferences[key] = value;
    }
    
    std::string getPreference(const std::string& key) const
    {
        auto it = preferences.find(key);
        if (it != preferences.end())
        {
            return it->second;
        }
        return "";
    }
    
    void addFavoriteProduct(const std::string& productId)
    {
        favoriteProducts.push_back(productId);
    }
    
    const std::vector<std::string>& getFavoriteProducts() const
    {
        return favoriteProducts;
    }
};

// 重构后的Customer类
class RefactoredCustomer
{
private:
    std::shared_ptr<PersonalInfo> personalInfo;
    std::shared_ptr<CustomerAccount> account;
    std::shared_ptr<OrderHistory> orderHistory;
    std::shared_ptr<PaymentManager> paymentManager;
    std::shared_ptr<CustomerPreferences> preferences;
    
public:
    RefactoredCustomer(const std::string& customerId, const std::string& customerName)
    {
        personalInfo = std::make_shared<PersonalInfo>(customerId, customerName);
        orderHistory = std::make_shared<OrderHistory>();
        paymentManager = std::make_shared<PaymentManager>();
        preferences = std::make_shared<CustomerPreferences>();
    }
    
    // 个人信息访问
    std::shared_ptr<PersonalInfo> getPersonalInfo()
    {
        return personalInfo;
    }
    
    // 账户管理
    void createAccount(const std::string& accNumber, const std::string& accType,
                      const std::string& currency)
    {
        account = std::make_shared<CustomerAccount>(accNumber, accType, currency);
    }
    
    std::shared_ptr<CustomerAccount> getAccount()
    {
        return account;
    }
    
    // 订单历史访问
    std::shared_ptr<OrderHistory> getOrderHistory()
    {
        return orderHistory;
    }
    
    // 支付管理访问
    std::shared_ptr<PaymentManager> getPaymentManager()
    {
        return paymentManager;
    }
    
    // 偏好设置访问
    std::shared_ptr<CustomerPreferences> getPreferences()
    {
        return preferences;
    }
    
    // 综合方法
    std::string getCustomerSummary() const
    {
        std::string summary = "Customer: " + personalInfo->getName() + "\n";
        summary += "Email: " + personalInfo->getEmail() + "\n";
        
        if (account)
        {
            summary += "Account Balance: $" + std::to_string(account->getBalance()) + "\n";
        }
        
        summary += "Total Orders: " + std::to_string(orderHistory->getOrderCount()) + "\n";
        summary += "Total Spent: $" + std::to_string(orderHistory->getTotalSpent()) + "\n";
        
        return summary;
    }
};

int main()
{
    // 使用重构前的过大类
    Customer oldCustomer("CUST001", "John Doe");
    oldCustomer.updatePersonalInfo("john@example.com", "123-456-7890", 
                                  "123 Main St", "Anytown", "CA", "12345", "USA");
    oldCustomer.createAccount("ACC001", "Checking", "USD");
    oldCustomer.deposit(1000.0);
    oldCustomer.addOrder("ORD001", 299.99);
    oldCustomer.addOrder("ORD002", 149.99);
    
    std::cout << "Old Customer Total Spent: $" << oldCustomer.getTotalSpent() << std::endl;
    std::cout << "Old Customer Balance: $" << oldCustomer.getAccountBalance() << std::endl;
    
    // 使用重构后的类
    RefactoredCustomer newCustomer("CUST002", "Jane Smith");
    newCustomer.getPersonalInfo()->updateInfo("jane@example.com", "987-654-3210",
                                             "456 Oak St", "Othertown", "NY", "54321", "USA");
    newCustomer.createAccount("ACC002", "Savings", "USD");
    newCustomer.getAccount()->deposit(2000.0);
    newCustomer.getOrderHistory()->addOrder("ORD003", 499.99);
    newCustomer.getOrderHistory()->addOrder("ORD004", 199.99);
    
    std::cout << "\nNew Customer Summary:\n" << newCustomer.getCustomerSummary() << std::endl;
    
    return 0;
}

3.4 过长参数列的识别与重构

当一个函数需要太多参数时,调用它会变得困难,而且难以理解每个参数的作用。过长参数列通常表示这些参数应该被组织成一个对象。

商业场景:用户注册系统

C# 示例:包含太多参数的注册函数
using System;

namespace UserRegistrationSystem
{
    // 过长参数列示例
    public class UserService
    {
        // 这个函数有太多参数,难以理解和使用
        public bool RegisterUser(
            string username,
            string email,
            string password,
            string firstName,
            string lastName,
            DateTime dateOfBirth,
            string phoneNumber,
            string addressLine1,
            string addressLine2,
            string city,
            string state,
            string zipCode,
            string country,
            bool acceptTerms,
            bool subscribeToNewsletter,
            string referralCode,
            string securityQuestion1,
            string securityAnswer1,
            string securityQuestion2,
            string securityAnswer2)
        {
            // 参数验证
            if (string.IsNullOrEmpty(username))
                throw new ArgumentException("Username is required");
            
            if (string.IsNullOrEmpty(email))
                throw new ArgumentException("Email is required");
            
            if (string.IsNullOrEmpty(password))
                throw new ArgumentException("Password is required");
            
            // 更多验证...
            
            // 用户注册逻辑
            Console.WriteLine($"Registering user: {username}");
            Console.WriteLine($"Email: {email}");
            Console.WriteLine($"Address: {addressLine1}, {city}, {state} {zipCode}");
            
            // 保存到数据库等操作...
            
            return true;
        }
        
        // 更新用户信息的函数也有同样的问题
        public bool UpdateUserProfile(
            string userId,
            string newEmail,
            string newPhoneNumber,
            string newAddressLine1,
            string newAddressLine2,
            string newCity,
            string newState,
            string newZipCode,
            string newCountry,
            bool changePassword,
            string newPassword,
            string newSecurityQuestion1,
            string newSecurityAnswer1)
        {
            // 参数验证和更新逻辑...
            return true;
        }
    }
    
    // 重构后:使用参数对象
    public class UserRegistrationData
    {
        public string Username { get; set; }
        public string Email { get; set; }
        public string Password { get; set; }
        
        // 个人信息
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime DateOfBirth { get; set; }
        public string PhoneNumber { get; set; }
        
        // 地址信息
        public string AddressLine1 { get; set; }
        public string AddressLine2 { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string ZipCode { get; set; }
        public string Country { get; set; }
        
        // 偏好设置
        public bool AcceptTerms { get; set; }
        public bool SubscribeToNewsletter { get; set; }
        public string ReferralCode { get; set; }
        
        // 安全信息
        public string SecurityQuestion1 { get; set; }
        public string SecurityAnswer1 { get; set; }
        public string SecurityQuestion2 { get; set; }
        public string SecurityAnswer2 { get; set; }
        
        public UserRegistrationData()
        {
            DateOfBirth = DateTime.MinValue;
        }
        
        public bool Validate()
        {
            if (string.IsNullOrEmpty(Username))
                throw new ArgumentException("Username is required");
            
            if (string.IsNullOrEmpty(Email))
                throw new ArgumentException("Email is required");
            
            if (string.IsNullOrEmpty(Password))
                throw new ArgumentException("Password is required");
            
            if (!AcceptTerms)
                throw new ArgumentException("Terms must be accepted");
            
            return true;
        }
    }
    
    public class UserProfileUpdateData
    {
        public string UserId { get; set; }
        public string NewEmail { get; set; }
        public string NewPhoneNumber { get; set; }
        
        // 地址更新
        public string NewAddressLine1 { get; set; }
        public string NewAddressLine2 { get; set; }
        public string NewCity { get; set; }
        public string NewState { get; set; }
        public string NewZipCode { get; set; }
        public string NewCountry { get; set; }
        
        // 密码更新
        public bool ChangePassword { get; set; }
        public string NewPassword { get; set; }
        
        // 安全信息更新
        public string NewSecurityQuestion1 { get; set; }
        public string NewSecurityAnswer1 { get; set; }
        
        public bool Validate()
        {
            if (string.IsNullOrEmpty(UserId))
                throw new ArgumentException("User ID is required");
            
            return true;
        }
    }
    
    public class RefactoredUserService
    {
        public bool RegisterUser(UserRegistrationData registrationData)
        {
            // 验证数据
            registrationData.Validate();
            
            // 用户注册逻辑
            Console.WriteLine($"Registering user: {registrationData.Username}");
            Console.WriteLine($"Email: {registrationData.Email}");
            Console.WriteLine($"Address: {registrationData.AddressLine1}, {registrationData.City}, " +
                            $"{registrationData.State} {registrationData.ZipCode}");
            
            // 保存到数据库等操作...
            
            return true;
        }
        
        public bool UpdateUserProfile(UserProfileUpdateData updateData)
        {
            // 验证数据
            updateData.Validate();
            
            // 更新逻辑...
            Console.WriteLine($"Updating profile for user: {updateData.UserId}");
            
            return true;
        }
        
        // 便捷方法:创建用户注册数据
        public UserRegistrationData CreateRegistrationData(string username, string email, 
                                                          string password, string firstName, 
                                                          string lastName)
        {
            return new UserRegistrationData
            {
                Username = username,
                Email = email,
                Password = password,
                FirstName = firstName,
                LastName = lastName,
                AcceptTerms = true
            };
        }
    }
    
    // 建造者模式进一步优化
    public class UserRegistrationDataBuilder
    {
        private UserRegistrationData data;
        
        public UserRegistrationDataBuilder(string username, string email, string password)
        {
            data = new UserRegistrationData
            {
                Username = username,
                Email = email,
                Password = password
            };
        }
        
        public UserRegistrationDataBuilder WithPersonalInfo(string firstName, string lastName, 
                                                           DateTime dateOfBirth, string phoneNumber)
        {
            data.FirstName = firstName;
            data.LastName = lastName;
            data.DateOfBirth = dateOfBirth;
            data.PhoneNumber = phoneNumber;
            return this;
        }
        
        public UserRegistrationDataBuilder WithAddress(string addressLine1, string city, 
                                                      string state, string zipCode, string country)
        {
            data.AddressLine1 = addressLine1;
            data.City = city;
            data.State = state;
            data.ZipCode = zipCode;
            data.Country = country;
            return this;
        }
        
        public UserRegistrationDataBuilder WithPreferences(bool acceptTerms, 
                                                          bool subscribeToNewsletter)
        {
            data.AcceptTerms = acceptTerms;
            data.SubscribeToNewsletter = subscribeToNewsletter;
            return this;
        }
        
        public UserRegistrationDataBuilder WithSecurityInfo(string question1, string answer1, 
                                                           string question2, string answer2)
        {
            data.SecurityQuestion1 = question1;
            data.SecurityAnswer1 = answer1;
            data.SecurityQuestion2 = question2;
            data.SecurityAnswer2 = answer2;
            return this;
        }
        
        public UserRegistrationData Build()
        {
            return data;
        }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            // 使用重构前的服务(参数过多,难以使用)
            UserService oldService = new UserService();
            
            try
            {
                bool result = oldService.RegisterUser(
                    "johndoe",
                    "john@example.com",
                    "password123",
                    "John",
                    "Doe",
                    new DateTime(1990, 1, 1),
                    "123-456-7890",
                    "123 Main St",
                    "",
                    "Anytown",
                    "CA",
                    "12345",
                    "USA",
                    true,
                    true,
                    "REF123",
                    "What is your pet's name?",
                    "Fluffy",
                    "What is your mother's maiden name?",
                    "Smith");
                
                Console.WriteLine($"Registration result: {result}");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error: {ex.Message}");
            }
            
            Console.WriteLine("\n---\n");
            
            // 使用重构后的服务
            RefactoredUserService newService = new RefactoredUserService();
            
            // 方法1:直接创建参数对象
            UserRegistrationData registrationData = new UserRegistrationData
            {
                Username = "janedoe",
                Email = "jane@example.com",
                Password = "password456",
                FirstName = "Jane",
                LastName = "Doe",
                PhoneNumber = "987-654-3210",
                AddressLine1 = "456 Oak St",
                City = "Othertown",
                State = "NY",
                ZipCode = "54321",
                Country = "USA",
                AcceptTerms = true,
                SubscribeToNewsletter = false
            };
            
            bool newResult = newService.RegisterUser(registrationData);
            Console.WriteLine($"Refactored registration result: {newResult}");
            
            Console.WriteLine("\n---\n");
            
            // 方法2:使用建造者模式
            UserRegistrationDataBuilder builder = new UserRegistrationDataBuilder(
                "bobsmith", "bob@example.com", "password789");
            
            UserRegistrationData builtData = builder
                .WithPersonalInfo("Bob", "Smith", new DateTime(1985, 5, 15), "555-123-4567")
                .WithAddress("789 Pine St", "Sometown", "TX", "67890", "USA")
                .WithPreferences(true, true)
                .Build();
            
            newResult = newService.RegisterUser(builtData);
            Console.WriteLine($"Builder pattern registration result: {newResult}");
        }
    }
}

3.5 发散式变化的识别与重构

发散式变化是指一个类因为不同的原因在不同的方向上发生变化。这意味着这个类有多个职责,当某个职责的需求变化时,就需要修改这个类。

商业场景:报告生成系统

Java 示例:承担多种报告职责的Report类
import java.util.Date;
import java.util.List;
import java.util.ArrayList;

// 发散式变化示例:Report类因为多种原因需要修改
class Report {
    private String title;
    private Date generationDate;
    private List<ReportData> data;
    private ReportFormat format;
    private String author;
    
    public Report(String title, List<ReportData> data, ReportFormat format, String author) {
        this.title = title;
        this.generationDate = new Date();
        this.data = data;
        this.format = format;
        this.author = author;
    }
    
    // 问题:这个类因为多个原因需要修改:
    // 1. 当报告内容变化时(如添加新的数据字段)
    // 2. 当报告格式变化时(如支持新的输出格式)
    // 3. 当报告分发方式变化时(如添加新的分发渠道)
    // 4. 当报告安全要求变化时(如添加加密)
    
    // 生成报告内容
    public String generateContent() {
        StringBuilder content = new StringBuilder();
        content.append("Report: ").append(title).append("\n");
        content.append("Generated on: ").append(generationDate).append("\n");
        content.append("Author: ").append(author).append("\n\n");
        
        for (ReportData item : data) {
            content.append(item.getName()).append(": ").append(item.getValue()).append("\n");
        }
        
        return content.toString();
    }
    
    // 格式化报告(HTML格式)
    public String formatAsHtml() {
        String content = generateContent();
        StringBuilder html = new StringBuilder();
        html.append("<html><head><title>").append(title).append("</title></head><body>");
        html.append("<h1>").append(title).append("</h1>");
        html.append("<p>Generated on: ").append(generationDate).append("</p>");
        html.append("<p>Author: ").append(author).append("</p>");
        html.append("<table border='1'>");
        html.append("<tr><th>Name</th><th>Value</th></tr>");
        
        for (ReportData item : data) {
            html.append("<tr>");
            html.append("<td>").append(item.getName()).append("</td>");
            html.append("<td>").append(item.getValue()).append("</td>");
            html.append("</tr>");
        }
        
        html.append("</table></body></html>");
        return html.toString();
    }
    
    // 格式化报告(CSV格式)
    public String formatAsCsv() {
        StringBuilder csv = new StringBuilder();
        csv.append("Report,").append(title).append("\n");
        csv.append("Generated on,").append(generationDate).append("\n");
        csv.append("Author,").append(author).append("\n\n");
        csv.append("Name,Value\n");
        
        for (ReportData item : data) {
            csv.append(item.getName()).append(",").append(item.getValue()).append("\n");
        }
        
        return csv.toString();
    }
    
    // 保存报告到文件
    public void saveToFile(String filename) {
        String content = "";
        if (format == ReportFormat.HTML) {
            content = formatAsHtml();
        } else if (format == ReportFormat.CSV) {
            content = formatAsCsv();
        } else {
            content = generateContent();
        }
        
        // 保存文件逻辑
        System.out.println("Saving report to file: " + filename);
        System.out.println("Content length: " + content.length() + " characters");
    }
    
    // 发送报告邮件
    public void sendByEmail(String recipient) {
        String subject = "Report: " + title;
        String body = generateContent();
        
        // 发送邮件逻辑
        System.out.println("Sending report to: " + recipient);
        System.out.println("Subject: " + subject);
        System.out.println("Body length: " + body.length() + " characters");
    }
    
    // 加密报告
    public String encryptReport() {
        String content = generateContent();
        // 简单的加密逻辑(示例)
        StringBuilder encrypted = new StringBuilder();
        for (char c : content.toCharArray()) {
            encrypted.append((char)(c + 1)); // 简单的字符偏移加密
        }
        return encrypted.toString();
    }
    
    // 解密报告
    public String decryptReport(String encryptedContent) {
        StringBuilder decrypted = new StringBuilder();
        for (char c : encryptedContent.toCharArray()) {
            decrypted.append((char)(c - 1)); // 解密
        }
        return decrypted.toString();
    }
}

enum ReportFormat {
    PLAIN_TEXT,
    HTML,
    CSV
}

class ReportData {
    private String name;
    private String value;
    
    public ReportData(String name, String value) {
        this.name = name;
        this.value = value;
    }
    
    public String getName() { return name; }
    public String getValue() { return value; }
}

// 重构后:将不同的职责分离到不同的类中
// 1. 报告内容生成器
class ReportContentGenerator {
    private String title;
    private Date generationDate;
    private List<ReportData> data;
    private String author;
    
    public ReportContentGenerator(String title, List<ReportData> data, String author) {
        this.title = title;
        this.generationDate = new Date();
        this.data = data;
        this.author = author;
    }
    
    public String generatePlainText() {
        StringBuilder content = new StringBuilder();
        content.append("Report: ").append(title).append("\n");
        content.append("Generated on: ").append(generationDate).append("\n");
        content.append("Author: ").append(author).append("\n\n");
        
        for (ReportData item : data) {
            content.append(item.getName()).append(": ").append(item.getValue()).append("\n");
        }
        
        return content.toString();
    }
    
    // 可以添加更多内容生成方法,但只负责内容生成
    public String generateWithCustomTemplate(String template) {
        // 使用模板生成内容
        return template.replace("{title}", title)
                      .replace("{date}", generationDate.toString())
                      .replace("{author}", author);
    }
}

// 2. 报告格式化器
interface ReportFormatter {
    String format(String content);
}

class HtmlReportFormatter implements ReportFormatter {
    @Override
    public String format(String content) {
        // 简化实现:实际中会将内容转换为HTML
        return "<html><body><pre>" + content + "</pre></body></html>";
    }
}

class CsvReportFormatter implements ReportFormatter {
    @Override
    public String format(String content) {
        // 简化实现:将内容转换为CSV格式
        String[] lines = content.split("\n");
        StringBuilder csv = new StringBuilder();
        for (String line : lines) {
            // 简单的转换逻辑
            csv.append(line.replace(": ", ",")).append("\n");
        }
        return csv.toString();
    }
}

class PdfReportFormatter implements ReportFormatter {
    @Override
    public String format(String content) {
        // 模拟PDF格式(实际会使用PDF库)
        return "PDF Content:\n" + content;
    }
}

// 3. 报告分发器
interface ReportDistributor {
    void distribute(String content, String destination);
}

class EmailReportDistributor implements ReportDistributor {
    @Override
    public void distribute(String content, String destination) {
        System.out.println("Sending report via email to: " + destination);
        System.out.println("Content length: " + content.length() + " characters");
    }
}

class FileReportDistributor implements ReportDistributor {
    @Override
    public void distribute(String content, String destination) {
        System.out.println("Saving report to file: " + destination);
        System.out.println("Content length: " + content.length() + " characters");
    }
}

class CloudStorageReportDistributor implements ReportDistributor {
    @Override
    public void distribute(String content, String destination) {
        System.out.println("Uploading report to cloud storage: " + destination);
        System.out.println("Content length: " + content.length() + " characters");
    }
}

// 4. 报告加密器
interface ReportEncryptor {
    String encrypt(String content);
    String decrypt(String encryptedContent);
}

class SimpleReportEncryptor implements ReportEncryptor {
    @Override
    public String encrypt(String content) {
        StringBuilder encrypted = new StringBuilder();
        for (char c : content.toCharArray()) {
            encrypted.append((char)(c + 1));
        }
        return encrypted.toString();
    }
    
    @Override
    public String decrypt(String encryptedContent) {
        StringBuilder decrypted = new StringBuilder();
        for (char c : encryptedContent.toCharArray()) {
            decrypted.append((char)(c - 1));
        }
        return decrypted.toString();
    }
}

// 5. 重构后的Report类(协调者)
class RefactoredReport {
    private ReportContentGenerator contentGenerator;
    private ReportFormatter formatter;
    private ReportDistributor distributor;
    private ReportEncryptor encryptor;
    
    public RefactoredReport(ReportContentGenerator contentGenerator) {
        this.contentGenerator = contentGenerator;
    }
    
    public void setFormatter(ReportFormatter formatter) {
        this.formatter = formatter;
    }
    
    public void setDistributor(ReportDistributor distributor) {
        this.distributor = distributor;
    }
    
    public void setEncryptor(ReportEncryptor encryptor) {
        this.encryptor = encryptor;
    }
    
    public String generateReport() {
        String content = contentGenerator.generatePlainText();
        
        if (formatter != null) {
            content = formatter.format(content);
        }
        
        if (encryptor != null) {
            content = encryptor.encrypt(content);
        }
        
        return content;
    }
    
    public void distributeReport(String destination) {
        String report = generateReport();
        
        if (distributor != null) {
            distributor.distribute(report, destination);
        } else {
            System.out.println("No distributor set. Report generated but not distributed.");
            System.out.println("Report content (first 100 chars): " + 
                             report.substring(0, Math.min(100, report.length())));
        }
    }
}

public class ReportSystemExample {
    public static void main(String[] args) {
        // 准备测试数据
        List<ReportData> data = new ArrayList<>();
        data.add(new ReportData("Sales Q1", "$100,000"));
        data.add(new ReportData("Sales Q2", "$120,000"));
        data.add(new ReportData("Sales Q3", "$150,000"));
        data.add(new ReportData("Sales Q4", "$180,000"));
        
        System.out.println("=== 使用重构前的Report类 ===");
        Report oldReport = new Report("Annual Sales Report", data, ReportFormat.HTML, "John Doe");
        oldReport.saveToFile("report.html");
        oldReport.sendByEmail("manager@example.com");
        
        System.out.println("\n=== 使用重构后的Report类 ===");
        
        // 创建内容生成器
        ReportContentGenerator contentGenerator = 
            new ReportContentGenerator("Annual Sales Report", data, "Jane Smith");
        
        // 创建报告对象
        RefactoredReport newReport = new RefactoredReport(contentGenerator);
        
        // 配置报告:HTML格式 + 邮件分发
        newReport.setFormatter(new HtmlReportFormatter());
        newReport.setDistributor(new EmailReportDistributor());
        
        // 生成并分发报告
        newReport.distributeReport("ceo@example.com");
        
        System.out.println("\n--- 配置变更:CSV格式 + 文件保存 ---");
        // 改变配置:CSV格式 + 文件保存
        newReport.setFormatter(new CsvReportFormatter());
        newReport.setDistributor(new FileReportDistributor());
        newReport.setEncryptor(new SimpleReportEncryptor());
        
        // 生成并分发报告
        newReport.distributeReport("sales_report.csv");
        
        System.out.println("\n--- 配置变更:PDF格式 + 云存储 ---");
        // 改变配置:PDF格式 + 云存储
        newReport.setFormatter(new PdfReportFormatter());
        newReport.setDistributor(new CloudStorageReportDistributor());
        newReport.setEncryptor(null); // 不加密
        
        // 生成并分发报告
        newReport.distributeReport("cloud://reports/sales.pdf");
    }
}

3.6 霰弹式修改的识别与重构

霰弹式修改是指当需要对系统进行一个修改时,需要在多个类中进行小修改。这与发散式变化相反,发散式变化是一个类因为多个原因需要修改,而霰弹式修改是一个修改需要影响多个类。

商业场景:价格计算系统

C++ 示例:价格计算逻辑分散在多个类中
#include <iostream>
#include <string>
#include <vector>
#include <memory>

// 霰弹式修改示例:价格计算逻辑分散在多个类中
// 当价格计算规则变化时,需要修改多个类

class Product
{
private:
    std::string name;
    double basePrice;
    
public:
    Product(const std::string& productName, double price)
        : name(productName), basePrice(price) {}
    
    // 价格计算方法1:在Product类中
    double calculatePriceWithTax(double taxRate)
    {
        return basePrice * (1 + taxRate);
    }
    
    std::string getName() const { return name; }
    double getBasePrice() const { return basePrice; }
};

class OrderItem
{
private:
    std::shared_ptr<Product> product;
    int quantity;
    
public:
    OrderItem(std::shared_ptr<Product> prod, int qty)
        : product(prod), quantity(qty) {}
    
    // 价格计算方法2:在OrderItem类中
    double calculateItemTotal(double discountRate)
    {
        double price = product->getBasePrice();
        double discountedPrice = price * (1 - discountRate);
        return discountedPrice * quantity;
    }
    
    std::shared_ptr<Product> getProduct() const { return product; }
    int getQuantity() const { return quantity; }
};

class ShoppingCart
{
private:
    std::vector<std::shared_ptr<OrderItem>> items;
    std::string customerType; // "Regular", "VIP", "Wholesale"
    
public:
    ShoppingCart(const std::string& type) : customerType(type) {}
    
    void addItem(std::shared_ptr<OrderItem> item)
    {
        items.push_back(item);
    }
    
    // 价格计算方法3:在ShoppingCart类中
    double calculateCartTotal()
    {
        double total = 0.0;
        
        for (const auto& item : items)
        {
            double discountRate = 0.0;
            
            // 根据客户类型应用折扣
            if (customerType == "VIP")
            {
                discountRate = 0.15; // VIP客户15%折扣
            }
            else if (customerType == "Wholesale")
            {
                discountRate = 0.25; // 批发客户25%折扣
            }
            else
            {
                discountRate = 0.05; // 普通客户5%折扣
            }
            
            total += item->calculateItemTotal(discountRate);
        }
        
        // 购物车总额折扣(满减)
        if (total > 1000.0)
        {
            total -= 50.0; // 满1000减50
        }
        else if (total > 500.0)
        {
            total -= 20.0; // 满500减20
        }
        
        return total;
    }
};

class Invoice
{
private:
    std::shared_ptr<ShoppingCart> cart;
    double taxRate;
    
public:
    Invoice(std::shared_ptr<ShoppingCart> shoppingCart, double rate)
        : cart(shoppingCart), taxRate(rate) {}
    
    // 价格计算方法4:在Invoice类中
    double calculateFinalAmount()
    {
        double subtotal = cart->calculateCartTotal();
        double tax = subtotal * taxRate;
        double shipping = calculateShipping(subtotal);
        
        return subtotal + tax + shipping;
    }
    
private:
    double calculateShipping(double amount)
    {
        if (amount > 500.0)
        {
            return 0.0; // 免运费
        }
        else if (amount > 200.0)
        {
            return 10.0; // 运费10元
        }
        else
        {
            return 20.0; // 运费20元
        }
    }
};

// 问题:价格计算逻辑分散在多个类中
// 当需要修改价格计算规则时(例如调整VIP折扣率),
// 需要在多个类中查找和修改相关代码

// 重构后:将价格计算逻辑集中到专门的类中
class PriceCalculationRule
{
public:
    virtual ~PriceCalculationRule() = default;
    virtual double calculatePrice(double basePrice, int quantity) = 0;
    virtual std::string getRuleName() const = 0;
};

class RegularCustomerPriceRule : public PriceCalculationRule
{
private:
    double discountRate;
    
public:
    RegularCustomerPriceRule(double rate = 0.05) : discountRate(rate) {}
    
    double calculatePrice(double basePrice, int quantity) override
    {
        double price = basePrice * (1 - discountRate);
        return price * quantity;
    }
    
    std::string getRuleName() const override
    {
        return "Regular Customer Price Rule";
    }
};

class VIPCustomerPriceRule : public PriceCalculationRule
{
private:
    double discountRate;
    
public:
    VIPCustomerPriceRule(double rate = 0.15) : discountRate(rate) {}
    
    double calculatePrice(double basePrice, int quantity) override
    {
        double price = basePrice * (1 - discountRate);
        return price * quantity;
    }
    
    std::string getRuleName() const override
    {
        return "VIP Customer Price Rule";
    }
};

class WholesalePriceRule : public PriceCalculationRule
{
private:
    double discountRate;
    int bulkQuantityThreshold;
    
public:
    WholesalePriceRule(double rate = 0.25, int threshold = 10) 
        : discountRate(rate), bulkQuantityThreshold(threshold) {}
    
    double calculatePrice(double basePrice, int quantity) override
    {
        double effectiveDiscount = discountRate;
        
        // 批量购买额外折扣
        if (quantity >= bulkQuantityThreshold)
        {
            effectiveDiscount += 0.05; // 额外5%折扣
        }
        
        double price = basePrice * (1 - effectiveDiscount);
        return price * quantity;
    }
    
    std::string getRuleName() const override
    {
        return "Wholesale Price Rule";
    }
};

class PriceCalculator
{
private:
    std::shared_ptr<PriceCalculationRule> priceRule;
    double taxRate;
    
public:
    PriceCalculator(std::shared_ptr<PriceCalculationRule> rule, double tax = 0.08)
        : priceRule(rule), taxRate(tax) {}
    
    void setPriceRule(std::shared_ptr<PriceCalculationRule> rule)
    {
        priceRule = rule;
    }
    
    double calculateItemPrice(double basePrice, int quantity)
    {
        if (!priceRule)
        {
            return basePrice * quantity;
        }
        return priceRule->calculatePrice(basePrice, quantity);
    }
    
    double calculateTax(double amount)
    {
        return amount * taxRate;
    }
    
    double calculateShipping(double amount)
    {
        if (amount > 500.0)
        {
            return 0.0;
        }
        else if (amount > 200.0)
        {
            return 10.0;
        }
        else
        {
            return 20.0;
        }
    }
    
    double calculateCartDiscount(double totalAmount)
    {
        if (totalAmount > 1000.0)
        {
            return 50.0;
        }
        else if (totalAmount > 500.0)
        {
            return 20.0;
        }
        return 0.0;
    }
};

// 重构后的Product类
class RefactoredProduct
{
private:
    std::string name;
    double basePrice;
    
public:
    RefactoredProduct(const std::string& productName, double price)
        : name(productName), basePrice(price) {}
    
    std::string getName() const { return name; }
    double getBasePrice() const { return basePrice; }
};

// 重构后的OrderItem类
class RefactoredOrderItem
{
private:
    std::shared_ptr<RefactoredProduct> product;
    int quantity;
    
public:
    RefactoredOrderItem(std::shared_ptr<RefactoredProduct> prod, int qty)
        : product(prod), quantity(qty) {}
    
    std::shared_ptr<RefactoredProduct> getProduct() const { return product; }
    int getQuantity() const { return quantity; }
};

// 重构后的ShoppingCart类
class RefactoredShoppingCart
{
private:
    std::vector<std::shared_ptr<RefactoredOrderItem>> items;
    std::shared_ptr<PriceCalculator> priceCalculator;
    
public:
    RefactoredShoppingCart(std::shared_ptr<PriceCalculator> calculator)
        : priceCalculator(calculator) {}
    
    void addItem(std::shared_ptr<RefactoredOrderItem> item)
    {
        items.push_back(item);
    }
    
    double calculateSubtotal()
    {
        double subtotal = 0.0;
        
        for (const auto& item : items)
        {
            double basePrice = item->getProduct()->getBasePrice();
            int quantity = item->getQuantity();
            
            subtotal += priceCalculator->calculateItemPrice(basePrice, quantity);
        }
        
        // 应用购物车折扣
        double discount = priceCalculator->calculateCartDiscount(subtotal);
        return subtotal - discount;
    }
    
    double calculateTotal()
    {
        double subtotal = calculateSubtotal();
        double tax = priceCalculator->calculateTax(subtotal);
        double shipping = priceCalculator->calculateShipping(subtotal);
        
        return subtotal + tax + shipping;
    }
};

int main()
{
    // 使用重构前的代码
    std::shared_ptr<Product> laptop = std::make_shared<Product>("Laptop", 999.99);
    std::shared_ptr<Product> mouse = std::make_shared<Product>("Mouse", 49.99);
    
    std::shared_ptr<OrderItem> item1 = std::make_shared<OrderItem>(laptop, 1);
    std::shared_ptr<OrderItem> item2 = std::make_shared<OrderItem>(mouse, 3);
    
    std::shared_ptr<ShoppingCart> cart = std::make_shared<ShoppingCart>("VIP");
    cart->addItem(item1);
    cart->addItem(item2);
    
    std::shared_ptr<Invoice> invoice = std::make_shared<Invoice>(cart, 0.08);
    
    std::cout << "=== 重构前的价格计算 ===" << std::endl;
    std::cout << "Cart Total: $" << cart->calculateCartTotal() << std::endl;
    std::cout << "Final Amount: $" << invoice->calculateFinalAmount() << std::endl;
    
    // 使用重构后的代码
    std::shared_ptr<RefactoredProduct> refactoredLaptop = 
        std::make_shared<RefactoredProduct>("Laptop", 999.99);
    std::shared_ptr<RefactoredProduct> refactoredMouse = 
        std::make_shared<RefactoredProduct>("Mouse", 49.99);
    
    std::shared_ptr<RefactoredOrderItem> refactoredItem1 = 
        std::make_shared<RefactoredOrderItem>(refactoredLaptop, 1);
    std::shared_ptr<RefactoredOrderItem> refactoredItem2 = 
        std::make_shared<RefactoredOrderItem>(refactoredMouse, 3);
    
    // 创建价格计算规则
    std::shared_ptr<PriceCalculationRule> vipRule = 
        std::make_shared<VIPCustomerPriceRule>(0.15);
    
    std::shared_ptr<PriceCalculator> priceCalculator = 
        std::make_shared<PriceCalculator>(vipRule, 0.08);
    
    std::shared_ptr<RefactoredShoppingCart> refactoredCart = 
        std::make_shared<RefactoredShoppingCart>(priceCalculator);
    
    refactoredCart->addItem(refactoredItem1);
    refactoredCart->addItem(refactoredItem2);
    
    std::cout << "\n=== 重构后的价格计算 ===" << std::endl;
    std::cout << "Using: " << vipRule->getRuleName() << std::endl;
    std::cout << "Cart Total: $" << refactoredCart->calculateTotal() << std::endl;
    
    // 改变价格计算规则
    std::shared_ptr<PriceCalculationRule> wholesaleRule = 
        std::make_shared<WholesalePriceRule>(0.25, 5);
    
    priceCalculator->setPriceRule(wholesaleRule);
    
    std::cout << "\n=== 改变价格计算规则 ===" << std::endl;
    std::cout << "Now using: " << wholesaleRule->getRuleName() << std::endl;
    std::cout << "Cart Total: $" << refactoredCart->calculateTotal() << std::endl;
    
    // 优势:当需要修改价格计算规则时,只需要修改PriceCalculationRule的实现
    // 而不需要在多个类中查找和修改代码
    
    return 0;
}

本章节只详细介绍了前六种代码坏味道的识别与重构方法。在实际项目中,识别这些坏味道并采取适当的重构措施,可以显著提高代码质量和可维护性。后续的坏味道(从3.7到3.22)虽然也很重要,但它们的识别和重构方法遵循类似的原则:识别问题模式,应用适当的重构技术,确保代码变得更加清晰、可维护和可扩展。

第三章(续):识别代码中的设计问题与重构策略(第二部分)

在软件开发的演进过程中,代码质量直接影响到系统的可维护性、可扩展性和开发效率。本章继续探讨更多代码坏味道,为每种坏味道提供具体的商业项目实例,并展示在C++、C#和Java三种语言中的识别和解决方法。

3.7 依恋情结:方法过度依赖其他类的数据

依恋情结是指一个方法过度访问其他类的数据,而对自身类的数据访问较少。这种坏味道表明该方法可能更适合放在它所依赖的类中。

商业场景:员工薪资计算系统

C++ 示例:薪资计算方法过度依赖员工数据
#include <iostream>
#include <string>
#include <vector>
#include <memory>
#include <ctime>

// 员工类
class Employee
{
private:
    std::string id;
    std::string name;
    std::string department;
    double baseSalary;
    int yearsOfService;
    std::tm hireDate;
    int overtimeHours;
    double overtimeRate;
    
public:
    Employee(const std::string& empId, const std::string& empName, 
             const std::string& dept, double salary)
        : id(empId), name(empName), department(dept), baseSalary(salary),
          yearsOfService(0), overtimeHours(0), overtimeRate(1.5)
    {
        // 设置入职日期为当前时间
        std::time_t now = std::time(nullptr);
        hireDate = *std::localtime(&now);
    }
    
    void setYearsOfService(int years) { yearsOfService = years; }
    void setOvertimeHours(int hours) { overtimeHours = hours; }
    void setOvertimeRate(double rate) { overtimeRate = rate; }
    
    // Getter方法
    std::string getId() const { return id; }
    std::string getName() const { return name; }
    std::string getDepartment() const { return department; }
    double getBaseSalary() const { return baseSalary; }
    int getYearsOfService() const { return yearsOfService; }
    int getOvertimeHours() const { return overtimeHours; }
    double getOvertimeRate() const { return overtimeRate; }
    std::tm getHireDate() const { return hireDate; }
};

// 薪资计算器类 - 存在依恋情结
class PayrollCalculator
{
public:
    // 这个方法过度依赖Employee类的数据,应该移到Employee类中
    double calculateMonthlySalary(const Employee& employee)
    {
        // 获取员工的所有数据
        double baseSalary = employee.getBaseSalary();
        int yearsOfService = employee.getYearsOfService();
        int overtimeHours = employee.getOvertimeHours();
        double overtimeRate = employee.getOvertimeRate();
        
        // 计算基础月薪
        double monthlyBase = baseSalary / 12.0;
        
        // 计算工龄津贴
        double seniorityBonus = 0.0;
        if (yearsOfService >= 10)
        {
            seniorityBonus = monthlyBase * 0.1; // 10%工龄津贴
        }
        else if (yearsOfService >= 5)
        {
            seniorityBonus = monthlyBase * 0.05; // 5%工龄津贴
        }
        
        // 计算加班费
        double hourlyRate = baseSalary / (52 * 40); // 假设每周40小时,每年52周
        double overtimePay = overtimeHours * hourlyRate * overtimeRate;
        
        // 计算部门津贴
        double departmentBonus = 0.0;
        std::string department = employee.getDepartment();
        if (department == "Engineering")
        {
            departmentBonus = monthlyBase * 0.15; // 工程部15%津贴
        }
        else if (department == "Sales")
        {
            departmentBonus = monthlyBase * 0.2; // 销售部20%津贴
        }
        
        return monthlyBase + seniorityBonus + overtimePay + departmentBonus;
    }
    
    // 这个方法也过度依赖Employee类的数据
    std::string generatePaySlip(const Employee& employee)
    {
        double salary = calculateMonthlySalary(employee);
        
        std::string slip = "Pay Slip for " + employee.getName() + "\n";
        slip += "Employee ID: " + employee.getId() + "\n";
        slip += "Department: " + employee.getDepartment() + "\n";
        slip += "Base Salary: $" + std::to_string(employee.getBaseSalary()) + "\n";
        slip += "Years of Service: " + std::to_string(employee.getYearsOfService()) + "\n";
        slip += "Overtime Hours: " + std::to_string(employee.getOvertimeHours()) + "\n";
        slip += "Monthly Salary: $" + std::to_string(salary) + "\n";
        
        return slip;
    }
};

// 重构后:将薪资计算逻辑移到Employee类中
class RefactoredEmployee
{
private:
    std::string id;
    std::string name;
    std::string department;
    double baseSalary;
    int yearsOfService;
    std::tm hireDate;
    int overtimeHours;
    double overtimeRate;
    
    // 私有计算方法
    double calculateHourlyRate() const
    {
        // 假设每周40小时,每年52周
        return baseSalary / (52 * 40);
    }
    
    double calculateSeniorityBonus() const
    {
        double monthlyBase = baseSalary / 12.0;
        
        if (yearsOfService >= 10)
        {
            return monthlyBase * 0.1;
        }
        else if (yearsOfService >= 5)
        {
            return monthlyBase * 0.05;
        }
        
        return 0.0;
    }
    
    double calculateOvertimePay() const
    {
        double hourlyRate = calculateHourlyRate();
        return overtimeHours * hourlyRate * overtimeRate;
    }
    
    double calculateDepartmentBonus() const
    {
        double monthlyBase = baseSalary / 12.0;
        
        if (department == "Engineering")
        {
            return monthlyBase * 0.15;
        }
        else if (department == "Sales")
        {
            return monthlyBase * 0.2;
        }
        
        return 0.0;
    }
    
public:
    RefactoredEmployee(const std::string& empId, const std::string& empName, 
                       const std::string& dept, double salary)
        : id(empId), name(empName), department(dept), baseSalary(salary),
          yearsOfService(0), overtimeHours(0), overtimeRate(1.5)
    {
        std::time_t now = std::time(nullptr);
        hireDate = *std::localtime(&now);
    }
    
    void setYearsOfService(int years) { yearsOfService = years; }
    void setOvertimeHours(int hours) { overtimeHours = hours; }
    void setOvertimeRate(double rate) { overtimeRate = rate; }
    
    // Getter方法
    std::string getId() const { return id; }
    std::string getName() const { return name; }
    std::string getDepartment() const { return department; }
    double getBaseSalary() const { return baseSalary; }
    int getYearsOfService() const { return yearsOfService; }
    int getOvertimeHours() const { return overtimeHours; }
    double getOvertimeRate() const { return overtimeRate; }
    
    // 薪资计算方法现在在Employee类中
    double calculateMonthlySalary() const
    {
        double monthlyBase = baseSalary / 12.0;
        double seniorityBonus = calculateSeniorityBonus();
        double overtimePay = calculateOvertimePay();
        double departmentBonus = calculateDepartmentBonus();
        
        return monthlyBase + seniorityBonus + overtimePay + departmentBonus;
    }
    
    std::string generatePaySlip() const
    {
        double salary = calculateMonthlySalary();
        
        std::string slip = "Pay Slip for " + name + "\n";
        slip += "Employee ID: " + id + "\n";
        slip += "Department: " + department + "\n";
        slip += "Base Salary: $" + std::to_string(baseSalary) + "\n";
        slip += "Years of Service: " + std::to_string(yearsOfService) + "\n";
        slip += "Overtime Hours: " + std::to_string(overtimeHours) + "\n";
        slip += "Monthly Salary: $" + std::to_string(salary) + "\n";
        
        return slip;
    }
};

// 重构后的薪资计算器类,现在只处理薪资计算策略
class SalaryCalculationStrategy
{
public:
    virtual ~SalaryCalculationStrategy() = default;
    virtual double calculateSalary(const RefactoredEmployee& employee) = 0;
    virtual std::string getStrategyName() const = 0;
};

class StandardSalaryStrategy : public SalaryCalculationStrategy
{
public:
    double calculateSalary(const RefactoredEmployee& employee) override
    {
        // 使用员工自身的计算方法
        return employee.calculateMonthlySalary();
    }
    
    std::string getStrategyName() const override
    {
        return "Standard Salary Calculation";
    }
};

class BonusSalaryStrategy : public SalaryCalculationStrategy
{
private:
    double bonusPercentage;
    
public:
    BonusSalaryStrategy(double percentage) : bonusPercentage(percentage) {}
    
    double calculateSalary(const RefactoredEmployee& employee) override
    {
        double baseSalary = employee.calculateMonthlySalary();
        return baseSalary * (1.0 + bonusPercentage);
    }
    
    std::string getStrategyName() const override
    {
        return "Bonus Salary Calculation (" + std::to_string(bonusPercentage * 100) + "%)";
    }
};

// 薪资处理器类
class PayrollProcessor
{
private:
    std::shared_ptr<SalaryCalculationStrategy> strategy;
    
public:
    PayrollProcessor(std::shared_ptr<SalaryCalculationStrategy> calcStrategy)
        : strategy(calcStrategy) {}
    
    void setStrategy(std::shared_ptr<SalaryCalculationStrategy> calcStrategy)
    {
        strategy = calcStrategy;
    }
    
    double processSalary(const RefactoredEmployee& employee)
    {
        if (strategy)
        {
            return strategy->calculateSalary(employee);
        }
        return employee.calculateMonthlySalary();
    }
    
    void printPayrollReport(const std::vector<RefactoredEmployee>& employees)
    {
        double totalPayroll = 0.0;
        
        std::cout << "Payroll Report\n";
        std::cout << "==============\n";
        
        for (const auto& employee : employees)
        {
            double salary = processSalary(employee);
            totalPayroll += salary;
            
            std::cout << employee.getName() << ": $" << salary << "\n";
        }
        
        std::cout << "\nTotal Payroll: $" << totalPayroll << "\n";
    }
};

int main()
{
    // 重构前:依恋情结示例
    Employee employee1("E001", "John Smith", "Engineering", 75000);
    employee1.setYearsOfService(8);
    employee1.setOvertimeHours(10);
    
    PayrollCalculator calculator;
    double salary1 = calculator.calculateMonthlySalary(employee1);
    std::string slip1 = calculator.generatePaySlip(employee1);
    
    std::cout << "=== 重构前:PayrollCalculator存在依恋情结 ===\n";
    std::cout << "Salary: $" << salary1 << "\n";
    std::cout << slip1 << "\n";
    
    // 重构后
    RefactoredEmployee employee2("E002", "Jane Doe", "Sales", 80000);
    employee2.setYearsOfService(12);
    employee2.setOvertimeHours(15);
    
    std::cout << "\n=== 重构后:薪资计算逻辑在Employee类中 ===\n";
    double salary2 = employee2.calculateMonthlySalary();
    std::string slip2 = employee2.generatePaySlip();
    std::cout << "Salary: $" << salary2 << "\n";
    std::cout << slip2 << "\n";
    
    // 使用策略模式处理薪资计算
    std::vector<RefactoredEmployee> employees;
    employees.push_back(employee2);
    
    RefactoredEmployee employee3("E003", "Bob Johnson", "Engineering", 90000);
    employee3.setYearsOfService(3);
    employees.push_back(employee3);
    
    auto standardStrategy = std::make_shared<StandardSalaryStrategy>();
    PayrollProcessor processor(standardStrategy);
    
    std::cout << "\n=== 使用标准薪资策略 ===\n";
    processor.printPayrollReport(employees);
    
    auto bonusStrategy = std::make_shared<BonusSalaryStrategy>(0.1); // 10%奖金
    processor.setStrategy(bonusStrategy);
    
    std::cout << "\n=== 使用奖金薪资策略 ===\n";
    processor.printPayrollReport(employees);
    
    return 0;
}

3.8 数据泥团:经常一起出现的多个数据项

数据泥团是指多个数据项经常一起出现,它们应该被组织成一个单独的对象或类。这样可以减少参数数量,提高代码的可读性和可维护性。

商业场景:订单系统中的地址信息

C# 示例:分散的地址数据项
using System;
using System.Collections.Generic;

namespace DataClumpsExample
{
    // 数据泥团示例:地址相关的数据项分散在多个地方
    public class CustomerOrder
    {
        public string OrderId { get; set; }
        
        // 送货地址数据泥团
        public string ShippingStreet { get; set; }
        public string ShippingCity { get; set; }
        public string ShippingState { get; set; }
        public string ShippingZipCode { get; set; }
        public string ShippingCountry { get; set; }
        
        // 账单地址数据泥团
        public string BillingStreet { get; set; }
        public string BillingCity { get; set; }
        public string BillingState { get; set; }
        public string BillingZipCode { get; set; }
        public string BillingCountry { get; set; }
        
        // 客户联系信息数据泥团
        public string CustomerName { get; set; }
        public string CustomerPhone { get; set; }
        public string CustomerEmail { get; set; }
        
        public CustomerOrder(string orderId)
        {
            OrderId = orderId;
        }
        
        // 验证地址的方法 - 参数列表过长
        public bool ValidateAddress(string street, string city, string state, 
                                   string zipCode, string country)
        {
            if (string.IsNullOrEmpty(street)) return false;
            if (string.IsNullOrEmpty(city)) return false;
            if (string.IsNullOrEmpty(state)) return false;
            if (string.IsNullOrEmpty(zipCode)) return false;
            if (string.IsNullOrEmpty(country)) return false;
            
            return true;
        }
        
        // 格式化地址的方法 - 参数列表过长
        public string FormatAddress(string street, string city, string state, 
                                   string zipCode, string country)
        {
            return $"{street}, {city}, {state} {zipCode}, {country}";
        }
        
        // 生成送货标签 - 使用数据泥团
        public string GenerateShippingLabel()
        {
            return $"{CustomerName}\n" +
                   $"{ShippingStreet}\n" +
                   $"{ShippingCity}, {ShippingState} {ShippingZipCode}\n" +
                   $"{ShippingCountry}";
        }
        
        // 生成账单 - 使用数据泥团
        public string GenerateInvoice()
        {
            return $"Invoice for Order: {OrderId}\n" +
                   $"Billing Address:\n" +
                   $"{BillingStreet}\n" +
                   $"{BillingCity}, {BillingState} {BillingZipCode}\n" +
                   $"{BillingCountry}\n" +
                   $"Contact: {CustomerPhone}, {CustomerEmail}";
        }
    }
    
    // 重构后:提取地址类
    public class Address
    {
        public string Street { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string ZipCode { get; set; }
        public string Country { get; set; }
        
        public Address()
        {
        }
        
        public Address(string street, string city, string state, string zipCode, string country)
        {
            Street = street;
            City = city;
            State = state;
            ZipCode = zipCode;
            Country = country;
        }
        
        public bool Validate()
        {
            if (string.IsNullOrEmpty(Street)) return false;
            if (string.IsNullOrEmpty(City)) return false;
            if (string.IsNullOrEmpty(State)) return false;
            if (string.IsNullOrEmpty(ZipCode)) return false;
            if (string.IsNullOrEmpty(Country)) return false;
            
            return true;
        }
        
        public string Format()
        {
            return $"{Street}, {City}, {State} {ZipCode}, {Country}";
        }
        
        public override string ToString()
        {
            return Format();
        }
    }
    
    // 提取联系信息类
    public class ContactInfo
    {
        public string Name { get; set; }
        public string Phone { get; set; }
        public string Email { get; set; }
        
        public ContactInfo()
        {
        }
        
        public ContactInfo(string name, string phone, string email)
        {
            Name = name;
            Phone = phone;
            Email = email;
        }
        
        public bool Validate()
        {
            if (string.IsNullOrEmpty(Name)) return false;
            if (string.IsNullOrEmpty(Phone)) return false;
            if (string.IsNullOrEmpty(Email)) return false;
            
            return true;
        }
        
        public override string ToString()
        {
            return $"{Name} ({Phone}, {Email})";
        }
    }
    
    // 重构后的订单类
    public class RefactoredOrder
    {
        public string OrderId { get; set; }
        public Address ShippingAddress { get; set; }
        public Address BillingAddress { get; set; }
        public ContactInfo CustomerContact { get; set; }
        
        public RefactoredOrder(string orderId)
        {
            OrderId = orderId;
        }
        
        // 验证订单
        public bool Validate()
        {
            if (string.IsNullOrEmpty(OrderId)) return false;
            if (ShippingAddress == null || !ShippingAddress.Validate()) return false;
            if (BillingAddress == null || !BillingAddress.Validate()) return false;
            if (CustomerContact == null || !CustomerContact.Validate()) return false;
            
            return true;
        }
        
        // 生成送货标签
        public string GenerateShippingLabel()
        {
            return $"{CustomerContact.Name}\n" +
                   $"{ShippingAddress.Format()}";
        }
        
        // 生成账单
        public string GenerateInvoice()
        {
            return $"Invoice for Order: {OrderId}\n" +
                   $"Billing Address: {BillingAddress.Format()}\n" +
                   $"Contact: {CustomerContact}";
        }
        
        // 检查是否需要填写关税信息
        public bool RequiresCustomsDeclaration()
        {
            // 如果送货地址和账单地址的国家不同,需要关税声明
            return ShippingAddress.Country != BillingAddress.Country;
        }
    }
    
    // 地址构建器(建造者模式)
    public class AddressBuilder
    {
        private Address address;
        
        public AddressBuilder()
        {
            address = new Address();
        }
        
        public AddressBuilder WithStreet(string street)
        {
            address.Street = street;
            return this;
        }
        
        public AddressBuilder WithCity(string city)
        {
            address.City = city;
            return this;
        }
        
        public AddressBuilder WithState(string state)
        {
            address.State = state;
            return this;
        }
        
        public AddressBuilder WithZipCode(string zipCode)
        {
            address.ZipCode = zipCode;
            return this;
        }
        
        public AddressBuilder WithCountry(string country)
        {
            address.Country = country;
            return this;
        }
        
        public Address Build()
        {
            if (!address.Validate())
            {
                throw new InvalidOperationException("Invalid address data");
            }
            return address;
        }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("=== 重构前:数据泥团示例 ===");
            
            CustomerOrder oldOrder = new CustomerOrder("ORD001")
            {
                CustomerName = "John Smith",
                CustomerPhone = "123-456-7890",
                CustomerEmail = "john@example.com",
                
                ShippingStreet = "123 Main St",
                ShippingCity = "Anytown",
                ShippingState = "CA",
                ShippingZipCode = "12345",
                ShippingCountry = "USA",
                
                BillingStreet = "456 Oak St",
                BillingCity = "Othertown",
                BillingState = "NY",
                BillingZipCode = "54321",
                BillingCountry = "USA"
            };
            
            Console.WriteLine("Shipping Label:\n" + oldOrder.GenerateShippingLabel());
            Console.WriteLine("\nInvoice:\n" + oldOrder.GenerateInvoice());
            
            Console.WriteLine("\n=== 重构后:使用提取的类 ===");
            
            // 使用建造者模式创建地址
            Address shippingAddress = new AddressBuilder()
                .WithStreet("123 Main St")
                .WithCity("Anytown")
                .WithState("CA")
                .WithZipCode("12345")
                .WithCountry("USA")
                .Build();
            
            Address billingAddress = new AddressBuilder()
                .WithStreet("456 Oak St")
                .WithCity("Othertown")
                .WithState("NY")
                .WithZipCode("54321")
                .WithCountry("USA")
                .Build();
            
            ContactInfo contact = new ContactInfo("John Smith", "123-456-7890", "john@example.com");
            
            RefactoredOrder newOrder = new RefactoredOrder("ORD002")
            {
                ShippingAddress = shippingAddress,
                BillingAddress = billingAddress,
                CustomerContact = contact
            };
            
            Console.WriteLine("Shipping Label:\n" + newOrder.GenerateShippingLabel());
            Console.WriteLine("\nInvoice:\n" + newOrder.GenerateInvoice());
            
            // 检查是否需要关税声明
            Console.WriteLine($"\nRequires Customs Declaration: {newOrder.RequiresCustomsDeclaration()}");
            
            // 测试国际订单
            Address internationalAddress = new AddressBuilder()
                .WithStreet("789 Maple St")
                .WithCity("Toronto")
                .WithState("ON")
                .WithZipCode("M5H 2N2")
                .WithCountry("Canada")
                .Build();
            
            RefactoredOrder internationalOrder = new RefactoredOrder("ORD003")
            {
                ShippingAddress = internationalAddress,
                BillingAddress = billingAddress, // 账单地址在美国
                CustomerContact = contact
            };
            
            Console.WriteLine($"\nInternational Order requires Customs Declaration: {internationalOrder.RequiresCustomsDeclaration()}");
            
            // 地址验证示例
            Console.WriteLine("\n=== 地址验证示例 ===");
            try
            {
                Address invalidAddress = new AddressBuilder()
                    .WithStreet("") // 空街道地址
                    .WithCity("Test City")
                    .WithState("TS")
                    .WithZipCode("12345")
                    .WithCountry("USA")
                    .Build(); // 这会抛出异常
            }
            catch (InvalidOperationException ex)
            {
                Console.WriteLine($"Address validation failed: {ex.Message}");
            }
        }
    }
}

3.9 基本类型偏执:过度使用基本类型而非对象

基本类型偏执是指过度使用基本数据类型(如int、string、double)来表示概念,而不是创建专门的类。这会导致相关行为分散在代码各处,难以维护。

商业场景:金融系统中的货币处理

Java 示例:使用基本类型处理货币
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Currency;
import java.util.Locale;

// 基本类型偏执示例:使用double表示金额
class BankAccountOld {
    private String accountNumber;
    private double balance; // 使用基本类型double
    private String currencyCode; // 使用字符串表示货币代码
    
    public BankAccountOld(String accountNumber, double initialBalance, String currencyCode) {
        this.accountNumber = accountNumber;
        this.balance = initialBalance;
        this.currencyCode = currencyCode;
    }
    
    public void deposit(double amount) {
        // 问题:没有验证amount是否为正数
        balance += amount;
    }
    
    public boolean withdraw(double amount) {
        if (amount <= balance) {
            balance -= amount;
            return true;
        }
        return false;
    }
    
    // 转账方法 - 存在精度问题和货币不匹配问题
    public boolean transferTo(BankAccountOld targetAccount, double amount) {
        if (withdraw(amount)) {
            targetAccount.deposit(amount);
            return true;
        }
        return false;
    }
    
    // 计算利息 - 存在精度问题
    public void addInterest(double interestRate) {
        double interest = balance * interestRate / 100;
        balance += interest;
    }
    
    public double getBalance() {
        return balance;
    }
    
    public String getFormattedBalance() {
        // 格式化问题:不同货币有不同的格式化规则
        DecimalFormat df = new DecimalFormat("#,##0.00");
        return currencyCode + " " + df.format(balance);
    }
    
    // 货币转换 - 问题:汇率逻辑分散在多个地方
    public double convertTo(String targetCurrencyCode, double exchangeRate) {
        return balance * exchangeRate;
    }
}

// 重构后:创建Money类
class Money {
    private final long amount; // 以最小货币单位存储(如分)
    private final Currency currency;
    
    // 工厂方法:从金额和货币代码创建Money
    public static Money of(double amount, String currencyCode) {
        Currency currency = Currency.getInstance(currencyCode);
        long amountInCents = Math.round(amount * getScaleFactor(currency));
        return new Money(amountInCents, currency);
    }
    
    // 工厂方法:从最小货币单位创建Money
    public static Money ofMinor(long amountInMinor, String currencyCode) {
        Currency currency = Currency.getInstance(currencyCode);
        return new Money(amountInMinor, currency);
    }
    
    private Money(long amount, Currency currency) {
        this.amount = amount;
        this.currency = currency;
    }
    
    // 获取货币的小数位数
    private static int getScaleFactor(Currency currency) {
        int defaultFractionDigits = currency.getDefaultFractionDigits();
        return (int) Math.pow(10, defaultFractionDigits);
    }
    
    // 加法
    public Money add(Money other) {
        validateSameCurrency(other);
        return new Money(this.amount + other.amount, this.currency);
    }
    
    // 减法
    public Money subtract(Money other) {
        validateSameCurrency(other);
        return new Money(this.amount - other.amount, this.currency);
    }
    
    // 乘法
    public Money multiply(double multiplier) {
        long result = Math.round(this.amount * multiplier);
        return new Money(result, this.currency);
    }
    
    // 除法
    public Money divide(double divisor) {
        if (divisor == 0) {
            throw new ArithmeticException("Division by zero");
        }
        long result = Math.round(this.amount / divisor);
        return new Money(result, this.currency);
    }
    
    // 比较
    public boolean isGreaterThan(Money other) {
        validateSameCurrency(other);
        return this.amount > other.amount;
    }
    
    public boolean isLessThan(Money other) {
        validateSameCurrency(other);
        return this.amount < other.amount;
    }
    
    public boolean isEqualTo(Money other) {
        validateSameCurrency(other);
        return this.amount == other.amount;
    }
    
    public boolean isZero() {
        return this.amount == 0;
    }
    
    public boolean isPositive() {
        return this.amount > 0;
    }
    
    public boolean isNegative() {
        return this.amount < 0;
    }
    
    // 验证货币是否相同
    private void validateSameCurrency(Money other) {
        if (!this.currency.equals(other.currency)) {
            throw new IllegalArgumentException("Currency mismatch: " + 
                this.currency + " vs " + other.currency);
        }
    }
    
    // 获取金额(double类型)
    public double getAmount() {
        int scaleFactor = getScaleFactor(currency);
        return (double) amount / scaleFactor;
    }
    
    // 获取金额(最小货币单位)
    public long getAmountInMinor() {
        return amount;
    }
    
    public Currency getCurrency() {
        return currency;
    }
    
    public String getCurrencyCode() {
        return currency.getCurrencyCode();
    }
    
    // 格式化
    @Override
    public String toString() {
        DecimalFormat df = new DecimalFormat("#,##0.00");
        return currency.getSymbol() + df.format(getAmount());
    }
    
    // 货币转换
    public Money convertTo(String targetCurrencyCode, double exchangeRate) {
        Currency targetCurrency = Currency.getInstance(targetCurrencyCode);
        double amountInSourceCurrency = getAmount();
        double amountInTargetCurrency = amountInSourceCurrency * exchangeRate;
        return Money.of(amountInTargetCurrency, targetCurrencyCode);
    }
}

// 重构后的银行账户类
class BankAccount {
    private String accountNumber;
    private Money balance;
    
    public BankAccount(String accountNumber, Money initialBalance) {
        this.accountNumber = accountNumber;
        this.balance = initialBalance;
    }
    
    public void deposit(Money amount) {
        validatePositiveAmount(amount);
        balance = balance.add(amount);
    }
    
    public boolean withdraw(Money amount) {
        validatePositiveAmount(amount);
        
        if (balance.isGreaterThan(amount) || balance.isEqualTo(amount)) {
            balance = balance.subtract(amount);
            return true;
        }
        return false;
    }
    
    // 转账 - 现在可以处理货币转换
    public boolean transferTo(BankAccount targetAccount, Money amount) {
        validatePositiveAmount(amount);
        
        if (withdraw(amount)) {
            // 如果货币不同,需要进行转换
            if (!balance.getCurrency().equals(targetAccount.balance.getCurrency())) {
                // 在实际应用中,这里会查询汇率
                double exchangeRate = getExchangeRate(
                    balance.getCurrencyCode(), 
                    targetAccount.balance.getCurrencyCode()
                );
                Money convertedAmount = amount.convertTo(
                    targetAccount.balance.getCurrencyCode(), 
                    exchangeRate
                );
                targetAccount.deposit(convertedAmount);
            } else {
                targetAccount.deposit(amount);
            }
            return true;
        }
        return false;
    }
    
    // 添加利息
    public void addInterest(double interestRate) {
        if (interestRate < 0) {
            throw new IllegalArgumentException("Interest rate cannot be negative");
        }
        
        Money interest = balance.multiply(interestRate / 100);
        balance = balance.add(interest);
    }
    
    // 获取余额
    public Money getBalance() {
        return balance;
    }
    
    public String getFormattedBalance() {
        return balance.toString();
    }
    
    // 验证金额是否为正数
    private void validatePositiveAmount(Money amount) {
        if (amount.isNegative() || amount.isZero()) {
            throw new IllegalArgumentException("Amount must be positive");
        }
    }
    
    // 获取汇率(简化实现)
    private double getExchangeRate(String sourceCurrency, String targetCurrency) {
        // 在实际应用中,这里会从汇率服务获取实时汇率
        // 这里使用硬编码的汇率作为示例
        if (sourceCurrency.equals("USD") && targetCurrency.equals("EUR")) {
            return 0.92; // 1 USD = 0.92 EUR
        } else if (sourceCurrency.equals("EUR") && targetCurrency.equals("USD")) {
            return 1.09; // 1 EUR = 1.09 USD
        } else if (sourceCurrency.equals("USD") && targetCurrency.equals("JPY")) {
            return 150.0; // 1 USD = 150 JPY
        }
        return 1.0; // 相同货币
    }
}

// 投资组合类,展示Money类的优势
class InvestmentPortfolio {
    private List<BankAccount> accounts;
    
    public InvestmentPortfolio() {
        accounts = new ArrayList<>();
    }
    
    public void addAccount(BankAccount account) {
        accounts.add(account);
    }
    
    // 计算总投资组合价值(转换为指定货币)
    public Money getTotalValue(String targetCurrencyCode) {
        Money total = Money.of(0, targetCurrencyCode);
        
        for (BankAccount account : accounts) {
            Money accountBalance = account.getBalance();
            
            if (accountBalance.getCurrencyCode().equals(targetCurrencyCode)) {
                total = total.add(accountBalance);
            } else {
                // 在实际应用中,这里会使用汇率服务
                double exchangeRate = getExchangeRate(
                    accountBalance.getCurrencyCode(), 
                    targetCurrencyCode
                );
                Money convertedBalance = accountBalance.convertTo(targetCurrencyCode, exchangeRate);
                total = total.add(convertedBalance);
            }
        }
        
        return total;
    }
    
    private double getExchangeRate(String sourceCurrency, String targetCurrency) {
        // 简化实现
        if (sourceCurrency.equals("USD") && targetCurrency.equals("EUR")) {
            return 0.92;
        } else if (sourceCurrency.equals("EUR") && targetCurrency.equals("USD")) {
            return 1.09;
        }
        return 1.0;
    }
}

// 另一个例子:百分比类
class Percentage {
    private final double value; // 0.0 到 1.0
    
    private Percentage(double value) {
        if (value < 0.0 || value > 1.0) {
            throw new IllegalArgumentException("Percentage must be between 0 and 1");
        }
        this.value = value;
    }
    
    public static Percentage of(double value) {
        return new Percentage(value);
    }
    
    public static Percentage fromPercent(double percent) {
        return new Percentage(percent / 100.0);
    }
    
    public double getValue() {
        return value;
    }
    
    public double getAsPercent() {
        return value * 100.0;
    }
    
    // 应用百分比到金额
    public Money applyTo(Money amount) {
        return amount.multiply(value);
    }
    
    // 百分比加法
    public Percentage add(Percentage other) {
        return new Percentage(this.value + other.value);
    }
    
    @Override
    public String toString() {
        return String.format("%.2f%%", getAsPercent());
    }
}

public class PrimitiveObsessionExample {
    public static void main(String[] args) {
        System.out.println("=== 重构前:使用基本类型处理货币 ===");
        
        BankAccountOld oldAccount = new BankAccountOld("ACC001", 1000.0, "USD");
        oldAccount.deposit(500.0);
        oldAccount.addInterest(5.0); // 5%利息
        
        System.out.println("Old Account Balance: " + oldAccount.getFormattedBalance());
        
        // 问题1:精度问题
        oldAccount.deposit(0.1);
        oldAccount.deposit(0.2);
        System.out.println("After depositing 0.1 + 0.2: " + oldAccount.getBalance());
        // 可能输出:1000.8(由于浮点数精度问题)
        
        System.out.println("\n=== 重构后:使用Money类 ===");
        
        // 创建Money对象
        Money initialBalance = Money.of(1000.0, "USD");
        BankAccount account = new BankAccount("ACC002", initialBalance);
        
        account.deposit(Money.of(500.0, "USD"));
        account.addInterest(5.0); // 5%利息
        
        System.out.println("Account Balance: " + account.getFormattedBalance());
        
        // 测试精度
        account.deposit(Money.of(0.1, "USD"));
        account.deposit(Money.of(0.2, "USD"));
        System.out.println("After depositing 0.1 + 0.2: " + account.getFormattedBalance());
        // 正确输出:$1,000.80
        
        // 测试货币转换
        System.out.println("\n=== 货币转换示例 ===");
        Money usdAmount = Money.of(100.0, "USD");
        Money eurAmount = usdAmount.convertTo("EUR", 0.92);
        System.out.println("100 USD = " + eurAmount);
        
        // 测试百分比类
        System.out.println("\n=== 百分比类示例 ===");
        Percentage discount = Percentage.fromPercent(20.0); // 20%折扣
        Money price = Money.of(100.0, "USD");
        Money discountAmount = discount.applyTo(price);
        Money finalPrice = price.subtract(discountAmount);
        
        System.out.println("Original Price: " + price);
        System.out.println("Discount (" + discount + "): " + discountAmount);
        System.out.println("Final Price: " + finalPrice);
        
        // 投资组合示例
        System.out.println("\n=== 投资组合示例 ===");
        InvestmentPortfolio portfolio = new InvestmentPortfolio();
        
        BankAccount usdAccount = new BankAccount("ACC003", Money.of(5000.0, "USD"));
        BankAccount eurAccount = new BankAccount("ACC004", Money.of(4000.0, "EUR"));
        
        portfolio.addAccount(usdAccount);
        portfolio.addAccount(eurAccount);
        
        Money totalInUSD = portfolio.getTotalValue("USD");
        System.out.println("Total Portfolio Value in USD: " + totalInUSD);
        
        Money totalInEUR = portfolio.getTotalValue("EUR");
        System.out.println("Total Portfolio Value in EUR: " + totalInEUR);
        
        // 测试货币不匹配的转账
        System.out.println("\n=== 跨国转账示例 ===");
        BankAccount jpyAccount = new BankAccount("ACC005", Money.of(100000.0, "JPY"));
        
        try {
            // 从美元账户转账100美元到日元账户
            boolean success = usdAccount.transferTo(jpyAccount, Money.of(100.0, "USD"));
            System.out.println("Transfer successful: " + success);
            System.out.println("USD Account Balance: " + usdAccount.getFormattedBalance());
            System.out.println("JPY Account Balance: " + jpyAccount.getFormattedBalance());
        } catch (Exception e) {
            System.out.println("Transfer failed: " + e.getMessage());
        }
    }
}

3.10 Switch惊悚现象:复杂的条件判断逻辑

Switch惊悚现象是指代码中存在复杂的switch或if-else语句,特别是当它们需要经常修改以添加新的条件分支时。这种代码违反了开闭原则,应该使用多态来重构。

商业场景:支付系统处理不同类型的支付

C++ 示例:使用switch处理不同支付类型
#include <iostream>
#include <string>
#include <memory>
#include <vector>
#include <stdexcept>

// Switch惊悚现象示例:使用switch处理不同支付类型
class PaymentProcessorOld
{
public:
    enum class PaymentType
    {
        CREDIT_CARD,
        PAYPAL,
        BANK_TRANSFER,
        CRYPTOCURRENCY,
        GIFT_CARD
    };
    
    struct PaymentDetails
    {
        PaymentType type;
        std::string details;
        double amount;
    };
    
    // 复杂的switch语句处理支付
    bool processPayment(const PaymentDetails& payment)
    {
        switch (payment.type)
        {
            case PaymentType::CREDIT_CARD:
                return processCreditCardPayment(payment.details, payment.amount);
                
            case PaymentType::PAYPAL:
                return processPayPalPayment(payment.details, payment.amount);
                
            case PaymentType::BANK_TRANSFER:
                return processBankTransfer(payment.details, payment.amount);
                
            case PaymentType::CRYPTOCURRENCY:
                return processCryptoPayment(payment.details, payment.amount);
                
            case PaymentType::GIFT_CARD:
                return processGiftCardPayment(payment.details, payment.amount);
                
            default:
                std::cerr << "Unknown payment type" << std::endl;
                return false;
        }
    }
    
    // 生成收据的复杂switch语句
    std::string generateReceipt(const PaymentDetails& payment)
    {
        std::string receipt = "Payment Receipt\n";
        receipt += "Amount: $" + std::to_string(payment.amount) + "\n";
        
        switch (payment.type)
        {
            case PaymentType::CREDIT_CARD:
                receipt += "Method: Credit Card\n";
                receipt += "Last 4 digits: " + payment.details.substr(payment.details.length() - 4) + "\n";
                break;
                
            case PaymentType::PAYPAL:
                receipt += "Method: PayPal\n";
                receipt += "Email: " + payment.details + "\n";
                break;
                
            case PaymentType::BANK_TRANSFER:
                receipt += "Method: Bank Transfer\n";
                receipt += "Account: " + payment.details + "\n";
                break;
                
            case PaymentType::CRYPTOCURRENCY:
                receipt += "Method: Cryptocurrency\n";
                receipt += "Wallet: " + payment.details + "\n";
                break;
                
            case PaymentType::GIFT_CARD:
                receipt += "Method: Gift Card\n";
                receipt += "Card Number: " + payment.details + "\n";
                break;
                
            default:
                receipt += "Method: Unknown\n";
                break;
        }
        
        receipt += "Status: Completed\n";
        return receipt;
    }
    
    // 验证支付方法的复杂switch语句
    bool validatePaymentMethod(PaymentType type, const std::string& details)
    {
        switch (type)
        {
            case PaymentType::CREDIT_CARD:
                return validateCreditCard(details);
                
            case PaymentType::PAYPAL:
                return validatePayPalEmail(details);
                
            case PaymentType::BANK_TRANSFER:
                return validateBankAccount(details);
                
            case PaymentType::CRYPTOCURRENCY:
                return validateCryptoWallet(details);
                
            case PaymentType::GIFT_CARD:
                return validateGiftCard(details);
                
            default:
                return false;
        }
    }
    
private:
    // 各种支付处理方法的实现
    bool processCreditCardPayment(const std::string& cardDetails, double amount)
    {
        std::cout << "Processing credit card payment: $" << amount << std::endl;
        // 实际处理逻辑
        return true;
    }
    
    bool processPayPalPayment(const std::string& email, double amount)
    {
        std::cout << "Processing PayPal payment from " << email << ": $" << amount << std::endl;
        // 实际处理逻辑
        return true;
    }
    
    bool processBankTransfer(const std::string& accountDetails, double amount)
    {
        std::cout << "Processing bank transfer to " << accountDetails << ": $" << amount << std::endl;
        // 实际处理逻辑
        return true;
    }
    
    bool processCryptoPayment(const std::string& walletAddress, double amount)
    {
        std::cout << "Processing cryptocurrency payment to " << walletAddress << ": $" << amount << std::endl;
        // 实际处理逻辑
        return true;
    }
    
    bool processGiftCardPayment(const std::string& cardNumber, double amount)
    {
        std::cout << "Processing gift card payment with card " << cardNumber << ": $" << amount << std::endl;
        // 实际处理逻辑
        return true;
    }
    
    // 验证方法
    bool validateCreditCard(const std::string& cardDetails)
    {
        // 简单的信用卡验证:16位数字
        if (cardDetails.length() != 16) return false;
        for (char c : cardDetails)
        {
            if (!std::isdigit(c)) return false;
        }
        return true;
    }
    
    bool validatePayPalEmail(const std::string& email)
    {
        return email.find('@') != std::string::npos;
    }
    
    bool validateBankAccount(const std::string& account)
    {
        return !account.empty();
    }
    
    bool validateCryptoWallet(const std::string& wallet)
    {
        return wallet.length() >= 26 && wallet.length() <= 35;
    }
    
    bool validateGiftCard(const std::string& cardNumber)
    {
        return cardNumber.length() == 16;
    }
};

// 问题:每次添加新的支付类型时,需要修改多个switch语句
// 违反了开闭原则

// 重构后:使用多态
class PaymentMethod
{
public:
    virtual ~PaymentMethod() = default;
    
    virtual bool processPayment(double amount) = 0;
    virtual std::string getReceiptDetails() const = 0;
    virtual bool validate() const = 0;
    virtual std::string getMethodName() const = 0;
    
    // 模板方法:通用的支付流程
    bool executePayment(double amount)
    {
        if (!validate())
        {
            std::cerr << "Payment validation failed for " << getMethodName() << std::endl;
            return false;
        }
        
        std::cout << "Starting payment process for " << getMethodName() << std::endl;
        bool success = processPayment(amount);
        
        if (success)
        {
            std::cout << "Payment completed successfully" << std::endl;
        }
        else
        {
            std::cerr << "Payment failed for " << getMethodName() << std::endl;
        }
        
        return success;
    }
    
    // 生成收据的通用方法
    std::string generateReceipt(double amount) const
    {
        std::string receipt = "Payment Receipt\n";
        receipt += "Method: " + getMethodName() + "\n";
        receipt += "Amount: $" + std::to_string(amount) + "\n";
        receipt += getReceiptDetails();
        receipt += "Status: Completed\n";
        return receipt;
    }
};

// 信用卡支付
class CreditCardPayment : public PaymentMethod
{
private:
    std::string cardNumber;
    std::string cardHolderName;
    std::string expiryDate;
    std::string cvv;
    
public:
    CreditCardPayment(const std::string& number, const std::string& name,
                     const std::string& expiry, const std::string& cvvCode)
        : cardNumber(number), cardHolderName(name), expiryDate(expiry), cvv(cvvCode)
    {
    }
    
    bool processPayment(double amount) override
    {
        std::cout << "Processing credit card payment: $" << amount << std::endl;
        std::cout << "Card: **** **** **** " << cardNumber.substr(cardNumber.length() - 4) << std::endl;
        // 实际处理逻辑:连接到支付网关等
        return true;
    }
    
    std::string getReceiptDetails() const override
    {
        return "Card: **** **** **** " + cardNumber.substr(cardNumber.length() - 4) + "\n";
    }
    
    bool validate() const override
    {
        if (cardNumber.length() != 16) return false;
        for (char c : cardNumber)
        {
            if (!std::isdigit(c)) return false;
        }
        
        if (cardHolderName.empty()) return false;
        if (expiryDate.length() != 5) return false; // MM/YY
        if (cvv.length() != 3) return false;
        
        return true;
    }
    
    std::string getMethodName() const override
    {
        return "Credit Card";
    }
};

// PayPal支付
class PayPalPayment : public PaymentMethod
{
private:
    std::string email;
    
public:
    PayPalPayment(const std::string& paypalEmail) : email(paypalEmail)
    {
    }
    
    bool processPayment(double amount) override
    {
        std::cout << "Processing PayPal payment from " << email << ": $" << amount << std::endl;
        // 实际处理逻辑:调用PayPal API
        return true;
    }
    
    std::string getReceiptDetails() const override
    {
        return "PayPal Email: " + email + "\n";
    }
    
    bool validate() const override
    {
        return email.find('@') != std::string::npos;
    }
    
    std::string getMethodName() const override
    {
        return "PayPal";
    }
};

// 银行转账
class BankTransferPayment : public PaymentMethod
{
private:
    std::string accountNumber;
    std::string routingNumber;
    std::string accountHolderName;
    
public:
    BankTransferPayment(const std::string& accNum, const std::string& routeNum,
                       const std::string& holderName)
        : accountNumber(accNum), routingNumber(routeNum), accountHolderName(holderName)
    {
    }
    
    bool processPayment(double amount) override
    {
        std::cout << "Processing bank transfer to account " << accountNumber << ": $" << amount << std::endl;
        // 实际处理逻辑:发起银行转账
        return true;
    }
    
    std::string getReceiptDetails() const override
    {
        return "Bank Account: " + accountNumber + "\n";
    }
    
    bool validate() const override
    {
        return !accountNumber.empty() && !routingNumber.empty() && !accountHolderName.empty();
    }
    
    std::string getMethodName() const override
    {
        return "Bank Transfer";
    }
};

// 加密货币支付
class CryptocurrencyPayment : public PaymentMethod
{
private:
    std::string walletAddress;
    std::string currency; // BTC, ETH等
    
public:
    CryptocurrencyPayment(const std::string& wallet, const std::string& cryptoCurrency)
        : walletAddress(wallet), currency(cryptoCurrency)
    {
    }
    
    bool processPayment(double amount) override
    {
        std::cout << "Processing " << currency << " payment to " << walletAddress << ": $" << amount << std::endl;
        // 实际处理逻辑:创建加密货币交易
        return true;
    }
    
    std::string getReceiptDetails() const override
    {
        return "Cryptocurrency: " + currency + "\nWallet: " + walletAddress + "\n";
    }
    
    bool validate() const override
    {
        return walletAddress.length() >= 26 && walletAddress.length() <= 35;
    }
    
    std::string getMethodName() const override
    {
        return currency + " (Cryptocurrency)";
    }
};

// 新增支付类型:移动支付
class MobilePayment : public PaymentMethod
{
private:
    std::string phoneNumber;
    std::string provider; // Apple Pay, Google Pay等
    
public:
    MobilePayment(const std::string& phone, const std::string& paymentProvider)
        : phoneNumber(phone), provider(paymentProvider)
    {
    }
    
    bool processPayment(double amount) override
    {
        std::cout << "Processing " << provider << " payment from " << phoneNumber << ": $" << amount << std::endl;
        // 实际处理逻辑
        return true;
    }
    
    std::string getReceiptDetails() const override
    {
        return "Mobile Payment: " + provider + "\nPhone: " + phoneNumber + "\n";
    }
    
    bool validate() const override
    {
        return !phoneNumber.empty() && !provider.empty();
    }
    
    std::string getMethodName() const override
    {
        return provider + " (Mobile Payment)";
    }
};

// 支付处理器(使用多态)
class PaymentProcessor
{
public:
    bool processPayment(PaymentMethod& method, double amount)
    {
        return method.executePayment(amount);
    }
    
    std::string generateReceipt(PaymentMethod& method, double amount)
    {
        return method.generateReceipt(amount);
    }
};

// 支付工厂
class PaymentFactory
{
public:
    static std::unique_ptr<PaymentMethod> createCreditCardPayment(
        const std::string& cardNumber, const std::string& name,
        const std::string& expiry, const std::string& cvv)
    {
        return std::make_unique<CreditCardPayment>(cardNumber, name, expiry, cvv);
    }
    
    static std::unique_ptr<PaymentMethod> createPayPalPayment(const std::string& email)
    {
        return std::make_unique<PayPalPayment>(email);
    }
    
    static std::unique_ptr<PaymentMethod> createBankTransferPayment(
        const std::string& accountNumber, const std::string& routingNumber,
        const std::string& holderName)
    {
        return std::make_unique<BankTransferPayment>(accountNumber, routingNumber, holderName);
    }
    
    static std::unique_ptr<PaymentMethod> createCryptocurrencyPayment(
        const std::string& walletAddress, const std::string& currency)
    {
        return std::make_unique<CryptocurrencyPayment>(walletAddress, currency);
    }
    
    static std::unique_ptr<PaymentMethod> createMobilePayment(
        const std::string& phoneNumber, const std::string& provider)
    {
        return std::make_unique<MobilePayment>(phoneNumber, provider);
    }
};

int main()
{
    std::cout << "=== 重构前:使用switch处理支付 ===" << std::endl;
    
    PaymentProcessorOld oldProcessor;
    PaymentProcessorOld::PaymentDetails payment;
    payment.type = PaymentProcessorOld::PaymentType::CREDIT_CARD;
    payment.details = "4111111111111111";
    payment.amount = 100.0;
    
    bool success = oldProcessor.processPayment(payment);
    std::cout << "Payment success: " << (success ? "Yes" : "No") << std::endl;
    
    std::string receipt = oldProcessor.generateReceipt(payment);
    std::cout << "\nReceipt:\n" << receipt << std::endl;
    
    std::cout << "\n=== 重构后:使用多态处理支付 ===" << std::endl;
    
    PaymentProcessor processor;
    
    // 测试信用卡支付
    auto creditCard = PaymentFactory::createCreditCardPayment(
        "4111111111111111", "John Doe", "12/25", "123");
    
    success = processor.processPayment(*creditCard, 150.0);
    std::cout << "\nCredit Card Payment success: " << (success ? "Yes" : "No") << std::endl;
    
    std::string newReceipt = processor.generateReceipt(*creditCard, 150.0);
    std::cout << "\nReceipt:\n" << newReceipt << std::endl;
    
    // 测试PayPal支付
    auto paypal = PaymentFactory::createPayPalPayment("john@example.com");
    success = processor.processPayment(*paypal, 75.50);
    std::cout << "\nPayPal Payment success: " << (success ? "Yes" : "No") << std::endl;
    
    // 测试加密货币支付
    auto crypto = PaymentFactory::createCryptocurrencyPayment(
        "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa", "BTC");
    success = processor.processPayment(*crypto, 200.0);
    std::cout << "\nCrypto Payment success: " << (success ? "Yes" : "No") << std::endl;
    
    // 测试新增的移动支付(无需修改现有代码)
    auto mobile = PaymentFactory::createMobilePayment("+1234567890", "Apple Pay");
    success = processor.processPayment(*mobile, 50.0);
    std::cout << "\nMobile Payment success: " << (success ? "Yes" : "No") << std::endl;
    
    // 测试无效支付
    std::cout << "\n=== 测试无效支付 ===" << std::endl;
    auto invalidCard = PaymentFactory::createCreditCardPayment(
        "1234", "Jane Doe", "12/25", "123"); // 无效卡号
    
    try
    {
        success = processor.processPayment(*invalidCard, 100.0);
        std::cout << "Invalid Payment success: " << (success ? "Yes" : "No") << std::endl;
    }
    catch (const std::exception& e)
    {
        std::cerr << "Payment failed: " << e.what() << std::endl;
    }
    
    // 优势:可以轻松添加新的支付类型
    std::cout << "\n=== 添加新的支付类型示例 ===" << std::endl;
    
    // 假设我们需要添加"先享后付"支付
    class BuyNowPayLaterPayment : public PaymentMethod
    {
    private:
        std::string provider;
        int installmentMonths;
        
    public:
        BuyNowPayLaterPayment(const std::string& paymentProvider, int months)
            : provider(paymentProvider), installmentMonths(months)
        {
        }
        
        bool processPayment(double amount) override
        {
            double monthlyPayment = amount / installmentMonths;
            std::cout << "Processing " << provider << " payment: $" << amount << std::endl;
            std::cout << "Monthly payment: $" << monthlyPayment << " for " << installmentMonths << " months" << std::endl;
            return true;
        }
        
        std::string getReceiptDetails() const override
        {
            return "Buy Now Pay Later: " + provider + "\n" +
                   "Installments: " + std::to_string(installmentMonths) + " months\n";
        }
        
        bool validate() const override
        {
            return !provider.empty() && installmentMonths > 0;
        }
        
        std::string getMethodName() const override
        {
            return provider + " (Buy Now Pay Later)";
        }
    };
    
    // 使用新支付类型
    BuyNowPayLaterPayment bnpl("Klarna", 6);
    success = processor.processPayment(bnpl, 600.0);
    std::cout << "\nBNPL Payment success: " << (success ? "Yes" : "No") << std::endl;
    
    // 注意:我们添加了新的支付类型,但没有修改任何现有代码
    // 这符合开闭原则
    
    return 0;
}

本章节详细介绍了代码坏味道3.7到3.10的识别与重构方法。这些坏味道在实际项目中非常常见,识别并采取适当的重构措施可以显著提高代码质量。后续的坏味道(从3.11到3.22)虽然也很重要,但它们的处理原则类似:识别问题模式,应用适当的设计模式和重构技术,使代码更加清晰、可维护和可扩展。在实际开发中,我们应该培养对这些坏味道的敏感性,并将其重构作为日常开发流程的一部分。

第三章(续):识别代码中的设计问题与重构策略(第三部分)

在软件开发的持续演进过程中,代码质量的维护是一个永无止境的任务。本章继续探讨剩余代码坏味道的识别与重构策略,为每种坏味道提供具体的商业项目实例,并展示在C++、C#和Java三种语言中的解决方法。

3.11 平行继承体系:重复的类层次结构

平行继承体系是指每当你为某个类增加一个子类,必须也为另一个类相应增加一个子类。这种坏味道表明两个继承体系之间存在紧密的耦合关系。

商业场景:图形编辑系统中的形状与渲染器

C++ 示例:形状与渲染器的平行继承
#include <iostream>
#include <string>
#include <memory>
#include <vector>

// 平行继承体系示例:形状和渲染器有平行的继承结构
class Shape
{
public:
    virtual ~Shape() = default;
    virtual void draw() = 0;
    virtual double calculateArea() = 0;
};

class Circle : public Shape
{
private:
    double radius;
    
public:
    Circle(double r) : radius(r) {}
    
    void draw() override
    {
        std::cout << "Drawing a circle" << std::endl;
    }
    
    double calculateArea() override
    {
        return 3.14159 * radius * radius;
    }
};

class Rectangle : public Shape
{
private:
    double width;
    double height;
    
public:
    Rectangle(double w, double h) : width(w), height(h) {}
    
    void draw() override
    {
        std::cout << "Drawing a rectangle" << std::endl;
    }
    
    double calculateArea() override
    {
        return width * height;
    }
};

// 平行继承:渲染器体系
class Renderer
{
public:
    virtual ~Renderer() = default;
    virtual void renderCircle() = 0;
    virtual void renderRectangle() = 0;
};

class ScreenRenderer : public Renderer
{
public:
    void renderCircle() override
    {
        std::cout << "Rendering circle on screen" << std::endl;
    }
    
    void renderRectangle() override
    {
        std::cout << "Rendering rectangle on screen" << std::endl;
    }
};

class PrinterRenderer : public Renderer
{
public:
    void renderCircle() override
    {
        std::cout << "Printing circle to printer" << std::endl;
    }
    
    void renderRectangle() override
    {
        std::cout << "Printing rectangle to printer" << std::endl;
    }
};

// 问题:每当添加新的形状(如Triangle),也必须添加新的渲染方法
// 这导致两个继承体系紧密耦合

// 重构后:使用桥接模式分离抽象和实现
class DrawingAPI
{
public:
    virtual ~DrawingAPI() = default;
    virtual void drawCircle(double x, double y, double radius) = 0;
    virtual void drawRectangle(double x, double y, double width, double height) = 0;
    virtual void drawTriangle(double x1, double y1, double x2, double y2, double x3, double y3) = 0;
};

class ScreenDrawingAPI : public DrawingAPI
{
public:
    void drawCircle(double x, double y, double radius) override
    {
        std::cout << "Drawing circle on screen at (" << x << "," << y 
                  << ") with radius " << radius << std::endl;
    }
    
    void drawRectangle(double x, double y, double width, double height) override
    {
        std::cout << "Drawing rectangle on screen at (" << x << "," << y 
                  << ") with size " << width << "x" << height << std::endl;
    }
    
    void drawTriangle(double x1, double y1, double x2, double y2, double x3, double y3) override
    {
        std::cout << "Drawing triangle on screen with points (" << x1 << "," << y1 
                  << "), (" << x2 << "," << y2 << "), (" << x3 << "," << y3 << ")" << std::endl;
    }
};

class PrinterDrawingAPI : public DrawingAPI
{
public:
    void drawCircle(double x, double y, double radius) override
    {
        std::cout << "Printing circle to printer at (" << x << "," << y 
                  << ") with radius " << radius << std::endl;
    }
    
    void drawRectangle(double x, double y, double width, double height) override
    {
        std::cout << "Printing rectangle to printer at (" << x << "," << y 
                  << ") with size " << width << "x" << height << std::endl;
    }
    
    void drawTriangle(double x1, double y1, double x2, double y2, double x3, double y3) override
    {
        std::cout << "Printing triangle to printer with points (" << x1 << "," << y1 
                  << "), (" << x2 << "," << y2 << "), (" << x3 << "," << y3 << ")" << std::endl;
    }
};

// 重构后的形状类
class RefactoredShape
{
protected:
    std::shared_ptr<DrawingAPI> drawingAPI;
    
public:
    RefactoredShape(std::shared_ptr<DrawingAPI> api) : drawingAPI(api) {}
    virtual ~RefactoredShape() = default;
    
    virtual void draw() = 0;
    virtual double calculateArea() = 0;
    virtual void move(double dx, double dy) = 0;
};

class RefactoredCircle : public RefactoredShape
{
private:
    double centerX;
    double centerY;
    double radius;
    
public:
    RefactoredCircle(double x, double y, double r, std::shared_ptr<DrawingAPI> api)
        : RefactoredShape(api), centerX(x), centerY(y), radius(r) {}
    
    void draw() override
    {
        drawingAPI->drawCircle(centerX, centerY, radius);
    }
    
    double calculateArea() override
    {
        return 3.14159 * radius * radius;
    }
    
    void move(double dx, double dy) override
    {
        centerX += dx;
        centerY += dy;
    }
    
    double getRadius() const { return radius; }
    void setRadius(double r) { radius = r; }
};

class RefactoredRectangle : public RefactoredShape
{
private:
    double x;
    double y;
    double width;
    double height;
    
public:
    RefactoredRectangle(double posX, double posY, double w, double h, std::shared_ptr<DrawingAPI> api)
        : RefactoredShape(api), x(posX), y(posY), width(w), height(h) {}
    
    void draw() override
    {
        drawingAPI->drawRectangle(x, y, width, height);
    }
    
    double calculateArea() override
    {
        return width * height;
    }
    
    void move(double dx, double dy) override
    {
        x += dx;
        y += dy;
    }
    
    double getWidth() const { return width; }
    double getHeight() const { return height; }
    void resize(double w, double h) { width = w; height = h; }
};

// 现在添加新形状(三角形)很容易,不需要修改渲染器
class Triangle : public RefactoredShape
{
private:
    double x1, y1, x2, y2, x3, y3;
    
public:
    Triangle(double x1, double y1, double x2, double y2, double x3, double y3,
             std::shared_ptr<DrawingAPI> api)
        : RefactoredShape(api), x1(x1), y1(y1), x2(x2), y2(y2), x3(x3), y3(y3) {}
    
    void draw() override
    {
        drawingAPI->drawTriangle(x1, y1, x2, y2, x3, y3);
    }
    
    double calculateArea() override
    {
        // 使用海伦公式计算三角形面积
        double a = std::sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
        double b = std::sqrt((x3-x2)*(x3-x2) + (y3-y2)*(y3-y2));
        double c = std::sqrt((x1-x3)*(x1-x3) + (y1-y3)*(y1-y3));
        double s = (a + b + c) / 2;
        return std::sqrt(s * (s-a) * (s-b) * (s-c));
    }
    
    void move(double dx, double dy) override
    {
        x1 += dx; y1 += dy;
        x2 += dx; y2 += dy;
        x3 += dx; y3 += dy;
    }
};

// 图形编辑器类
class GraphicsEditor
{
private:
    std::vector<std::shared_ptr<RefactoredShape>> shapes;
    
public:
    void addShape(std::shared_ptr<RefactoredShape> shape)
    {
        shapes.push_back(shape);
    }
    
    void drawAll()
    {
        std::cout << "\nDrawing all shapes:" << std::endl;
        for (const auto& shape : shapes)
        {
            shape->draw();
        }
    }
    
    double calculateTotalArea()
    {
        double total = 0.0;
        for (const auto& shape : shapes)
        {
            total += shape->calculateArea();
        }
        return total;
    }
    
    void moveAll(double dx, double dy)
    {
        for (const auto& shape : shapes)
        {
            shape->move(dx, dy);
        }
    }
};

int main()
{
    std::cout << "=== 平行继承体系示例 ===" << std::endl;
    
    // 使用平行继承体系
    Circle circle(5.0);
    Rectangle rectangle(4.0, 6.0);
    
    circle.draw();
    rectangle.draw();
    
    ScreenRenderer screenRenderer;
    screenRenderer.renderCircle();
    screenRenderer.renderRectangle();
    
    std::cout << "\n=== 重构后:使用桥接模式 ===" << std::endl;
    
    // 创建不同的绘制API
    auto screenAPI = std::make_shared<ScreenDrawingAPI>();
    auto printerAPI = std::make_shared<PrinterDrawingAPI>();
    
    // 创建图形编辑器
    GraphicsEditor editor;
    
    // 添加使用屏幕API的形状
    editor.addShape(std::make_shared<RefactoredCircle>(10, 10, 5, screenAPI));
    editor.addShape(std::make_shared<RefactoredRectangle>(20, 20, 8, 6, screenAPI));
    
    // 添加使用打印机API的形状
    editor.addShape(std::make_shared<RefactoredCircle>(50, 50, 3, printerAPI));
    
    // 添加新形状:三角形(不需要修改渲染器)
    editor.addShape(std::make_shared<Triangle>(0, 0, 10, 0, 5, 8.66, screenAPI));
    
    // 绘制所有形状
    editor.drawAll();
    
    // 计算总面积
    std::cout << "\nTotal area: " << editor.calculateTotalArea() << std::endl;
    
    // 移动所有形状
    editor.moveAll(5, 5);
    std::cout << "\nAfter moving all shapes by (5, 5):" << std::endl;
    editor.drawAll();
    
    // 添加新的绘制API很容易,不需要修改形状类
    class OpenGLDrawingAPI : public DrawingAPI
    {
    public:
        void drawCircle(double x, double y, double radius) override
        {
            std::cout << "Drawing circle with OpenGL at (" << x << "," << y 
                      << ") with radius " << radius << std::endl;
        }
        
        void drawRectangle(double x, double y, double width, double height) override
        {
            std::cout << "Drawing rectangle with OpenGL at (" << x << "," << y 
                      << ") with size " << width << "x" << height << std::endl;
        }
        
        void drawTriangle(double x1, double y1, double x2, double y2, double x3, double y3) override
        {
            std::cout << "Drawing triangle with OpenGL with points (" << x1 << "," << y1 
                      << "), (" << x2 << "," << y2 << "), (" << x3 << "," << y3 << ")" << std::endl;
        }
    };
    
    auto openGLAPI = std::make_shared<OpenGLDrawingAPI>();
    editor.addShape(std::make_shared<RefactoredCircle>(100, 100, 7, openGLAPI));
    
    std::cout << "\n=== 添加OpenGL渲染后的结果 ===" << std::endl;
    editor.drawAll();
    
    return 0;
}

3.12 冗赘类:功能过少的类

冗赘类是指一个类的功能太少,与其存在带来的复杂性不成比例。这类类通常是由于过度设计或重构后留下的"僵尸类"。

商业场景:用户权限系统中的过度设计

C# 示例:功能过小的权限类
using System;
using System.Collections.Generic;

namespace AuthorizationSystem
{
    // 冗赘类示例:过度细分的权限类
    public class UserPermissionChecker
    {
        public bool CanRead { get; set; }
        public bool CanWrite { get; set; }
        public bool CanDelete { get; set; }
        
        public UserPermissionChecker(bool read, bool write, bool delete)
        {
            CanRead = read;
            CanWrite = write;
            CanDelete = delete;
        }
        
        public bool CheckReadPermission()
        {
            return CanRead;
        }
        
        public bool CheckWritePermission()
        {
            return CanWrite;
        }
        
        public bool CheckDeletePermission()
        {
            return CanDelete;
        }
    }
    
    public class AdminPermissionChecker
    {
        public bool IsAdmin { get; set; }
        
        public AdminPermissionChecker(bool isAdmin)
        {
            IsAdmin = isAdmin;
        }
        
        public bool CheckAdminPermission()
        {
            return IsAdmin;
        }
    }
    
    public class AuditPermissionChecker
    {
        public bool CanAudit { get; set; }
        
        public AuditPermissionChecker(bool canAudit)
        {
            CanAudit = canAudit;
        }
        
        public bool CheckAuditPermission()
        {
            return CanAudit;
        }
    }
    
    public class ReportPermissionChecker
    {
        public bool CanGenerateReports { get; set; }
        
        public ReportPermissionChecker(bool canGenerateReports)
        {
            CanGenerateReports = canGenerateReports;
        }
        
        public bool CheckReportPermission()
        {
            return CanGenerateReports;
        }
    }
    
    // 使用这些冗赘类
    public class UserAccessManagerOld
    {
        private UserPermissionChecker userChecker;
        private AdminPermissionChecker adminChecker;
        private AuditPermissionChecker auditChecker;
        private ReportPermissionChecker reportChecker;
        
        public UserAccessManagerOld(bool isAdmin, bool canRead, bool canWrite, 
                                    bool canDelete, bool canAudit, bool canGenerateReports)
        {
            userChecker = new UserPermissionChecker(canRead, canWrite, canDelete);
            adminChecker = new AdminPermissionChecker(isAdmin);
            auditChecker = new AuditPermissionChecker(canAudit);
            reportChecker = new ReportPermissionChecker(canGenerateReports);
        }
        
        public bool HasFullAccess()
        {
            return adminChecker.CheckAdminPermission();
        }
        
        public bool CanModifyContent()
        {
            return userChecker.CheckWritePermission() || adminChecker.CheckAdminPermission();
        }
        
        // 每个方法都需要检查多个检查器
        public bool CanPerformAudit()
        {
            return auditChecker.CheckAuditPermission() || adminChecker.CheckAdminPermission();
        }
        
        public bool CanGenerateReport()
        {
            return reportChecker.CheckReportPermission() || adminChecker.CheckAdminPermission();
        }
    }
    
    // 问题:每个权限检查器只有一个方法,过于简单
    // 重构:将这些类合并或内联
    
    // 重构后:使用权限标志枚举
    [Flags]
    public enum PermissionFlags
    {
        None = 0,
        Read = 1 << 0,
        Write = 1 << 1,
        Delete = 1 << 2,
        Audit = 1 << 3,
        GenerateReports = 1 << 4,
        Admin = 1 << 5,
        
        // 组合权限
        BasicUser = Read | Write,
        PowerUser = Read | Write | Delete | GenerateReports,
        Auditor = Read | Audit,
        FullAccess = Read | Write | Delete | Audit | GenerateReports | Admin
    }
    
    // 重构后的权限类
    public class UserPermissions
    {
        private PermissionFlags permissions;
        
        public UserPermissions(PermissionFlags initialPermissions)
        {
            permissions = initialPermissions;
        }
        
        // 检查单个权限
        public bool HasPermission(PermissionFlags permission)
        {
            return (permissions & permission) == permission;
        }
        
        // 检查多个权限(所有都必须满足)
        public bool HasAllPermissions(PermissionFlags requiredPermissions)
        {
            return (permissions & requiredPermissions) == requiredPermissions;
        }
        
        // 检查多个权限(至少满足一个)
        public bool HasAnyPermission(PermissionFlags possiblePermissions)
        {
            return (permissions & possiblePermissions) != PermissionFlags.None;
        }
        
        // 添加权限
        public void GrantPermission(PermissionFlags permission)
        {
            permissions |= permission;
        }
        
        // 移除权限
        public void RevokePermission(PermissionFlags permission)
        {
            permissions &= ~permission;
        }
        
        // 获取所有权限
        public PermissionFlags GetAllPermissions()
        {
            return permissions;
        }
        
        // 便捷方法:检查常见权限组合
        public bool CanRead => HasPermission(PermissionFlags.Read);
        public bool CanWrite => HasPermission(PermissionFlags.Write);
        public bool CanDelete => HasPermission(PermissionFlags.Delete);
        public bool CanAudit => HasPermission(PermissionFlags.Audit);
        public bool CanGenerateReports => HasPermission(PermissionFlags.GenerateReports);
        public bool IsAdmin => HasPermission(PermissionFlags.Admin);
        
        // 复杂的权限检查逻辑
        public bool CanModifyContent => CanWrite || IsAdmin;
        public bool CanManageUsers => IsAdmin;
        public bool CanViewAuditLogs => CanAudit || IsAdmin;
        
        // 工厂方法:创建常见角色
        public static UserPermissions CreateGuest()
        {
            return new UserPermissions(PermissionFlags.Read);
        }
        
        public static UserPermissions CreateBasicUser()
        {
            return new UserPermissions(PermissionFlags.BasicUser);
        }
        
        public static UserPermissions CreatePowerUser()
        {
            return new UserPermissions(PermissionFlags.PowerUser);
        }
        
        public static UserPermissions CreateAuditor()
        {
            return new UserPermissions(PermissionFlags.Auditor);
        }
        
        public static UserPermissions CreateAdministrator()
        {
            return new UserPermissions(PermissionFlags.FullAccess);
        }
    }
    
    // 重构后的访问管理器
    public class UserAccessManager
    {
        private UserPermissions permissions;
        
        public UserAccessManager(UserPermissions userPermissions)
        {
            permissions = userPermissions;
        }
        
        public UserAccessManager(PermissionFlags permissionFlags)
        {
            permissions = new UserPermissions(permissionFlags);
        }
        
        // 权限检查现在很简单
        public bool HasFullAccess()
        {
            return permissions.IsAdmin;
        }
        
        public bool CanModifyContent()
        {
            return permissions.CanModifyContent;
        }
        
        public bool CanPerformAudit()
        {
            return permissions.CanViewAuditLogs;
        }
        
        public bool CanGenerateReport()
        {
            return permissions.CanGenerateReports || permissions.IsAdmin;
        }
        
        // 动态权限检查
        public bool CheckAccess(string operation)
        {
            switch (operation.ToLower())
            {
                case "read":
                    return permissions.CanRead;
                case "write":
                    return permissions.CanWrite;
                case "delete":
                    return permissions.CanDelete;
                case "audit":
                    return permissions.CanAudit;
                case "report":
                    return permissions.CanGenerateReports;
                case "admin":
                    return permissions.IsAdmin;
                default:
                    return false;
            }
        }
        
        // 基于资源的权限检查
        public bool CheckResourceAccess(string resourceType, string action)
        {
            // 简化实现:实际中会有更复杂的规则
            if (permissions.IsAdmin)
            {
                return true;
            }
            
            switch (resourceType.ToLower())
            {
                case "document":
                    return action.ToLower() switch
                    {
                        "view" => permissions.CanRead,
                        "edit" => permissions.CanWrite,
                        "delete" => permissions.CanDelete,
                        _ => false
                    };
                    
                case "auditlog":
                    return action.ToLower() == "view" && permissions.CanAudit;
                    
                case "report":
                    return action.ToLower() == "generate" && permissions.CanGenerateReports;
                    
                default:
                    return false;
            }
        }
    }
    
    // 权限策略类(如果需要更复杂的规则)
    public interface IPermissionPolicy
    {
        bool CheckAccess(UserPermissions permissions, string resource, string action);
    }
    
    public class DocumentPermissionPolicy : IPermissionPolicy
    {
        public bool CheckAccess(UserPermissions permissions, string resource, string action)
        {
            if (permissions.IsAdmin)
            {
                return true;
            }
            
            return action.ToLower() switch
            {
                "view" => permissions.CanRead,
                "edit" => permissions.CanWrite && permissions.HasPermission(PermissionFlags.Read),
                "delete" => permissions.CanDelete && permissions.HasPermission(PermissionFlags.Read),
                "share" => permissions.CanWrite && permissions.CanRead,
                _ => false
            };
        }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("=== 冗赘类示例:过度细分的权限检查器 ===");
            
            // 使用重构前的代码
            UserAccessManagerOld oldManager = new UserAccessManagerOld(
                isAdmin: false,
                canRead: true,
                canWrite: true,
                canDelete: false,
                canAudit: false,
                canGenerateReports: true
            );
            
            Console.WriteLine("Old Manager - Can Modify Content: " + oldManager.CanModifyContent());
            Console.WriteLine("Old Manager - Can Generate Report: " + oldManager.CanGenerateReport());
            
            Console.WriteLine("\n=== 重构后:使用权限枚举 ===");
            
            // 创建权限
            PermissionFlags userPermissions = PermissionFlags.Read | 
                                             PermissionFlags.Write | 
                                             PermissionFlags.GenerateReports;
            
            UserPermissions permissions = new UserPermissions(userPermissions);
            UserAccessManager manager = new UserAccessManager(permissions);
            
            Console.WriteLine("New Manager - Can Read: " + manager.CheckAccess("read"));
            Console.WriteLine("New Manager - Can Write: " + manager.CheckAccess("write"));
            Console.WriteLine("New Manager - Can Modify Content: " + manager.CanModifyContent());
            Console.WriteLine("New Manager - Can Generate Report: " + manager.CanGenerateReport());
            
            // 测试基于资源的权限检查
            Console.WriteLine("\n=== 基于资源的权限检查 ===");
            Console.WriteLine("Can view document: " + 
                manager.CheckResourceAccess("document", "view"));
            Console.WriteLine("Can edit document: " + 
                manager.CheckResourceAccess("document", "edit"));
            Console.WriteLine("Can delete document: " + 
                manager.CheckResourceAccess("document", "delete"));
            Console.WriteLine("Can view audit log: " + 
                manager.CheckResourceAccess("auditlog", "view"));
            
            // 创建管理员用户
            Console.WriteLine("\n=== 管理员权限示例 ===");
            UserPermissions adminPermissions = UserPermissions.CreateAdministrator();
            UserAccessManager adminManager = new UserAccessManager(adminPermissions);
            
            Console.WriteLine("Admin - Can view document: " + 
                adminManager.CheckResourceAccess("document", "view"));
            Console.WriteLine("Admin - Can delete document: " + 
                adminManager.CheckResourceAccess("document", "delete"));
            Console.WriteLine("Admin - Can view audit log: " + 
                adminManager.CheckResourceAccess("auditlog", "view"));
            
            // 动态修改权限
            Console.WriteLine("\n=== 动态权限修改示例 ===");
            UserPermissions dynamicPermissions = UserPermissions.CreateBasicUser();
            Console.WriteLine("Initial - Can delete: " + dynamicPermissions.CanDelete);
            
            dynamicPermissions.GrantPermission(PermissionFlags.Delete);
            Console.WriteLine("After granting delete - Can delete: " + dynamicPermissions.CanDelete);
            
            dynamicPermissions.RevokePermission(PermissionFlags.Write);
            Console.WriteLine("After revoking write - Can write: " + dynamicPermissions.CanWrite);
            
            // 使用权限策略
            Console.WriteLine("\n=== 使用权限策略 ===");
            IPermissionPolicy documentPolicy = new DocumentPermissionPolicy();
            
            bool canEdit = documentPolicy.CheckAccess(dynamicPermissions, "document", "edit");
            bool canShare = documentPolicy.CheckAccess(dynamicPermissions, "document", "share");
            
            Console.WriteLine("With current permissions:");
            Console.WriteLine("  Can edit document: " + canEdit);
            Console.WriteLine("  Can share document: " + canShare);
            
            // 授予缺失的权限
            dynamicPermissions.GrantPermission(PermissionFlags.Read);
            canEdit = documentPolicy.CheckAccess(dynamicPermissions, "document", "edit");
            canShare = documentPolicy.CheckAccess(dynamicPermissions, "document", "share");
            
            Console.WriteLine("After granting read permission:");
            Console.WriteLine("  Can edit document: " + canEdit);
            Console.WriteLine("  Can share document: " + canShare);
        }
    }
}

3.13 夸夸其谈未来性:过度设计应对未来变化

夸夸其谈未来性是指为了应对可能发生(但通常不会发生)的未来变化而进行的过度设计。这种设计增加了系统的复杂性,但带来的价值有限。

商业场景:订单系统中的过度抽象

Java 示例:为未来扩展过度设计的订单系统
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

// 夸夸其谈未来性示例:过度抽象的订单系统
interface IOrderItem {
    double calculatePrice();
    String getDescription();
}

interface IOrder {
    void addItem(IOrderItem item);
    double calculateTotal();
    String generateInvoice();
}

interface IPaymentProcessor {
    boolean processPayment(double amount);
}

interface IShippingCalculator {
    double calculateShippingCost(String address);
}

interface ITaxCalculator {
    double calculateTax(double amount, String country);
}

interface IDiscountCalculator {
    double calculateDiscount(double amount, String customerType);
}

// 具体实现类
class BasicOrderItem implements IOrderItem {
    private String name;
    private double price;
    private int quantity;
    
    public BasicOrderItem(String name, double price, int quantity) {
        this.name = name;
        this.price = price;
        this.quantity = quantity;
    }
    
    @Override
    public double calculatePrice() {
        return price * quantity;
    }
    
    @Override
    public String getDescription() {
        return name + " x" + quantity;
    }
}

// 为未来可能的各种订单类型做准备
class StandardOrder implements IOrder {
    private List<IOrderItem> items;
    private IPaymentProcessor paymentProcessor;
    private IShippingCalculator shippingCalculator;
    private ITaxCalculator taxCalculator;
    private IDiscountCalculator discountCalculator;
    
    public StandardOrder(IPaymentProcessor paymentProcessor,
                        IShippingCalculator shippingCalculator,
                        ITaxCalculator taxCalculator,
                        IDiscountCalculator discountCalculator) {
        this.items = new ArrayList<>();
        this.paymentProcessor = paymentProcessor;
        this.shippingCalculator = shippingCalculator;
        this.taxCalculator = taxCalculator;
        this.discountCalculator = discountCalculator;
    }
    
    @Override
    public void addItem(IOrderItem item) {
        items.add(item);
    }
    
    @Override
    public double calculateTotal() {
        double subtotal = 0;
        for (IOrderItem item : items) {
            subtotal += item.calculatePrice();
        }
        
        // 计算各种费用
        double shipping = shippingCalculator.calculateShippingCost("default");
        double tax = taxCalculator.calculateTax(subtotal, "US");
        double discount = discountCalculator.calculateDiscount(subtotal, "regular");
        
        return subtotal + shipping + tax - discount;
    }
    
    @Override
    public String generateInvoice() {
        StringBuilder invoice = new StringBuilder();
        invoice.append("Invoice\n");
        invoice.append("=======\n");
        
        for (IOrderItem item : items) {
            invoice.append(item.getDescription()).append(": $")
                   .append(item.calculatePrice()).append("\n");
        }
        
        invoice.append("Total: $").append(calculateTotal()).append("\n");
        return invoice.toString();
    }
}

// 各种计算器的简单实现
class SimplePaymentProcessor implements IPaymentProcessor {
    @Override
    public boolean processPayment(double amount) {
        System.out.println("Processing payment of $" + amount);
        return true;
    }
}

class SimpleShippingCalculator implements IShippingCalculator {
    @Override
    public double calculateShippingCost(String address) {
        // 简化实现
        return 10.0;
    }
}

class SimpleTaxCalculator implements ITaxCalculator {
    @Override
    public double calculateTax(double amount, String country) {
        if ("US".equals(country)) {
            return amount * 0.08; // 8%税率
        }
        return amount * 0.1; // 默认10%
    }
}

class SimpleDiscountCalculator implements IDiscountCalculator {
    @Override
    public double calculateDiscount(double amount, String customerType) {
        if ("premium".equals(customerType)) {
            return amount * 0.1; // 10%折扣
        }
        return 0;
    }
}

// 问题:这个系统为未来做了太多抽象,但实际上可能只需要简单的订单处理
// 重构:根据当前需求简化设计,当需要扩展时再添加抽象

// 重构后的简单订单系统(满足当前需求)
class Product {
    private String name;
    private double price;
    
    public Product(String name, double price) {
        this.name = name;
        this.price = price;
    }
    
    public String getName() { return name; }
    public double getPrice() { return price; }
}

class OrderItem {
    private Product product;
    private int quantity;
    
    public OrderItem(Product product, int quantity) {
        this.product = product;
        this.quantity = quantity;
    }
    
    public double getItemTotal() {
        return product.getPrice() * quantity;
    }
    
    public String getDescription() {
        return product.getName() + " x" + quantity;
    }
    
    public Product getProduct() { return product; }
    public int getQuantity() { return quantity; }
}

// 根据当前需求设计订单类
class SimpleOrder {
    private List<OrderItem> items;
    private Date orderDate;
    private String customerId;
    private String shippingAddress;
    
    public SimpleOrder(String customerId, String shippingAddress) {
        this.items = new ArrayList<>();
        this.orderDate = new Date();
        this.customerId = customerId;
        this.shippingAddress = shippingAddress;
    }
    
    public void addProduct(Product product, int quantity) {
        // 检查是否已存在该产品
        for (OrderItem item : items) {
            if (item.getProduct().equals(product)) {
                // 可以合并数量或抛出异常,根据业务需求
                return;
            }
        }
        items.add(new OrderItem(product, quantity));
    }
    
    public double calculateSubtotal() {
        double subtotal = 0;
        for (OrderItem item : items) {
            subtotal += item.getItemTotal();
        }
        return subtotal;
    }
    
    public double calculateShipping() {
        // 简化实现:根据订单金额计算运费
        double subtotal = calculateSubtotal();
        if (subtotal > 100) {
            return 0; // 免运费
        } else if (subtotal > 50) {
            return 5.99;
        } else {
            return 9.99;
        }
    }
    
    public double calculateTax() {
        // 简化实现:固定税率
        return calculateSubtotal() * 0.08;
    }
    
    public double calculateDiscount() {
        // 简化实现:没有折扣逻辑
        return 0;
    }
    
    public double calculateTotal() {
        return calculateSubtotal() + calculateShipping() + 
               calculateTax() - calculateDiscount();
    }
    
    public String generateInvoice() {
        StringBuilder invoice = new StringBuilder();
        invoice.append("Invoice\n");
        invoice.append("=======\n");
        invoice.append("Order Date: ").append(orderDate).append("\n");
        invoice.append("Customer ID: ").append(customerId).append("\n");
        invoice.append("Shipping Address: ").append(shippingAddress).append("\n\n");
        
        invoice.append("Items:\n");
        for (OrderItem item : items) {
            invoice.append("  ").append(item.getDescription())
                   .append(": $").append(String.format("%.2f", item.getItemTotal()))
                   .append("\n");
        }
        
        invoice.append("\nSummary:\n");
        invoice.append("  Subtotal: $").append(String.format("%.2f", calculateSubtotal())).append("\n");
        invoice.append("  Shipping: $").append(String.format("%.2f", calculateShipping())).append("\n");
        invoice.append("  Tax: $").append(String.format("%.2f", calculateTax())).append("\n");
        invoice.append("  Discount: $").append(String.format("%.2f", calculateDiscount())).append("\n");
        invoice.append("  Total: $").append(String.format("%.2f", calculateTotal())).append("\n");
        
        return invoice.toString();
    }
    
    public boolean processPayment() {
        double total = calculateTotal();
        System.out.println("Processing payment of $" + 
                          String.format("%.2f", total) + 
                          " for order");
        // 简化实现
        return true;
    }
    
    // Getter方法
    public List<OrderItem> getItems() { return items; }
    public Date getOrderDate() { return orderDate; }
    public String getCustomerId() { return customerId; }
    public String getShippingAddress() { return shippingAddress; }
}

// 当需求增长时,可以逐步添加抽象
// 例如,添加折扣策略接口
interface DiscountStrategy {
    double calculateDiscount(double subtotal, String customerType);
}

class PremiumCustomerDiscount implements DiscountStrategy {
    @Override
    public double calculateDiscount(double subtotal, String customerType) {
        if ("premium".equals(customerType)) {
            return subtotal * 0.1; // 10%折扣
        }
        return 0;
    }
}

class SeasonalDiscount implements DiscountStrategy {
    private double discountRate;
    
    public SeasonalDiscount(double discountRate) {
        this.discountRate = discountRate;
    }
    
    @Override
    public double calculateDiscount(double subtotal, String customerType) {
        return subtotal * discountRate;
    }
}

// 增强的订单类(在需要时添加抽象)
class EnhancedOrder extends SimpleOrder {
    private DiscountStrategy discountStrategy;
    private String customerType;
    
    public EnhancedOrder(String customerId, String shippingAddress, 
                         String customerType, DiscountStrategy discountStrategy) {
        super(customerId, shippingAddress);
        this.customerType = customerType;
        this.discountStrategy = discountStrategy;
    }
    
    @Override
    public double calculateDiscount() {
        if (discountStrategy != null) {
            return discountStrategy.calculateDiscount(calculateSubtotal(), customerType);
        }
        return super.calculateDiscount();
    }
    
    @Override
    public String generateInvoice() {
        String baseInvoice = super.generateInvoice();
        if (discountStrategy != null && calculateDiscount() > 0) {
            baseInvoice += "\nApplied discount strategy: " + 
                          discountStrategy.getClass().getSimpleName();
        }
        return baseInvoice;
    }
}

public class SpeculativeGeneralityExample {
    public static void main(String[] args) {
        System.out.println("=== 夸夸其谈未来性示例:过度抽象的订单系统 ===\n");
        
        // 使用过度设计的系统
        IPaymentProcessor paymentProcessor = new SimplePaymentProcessor();
        IShippingCalculator shippingCalculator = new SimpleShippingCalculator();
        ITaxCalculator taxCalculator = new SimpleTaxCalculator();
        IDiscountCalculator discountCalculator = new SimpleDiscountCalculator();
        
        StandardOrder complexOrder = new StandardOrder(
            paymentProcessor, shippingCalculator, taxCalculator, discountCalculator
        );
        
        complexOrder.addItem(new BasicOrderItem("Laptop", 999.99, 1));
        complexOrder.addItem(new BasicOrderItem("Mouse", 29.99, 2));
        
        System.out.println("Complex Order System:");
        System.out.println(complexOrder.generateInvoice());
        System.out.println("Payment processed: " + paymentProcessor.processPayment(complexOrder.calculateTotal()));
        
        System.out.println("\n=== 重构后:简单的订单系统 ===\n");
        
        // 使用重构后的简单系统
        Product laptop = new Product("Laptop", 999.99);
        Product mouse = new Product("Mouse", 29.99);
        
        SimpleOrder simpleOrder = new SimpleOrder("CUST001", "123 Main St, Anytown, USA");
        simpleOrder.addProduct(laptop, 1);
        simpleOrder.addProduct(mouse, 2);
        
        System.out.println("Simple Order System:");
        System.out.println(simpleOrder.generateInvoice());
        System.out.println("Payment processed: " + simpleOrder.processPayment());
        
        System.out.println("\n=== 当需要扩展时:增强的订单系统 ===\n");
        
        // 当需要折扣功能时,使用增强版本
        DiscountStrategy premiumDiscount = new PremiumCustomerDiscount();
        EnhancedOrder enhancedOrder = new EnhancedOrder(
            "CUST002", "456 Oak St, Othertown, USA", "premium", premiumDiscount
        );
        
        enhancedOrder.addProduct(laptop, 1);
        
        System.out.println("Enhanced Order System (with premium discount):");
        System.out.println(enhancedOrder.generateInvoice());
        System.out.println("Payment processed: " + enhancedOrder.processPayment());
        
        System.out.println("\n=== 添加季节性折扣 ===\n");
        
        // 添加新的折扣策略
        DiscountStrategy seasonalDiscount = new SeasonalDiscount(0.15); // 15%季节性折扣
        EnhancedOrder seasonalOrder = new EnhancedOrder(
            "CUST003", "789 Pine St, Sometown, USA", "regular", seasonalDiscount
        );
        
        seasonalOrder.addProduct(new Product("Tablet", 299.99), 1);
        seasonalOrder.addProduct(new Product("Case", 19.99), 1);
        
        System.out.println("Seasonal Order (with 15% discount):");
        System.out.println(seasonalOrder.generateInvoice());
        
        // 对比两种设计的复杂度
        System.out.println("\n=== 设计复杂度对比 ===\n");
        System.out.println("过度设计:");
        System.out.println("- 6个接口");
        System.out.println("- 8个类");
        System.out.println("- 大量抽象,即使对于简单订单");
        System.out.println("- 难以理解和维护");
        
        System.out.println("\n适度设计:");
        System.out.println("- 开始时:1个简单类,1个增强类(当需要时)");
        System.out.println("- 按需添加抽象");
        System.out.println("- 易于理解和维护");
        System.out.println("- 满足当前需求,同时为未来扩展留有余地");
        
        // 关键原则:YAGNI (You Ain't Gonna Need It)
        // 不要为未来可能需要的功能添加复杂性
        // 当功能确实需要时,再进行重构和抽象
    }
}

3.14 令人迷惑的暂时字段:仅在特定情况下使用的字段

暂时字段是指在类中只有某些方法使用的字段,其他时候为空或无效。这种字段会让阅读代码的人困惑,不明白为什么这个字段存在。

商业场景:电商系统中的购物车计算

C++ 示例:购物车中的临时计算字段
#include <iostream>
#include <string>
#include <vector>
#include <memory>
#include <cmath>
#include <optional>

// 令人迷惑的暂时字段示例:购物车中的临时字段
class ShoppingCartOld
{
private:
    std::vector<std::pair<std::string, double>> items;
    
    // 暂时字段:仅在calculateTotal方法中使用
    double cachedTotal;
    bool isTotalCached;
    
    // 暂时字段:仅在applyDiscount方法中使用
    double discountAmount;
    std::string discountCode;
    
    // 暂时字段:仅在calculateTax方法中使用
    double taxRate;
    double taxableAmount;
    
public:
    ShoppingCartOld() : cachedTotal(0), isTotalCached(false), 
                       discountAmount(0), taxRate(0.08), taxableAmount(0) {}
    
    void addItem(const std::string& name, double price)
    {
        items.push_back(std::make_pair(name, price));
        isTotalCached = false; // 添加商品后,缓存失效
    }
    
    double calculateSubtotal()
    {
        double subtotal = 0;
        for (const auto& item : items)
        {
            subtotal += item.second;
        }
        return subtotal;
    }
    
    double calculateTotal()
    {
        // 如果已缓存,使用缓存值
        if (isTotalCached)
        {
            return cachedTotal;
        }
        
        double subtotal = calculateSubtotal();
        double total = subtotal - discountAmount;
        
        // 计算税费
        taxableAmount = total; // 设置暂时字段
        double tax = calculateTax();
        total += tax;
        
        // 缓存结果
        cachedTotal = total;
        isTotalCached = true;
        
        return total;
    }
    
    double calculateTax()
    {
        // 使用暂时字段taxableAmount
        return taxableAmount * taxRate;
    }
    
    void applyDiscount(const std::string& code, double amount)
    {
        discountCode = code; // 设置暂时字段
        discountAmount = amount; // 设置暂时字段
        isTotalCached = false; // 折扣变化,缓存失效
    }
    
    void removeDiscount()
    {
        discountCode = "";
        discountAmount = 0;
        isTotalCached = false;
    }
    
    // 问题:阅读代码的人会困惑:
    // - cachedTotal和isTotalCached何时有效?
    // - discountAmount和discountCode何时设置?
    // - taxableAmount何时计算?
};

// 重构后:将临时数据封装在专门的对象中
class CartCalculationContext
{
private:
    double subtotal;
    double discountAmount;
    std::optional<std::string> discountCode;
    double taxRate;
    
public:
    CartCalculationContext(double subtotalValue, double tax = 0.08)
        : subtotal(subtotalValue), discountAmount(0), taxRate(tax) {}
    
    void applyDiscount(double amount, const std::string& code = "")
    {
        discountAmount = amount;
        if (!code.empty())
        {
            discountCode = code;
        }
    }
    
    double getDiscountedSubtotal() const
    {
        return subtotal - discountAmount;
    }
    
    double calculateTax() const
    {
        return getDiscountedSubtotal() * taxRate;
    }
    
    double calculateTotal() const
    {
        return getDiscountedSubtotal() + calculateTax();
    }
    
    bool hasDiscount() const
    {
        return discountAmount > 0;
    }
    
    std::string getDiscountCode() const
    {
        return discountCode.value_or("");
    }
    
    double getSubtotal() const { return subtotal; }
    double getDiscountAmount() const { return discountAmount; }
    double getTaxRate() const { return taxRate; }
    
    void setTaxRate(double rate) { taxRate = rate; }
};

// 计算策略接口
class ICartCalculationStrategy
{
public:
    virtual ~ICartCalculationStrategy() = default;
    virtual double calculate(const CartCalculationContext& context) = 0;
    virtual std::string getDescription() const = 0;
};

class SubtotalCalculationStrategy : public ICartCalculationStrategy
{
public:
    double calculate(const CartCalculationContext& context) override
    {
        return context.getSubtotal();
    }
    
    std::string getDescription() const override
    {
        return "Subtotal";
    }
};

class TaxCalculationStrategy : public ICartCalculationStrategy
{
public:
    double calculate(const CartCalculationContext& context) override
    {
        return context.calculateTax();
    }
    
    std::string getDescription() const override
    {
        return "Tax";
    }
};

class TotalCalculationStrategy : public ICartCalculationStrategy
{
public:
    double calculate(const CartCalculationContext& context) override
    {
        return context.calculateTotal();
    }
    
    std::string getDescription() const override
    {
        return "Total";
    }
};

// 折扣策略
class IDiscountStrategy
{
public:
    virtual ~IDiscountStrategy() = default;
    virtual double calculateDiscount(double subtotal) = 0;
    virtual std::string getCode() const = 0;
};

class PercentageDiscountStrategy : public IDiscountStrategy
{
private:
    std::string code;
    double percentage;
    
public:
    PercentageDiscountStrategy(const std::string& discountCode, double percent)
        : code(discountCode), percentage(percent) {}
    
    double calculateDiscount(double subtotal) override
    {
        return subtotal * percentage;
    }
    
    std::string getCode() const override
    {
        return code;
    }
};

class FixedAmountDiscountStrategy : public IDiscountStrategy
{
private:
    std::string code;
    double amount;
    
public:
    FixedAmountDiscountStrategy(const std::string& discountCode, double discountAmount)
        : code(discountCode), amount(discountAmount) {}
    
    double calculateDiscount(double subtotal) override
    {
        return amount;
    }
    
    std::string getCode() const override
    {
        return code;
    }
};

// 重构后的购物车类
class ShoppingCart
{
private:
    struct CartItem
    {
        std::string name;
        double price;
        int quantity;
        
        CartItem(const std::string& itemName, double itemPrice, int qty = 1)
            : name(itemName), price(itemPrice), quantity(qty) {}
        
        double getTotal() const
        {
            return price * quantity;
        }
    };
    
    std::vector<CartItem> items;
    std::shared_ptr<IDiscountStrategy> discountStrategy;
    double taxRate;
    
public:
    ShoppingCart(double tax = 0.08) : taxRate(tax) {}
    
    void addItem(const std::string& name, double price, int quantity = 1)
    {
        // 检查是否已存在相同商品
        for (auto& item : items)
        {
            if (item.name == name && std::abs(item.price - price) < 0.001)
            {
                item.quantity += quantity;
                return;
            }
        }
        
        items.emplace_back(name, price, quantity);
    }
    
    void removeItem(const std::string& name)
    {
        items.erase(
            std::remove_if(items.begin(), items.end(),
                [&](const CartItem& item) { return item.name == name; }),
            items.end()
        );
    }
    
    void updateQuantity(const std::string& name, int newQuantity)
    {
        for (auto& item : items)
        {
            if (item.name == name)
            {
                item.quantity = newQuantity;
                return;
            }
        }
    }
    
    double calculateSubtotal() const
    {
        double subtotal = 0;
        for (const auto& item : items)
        {
            subtotal += item.getTotal();
        }
        return subtotal;
    }
    
    void applyDiscount(std::shared_ptr<IDiscountStrategy> strategy)
    {
        discountStrategy = strategy;
    }
    
    void removeDiscount()
    {
        discountStrategy.reset();
    }
    
    CartCalculationContext createCalculationContext() const
    {
        double subtotal = calculateSubtotal();
        CartCalculationContext context(subtotal, taxRate);
        
        if (discountStrategy)
        {
            double discount = discountStrategy->calculateDiscount(subtotal);
            context.applyDiscount(discount, discountStrategy->getCode());
        }
        
        return context;
    }
    
    double calculateTotal() const
    {
        return createCalculationContext().calculateTotal();
    }
    
    void printReceipt() const
    {
        auto context = createCalculationContext();
        
        std::cout << "=== Shopping Cart Receipt ===\n";
        std::cout << "Items:\n";
        
        for (const auto& item : items)
        {
            std::cout << "  " << item.name << " x" << item.quantity 
                      << " @ $" << item.price << " = $" 
                      << item.getTotal() << "\n";
        }
        
        std::cout << "\nSummary:\n";
        std::cout << "  Subtotal: $" << context.getSubtotal() << "\n";
        
        if (context.hasDiscount())
        {
            std::cout << "  Discount: -$" << context.getDiscountAmount();
            if (!context.getDiscountCode().empty())
            {
                std::cout << " (Code: " << context.getDiscountCode() << ")";
            }
            std::cout << "\n";
            std::cout << "  After discount: $" << context.getDiscountedSubtotal() << "\n";
        }
        
        std::cout << "  Tax (" << (context.getTaxRate() * 100) << "%): $" 
                  << context.calculateTax() << "\n";
        std::cout << "  Total: $" << context.calculateTotal() << "\n";
    }
    
    // 使用策略模式进行计算
    void printDetailedCalculation() const
    {
        auto context = createCalculationContext();
        
        std::vector<std::shared_ptr<ICartCalculationStrategy>> strategies;
        strategies.push_back(std::make_shared<SubtotalCalculationStrategy>());
        
        if (context.hasDiscount())
        {
            // 可以添加折扣计算策略
        }
        
        strategies.push_back(std::make_shared<TaxCalculationStrategy>());
        strategies.push_back(std::make_shared<TotalCalculationStrategy>());
        
        std::cout << "\n=== Detailed Calculation ===\n";
        for (const auto& strategy : strategies)
        {
            std::cout << strategy->getDescription() << ": $" 
                      << strategy->calculate(context) << "\n";
        }
    }
};

int main()
{
    std::cout << "=== 令人迷惑的暂时字段示例 ===" << std::endl;
    
    // 使用旧版本的购物车
    ShoppingCartOld oldCart;
    oldCart.addItem("Laptop", 999.99);
    oldCart.addItem("Mouse", 29.99);
    oldCart.applyDiscount("SAVE10", 50.0);
    
    std::cout << "Old Cart Total: $" << oldCart.calculateTotal() << std::endl;
    
    std::cout << "\n=== 重构后:清晰的购物车 ===" << std::endl;
    
    // 使用新版本的购物车
    ShoppingCart cart;
    cart.addItem("Laptop", 999.99);
    cart.addItem("Mouse", 29.99, 2); // 2个鼠标
    cart.addItem("USB Cable", 9.99);
    
    // 应用百分比折扣
    auto percentageDiscount = std::make_shared<PercentageDiscountStrategy>("SUMMER20", 0.2); // 20%折扣
    cart.applyDiscount(percentageDiscount);
    
    cart.printReceipt();
    
    std::cout << "\n=== 更改折扣策略 ===" << std::endl;
    
    // 更改为固定金额折扣
    auto fixedDiscount = std::make_shared<FixedAmountDiscountStrategy>("SAVE50", 50.0);
    cart.applyDiscount(fixedDiscount);
    
    cart.printReceipt();
    
    std::cout << "\n=== 移除折扣 ===" << std::endl;
    
    cart.removeDiscount();
    cart.printReceipt();
    
    std::cout << "\n=== 修改购物车内容 ===" << std::endl;
    
    cart.removeItem("USB Cable");
    cart.updateQuantity("Mouse", 1); // 减少鼠标数量
    cart.addItem("Keyboard", 79.99);
    
    cart.printReceipt();
    
    // 计算上下文可以独立使用
    std::cout << "\n=== 独立使用计算上下文 ===" << std::endl;
    
    CartCalculationContext context(500.0); // 500美元小计
    context.applyDiscount(50.0, "TESTCODE");
    
    std::cout << "Independent calculation:\n";
    std::cout << "Subtotal: $" << context.getSubtotal() << "\n";
    std::cout << "Discount: $" << context.getDiscountAmount() << "\n";
    std::cout << "Discounted subtotal: $" << context.getDiscountedSubtotal() << "\n";
    std::cout << "Tax: $" << context.calculateTax() << "\n";
    std::cout << "Total: $" << context.calculateTotal() << "\n";
    
    // 优势:不再有令人困惑的暂时字段
    // 所有计算相关数据都封装在CartCalculationContext中
    // 购物车类不再包含只在某些方法中使用的字段
    
    return 0;
}

由于篇幅限制,本章节详细介绍了代码坏味道3.11到3.14的识别与重构方法。这些坏味道在实际项目中非常常见,识别并采取适当的重构措施可以显著提高代码质量。后续的坏味道(从3.15到3.22)虽然也很重要,但它们的处理原则类似:识别问题模式,应用适当的设计模式和重构技术,使代码更加清晰、可维护和可扩展。在实际开发中,我们应该培养对这些坏味道的敏感性,并将其重构作为日常开发流程的一部分。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小宝哥Code

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值