//工厂模式:这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
//在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象
//
//例子:
//小时候,妈妈跟小朋友说你好好读书,你考上大学,我给你买一个拍照设备。当时妈妈就思考小朋友长大了以后依据小朋友的意愿,给他买一个相机或者DV.
//
//于是就有了
//
#include <iostream>
using namespace std;
class PhotoDevice
{
public:
virtual void takePhoto() = 0;
virtual ~PhotoDevice(){};
};
class Camera : public PhotoDevice
{
public:
void takePhoto()
{
cout << "咔嚓,我是照相机" << endl;
}
};
class DV : public PhotoDevice
{
public:
void takePhoto()
{
cout << "嘀,我是录像机" << endl;
}
};
class Mother
{
public:
PhotoDevice* giveGiftWithCamera(int flag)
{
switch (flag) //**** 代码细节
{
case 1:
return new Camera;
break;
case 2:
return new DV;
break;
default:
return NULL;
}
return NULL;
}
};
int main()
{
//...小朋友高考完了,说妈妈,我要照相机
//...妈妈意向,这就是我当时的一个号方案。
Mother *mother = new Mother;
PhotoDevice *gift = mother->giveGiftWithCamera(1);
gift->takePhoto();
}
//这种写法不好。这种方法违背了依赖倒置原则——不要依赖具体(应该依赖抽象(类),即接口)和代码细节(代码细节)。此时这种写法已经有了PhotoDevice虚基类,但是****部分是代码细节,是一个紧耦合。
//
//如果小朋友长大了,10年过去了,出现了智能手机,小朋友要的拍照设备是智能手机怎么办?需要修改****部分代码。
//于是有了工厂方法模式。
抽象工厂模式
/*是封装类中变化的部分,提取其中个性化善变的部分为独立类,通过依赖注入以达到解耦、复用和方便后期维护拓展的目的。它的核心结构有四个角色,分别是抽象工厂;具体工厂;抽象产品;具体产品
*/
#include <iostream>
using namespace std;
class PhotoDevice
{
public:
virtual void takePhoto() = 0;
virtual ~PhotoDevice(){};
};
class Camera : public PhotoDevice
{
public:
void takePhoto()
{
cout << "咔嚓,我是照相机" << endl;
}
};
class DV : public PhotoDevice
{
public:
void takePhoto()
{
cout << "嘀,我是录像机" << endl;
}
};
class Factory
{
public:
virtual PhotoDevice* createPhotoDevice() = 0;
virtual ~Factory(){};
};
class CameraFactory : public Factory
{
PhotoDevice* createPhotoDevice()
{
return new Camera;
}
};
class DVFactory : public Factory
{
PhotoDevice* createPhotoDevice()
{
return new DV;
}
};
class Mother
{
public:
PhotoDevice* giveGift(Factory* factory)
{
return factory->createPhotoDevice();
}
};
int main()
{
//...小朋友长大了,说我要一个相机
//...妈妈一番思考,然后说需要一个Caremafactory
//Factory *factory = new CameraFactory;
Factory *factory = new DVFactory;
Mother *mother = new Mother;
PhotoDevice* gift = mother->giveGift(factory);
gift->takePhoto();
return 0;
}
/*
此时如果小朋友说,我要智能手机,妈妈可以在建两个类, SmartPhone : public PhotoDevice
和SmartPhotoFactory : public Factory.不需要去修改giveGift方法。
*/
现在问题拓展一下,为了有更强的续航能力,妈妈决定在送相机或者DV的同时,送一块额外的电池(DV和相机的电池不同)。
可以这样写
#include <iostream>
using namespace std;
class PhotoDevice
{
public:
virtual void takePhoto() = 0;
virtual ~PhotoDevice(){};
};
class Camera : public PhotoDevice
{
public:
void takePhoto()
{
cout << "咔嚓,我是照相机" << endl;
}
};
class DV : public PhotoDevice
{
public:
void takePhoto()
{
cout << "嘀,我是录像机" << endl;
}
};
class PhotoDeviceFactory
{
public:
virtual PhotoDevice* createPhotoDevice() = 0;
virtual ~PhotoDeviceFactory(){};
};
class CameraFactory : public PhotoDeviceFactory
{
PhotoDevice* createPhotoDevice()
{
return new Camera;
}
};
class DVFactory : public PhotoDeviceFactory
{
PhotoDevice* createPhotoDevice()
{
return new DV;
}
};
class Battery
{
public:
virtual void sayHi() = 0;
};
class DVBattery : public Battery
{
public:
void sayHi()
{
cout << "我是DV电池,我要给录像机充电" << endl;
}
};
class CameraBattery: public Battery
{
public:
void sayHi()
{
cout << "我是相机电池,我要给相机充电" << endl;
}
};
class BatteryFactory
{
public:
virtual Battery* createBattery() = 0;
virtual ~BatteryFactory(){};
};
class CameraBatteryFacotry : public BatteryFactory
{
public:
Battery* createBattery()
{
return new CameraBattery;
}
};
class DVBattryFacotry : public BatteryFactory
{
public:
Battery* createBattery()
{
return new DVBattery;
}
};
class Gift
{
public:
PhotoDevice *pd;
Battery *battery;
};
class Mother
{
public:
Gift* giveGift(PhotoDeviceFactory* p_factory, BatteryFactory *b_factory)
{
return new Gift{p_factory->createPhotoDevice(), b_factory->createBattery()};
}
};
int main()
{
//...小朋友长大了,说我要一个相机
//...妈妈一番思考,然后说需要一个Caremafactory
//Factory *factory = new CameraFactory;
PhotoDeviceFactory *p_factory = new DVFactory;
BatteryFactory *b_factory = new DVBattryFacotry;
Mother *mother = new Mother;
Gift* gift = mother->giveGift(p_factory, b_factory);
gift->pd->takePhoto();
gift->battery->sayHi();
return 0;
}
//但是有可能出现这样的问题,就是妈妈一不小心送错了,买了相机和DV电池。
于是就有了在抽象工厂里,封装两个接口,一个接口创建拍照设备,一个接口创建电池。然后分别从相机套装和DV套装角度实现这个抽象工厂。这样,在工厂创建设备和电池时,可以保证不会混乱。
#include <iostream>
using namespace std;
class PhotoDevice
{
public:
virtual void takePhoto() = 0;
virtual ~PhotoDevice(){};
};
class Camera : public PhotoDevice
{
public:
void takePhoto()
{
cout << "咔嚓,我是照相机" << endl;
}
};
class DV : public PhotoDevice
{
public:
void takePhoto()
{
cout << "嘀,我是录像机" << endl;
}
};
class Battery
{
public:
virtual void sayHi() = 0;
};
class DVBattery : public Battery
{
public:
void sayHi()
{
cout << "我是DV电池,我要给录像机充电" << endl;
}
};
class CameraBattery: public Battery
{
public:
void sayHi()
{
cout << "我是相机电池,我要给相机充电" << endl;
}
};
class Factory
{
public:
virtual ~Factory(){};
virtual PhotoDevice* createPhotoDevice() = 0;
virtual Battery* createBattery() = 0;
};
class CameraSuitFactory : public Factory
{
public:
CameraSuitFactory(){};
PhotoDevice* createPhotoDevice()
{
return new Camera;
}
virtual Battery* createBattery()
{
return new CameraBattery;
}
};
class DVSuitFactory : public Factory
{
public:
DVSuitFactory(){};
PhotoDevice* createPhotoDevice()
{
return new DV;
}
virtual Battery* createBattery()
{
return new DVBattery;
}
};
class Gift
{
public:
PhotoDevice *pd;
Battery *battery;
};
class Mother
{
public:
Gift* giveGift(Factory *factory)
{
return new Gift{factory->createPhotoDevice(), factory->createBattery()};
}
};
int main()
{
//...小朋友长大了,说我要一个相机
//...妈妈一番思考,然后说需要一个CaremaSuitfactory
Factory *factory = new CameraSuitFactory;
Mother *mother = new Mother;
Gift* gift = mother->giveGift(factory);
gift->pd->takePhoto();
gift->battery->sayHi();
return 0;
}