工厂模式二:工厂方法模式

定义

工厂方法模式(Factory Method Pattern)又称为工厂模式,也叫虚拟构造器(Virtual Constructor)模式或者多态工厂(Polymorphic Factory)模式,它属于类创建型模式。

在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类。

模式结构图

在这里插入图片描述

工厂方法模式角色

  • Product:抽象产品,工厂方法模式所创建的对象的超类,也就是所有产品类的共同父类或共同拥有的接口。在实际的系统中,这个角色也常常使用抽象类实现。
  • ConcreteProduct:具体产品,这个角色实现了抽象产品(Product)所声明的接口,工厂方法模式所创建的每一个对象都是某个具体产品的实例。
  • Factory:抽象工厂,担任这个角色的是工厂方法模式的核心,任何在模式中创建对象的工厂类必须实现这个接口。在实际的系统中,这个角色也常常使用抽象类实现。
  • ConcreteFactory:具体工厂,担任这个角色的是实现了抽象工厂接口的具体类。具体工厂角色含有与业务密切相关的逻辑,并且受到使用者的调用以创建具体产品对象。

时序图

在这里插入图片描述
①先调用具体工厂对象中的方法createProduct()

②根据传入产品类型参数(也可以无参),获得具体的产品对象

③返回产品对象并使用

c++代码示例

#include <iostream>

using namespace std;

//抽象产品
class Fruit
{
public:
	virtual void printInfo() = 0;		//将printInfo 声明为纯虚函数,拥有纯虚函数的类是抽象基类
};

//具体产品1
class Apple : public Fruit		//共有继承抽象基类
{
public:
	virtual void printInfo() { cout << "Apple::printInfo()\n"; }
};

//具体产品2
class Banana : public Fruit
{
public:
	virtual void printInfo() { cout << "Banana::printInfo()\n"; }
};

/*
	补充知识:
		1.父类的static变量和函数在派生类中依然可用,但是受访问性控制(比如,父类的private域中的就不可访问),
		  而且对static变量来说,派生类和父类中的static变量是共用空间的,这点在利用static变量进行引用计数的时候要特别注意。   

 		2.static函数没有“虚函数”一说。因为static函数实际上是“加上了访问控制的全局函数”,全局函数哪来的什么虚函数?   

 		3.派生类的friend函数可以访问派生类本身的一切变量,包括从父类继承下来的protected域中的变量。但是对父类来说,他并不是friend						   的。
 	
*/

//抽象工厂
class FruitFactory
{
public:
	virtual Fruit* createFruit() = 0;		//声明为纯虚函数,则FruitFactory类为抽象基类
};

//具体工厂1:专门生产苹果的工厂
class AppleFactory
{
public:
	//这里不在加virtual 是因为静态函数不能声明为虚函数。为什么用static?因为静态方法属于类方法,生存期大于实例对象,因此可以通过类名::方法名来调用而无需创建实例对象了。
	static Fruit* createFruit()
	{
		//因为苹果工厂只生产苹果,直接return Apple实例即可,无需判断像简单工厂中的参数(实际上这里也没有参数)
		return new Apple();
	}
};

//具体工厂2:专门生产香蕉的工厂
class BananaFactory
{
public:
	static Fruit* createFruit()
	{
		return new Banana();
	}
};

int main()
{
	//工厂模式之工厂方法模式
	//通过苹果工厂得到苹果(实例对象),无需传入参数,也无需知道实现细节, 甚至也无需创建实例工厂角色。
	Fruit* apple = AppleFactory::createFruit();
	apple->printInfo();

	同理通过香蕉工厂得到香蕉
	Fruit* banana = BananaFactory::createFruit();
	banana->printInfo();
	return 0;
}

测试结果

在这里插入图片描述

工厂方法模式的优缺点

优点

①在工厂方法模式中,工厂方法用来创建客户所需要的产品,同时还向客户隐藏了哪种具体产品类将被实例化这一细节,用户只需要关心所需产品对应的工厂,无须关心创建细节,甚至无须知道具体产品类的类名。

②基于工厂角色和产品角色的多态性设计是工厂方法模式的关键。它能够使工厂可以自主确定创建何种产品对象,而如何创建这个对象的细节则完全封装在具体工厂内部。工厂方法模式之所以又被称为多态工厂模式,是因为所有的具体工厂类都具有同一抽象父类。

③使用工厂方法模式的另一个优点是在系统中加入新产品时,无须修改抽象工厂和抽象产品提供的接口,无须修改客户端,也无须修改其他的具体工厂和具体产品,而只要添加一个具体工厂和具体产品就可以了。这样,系统的可扩展性也就变得非常好,完全符合“开闭原则”,这点比简单工厂模式更优秀。

缺点
①在添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,****,有更多的类需要编译和运行,会给系统带来一些额外的开销。

②由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,增加了系统的实现难度。

适用场景

在以下情况下可以使用工厂方法模式:

①一个类不知道它所需要的对象的类:在工厂方法模式中,客户端不需要知道具体产品类的类名,只需要知道所对应的工厂即可,具体的产品对象由具体工厂类创建;客户端需要知道创建具体产品的工厂类。

②一个类通过其子类来指定创建哪个对象:在工厂方法模式中,对于抽象工厂类只需要提供一个创建产品的接口,而由其子类来确定具体要创建的对象,利用面向对象的多态性和里氏代换原则,在程序运行时,子类对象将覆盖父类对象,从而使得系统更容易扩展。

③将创建对象的任务委托给多个工厂子类中的某一个,客户端在使用时可以无须关心是哪一个工厂子类创建产品子类,需要时再动态指定,可将具体工厂类的类名存储在配置文件或数据库中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值