抽象工厂结构的差异
difference in structure of abstract factory
我为抽象工厂编写了 2 种类型的代码:类型1 和类型2
类型1是我通过互联网
网站得出的,但类型2是我应该是一个更好的约定
类型1
首先是所需最终产品的基类。有必需的工厂基类。决定所需的工厂品牌。通过派生实例化它们的具体类。确定每个品牌的工厂应该提供哪些常见类别。然后通过推导实例化每个最终产品的最终产品的混凝土。但是在 main 函数中,您直接创建工厂对象。此类代码中将需要更多的维护。
class Shoe
{
public:
virtual void Detail() = 0;
char make[2];
int size;
};
class Shoe_B5:public Shoe //small
{
public:
Shoe_B5()
{
strcpy(make,"B");
size = 5;
}
void Detail()
{
cout<<"Shoe"<<make<<size<<endl;
}
};
class Shoe_B6:public Shoe //medium
{
public:
Shoe_B6()
{
strcpy(make,"B");
size = 6;
}
void Detail()
{
cout<<"Shoe"<<make<<size<<endl;
}
};
class Shoe_B7:public Shoe //large
{
public:
Shoe_B7()
{
strcpy(make,"B");
size = 7;
}
void Detail()
{
cout<<"Shoe"<<make<<size<<endl;
}
};
class Shoe_B8:public Shoe //XL
{
public:
Shoe_B8()
{
strcpy(make,"B");
size = 8;
}
void Detail()
{
cout<<"Shoe"<<make<<size<<endl;
}
};
class Shoe_RT5:public Shoe //small
{
public:
Shoe_RT5()
{
strcpy(make,"RT");
size = 5;
}
void Detail()
{
cout<<"Shoe"<<make<<size<<endl;
}
};
class Shoe_RT6:public Shoe //medium
{
public:
Shoe_RT6()
{
strcpy(make,"RT");
size = 6;
}
void Detail()
{
cout<<"Shoe"<<make<<size<<endl;
}
};
class Shoe_RT7:public Shoe //Large
{
public:
Shoe_RT7()
{
strcpy(make,"RT");
size = 7;
}
void Detail()
{
cout<<"Shoe"<<make<<size<<endl;
}
};
class Shoe_RT8:public Shoe //XL
{
public:
Shoe_RT8()
{
strcpy(make,"RT");
size = 8;
}
void Detail()
{
cout<<"Shoe"<<make<<size<<endl;
}
};
class Factory
{
public:
virtual Shoe* createSmall() = 0;
virtual Shoe* createMedium() = 0;
virtual Shoe* createLarge() = 0;
virtual Shoe* createXL() = 0;
};
class BataFactory: public Factory
{
public:
Shoe* createSmall()
{
return new Shoe_B5;
}
Shoe* createMedium()
{
return new Shoe_B6;
}
Shoe* createLarge()
{
return new Shoe_B7;
}
Shoe* createXL()
{
return new Shoe_B8;
}
};
class RedTapeFactory: public Factory
{
public:
Shoe* createSmall()
{
return new Shoe_RT5;
}
Shoe* createMedium()
{
return new Shoe_RT6;
}
Shoe* createLarge()
{
return new Shoe_RT7;
}
Shoe* createXL()
{
return new Shoe_RT8;
}
};
class Client
{
Factory* fac;
Shoe* s;
public:
Client(Factory* factory)
{
fac = factory;
}
Shoe* Create(int num)
{
switch(num)
{
case 1:
s = fac->createSmall();
break;
case 2:
s = fac->createMedium();
break;
case 3:
s = fac->createLarge();
break;
case 4:
s = fac->createXL();
break;
}
}
void getDetails()
{
s->Detail();
}
};
int main()
{
Factory * fac;
if(condition)
fac = new BataFactory;
else
fac = new RedTapeFactory;
Client * c = new Client(fac);
c->create(Size);
c->getDetails();
}
类型 2 的区别
但是在 main 函数中,您正在像在工厂方法中一样创建工厂。此类代码中所需的维护较少。
class Factory
{
public:
//produce allowed category of shoes
virtual Shoe* createSmall() = 0;
virtual Shoe* createMedium() = 0;
virtual Shoe* createLarge() = 0;
virtual Shoe* createXL() = 0;
//produce allowed category of factories
static Factory* CreateFactory(int num);
};
Factory* Factory::CreateFactory(int num)
{
switch(num)
{
case 1:
return new BataFactory;
break;
case 2:
return new RedTapeFactory;
break;
}
}
int main()
{
Factory * fac;
switch(condition)
{
case 1:
fac = Factory::CreateFactory(1);
break;
case 2:
fac = Factory::CreateFactory(2);
break;
}
Client * c = new Client(fac);
c->create(Size);
c->getDetails();
}
嗯,您正在使用new
和原始指针来拥有自己的内存。这不应该在C++中完成。它总是会产生问题。
例如,在代码中,您永远不会删除此内存。这将导致内存泄漏。因此,请不要将new
和原始指针用于拥有的记忆。将来使用"std::unique_ptr"或类似名称。
我还看到案例陈述。这也不是现代工厂变体的常用方法。您应该使用std::map
,选择器作为键,函数指针作为值。
如果使用可变参数模板允许构造具有不同参数数的类,则可以增加更多的灵活性。
请参阅此处(众多(工厂实施的可能解决方案之一。
`#include <iostream>
#include <map>
#include <utility>
#include <any>
// Some demo classes ----------------------------------------------------------------------------------
struct Base {
Base(int d) : data(d) {};
virtual ~Base() { std::cout << "Destructor Basen"; }
virtual void print() { std::cout << "Print Basen"; }
int data{};
};
struct Child1 : public Base {
Child1(int d, std::string s) : Base(d) { std::cout << "Constructor Child1 " << d << " " << s << "n"; }
virtual ~Child1() { std::cout << "Destructor Child1n"; }
virtual void print() { std::cout << "Print Child1: " << data << "n"; }
};
struct Child2 : public Base {
Child2(int d, char c, long l) : Base(d) { std::cout << "Constructor Child2 " << d << " " << c << " " << l << "n"; }
virtual ~Child2() { std::cout << "Destructor Child2n"; }
virtual void print() { std::cout << "Print Child2: " << data << "n"; }
};
struct Child3 : public Base {
Child3(int d, long l, char c, std::string s) : Base(d) { std::cout << "Constructor Child3 " << d << " " << l << " " << c << " " << s << "n"; }
virtual ~Child3() { std::cout << "Destructor Child3n"; }
virtual void print() { std::cout << "Print Child3: " << data << "n"; }
};
using UPTRB = std::unique_ptr<Base>;
template <class Child, typename ...Args>
UPTRB createClass(Args...args) { return std::make_unique<Child>(args...); }
// The Factory ----------------------------------------------------------------------------------------
template <class Key, class Object>
class Factory
{
std::map<Key, std::any> selector;
public:
Factory() : selector() {}
Factory(std::initializer_list<std::pair<const Key, std::any>> il) : selector(il) {}
template<typename Function>
void add(Key key, Function&& someFunction) { selector[key] = std::any(someFunction); };
template <typename ... Args>
Object create(Key key, Args ... args) {
if (selector.find(key) != selector.end()) {
return std::any_cast<std::add_pointer_t<Object(Args ...)>>(selector[key])(args...);
}
else return nullptr;
}
};
int main()
{
// Define the factory with an initializer list
Factory<int, UPTRB> factory{
{1, createClass<Child1, int, std::string>},
{2, createClass<Child2, int, char, long>}
};
// Add a new entry for the factory
factory.add(3, createClass<Child3, int, long, char, std::string>);
// Some test values
std::string s1(" Hello1 "); std::string s3(" Hello3 ");
int i = 1; const int ci = 1; int& ri = i; const int& cri = i; int&& rri = 1;
UPTRB b1 = factory.create(1, 1, s1);
UPTRB b2 = factory.create(2, 2, '2', 2L);
UPTRB b3 = factory.create(3, 3, 3L, '3', s3);
b1->print();
b2->print();
b3->print();
b1 = factory.create(2, 4, '4', 4L);
b1->print();
return 0;
}
相关文章:
- 如何循环打印顶点结构
- 通过方法访问结构
- 使用不带参数的函数访问结构元素
- 预处理器:插入结构名称中的前一个行号
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 孤立代码块在结构中引发异常
- 有什么方法可以遍历结构吗
- 如何在 C# 中映射双 C 结构指针?
- 如何在C++中使用结构生成映射
- 无法将结构注册为增强几何体3D点
- 多成员Constexpr结构初始化
- C++将文本文件中的数据读取到结构数组中
- 如何重构类层次结构以避免菱形问题
- 如何在C++中序列化结构数据
- std::vector的包装器,使数组的结构看起来像结构的数组
- 没有为自己的结构调用列表推回方法
- 奇怪的结构&GCC&clang(void*返回类型)
- 抽象工厂结构的差异
- 如何为所有“ std :: array”的工厂结构进行部分专业化,该结构超过4`元素
- 将 C 结构工厂函数与其相应的 C++ 包装类构造函数合并