与工厂模式对比
工厂模式
工厂模式是类创建模式。在工厂模式中,只需要生产同一种产品,只不过是生产厂家不同。
所以产品类的设计:
- 抽象的产品类
Product
- 具体的产品类
Product_A
,Product_B
,Product_C
,Product_D
……
工厂的设计:
- 抽象的工厂
Factory
- 与产品对应的
Factory_A
,Factory_B
,Factory_C
,Factory_D
……
特点是每增加一个厂家,就会成对地增加类。
不考虑增加产品种类,否则就会升级为抽象工厂模式。
抽象工厂模式
抽象工厂模式是对象创建模式。抽象工厂模式中,每个厂家都生产多种产品。
反映到我们的工厂类,就是需要提供更多的产品制造接口。
优点
每增加一个厂家,就要有一个具体的工厂类产生、多个具体的产品类产生。
只需让具体的工厂继承Factory
抽象的工厂、具体的产品继承抽象的产品、具体的工厂负责制造具体的产品。对其他类没有影响。
缺点/限制
当增加一种新的产品时(不推荐),每个已有的工厂都需要增加新的方法,来制造对应的产品,违背了开闭原则。
产品已有的种类是固定的,而品阶/等级/厂商可以变。
有时这也算是个优点,因为将每个工厂的产品视为一套产品,这很符合一些应用场合。
例如对不同的操作系统提供一套UI组件,对不同操作系统使用不同的具体工厂来产生一套组件。
又比如在数据相关类的设计中,有不同的数据库,不同的数据库会给出不同的连接类、语句类。数据库就像具体的工厂,连接类、语句类则是产品。不同的数据库自成一套。
类图
下面的例子模拟不同的文具工厂生产各种文具,
假设厂家有:爱好,晨光……
假设文具有:书、铅笔、尺子……
代码
#include <iostream>
#include <memory>
#include <vector>
using namespace std;
class Book;
class AiHaoBook;
class ChenGuangBook;
class Pencil;
class AiHaoPencil;
class ChenGuangPencil;
class Ruler;
class AiHaoRuler;
class ChenGuangRuler;
class Factory;
class ChenGuangFactory;
class AiHaoFactory;
class Factory {
public:
virtual ~Factory() = default;
virtual unique_ptr<Book> make_book() = 0;
virtual unique_ptr<Pencil> make_pencil() = 0;
virtual unique_ptr<Ruler> make_ruler() = 0;
};
class AiHaoFactory : public Factory {
public:
unique_ptr<Book> make_book() override;
unique_ptr<Pencil> make_pencil() override;
unique_ptr<Ruler> make_ruler() override;
};
class ChenGuangFactory : public Factory {
public:
unique_ptr<Book> make_book() override;
unique_ptr<Pencil> make_pencil() override;
unique_ptr<Ruler> make_ruler() override;
};
class Book {
public:
virtual ~Book() = default;
virtual string get_brand() const = 0;
string get_type() const;
private:
static const string type;
};
class Pencil {
public:
virtual ~Pencil() = default;
virtual string get_brand() const = 0;
string get_type() const;
private:
static const string type;
};
class Ruler {
public:
virtual ~Ruler() = default;
virtual string get_brand() const = 0;
string get_type() const;
private:
static const string type;
};
const string Book::type ("Book");
const string Pencil::type ("Pencil");
const string Ruler::type ("Ruler");
string
Book::get_type() const
{
return Book::type;
}
string
Pencil::get_type() const
{
return Pencil::type;
}
string
Ruler::get_type() const
{
return Ruler::type;
}
class AiHaoBook: public Book {
public:
string get_brand() const override;
private:
static const string brand;
};
class AiHaoPencil : public Pencil {
public:
string get_brand() const override;
private:
static const string brand;
};
class AiHaoRuler : public Ruler {
public:
string get_brand() const override;
private:
static const string brand;
};
class ChenGuangBook: public Book {
public:
string get_brand() const override;
private:
static const string brand;
};
class ChenGuangPencil : public Pencil {
public:
string get_brand() const override;
private:
static const string brand;
};
class ChenGuangRuler : public Ruler {
public:
string get_brand() const override;
private:
static const string brand;
};
const string AiHaoBook::brand ("AiHao");
const string AiHaoPencil::brand ("AiHao");
const string AiHaoRuler::brand ("AiHao");
const string ChenGuangBook::brand ("ChenGuang");
const string ChenGuangPencil::brand ("ChenGuang");
const string ChenGuangRuler::brand ("ChenGuang");
string
AiHaoBook::get_brand() const
{
return AiHaoBook::brand;
}
string
AiHaoPencil::get_brand() const
{
return AiHaoPencil::brand;
}
string
AiHaoRuler::get_brand() const
{
return AiHaoRuler::brand;
}
string
ChenGuangBook::get_brand() const
{
return ChenGuangBook::brand;
}
string
ChenGuangPencil::get_brand() const
{
return ChenGuangPencil::brand;
}
string
ChenGuangRuler::get_brand() const
{
return ChenGuangRuler::brand;
}
unique_ptr<Book>
AiHaoFactory::make_book()
{
return make_unique<AiHaoBook>();
}
unique_ptr<Pencil>
AiHaoFactory::make_pencil()
{
return make_unique<AiHaoPencil>();
}
unique_ptr<Ruler>
AiHaoFactory::make_ruler()
{
return make_unique<AiHaoRuler>();
}
unique_ptr<Book>
ChenGuangFactory::make_book()
{
return make_unique<ChenGuangBook>();
}
unique_ptr<Pencil>
ChenGuangFactory::make_pencil()
{
return make_unique<ChenGuangPencil>();
}
unique_ptr<Ruler>
ChenGuangFactory::make_ruler()
{
return make_unique<ChenGuangRuler>();
}
int
main (void)
{
vector<unique_ptr<Factory>> makers;
makers.emplace_back (make_unique<AiHaoFactory>());
makers.emplace_back (make_unique<ChenGuangFactory>());
for (auto &maker : makers) {
unique_ptr<Book> book = maker->make_book();
unique_ptr<Pencil> pencil = maker->make_pencil();
unique_ptr<Ruler> ruler = maker->make_ruler();
cout << book->get_brand() << " " << book->get_type() << endl;
cout << pencil->get_brand() << " " << pencil->get_type() << endl;
cout << ruler->get_brand() << " " << ruler->get_type() << endl;
}
}
plantuml
@startuml
/' Objects '/
class AiHaoBook {
+get_brand() : string
--
-brand : static const string
}
class AiHaoFactory {
+make_book() : unique_ptr<Book>
+make_pencil() : unique_ptr<Pencil>
+make_ruler() : unique_ptr<Ruler>
}
class AiHaoPencil {
+get_brand() : string
--
-brand : static const string
}
class AiHaoRuler {
-brand : static const string
+get_brand() : string
}
abstract class Book {
+{abstract}~Book()
+virtual get_brand() : string
+get_type() : string
--
-type : static const string
}
class ChenGuangBook {
+get_brand() : string
--
-brand : static const string
}
class ChenGuangFactory {
+make_book() : unique_ptr<Book>
+make_pencil() : unique_ptr<Pencil>
+make_ruler() : unique_ptr<Ruler>
}
class ChenGuangPencil {
+get_brand() : string
--
-brand : static const string
}
class ChenGuangRuler {
+get_brand() : string
--
-brand : static const string
}
abstract class Factory {
+{abstract}~Factory()
+virtual make_book() : unique_ptr<Book>
+virtual make_pencil() : unique_ptr<Pencil>
+virtual make_ruler() : unique_ptr<Ruler>
}
abstract class Pencil {
+{abstract}~Pencil()
+virtual get_brand() : string
+get_type() : string
--
-type : static const string
}
abstract class Ruler {
+{abstract}~Ruler()
+virtual get_brand() : string
+get_type() : string
--
-type : static const string
}
/' Inheritance relationships '/
Book <|----- AiHaoBook
Book <|----- ChenGuangBook
Factory <|-- AiHaoFactory
Factory <|-- ChenGuangFactory
Pencil <|----- AiHaoPencil
Pencil <|----- ChenGuangPencil
Ruler <|----- AiHaoRuler
Ruler <|----- ChenGuangRuler
.ChenGuangFactory .....> .ChenGuangBook
.ChenGuangFactory .....> .ChenGuangPencil
.ChenGuangFactory .....> .ChenGuangRuler
.AiHaoFactory .....> .AiHaoBook
.AiHaoFactory .....> .AiHaoPencil
.AiHaoFactory .....> .AiHaoRuler
/' Aggregation relationships '/
/' Nested objects '/
@enduml