简单工厂模式
//一般来说,自己创建一个对象的方法是在自己写的业务函数中直接new一个对象出来
//但是现实需求,我不想创建对象,我只想拿来用。(创建类的步骤比较复杂)
//好处,1、客户端和具体实现类解耦。2、对于某些对象创建过程比较复杂情况,我们不用考虑这些了。
//坏处,1、简单工厂模式,增加新的功能是通过源代码实现的,不符合开闭原则。2、这个类的职责过重,这个类发生问题,会影响很多使用这个工厂模块。
//抽象水果 class AbstractFruit{ public: virtual void ShowName() = 0; };//苹果 class Apple: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 == "pear"){return new Pear;}elsereturn NULL;} };void test1(){FruitFactory* factory = new FruitFactroy;AbstractFruit* apple = factory->CreateFruite("apple");apple->ShowName();AbstracFruit* banana = factory->CreateFruite("banana");banana->ShowName();delete factory;delete apple;delete banana;}
工厂方法模式
问题,1、类的个数成倍增加,导致类越来越多,增加维护成本。
好处,1、符合开闭原则
简单工厂模式 + “开闭原则” = 工厂方法模式
优点:1,不需要记住具体类名,甚至连具体参数都不用记忆。
2,实现了对象创建和使用的分离。
3,系统的可扩展性也就变得非常好,无需修改接口和原类。
缺点:1,增加系统中类的个数,复杂度和理解度增加。
2,增加了系统的抽象性和理解难度。
//抽象水果类
class AbstractFruit{ public: virtual void ShowName() = 0; };//苹果 class Apple: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 AbstracFruit* CreateFruit(){
return new Apple;
}
};
//鸭梨工厂
class PearFactory:public AbstractFruitFactory{
public:
virtual AbstracFruit* CreateFruit(){
return new Pear;
}
};
void test(){
AbstractFruitFactory* factory = NULL;
AbstractFruit* fruit = NULL;
//创建一个苹果工厂
factory = new AppleFactory;
fruit = factory->CreateFruit();
fruit->ShowName();
delete factory;
delete fruit;
//创建一个鸭梨工厂
factory = new PearFactory;
fruit = factory->CreateFruit();
fruit->ShowName();
delete factory;
delete fruit;
}
简单工厂模式和工厂方法模式适用场景
简单工厂模式:
1,工厂类负责创建的对象比较少,由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂。
2,客户端只知道传入工厂类的参数,对于如何创建对象不太关心。
工厂方法模式
1,客户端不知道它所需要的对象的类。
2,抽象工厂类通过其子类来指定创建哪个对象。
抽象工厂模式
抽象工厂针对的是产品族,而不是产品等级结构。产品族:同一产地或者同一厂商,功能不同。产品等级:功能相同,产地或者厂商不同。
//抽象苹果 class AbstractApple{ public:virtual void ShowName() = 0; };class ChineseApple:public AbstractApple{ public:virtual void ShowName(){cout << "中国苹果" << endl;} };//美国苹果 class USAApple:public AbstractApple{ public:virtual void ShowName(){cout << "美国苹果" << endl;} };//日本苹果 class JapaneseApple:public AbstractApple{ public:virtual void ShowName(){cout << "日本苹果" << endl;} };//抽象香蕉 class AbstractBanana{ public:virtual void ShowName() = 0; };//中国香蕉 class ChineseBanana:public AbstractBanana{ public:virtual void ShowName(){cout << "中国香蕉" << endl;} };//美国香蕉 class USABanana:public AbstractBanana{ public:virtual void ShowName(){cout << "美国香蕉" << endl;} };//日本香蕉 class JapaneseBanana:public AbstractBanana{ public:virtual void ShowName(){cout << "日本香蕉" << endl;} };//抽象工厂 针对产品族 class AbstractFactory{ public:virtual AbstractApple* CreateApple() = 0;virtual AbstractBanana* CreateBanana() = 0;virtual AbstractPear* CreatePear() = 0; };//中国工厂 class ChineseFactory:public AbstracFactory{ public:virtual AbstractApple* CreateApple() {return new ChineseApple;}virtual AbstractBanana* CreateBanana(){return new ChineseBanana;}virtual AbstractPear* CreatePear(){return new ChinesePear;} };//美国工厂 class USAFactory:public AbstracFactory{ public:virtual AbstractApple* CreateApple() {return new USAApple;}virtual AbstractBanana* CreateBanana(){return new USABanana;}virtual AbstractPear* CreatePear(){return new USAPear;} };//日本工厂 class JapaneseFactory:public AbstracFactory{ public:virtual AbstractApple* CreateApple() {return new JapaneseApple;}virtual AbstractBanana* CreateBanana(){return new JapaneseBanana;}virtual AbstractPear* CreatePear(){return new JapanesePear;} };test(){AbstractFactory* factory = NULL;AbstractApple* apple = NULL;AbstractBanana* banana = NULL:AbstractPear* pear = NULL;//中国工厂factory = new ChineseFactory; apple = factory->CreateApple();banana = factory->CreateBanana();pear = factory->CreatePear();}
总结
一、简单工厂模式
我们在实例化对象的时候通常用的式New关键字,但是有了工厂,我们在声明对象的时候就可以用工厂了,用new导致代码不够灵活,用工厂来实例化对象很灵活。
优点,1,简单工厂包含必要的判断逻辑,简单工厂实现了对象的创建和使用的分离。
2,客户端无需知道所创建的具体产品类的类名,只需要具体产品类对应的参数即可。
3,在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。
缺点,1,工厂类的职责过重,简单工厂中包含逻辑判断语句,他一旦有问题,整个系统都要出问题。
2,在添加新类的时候,简单工厂就要修改,违反了开闭原则。
二、工厂方法模式
工厂方法式简单工厂的进一步的延申,这样说是因为简单工厂违反了开闭原则,而工厂方法可以完美解决这个问题。
优点,1,工厂方法用来创建类,同时隐藏了具体产品类被实例化的细节,用户只需要关注工厂,不需要关注创建的细节。
2,再增加新的运算类时不需要修改代码,只需要增加对应的工厂即可。符合开闭原则。
缺点,1,再增加新的类时,也必须增加新的工厂类,会带来额外的开销
2,抽象层的加入使得理解难度加大。
三、抽象工厂
抽象工厂模式是工厂方法的进一步延伸,由于它提供了功能更为强大的工厂类并且具备较好的可扩展性。
有缺点:抽象工厂模式增加一个产品族很简单,但是增加一个新的产品就会非常复杂。