可变性隔离

在架构设计中,可以通过隔离可变性来将应用程序中的内部服务进行分割,划分为可变组件和不可变组件。不可变组件不修改任何状态,而可变组件则负责修改变量状态并与不可变组件进行通信。

假设我们正在设计一个电子商务平台,其中包含以下两个组件:ProductCatalog(产品目录)和ShoppingCart(购物车)。ProductCatalog负责管理产品的信息和库存,而ShoppingCart负责管理用户的购物车内容。

  1. 首先,我们定义一个不可变组件ProductCatalog,它使用纯函数实现,不修改任何状态:
class ProductCatalog 
{
public:
    std::vector<Product> getProducts() const 
    {
        // 返回产品目录中的产品列表
    }

    bool checkAvailability(const Product& product) const 
    {
        // 检查产品的库存是否可用
    }
};
  • 在ProductCatalog组件中,我们只提供了获取产品列表和检查产品库存可用性的方法,这些方法不会修改任何状态,只是根据当前产品目录的状态进行计算。
  1. 接下来,我们定义一个可变组件ShoppingCart,它负责修改购物车的状态,并与ProductCatalog组件进行通信:
class ShoppingCart 
{
private:
    std::vector<Product> items;

public:
    void addItem(const Product& product, const ProductCatalog& catalog) 
    {
        // 检查产品库存是否可用
        if (catalog.checkAvailability(product)) 
        {
            // 将产品添加到购物车中
            items.push_back(product);
        }
    }

    void removeItem(const Product& product) 
    {
        // 从购物车中移除产品
        // 修改购物车的状态
    }

    std::vector<Product> getItems() const 
    {
        // 返回购物车中的产品列表
    }

    double getTotalPrice() const 
    {
        // 计算购物车中产品的总价格
    }
};
  • 在ShoppingCart组件中,我们提供了添加产品到购物车、从购物车中移除产品、获取购物车产品列表和计算总价格的方法。这些方法会修改购物车的状态,但不会直接修改ProductCatalog组件的状态。
  • 通过将可变性隔离到ShoppingCart组件中,我们实现了不可变的ProductCatalog组件和可变的ShoppingCart组件之间的分离。ProductCatalog组件只关注产品信息和库存管理,而ShoppingCart组件负责修改购物车的状态。
  • 这种架构设计的好处是,我们可以更容易地测试和调试ProductCatalog组件,因为它是不可变的,没有副作用。同时,ShoppingCart组件可以独立地进行修改和扩展,而不会影响到ProductCatalog组件的实现。
  1. 最后main函数中使用了ProductCatalog组件的getProducts方法来获取产品列表,并将产品添加到购物车中:
int main() {
    ProductCatalog catalog;
    ShoppingCart cart;

    // 获取产品列表
    std::vector<Product> products = catalog.getProducts();

    // 将产品添加到购物车中
    for (const auto& product : products) {
        cart.addItem(product, catalog);
    }

    // 获取购物车中的产品列表
    std::vector<Product> cartItems = cart.getItems();

    // 输出购物车中的产品信息
    for (const auto& item : cartItems) {
        std::cout << item.getName() << std::endl;
    }

    return 0;
}
09-22 00:33