ITKeyword,专注技术干货聚合推荐

注册 | 登录

Cocos2d-x3.2与设计模式(一)创建型模式之ABSTRACT FACTORY(抽象工厂)--对象创建型模式

分享于 2014-08-30

推荐:【设计模式】创建型模式-抽象工厂

概述 提供一个创建一系列相关或相互依赖对象的接口, 而无需指定它们具体的类。  适用性 1.一个系统要独立于它的产品的创建、组合和表示时。 2.一

2020腾讯云“6.18”活动开始了!!!(巨大优惠重现!4核8G,5M带宽 1999元/3年),
地址https://cloud.tencent.com/act/cps/redirect?redirect=1059

2020阿里云最低价产品入口,含代金券(新老用户有优惠),
地址https://www.aliyun.com/minisite/goods

在本篇文章中,我将讲解抽象工厂模式以及结合Cocos2d-x3.2中某些源码来作为实例说明。

1.模式定义

在基类中定义一系列只有名称而没有实现的接口,具体实现需要在其子类中定义。或者在基类中定义一系列有名称且有简单实现的接口,具体实现还是需要在其子类中定义。抽象工厂模式可能会用工厂方法(Factory Method)或原型模式(Prototype)模式来实现。也就是说在一种模式的实现中可以应用其他设计模式,所以当你学习时,不能死背一种模式,而应该把多种模式结合起来理解。这会使得我们在平常写代码中能合理利用多种设计模式。

在C++中实现,通常把接口定义为虚函数,这是为了用父类指针指向子类后能动态执行,这样实现比较灵活。在C++中也可以把接口定义为非虚函数,这样就需要用该类的指针来指向它来执行操作。至于上面所说的只有名称没有实现的接口就是用纯虚函数来实现的。

下面我就用代码1来说明一下。

代码1: class baseFactory{

public:

virtual Type function1(Parameters A) =0;};class subclassFactory1:public baseFactory{public: virtual Type function1(Parameters A) {

具体实现1... }};class subclassFactory2:public baseFactory{public: virtual Type function2(Parameters A) {

具体实现2... }};

为什么在subclassFactory1中的function1也为虚函数,这是因为 subclassFactory1也有可能是其他类的父类,这样方便用父类指针指向子类后能动态执行。

从代码1我们可以看出,一个基类衍生出了多个子类,并且具体实现是与该子类有关而不是与基类有关。这样我们在编写一个系统时就可以设置一个统一备置,而每个子类就可以自由发挥地实现自己想要实现的效果了。在我们生活中,车就是一个基类,它配置好了参数,然后不同厂商生产不同品牌且性能不同的车。不同品牌的车就是车的子类了,不同厂商可以根据自己喜好来设计生产车。

2.模式应用场景

1.一个系统要独立于它的产品的创建、组合和表示时。

2.一个系统要有多个产品系列中的一个来配置时。

3.当你要强调一系列的相关的产品对象设计以便进行联合使用时。

4.当你提供一个产品类库,而只想显示他们的接口而不是实现时。

3.模式在Cocos2d-x3.2中的应用

在Cocos2d-x3.2中应用这种模式的大多是xxxProtocol类,这些类声明在...\cocos2d\cocos\base\CCProtocols.h目录下,大家可以去看看。

那接下来我就以TextureProtocol作为例子来讲解。

我们先看看TextureProtocal的源码,代码2。

代码2: class CC_DLL TextureProtocol : public BlendProtocol{public:

virtual ~TextureProtocol() {}

virtual Texture2D* getTexture() const = 0;

virtual void setTexture(Texture2D *texture) = 0;};

在代码2中,我们可以看到TextureProtocol继承了BlendProtocol,BlendProtocl的声明如代码3。

代码3: class CC_DLL BlendProtocol{public:

virtual ~BlendProtocol() {}

virtual void setBlendFunc(const BlendFunc &blendFunc) = 0;

virtual const BlendFunc &getBlendFunc() const = 0;};

那我们为什么不以 BlendProtocol来讲解,而是用 TextureProtocol来说明?当我们追寻 BlendProtocol的setBlendFun c或getBlendFunc的具体在那个些子类中实现时,就会发现这个两个接口只在Sprite类中实现了而没有在其他子类中实现,这太没有代表性。所以我们用TextureProtocol来讲解。

那么我们现在就追寻TextureProtocol中的setTexture具体在哪些子类实现。在Visual Studio环境下点击右键转到定义,得到的结果如图1。

图1:

从图1中,我们可以看到Sprite、ParticleSystem、SpriteBatchNode等等都继承了TextureProtocol,并且都按各自需求实现了setTexture接口。这里我们就看到了这种设计模式的优点了,即基类配置参数,子类按照自己需要实现,各个子类的实现相互独立。

那接下来,我们也就setTexture在Sprite和ParticleSystem中的实现,如代码4和代码5。

代码4: void Sprite::se

推荐:【设计模式学习笔记三】【创建型模式】【抽象工厂(Abstract Factory)】

本文是我学习刘伟技术博客的笔记,博客链接如下: http://blog.csdn.net/lovelion/article/details/17517213 我做的这部分笔记,鉴于自身水平有限,我只是对上面

tTexture(Texture2D *texture){

// If batchnode, then texture id should be the same

CCASSERT(! _batchNode || texture->getName() == _batchNode->getTexture()->getName(), "CCSprite: Batched sprites should use the same texture as the batchnode");

// accept texture==nil as argument

CCASSERT( !texture || dynamic_cast<Texture2D*>(texture), "setTexture expects a Texture2D. Invalid argument");

if (texture == nullptr)

{

// Gets the texture by key firstly.

texture = Director::getInstance()->getTextureCache()->getTextureForKey(CC_2x2_WHITE_IMAGE_KEY);

// If texture wasn't in cache, create it from RAW data.

if (texture == nullptr)

{

Image* image = new Image();

bool isOK = image->initWithRawData(cc_2x2_white_image, sizeof(cc_2x2_white_image), 2, 2, 8);

CC_UNUSED_PARAM(isOK);

CCASSERT(isOK, "The 2x2 empty texture was created unsuccessfully.");

texture = Director::getInstance()->getTextureCache()->addImage(image, CC_2x2_WHITE_IMAGE_KEY);

CC_SAFE_RELEASE(image);

}

}

if (!_batchNode && _texture != texture)

{

CC_SAFE_RETAIN(texture);

CC_SAFE_RELEASE(_texture);

_texture = texture;

updateBlendFunc();

}}

代码5: void ParticleSystem::setTexture(Texture2D* var){

if (_texture != var)

{

CC_SAFE_RETAIN(var);

CC_SAFE_RELEASE(_texture);

_texture = var;

updateBlendFunc();

}}

从代码4和5中,我们看到了setTexture在各个子类中按需求实现的。

4.模式结构与参与者

此模式的结构如图2。

图2:

1.AbstractFactory()

声明一个创建抽象产品对象的操作接口。在这里没有调用Sprite、ParticleSystem的操作接口。

2.ConcreteFactory()

实现创建具体产品对象的操作。在这里没有调用Sprite、ParticleSystem的操作。

3.AbstractProduct(TextureProtocol)

为一类产品对象声明一个接口。在这里为TextureProtocol。

4.ConcreteProduct(Sprite、ParticleSystem...)

定义一个将被相应的具体工厂创建的产品对象。实现AbstractProduct接口。在这里为Sprite、ParticleSystem...。

5.Client

仅使用有AbstractFactory和AbstractProduct类声明的接口。

5.模式的优缺点

优点:在基类声明同一接口,在不同子类中按照各自需要来实现,分离了具体的类。这使得在调用处可以方便切

换到不同的实现类。

缺点:难于在基类中添加新的接口来支持新的类,因为这需要在每个子类中添加新的接口的定义,代码量大。

如需转载,请标明出处:http://blog.csdn.net/cbbbc/article/details/38950569

推荐:设计模式学习(创建型模式)—抽象工厂模式(Abstract Factory)

抽象工厂模式(Abstract Factory)针对多个对象的情况,而工厂方法模式针对单一对象的情况。 [java]  view plain copy public class TestAbstractFactory {     

   在本篇文章中,我将讲解抽象工厂模式以及结合Cocos2d-x3.2中某些源码来作为实例说明。    1.模式定义       在基类中定义一系列只有名称而没有实现的接口,具体实现需要在其子类中定义。或者

相关阅读排行


相关内容推荐

最新文章

×

×

请激活账号

为了能正常使用评论、编辑功能及以后陆续为用户提供的其他产品,请激活账号。

您的注册邮箱: 修改

重新发送激活邮件 进入我的邮箱

如果您没有收到激活邮件,请注意检查垃圾箱。