【发布时间】:2016-07-01 08:00:46
【问题描述】:
我认为这个任务很常见,但我找不到合适的解决方案。
我有一个“产品”层次结构,其中包含一些“特征”,所以我决定对产品使用模板化接口,其中模板参数是“特征”:
这些是特征:
struct Foo {
static std::string get_name() { return "Foo"; }
Foo(int a) : a_(a) {}
int operator()() const { return a_; }
private:
int a_;
};
struct Bar {
static std::string get_name() { return "Bar"; }
Bar(int a, int b) : a_(a), b_(b) {}
int operator()() const { return a_ + b_; }
private:
int a_;
int b_;
};
struct Spam {
Spam(int a, int b) : a_(a), b_(b), c_(0) {}
void operator()() { c_++; }
private:
int a_;
int b_;
int c_;
};
这些是产品层次结构:
template <class T>
class Product {
public:
typedef T T_type;
virtual T get() = 0;
virtual ~Product() {}
};
template <class T>
class ProductA : public Product<T> {
typedef Product<T> base_type;
public:
ProductA(int a) : a_(a) {}
virtual ~ProductA() {}
virtual T get() {
return T(a_);
}
private:
int a_;
};
template <class T, class U>
class ProductB : public Product<T> {
typedef Product<T> base_type;
public:
typedef U U_type;
ProductB(int a, int b) : a_(a), b_(b) {}
virtual ~ProductB();
virtual T get() {
init(); // U is being used here
return T(a_, b_);
}
protected:
void init() {}
private:
int a_;
int b_;
};
由于ProductA 和ProductB 的接口不同,我需要使用额外的继承级别——它们有不同的c-tors。
这里是具体的产品:
class ProductA1 : public ProductA<Foo> {
typedef ProductA<Foo> base_type;
public:
ProductA1(int a) : base_type(a) { std::cout << "A1 created" << std::endl; }
virtual ~ProductA1() { std::cout << "A1 deleted" << std::endl; }
};
class ProductB1 : public ProductB<Bar, Spam> {
typedef ProductB<Bar, Spam> base_type;
public:
ProductB1(int a, int b) : base_type(a, b) { std::cout << "B1 created" << std::endl; }
virtual ~ProductB1() { std::cout << "B1 deleted" << std::endl; }
};
现在我想以某种方式将字符串传递给某个方法,从而有一种“统一”创建产品的机制(在此示例中为两种类型 ProductA1 和 ProductB1)。显然我需要工厂...
所以我为层次结构的不同分支实现了工厂(以创建 ProductA 和 ProductB 类型的对象),以便我可以创建通过模板参数传递其类型的对象:
template <class P>
struct ProductAFactory {
typedef typename P::T_type T_type;
typedef ProductA<T_type> product_type;
static
product_type* create(int a) {
return new P(a);
}
};
template <class P>
struct ProductBFactory {
typedef typename P::T_type T_type;
typedef typename P::U_type U_type;
typedef ProductB<T_type,
U_type> product_type;
static
product_type* create(int a, int b) {
return new P(a, b);
}
};
拥有这些工厂,我必须有一个工厂来构造必要类型的产品并返回指向 Product<T> 接口产品的指针:
template <class T>
class ProductFactory {
public:
static
Product<T>*
create(const std::string& product_name,
const int a,
const int b) {
const std::string product_a1 = "A1";
const std::string product_b1 = "B1";
if (product_name == product_a1)
return ProductAFactory<ProductA1>::create(a);
else if (product_name == product_b1)
return ProductBFactory<ProductB1>::create(a, b); // (*) <--- compiler error
else
throw std::runtime_error("Unsupported product: " + product_name);
}
};
所有这些代码都旨在以这样的方式使用:
void main() {
typedef Foo T;
std::shared_ptr<Product<T>> p(ProductFactory<T>::create("A1", 1, 1));
T t = p->get();
std::cout << t.get_name() << ": " << t() << std::endl;
}
在这里我遇到了编译这段代码的问题——错误是return value type does not match the function type(*)。看来ProductB<Foo, Spam>不能自动转换成它的基类型Product<Foo>...
我不是一个优秀的工厂开发人员,也许我不了解基本原理和概念。任何人都可以帮助更正此代码或这种方法。谢谢!
【问题讨论】:
标签: c++ templates factory abstract-factory