简单工厂模式
又叫做静态工厂方法模式,就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建。但是这存在一个问题就是不符合开闭原则。
假设有一个动物类接口,分别实现狗、猫、鸭子的子类,通过一个简单工厂的类,包含创建动物的方法,使用判断选择创建的对象。
#include <iostream>
#include <cstring>
using namespace std;
class Animal
{
public:
virtual ~Animal(){}
virtual void say()=0;
};
class Dog : public Animal
{
public:
virtual void say()
{
cout<<"woof woof"<<endl;
}
};
class Cat : public Animal
{
public:
virtual void say()
{
cout<<"mew mew"<<endl;
}
};
class Duck : public Animal
{
public:
virtual void say()
{
cout<<"quack quack"<<endl;
}
};
class SimpleFactory
{
public:
Animal *createAnimal(char *p)
{
if(!strcmp(p, "dog"))
return new Dog();
else if(!strcmp(p, "cat"))
return new Cat();
else if(!strcmp(p,"Duck"))
return new Duck();
else
return NULL;
}
};
int main()
{
SimpleFactory *sim = new SimpleFactory();
Animal *dog = sim->createAnimal("cat");
if(dog!=NULL){
dog->say();
delete dog;
dog = NULL;
}
return 0;
}
通过上面的代码很容易发现,随着类的不断增加,对于代码的修改也会不断增加,很明显这不符合开闭原则的“对扩展开放,对修改关闭”。
工厂方法模式
简单工厂方法模式中暴露出了不符合开闭原则的结果,改进的结果是:添加新的动物而不需要修改原有的代码,只需要添加新的代码。添加一种新的动物就只需要添加一个动物类,然后添加与之对应的新的工厂,这样就避免了使用switch-case模块,提高了代码的可读性和扩展性。具体实现如下:
#include <iostream>
#include <cstring>
using namespace std;
class Animal
{
public:
virtual ~Animal(){}
virtual void say()=0;
};
class Dog : public Animal
{
public:
virtual void say()
{
cout<<"woof woof"<<endl;
}
};
class Cat : public Animal
{
public:
virtual void say()
{
cout<<"mew mew"<<endl;
}
};
class Facrtory
{
public:
virtual ~Facrtory(){}
virtual Animal *createAnimal()=0;
};
class DogFactory : public Facrtory
{
public:
Animal *createAnimal(){
return new Dog();
}
};
class CatFactory : public Facrtory
{
public:
Animal *createAnimal(){
return new Cat();
}
};
int main()
{
Facrtory *factory = NULL;
Animal *animal = NULL;
factory = new DogFactory();
animal = factory->createAnimal();
animal->say();
delete animal;
delete factory;
factory = new CatFactory();
animal = factory->createAnimal();
animal->say();
delete animal;
delete factory;
return 0;
}
由上面的代码我们可以得出,工厂模式是用来生产同一等级结构中的固定产品,它支持增加任意产品, 但是如何生产一系列相关的产品呢?
抽象工厂模式
提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式最大的好处是易于交换产品系列,它只需要改变具体工厂即可使用不同的产品配置。不管是任何人的设计都无法去完全防止需求的更改,或者项目的维护,那么我们的理想便是让改动变得最小、最容易,例如我现在要更改以上代码的数据库访问时,只需要更改具体的工厂即可,产生产品族。
#include <iostream>
#include <cstring>
using namespace std;
class Phone{
public:
virtual ~Phone(){}
virtual void start()=0;
virtual void stop()=0;
virtual void call()=0;
virtual void sendMessage()=0;
void use(){
start();
call();
sendMessage();
stop();
}
};
class Router
{
public:
virtual ~Router(){}
virtual void start()=0;
virtual void stop()=0;
virtual void wifi()=0;
virtual void setting()=0;
void use(){
start();
setting();
wifi();
stop();
}
};
class MiPhone : public Phone
{
public:
virtual void start(){
cout<<"MiPhone start"<<endl;
}
virtual void stop(){
cout<<"MiPhone stop"<<endl;
}
virtual void call(){
cout<<"MiPhone call"<<endl;
}
virtual void sendMessage(){
cout<<"MiPhone sendMessage"<<endl;
}
};
class MiRouter : public Router
{
public:
virtual void start(){
cout<<"MiRouter start"<<endl;
}
virtual void stop(){
cout<<"MiRouter stop"<<endl;
}
virtual void wifi(){
cout<<"MiRouter wifi"<<endl;
}
virtual void setting(){
cout<<"MiRouter setting"<<endl;
}
};
class HuaweiPhone : public Phone
{
public:
virtual void start(){
cout<<"HuaweiPhone start"<<endl;
}
virtual void stop(){
cout<<"HuaweiPhone stop"<<endl;
}
virtual void call(){
cout<<"HuaweiPhone call"<<endl;
}
virtual void sendMessage(){
cout<<"HuaweiPhone sendMessage"<<endl;
}
};
class HuaweiRouter : public Router
{
public:
virtual void start(){
cout<<"HuaweiRouter start"<<endl;
}
virtual void stop(){
cout<<"HuaweiRouter stop"<<endl;
}
virtual void wifi(){
cout<<"HuaweiRouter wifi"<<endl;
}
virtual void setting(){
cout<<"HuaweiRouter setting"<<endl;
}
};
class Factory
{
public:
virtual ~Factory(){}
virtual Phone *createPhone()=0;
virtual Router *createRouter()=0;
};
class MiFactory : public Factory
{
public:
virtual Phone *createPhone(){
return new MiPhone();
}
virtual Router *createRouter(){
return new MiRouter();
}
};
class HuaweiFactory : public Factory
{
public:
virtual Phone *createPhone(){
return new HuaweiPhone();
}
virtual Router *createRouter(){
return new HuaweiRouter();
}
};
int main()
{
Factory *factory = NULL;
Phone *phone = NULL;
Router *router = NULL;
factory = new MiFactory();
phone = factory->createPhone();
router = factory->createRouter();
phone->use();
router->use();
delete router;
delete phone;
delete factory;
cout<<endl;
factory = new HuaweiFactory();
phone = factory->createPhone();
router = factory->createRouter();
phone->use();
router->use();
delete router;
delete phone;
delete factory;
return 0;
}