0、模式类型
"对象创建"模式
- 通过“对象创建”模式绕开new,来避免对象创建(new)过程中导致的紧耦合(依赖具体类),从而支持对象创建的稳定。他是接口抽象之后的第一步工作。
典型模式
- Factory Method
- Abstract Factory
- Prototype
- Builder
1、Abstract Factory
1.1、动机
- 在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作;同时,由于需求的变化,往往存在更多系列对象的创建工作。
- 如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种“封装机制”来避免客户程序和这种“多系列具体对象创建工作的紧耦合?”
1.2、实现
需求:家具店里有沙发、椅子、茶几等产品。产品有不同风格,如现代、北欧、工业。希望确保客户收到的产品风格统一,并可以方便的添加新产品和风格。
第一种实现方式:
- 第一种实现方式没有使用工厂方法。
#ifndef __UNUSE_FACTORY__
#define __UNUSE_FACTORY__
#include<iostream>
class Chair{
public:
virtual ~Chair(){}
//椅子方法
virtual void sitOn() const = 0;
};
class ModernChair: public Chair{
public:
virtual void sitOn() const override{
std::cout << "Modern Chair, you can sit on it!" << std::endl;
}
};
class ChineseChair: public Chair{
public:
virtual void sitOn() const override{
std::cout << "Chinese Chain, you can sit on it!" << std::endl;
}
};
class Desk{
public:
virtual ~Desk(){}
//桌子方法
virtual void putOn() const = 0;
};
class ModernDesk: public Desk{
public:
virtual void putOn() const override{
std::cout << "Modern Desk, you can put something on it!" << std::endl;
}
};
class ChineseDesk: public Desk{
public:
virtual void putOn() const override{
std::cout << "Chinese Desk, you can put something on it!" << std::endl;
}
};
class Client{
public:
void buySomething()
{
//每次新的顾客要买别的风格家具都要重新改写代码。
Chair* chair = new ModernChair();
Desk* desk = new ModernDesk();
chair->sitOn();
desk->putOn();
delete chair;
delete desk;
}
};
#endif
#include"unuse_factory.h"
int main()
{
Client* client = new Client();
client->buySomething();
delete client;
return 0;
}
运行结果:
第二种实现方式:
- 使用了抽象工厂方法
#ifndef __ABSTRACT_FACTORY__
#define __ABSTRACT_FACTORY__
#include<iostream>
class Chair{
public:
virtual ~Chair(){}
//椅子方法
virtual void sitOn() const = 0;
};
class ModernChair: public Chair{
public:
virtual void sitOn() const override{
std::cout << "Modern Chair, you can sit on it!" << std::endl;
}
};
class ChineseChair: public Chair{
public:
virtual void sitOn() const override{
std::cout << "Chinese Chain, you can sit on it!" << std::endl;
}
};
class Desk{
public:
virtual ~Desk(){}
//桌子方法
virtual void putOn() const = 0;
};
class ModernDesk: public Desk{
public:
virtual void putOn() const override{
std::cout << "Modern Desk, you can put something on it!" << std::endl;
}
};
class ChineseDesk: public Desk{
public:
virtual void putOn() const override{
std::cout << "Chinese Desk, you can put something on it!" << std::endl;
}
};
// 创建抽象工厂
class Factory{
public:
virtual ~Factory(){}
virtual void CreateProduct() const = 0;
};
class ModernFactory:public Factory{
public:
virtual void CreateProduct() const override{
Desk* desk= new ModernDesk();
Chair* chair = new ModernChair();
desk->putOn();
chair->sitOn();
delete desk;
delete chair;
}
};
// 缺点就是如果后续需要在同一种风格中添加新的商品,就需要修改代码了。
class ChineseFactory:public Factory{
public:
virtual void CreateProduct() const override{
Desk* desk = new ChineseDesk();
Chair* chair = new ChineseChair();
desk->putOn();
chair->sitOn();
delete desk;
delete chair;
}
};
class Client{
private:
Factory* factory;
public:
void buySomething(Factory* factory)
{
//每次新的顾客要买别的风格家具都要重新改写代码。
factory->CreateProduct();
}
};
#endif
// #include"unuse_factory.h"
#include "abstract_factory.h"
int main()
{
Client* client = new Client();
client->buySomething(new ChineseFactory());
return 0;
}
运行结果:
2、模式定义
提供一个接口,让该接口负责创建一系列“相关或者相互依赖的对象”,无需指定他们具体的类 ——《设计模式》GoF.
3、结构
4、总结
- 如果没有应对“多系列对象创建”的需求变化,则没有必要使用Abstruct Factory模式,这时候使用简单的工厂完全可以。
- “系列对象”指的是在某一特定系列下的对象之间有相互依赖、或作用的关系。不同系列的对象之间不能相互依赖。
- Abstract Factory模式主要在于应对“新系列”的需求变动。其缺点在于难于应对“新对象”的需求变动。(在产品族中扩展新的产品需要修改抽象工厂的接口代码)。