优点:
缺点:
应用场景
对于产品种类相对较少的情况,考虑使用简单工厂模式。使用简单工厂模式的客户端只需要传入工厂类的参数,不需要关心如何创建对象的逻辑,可以很方便地创建所需产品。
示例图:
简单工厂案例:
#include
using namespace std;
//简单工厂案例
class AbstractFruit {
public:
virtual void ShowName() = 0;
};
//苹果
class Apple : public AbstractFruit {
public:
virtual void ShowName() {
cout << "我是苹果" << endl;
}
};
//香蕉
class Banana : public AbstractFruit {
public:
virtual void ShowName() {
cout << "我是香蕉" << endl;
}
};
//鸭梨
class Pear : public AbstractFruit {
public:
virtual void ShowName() {
cout << "我是鸭梨" << endl;
}
};
//水果工厂
class FruitFactory {
public:
//设置为静态 为该类的所有对象共享
static AbstractFruit* CreateFruit(string flag) {
if (flag == "apple") {
return new Apple;
}
else if (flag == "banana") {
return new Banana;
}
else if (flag == "pear") {
return new Pear;
}
else {
return NULL;
}
}
};
void test01() {
//创建一个工厂对象
FruitFactory* factory = new FruitFactory;
//这里我们发现不再像普通的多态一样需要new Apple;
//而是在工厂的成员函数参数中传入一个string
//让工厂类自动帮我们创建一个Apple对象
//不用考虑创建过程 拿来直接用 减少了耦合性
AbstractFruit* fruit = factory->CreateFruit("apple");
fruit->ShowName();
delete fruit;
fruit = factory->CreateFruit("banana");
fruit->ShowName();
delete fruit;
fruit = factory->CreateFruit("pear");
fruit->ShowName();
delete fruit;
delete factory;
}
int main() {
test01();
return 0;
}
总结:好代码就是让耦合性不断的变低 这里直接传一个string就可以创建对象了 比传统的多态更进了一步
优点:
缺点:
应用场景:
思考:简单工厂模式虽然降低了耦合性 但是不符合开闭原则 增加一个水果类需要修改工厂类的源代码 如何让工厂也符合开闭原则呢? 答案就是让工厂也抽象出去
示例图:
简单工厂模式 + 开闭原则 = 工厂方法模式
#include
using namespace std;
//工厂方法案例
class AbstractFruit {
public:
virtual void ShowName() = 0;
};
//苹果
class Apple : public AbstractFruit {
public:
virtual void ShowName() {
cout << "我是苹果" << endl;
}
};
//香蕉
class Banana : public AbstractFruit {
public:
virtual void ShowName() {
cout << "我是香蕉" << endl;
}
};
//鸭梨
class Pear : public AbstractFruit {
public:
virtual void ShowName() {
cout << "我是鸭梨" << endl;
}
};
//抽象工厂
class AbstractFruitFactory {
public:
virtual AbstractFruit* CreateFruit() = 0;
};
//苹果工厂
class AppleFactory : public AbstractFruitFactory {
public:
virtual AbstractFruit* CreateFruit() {
return new Apple;
}
};
//香蕉工厂
class BananaFactory : public AbstractFruitFactory {
public:
virtual AbstractFruit* CreateFruit() {
return new Banana;
}
};
//鸭梨工厂
class PearFactory : public AbstractFruitFactory {
public:
virtual AbstractFruit* CreateFruit() {
return new Pear;
}
};
void test01() {
AbstractFruitFactory* factory = NULL;
AbstractFruit* fruit = NULL;
//创建一个苹果工厂对象 用抽象类factory接收
factory = new AppleFactory;
//用factory接口去访问子类CreateFruit成员函数
//在CreateFruit()内部返回了一个水果Apple类对象
//并用水果的抽象父类接收
fruit = factory->CreateFruit();
//使用水果的抽象类接口去访问水果子类的成员函数ShowName()
fruit->ShowName();
delete fruit;
delete factory;
//创建一个香蕉工厂
factory = new BananaFactory;
fruit = factory->CreateFruit();
fruit->ShowName();
delete fruit;
delete factory;
//创建一个鸭梨工厂
factory = new PearFactory;
fruit = factory->CreateFruit();
fruit->ShowName();
delete fruit;
delete factory;
}
int main() {
test01();
return 0;
}
总结:可以看出来代码量成倍的增长 增加了抽象理解难度 在工厂方法模式下 当我们想要增加一种新的水果 我们只需要增加一个水果类和一个对应的水果工厂类即可 不需要修改源代码
所以说如果后期不需要新增太多的类 可以用简单工厂模式 而如果后期需要不断的新增类 那么工厂方法模式更易于维护
抽象工厂(AbstractFactory)模式的定义:是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。
抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。
使用抽象工厂模式一般要满足以下条件。
抽象工厂模式除了具有工厂方法模式的优点外,其他主要优点如下。
其缺点是:当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。增加了系统的抽象性和理解难度。
示例图:
#include
using namespace std;
//抽象工厂案例
//首先我们根据产品族抽象出来三种水果
//抽象苹果
class AbstractApple {
public:
virtual void ShowName() = 0;
};
//中国苹果
class ChinaApple : public AbstractApple {
public:
virtual void ShowName() {
cout << "中国苹果" << endl;
}
};
//美国苹果
class USAApple : public AbstractApple {
public:
virtual void ShowName() {
cout << "美国苹果" << endl;
}
};
//巴西苹果
class BrasiliaApple : public AbstractApple {
public:
virtual void ShowName() {
cout << "巴西苹果" << endl;
}
};
//抽象香蕉------------------------------------
class AbstractBanana {
public:
virtual void ShowName() = 0;
};
//中国香蕉
class ChinaBanana : public AbstractBanana {
public:
virtual void ShowName() {
cout << "中国香蕉" << endl;
}
};
//美国香蕉
class USABanana : public AbstractBanana {
public:
virtual void ShowName() {
cout << "美国香蕉" << endl;
}
};
//巴西香蕉
class BrasiliaBanana : public AbstractBanana {
public:
virtual void ShowName() {
cout << "巴西香蕉" << endl;
}
};
//抽象鸭梨-------------------------------
class AbstractPear {
public:
virtual void ShowName() = 0;
};
//中国鸭梨
class ChinaPear : public AbstractPear {
public:
virtual void ShowName() {
cout << "中国鸭梨" << endl;
}
};
//美国鸭梨
class USAPear : public AbstractPear {
public:
virtual void ShowName() {
cout << "美国鸭梨" << endl;
}
};
//巴西鸭梨
class BrasiliaPear : public AbstractPear {
public:
virtual void ShowName() {
cout << "巴西鸭梨" << endl;
}
};
//抽象工厂 针对产品族的--------------------------
class AbstractFactory {
public:
virtual AbstractApple* CreateApple() = 0;
virtual AbstractBanana* CreateBanana() = 0;
virtual AbstractPear* CreatePear() = 0;
};
//中国工厂
class ChinaFactory : public AbstractFactory {
public:
virtual AbstractApple* CreateApple() {
return new ChinaApple;
}
virtual AbstractBanana* CreateBanana() {
return new ChinaBanana;
}
virtual AbstractPear* CreatePear() {
return new ChinaPear;
}
};
//美国工厂
class USAFactory : public AbstractFactory {
public:
virtual AbstractApple* CreateApple() {
return new USAApple;
}
virtual AbstractBanana* CreateBanana() {
return new USABanana;
}
virtual AbstractPear* CreatePear() {
return new USAPear;
}
};
//巴西工厂
class BrasiliaFactory : public AbstractFactory {
public:
virtual AbstractApple* CreateApple() {
return new BrasiliaApple;
}
virtual AbstractBanana* CreateBanana() {
return new BrasiliaBanana;
}
virtual AbstractPear* CreatePear() {
return new BrasiliaPear;
}
};
void test01() {
AbstractFactory* factory = NULL;
AbstractApple* apple = NULL;
AbstractBanana* banana = NULL;
AbstractPear* pear = NULL;
//中国工厂
//创建一个中国工厂对象 用factory抽象类接收
factory = new ChinaFactory;
//抽象父类访问子类的成员函数 返回一个中国苹果类
//用抽象苹果去接收
apple = factory->CreateApple();
banana = factory->CreateBanana();
pear = factory->CreatePear();
//父类抽象苹果访问子类中国苹果的成员函数ShowName()
apple->ShowName();
banana->ShowName();
pear->ShowName();
delete pear;
delete banana;
delete apple;
delete factory;
//美国工厂
factory = new USAFactory;
apple = factory->CreateApple();
banana = factory->CreateBanana();
pear = factory->CreatePear();
apple->ShowName();
banana->ShowName();
pear->ShowName();
delete pear;
delete banana;
delete apple;
delete factory;
}
int main() {
test01();
return 0;
}
总结:这个抽象工厂模型其实算是简单工厂模型和工厂方法模型的一个结合 针对产品族和产品等级 其开闭原则是不同的 当我们新增加一个工厂的时候 比如加一个日本工厂 是不需要修改源代码的 符合开闭原则(产品族) 而新增加一个水果 比如西瓜的时候 是需要修改源代码的 不符合开闭原则(产品等级) 所以这就是为什么说抽象工厂模型是针对于产品族而不是产品等级的原因了