gpt4 book ai didi

c++ - 在 C++ 中使用映射器处理派生类创建

转载 作者:太空宇宙 更新时间:2023-11-04 13:47:48 25 4
gpt4 key购买 nike

我正在通读 Martin Fowler 的 PoEAA,了解对象关系结构模式。作为一个在学习它们的同时要做的项目,我想我会用 C++ 构建一个迷你电子商务系统。我无法弄清楚如何从映射器返回对象。

我有一个 Product 基类,它有派生类 HatShirtProducts 有一个 type 成员来标识它们是哪个派生类。我还有一个 ProductMapper 类,带有派生类 HatMapperShirtMapper,所有这些都实现了一堆让我尝试检索的查找器方法某些帽子和衬衫。

class Product
{
unsigned long long int id;
std::string name;
unsigned int type;
};


// Derived classes don't necessarily have the same members.

class Hat : public Product
{
unsigned char fitted;
unsigned char color;
unsigned char style;
};

class Shirt : public Product
{
unsigned char size;
};

在我要实例化这些映射器并检索产品的应用程序的逻辑部分,我遇到了麻烦。我可以实例化一个 HatMapper 并毫无问题地拉回 Hat 对象,与 ShirtMapperShirt 对象一样。这些模式在这些情况下效果很好(特别是我使用类表继承,即一个包含产品数据的产品表,一个包含帽子特定数据的帽子表,以及一个包含衬衫特定数据的衬衫表)。

我的问题是,如果我想检索所有产品,包括帽子和衬衫,我该怎么办?我可以实例化一个 ProductMapper 并获取所有产品数据,但这似乎是错误的方法,因为我必须循环遍历我检索和构建的所有 Products HatsShirts 基于它们在我的程序逻辑部分中的类型。此外,当我添加新产品类型时,我必须修改以这种方式处理这种情况的任何代码。看起来很糟糕。

Fowler 书中有使用派生映射器的基础映射器的映射器示例,这对我来说似乎是完全错误的(每次我添加新产品时都必须修改基础映射器,这不是很好)。这是一个简单的例子,说明它是如何在那里完成的:

class ProductMapper
{
unsigned long long int productId;
unsigned long long int productType;

HatMapper * hm;
ShirtMapper * sm;

Product * FindById(unsigned long long int id)
{
// Query database for data.

if (this->productType == PRODUCT_TYPE_HAT)
{
return hm->FindById(id); // Hat object.
}

else if (this->productType == PRODUCT_TYPE_SHIRT)
{
return sm->FindById(id); // Shirt object.
}

return NULL;
}
};

以下是我在程序的逻辑部分如何使用它。书中没有提供这样的例子:

ProductMapper * pm = new ProductMapper();
Product * p = pm->FindById(1); // It's a Product, but a Hat or Shirt?

// Have to check type since a Product was returned.
switch (p->type)
{
case PRODUCT_TYPE_HAT:
{
Hat * h = (Hat) p;
break;
}

// Etc. Modify this every time a new product type is added or removed.
}

这会引入循环依赖。此外,假设我以某种方式消除了循环依赖,HatMapperShirtMapper 类的结果是 Hat 对象和 Shirt 对象。因此,当我从 ProductMapper 返回时,我会感到沮丧,因此我不得不再次在我的逻辑中操作结果,这再次引入了在我引入新产品类型时修改代码的问题。

我不知道该怎么办。在一个完美的世界中,我想要一个 Product 类和一个 ProductMapper 类,我可以快速扩展这两个类,引入新的产品类型而无需修改现有的代码(至少太多了)。

我希望能够使用 PoEAA 中的这些模式,它们看起来确实不错而且很有用,但我不确定这是否只是我不能在 C++ 中做的事情,或者我遗漏了一些阻止我使用的东西正在做。替代模式和方法也非常受欢迎。

最佳答案

感觉就像Type Object pattern在这种情况下可能会有所帮助,我知道链接是关于游戏编程的,但足以将该模式应用于其他领域。

现在的问题是,如果您想添加产品,您必须添加几个类,正如您所注意到的那样,这些类可能变得难以维护。

编辑:也许您可以使用类似的东西(代码是 C++11 以简化示例):

class ProductProperty
{
typedef std::map<std::string, unsigned char> PropertyMap;

PropertyMap properties;

public:
ProductProperty(std::initializer_list<PropertyMap::value_type> il):
properties(il)
{}
// Use of at() is intended to only deal with the defined properties
const PropertyMap::value_type::second_type&
get(const PropertyMap::value_type::first_type& prop) const
{
return properties.at(prop);
}
PropertyMap::value_type::second_type&
get(const PropertyMap::value_type::first_type& prop)
{
return properties.at(prop);
}

};

// Some helpers to illustrate
std::shared_ptr<ProductProperty> makeHatProperty()
{
return std::make_shared<ProductProperty>(
ProductProperty{
{"fitted", ***whatever**},
{"color", ***whatever**},
{"style", ***whatever**}
});
}

std::shared_ptr<ProductProperty> makeShirtProperty()
{
return std::make_shared<ProductProperty>(
ProductProperty{{"size", ***whatever**}}
);
}

class Product
{
unsigned long long int id;
std::string name;
unsigned int type;

std::shared_ptr<ProductProperty> properties;

public:
Product(std::shared_ptr<ProductProperty> props):
properties(props)
{}

// Whatever function you need to get/set/check properties
};

关于c++ - 在 C++ 中使用映射器处理派生类创建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25030800/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com