假如我们要买水果,水果的产地来自中国、日本、美国,每个国家的水果种类都可以分为苹果、香蕉、梨子。
作为开发者,我们就不得不创建苹果类(香蕉和梨子类似),然后每种苹果都继承自苹果类。每上架一个国家的苹果我们都要实现一次苹果类,这样就会有成千上万的苹果类需要被创建,AbstractFactory 模式就是用来解决这类问题的:要创建一组相关或者相互依赖的对象。
举例:
代码:
//product.h
#ifndef _PRODUCT_H_
#define _PRODUCT_H_
#include <iostream>
using namespace std;
//苹果的抽象
class AbstractApple
{
public:
//务必定义虚析构函数,否则销毁派生类对象时,基类指针直接析构基类,导致派生类对象销毁不完整
virtual ~AbstractApple()
{
cout<<"~AbstractApple"<<endl;
};
virtual void showName() = 0;
};
//中国苹果
class ChinaApple:public AbstractApple
{
public:
~ChinaApple()
{
cout<<"~ChinaApple"<<endl;
};
virtual void showName()
{
cout<<"中国苹果"<<endl;
}
};
//美国苹果
class UsaApple:public AbstractApple
{
public:
virtual void showName()
{
cout<<"美国苹果"<<endl;
}
};
//日本苹果
class JapanApple:public AbstractApple
{
public:
virtual void showName()
{
cout<<"日本苹果"<<endl;
}
};
//香蕉的抽象
class AbstractBanana
{
public:
//务必定义虚析构函数,否则销毁派生类对象时,基类指针直接析构基类,导致派生类对象销毁不完整
virtual ~AbstractBanana()
{
cout<<"~AbstractBanana"<<endl;
};
virtual void showName() = 0;
};
//中国香蕉
class ChinaBanana:public AbstractBanana
{
public:
~ChinaBanana()
{
cout<<"~ChinaBanana"<<endl;
};
virtual void showName()
{
cout<<"中国香蕉"<<endl;
}
};
//美国香蕉
class UsaBanana:public AbstractBanana
{
public:
virtual void showName()
{
cout<<"美国香蕉"<<endl;
}
};
//日本香蕉
class JapanBanana:public AbstractBanana
{
public:
virtual void showName()
{
cout<<"日本香蕉"<<endl;
}
};
//鸭梨的抽象
class AbstractPear
{
public:
//务必定义虚析构函数,否则销毁派生类对象时,基类指针直接析构基类,导致派生类对象销毁不完整
virtual ~AbstractPear()
{
cout<<"~AbstractPear"<<endl;
};
virtual void showName() = 0;
};
//中国鸭梨
class ChinaPear:public AbstractPear
{
public:
~ChinaPear()
{
cout<<"~ChinaPear"<<endl;
};
virtual void showName()
{
cout<<"中国鸭梨"<<endl;
}
};
//美国鸭梨
class UsaPear:public AbstractPear
{
public:
virtual void showName()
{
cout<<"美国鸭梨"<<endl;
}
};
//日本鸭梨
class JapanPear:public AbstractPear
{
public:
virtual void showName()
{
cout<<"日本鸭梨"<<endl;
}
};
#endif // _PRODUCT_H_
//factory.h
#ifndef _FACTORY_H_
#define _FACTORY_H_
#include <iostream>
#include "product.h"
using namespace std;
//工厂的抽象
class AbstractFactory
{
public:
//务必定义虚析构函数,否则销毁派生类对象时,基类指针直接析构基类,导致派生类对象销毁不完整
virtual ~AbstractFactory()
{
cout<<"~AbstractFactory"<<endl;
};
virtual AbstractApple* CreateApple() = 0;
virtual AbstractBanana* CreateBanana() = 0;
virtual AbstractPear* CreatePear() = 0;
};
//中国工厂,可生产中国版苹果香蕉和梨(派生类),返回的是苹果香蕉和梨的基类
class ChinaFactory:public AbstractFactory
{
~ChinaFactory()
{
cout<<"~ChinaFactory"<<endl;
};
virtual AbstractApple* CreateApple()
{
return new ChinaApple;
}
virtual AbstractBanana* CreateBanana()
{
return new ChinaBanana;
}
virtual AbstractPear* CreatePear()
{
return new ChinaPear;
}
};
//美国工厂,可生产美国版苹果香蕉和梨(派生类),返回的是苹果香蕉和梨的基类
class UsaFactory:public AbstractFactory
{
virtual AbstractApple* CreateApple()
{
return new UsaApple;
}
virtual AbstractBanana* CreateBanana()
{
return new UsaBanana;
}
virtual AbstractPear* CreatePear()
{
return new UsaPear;
}
};
//日本工厂,可生产日本版苹果香蕉和梨(派生类),返回的是苹果香蕉和梨的基类
class JapanFactory:public AbstractFactory
{
virtual AbstractApple* CreateApple()
{
return new JapanApple;
}
virtual AbstractBanana* CreateBanana()
{
return new JapanBanana;
}
virtual AbstractPear* CreatePear()
{
return new JapanPear;
}
};
#endif // _FACTORY_H_
//main.c
#include <iostream>
#include "factory.h"
#include "product.h"
using namespace std;
int main()
{
AbstractFactory *factory_ptr = NULL;
AbstractApple *apple_ptr = NULL;
AbstractBanana *banana_ptr = NULL;
AbstractPear *pear_ptr = NULL;
//中国工厂,生产中国版的水果
factory_ptr = new ChinaFactory;
apple_ptr = factory_ptr->CreateApple();
banana_ptr = factory_ptr->CreateBanana();
pear_ptr = factory_ptr->CreatePear();
//调用中国版水果的接口
apple_ptr->showName();
banana_ptr->showName();
pear_ptr->showName();
delete pear_ptr;
delete apple_ptr;
delete banana_ptr;
delete factory_ptr;
return 0;
}
运行结果:
总结:
AbstractFactory 模式和 Factory模式的区别是初学设计模式时候的一个容易引起困惑的地方。
实际上,AbstractFactory模式是为创建一系列相关的对象提供创建接口,而 Factory模式是为某一类对象提供创建接口或延迟对象的创建到子类中实现。并且可以看到,AbstractFactory模式通常都是使用 Factory 模式实现。
抽象工厂模式关注于创建一系列相关的产品对象,如果需要添加新的产品族,则需要定义新的工厂类并实现具体的某个Factory
接口。
抽象工厂模式和工厂模式的区别:
相同点:
- 两者都是创建型设计模式,用于创建对象。
- 两者都提供了对客户端隐藏具体实现细节的好处,客户端只需要知道接口或抽象类型。
不同点:
- 对象创建范围和灵活性:工厂模式主要用于创建单个对象,而抽象工厂模式可以创建多个复杂对象。当需要创建多个对象时,使用抽象工厂模式可以更加灵活地满足需求。另外,抽象工厂模式中不同的工厂方法可以有不同的实现,从而进一步提高对象创建的灵活性。
- 可维护和可扩展性:工厂模式在添加新产品时,通常只需要修改工厂类。而抽象工厂模式在添加新产品族时,需要定义新的工厂类和一系列新的产品类。虽然工厂模式简单直观,但随着需求的增加,可能需要修改或扩展工厂类,这可能导致代码的维护变得困难。而抽象工厂模式虽然比工厂模式复杂,但可以提供更多的抽象和封装,使得代码更加模块化,从而提高了代码的可维护性和可扩展性。
- 复杂度和聚合程度:抽象工厂模式比工厂模式更复杂,因为它涉及更多的接口和类。工厂模式通常只创建一个对象,而抽象工厂模式创建的对象较多,聚合程度较高。因此,如果需要创建聚合程度较高的对象,使用抽象工厂模式可以更好地实现。
抽象工厂模式和工厂模式在对象创建的范围、扩展性和复杂度方面存在显著的差异。在选择使用哪种模式时,需要根据具体的应用场景和需求来权衡。在简单的对象创建场景下,工厂模式可能更为适合;而在需要创建多个复杂对象,且希望提高代码的可维护性和可扩展性的情况下,抽象工厂模式可能更为理想。
靠谱推荐:Free Pos,微信JOCIHEZ