三种工厂模式比较
- 简单工厂模式:专门定义一个类来创建其他类的示例,被创建的实例通常有相同的父亲
- 工厂模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类,使一个类的实例化延迟到子类
- 抽象工厂模式:提供一个创建一系列相关或者相互依赖的接口,或无需指定他们具体的类
简单工厂模式
- 简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一
- 简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例
- 简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现
优点
工厂类是整个模式的关键.包含了必要的逻辑判断,根据外界给定的信息,决定究竟应该创建哪个具体类的对象.通过使用工厂类,外界可以从直接创建具体产品对象的尴尬局面摆脱出来,仅仅需要负责“消费”对象就可以了。而不必管这些对象究竟如何创建及如何组织的.明确了各自的职责和权利,有利于整个软件体系结构的优化。
缺点
- 由于工厂类集中了所有实例的创建逻辑,违反了高内聚责任分配原则,将全部创建逻辑集中到了一个工厂类中;它所能创建的类只能是事先考虑到的,如果需要添加新的类,则就需要改变工厂类了。
- 当系统中的具体产品类不断增多时候,可能会出现要求工厂类根据不同条件创建不同实例的需求.这种对条件的判断和对具体产品类型的判断交错在一起,很难避免模块功能的蔓延,对系统的维护和扩展非常不利;
使用场景
由于简单工厂很容易违反高内聚责任分配原则,因此一般只在很简单的情况下应用。
- 日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。
- 数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。
- 设计一个连接服务器的框架,需要三个协议,”POP3”、”IMAP”、”HTTP”,可以把这三个作为产品类,共同实现一个接口。
#include "pch.h"
#include <iostream>
// 鼠标接口
class IMouse
{
public:
virtual void Info() = 0;
};
// 惠普鼠标
class HPMouse : public IMouse
{
public:
virtual void Info()
{
std::cout << "HP Mouse" << std::endl;
}
};
// 戴尔鼠标
class DellMouse : public IMouse
{
public:
virtual void Info()
{
std::cout << "Dell Mouse" << std::endl;
}
};
// 鼠标工厂类
class MouseFactory
{
public:
IMouse* CreateMouse(int shapeType)
{
IMouse* mouse = NULL;
switch(shapeType)
{
case MOUSE_HP:
mouse = new HPMouse();
break;
case MOUSE_Dell:
mouse = new DellMouse();
break;
default:
break;
}
return mouse;
}
public:
enum ShapeType {
MOUSE_HP = 0,
MOUSE_Dell = 1
};
};
// 调用示例
int main()
{
MouseFactory* mouseFactory = new MouseFactory();
IMouse* HPMouse = mouseFactory->CreateMouse(MouseFactory::ShapeType::MOUSE_HP);
HPMouse->Info();
IMouse* DellMouse = mouseFactory->CreateMouse(MouseFactory::ShapeType::MOUSE_Dell);
DellMouse->Info();
}
工厂模式
优点
- 屏蔽产品的具体实现,调用者只关心产品的接口。
- 扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
缺点
每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。
使用场景
抽象工厂的简化模式
#include "pch.h"
#include <iostream>
// 鼠标接口
class IMouse
{
public:
virtual void Info() = 0;
};
// 惠普鼠标
class HPMouse : public IMouse
{
public:
virtual void Info()
{
std::cout << "HP Mouse" << std::endl;
}
};
// 戴尔鼠标
class DellMouse : public IMouse
{
public:
virtual void Info()
{
std::cout << "Dell Mouse" << std::endl;
}
};
// 鼠标工厂类
class MouseFactory
{
public:
virtual IMouse* CreateMouse() = 0;
};
class HPMouseFactory : public MouseFactory
{
public:
IMouse* CreateMouse()
{
return new HPMouse();
}
};
class DellMouseFactory : public MouseFactory
{
public:
IMouse* CreateMouse()
{
return new DellMouse();
}
};
// 调用示例
int main()
{
MouseFactory* HPmf = new HPMouseFactory();
IMouse* HPm = HPmf->CreateMouse();
HPm->Info();
MouseFactory* Dellmf = new DellMouseFactory();
IMouse* Dellm = Dellmf->CreateMouse();
Dellm->Info();
}
抽象工厂模式
- 抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。
- 抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。
- 抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。
- 根据里氏替换原则,任何接受父类型的地方,都应当能够接受子类型。因此,实际上系统所需要的,仅仅是类型与这些抽象产品角色相同的一些实例,而不是这些抽象产品的实例。换言之,也就是这些抽象产品的具体子类的实例。工厂类负责创建抽象产品的具体子类的实例。
优点
当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
缺点
产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。
使用场景
- QQ 换皮肤,一整套一起换。
- 生成不同操作系统的程序。
#include "pch.h"
#include <iostream>
// 鼠标接口
class IMouse
{
public:
virtual void Info() = 0;
};
// 惠普鼠标
class HPMouse : public IMouse
{
public:
virtual void Info()
{
std::cout << "HP Mouse" << std::endl;
}
};
// 戴尔鼠标
class DellMouse : public IMouse
{
public:
virtual void Info()
{
std::cout << "Dell Mouse" << std::endl;
}
};
// 键盘接口
class IKeyboard
{
public:
virtual void Info() = 0;
};
// 惠普键盘
class HPKeyboard : public IKeyboard
{
public:
virtual void Info()
{
std::cout << "HP Keyboard" << std::endl;
}
};
// 戴尔键盘
class DellKeyboard : public IKeyboard
{
public:
virtual void Info()
{
std::cout << "Dell Keyboard" << std::endl;
}
};
// 电脑工厂类
class PCFactory
{
public:
virtual IMouse* CreateMouse() = 0;
virtual IKeyboard* CreateKeyboard() = 0;
};
// 惠普PC工厂
class HPPCFactory : public PCFactory
{
public:
IMouse* CreateMouse()
{
return new HPMouse();
}
IKeyboard* CreateKeyboard()
{
return new HPKeyboard();
}
};
// 戴尔PC工厂
class DellPCFactory : public PCFactory
{
public:
IMouse* CreateMouse()
{
return new DellMouse();
}
IKeyboard* CreateKeyboard()
{
return new DellKeyboard();
}
};
// 调用示例
int main()
{
PCFactory* HPf = new HPPCFactory();
IMouse* HPm = HPf->CreateMouse();
IKeyboard* HPkb = HPf->CreateKeyboard();
HPm->Info();
HPkb->Info();
PCFactory* Dellf = new DellPCFactory();
IMouse* Dellm = Dellf->CreateMouse();
IKeyboard* Dellkb = Dellf->CreateKeyboard();
Dellm->Info();
Dellkb->Info();
}