简单工厂模式
简单工厂模式与其说是一种设计模式倒不如说是一种编程习惯。现实生活中,我们用的许多东西都是工厂里生产出来的,刷牙的牙膏、牙刷,洗脸用的洗面奶、毛巾等等。前一篇文章我们说过编程是为了解决问题,解决问题就要有相应的工具,就好比我们用牙膏牙刷解决刷牙的问题,用洗面奶毛巾解决洗脸的问题一样,唯一不同的是,解决刷牙洗脸这些问题的工具是可见的实实在在的工具,而我们编程解决的问题要使用的所谓工具,可能是个类或者一个接口函数。工厂设计模式,其实就是说我们编程的时候先建一个工厂,然后这个工厂会根据我们所要解决的问题生成相应的类(工具)。
比如,现在我们编程解决顾客吃水果的问题,比如顾客要吃苹果和梨,我们的程序就要给他/她提供苹果或者梨,使用简单工厂模式我们该如何编程呢?
我们可先创建一个类,这个类的名字就叫Fruits,这个类对外提供一个获取水果名字的接口,然后我们继承这个类,生成苹果和梨的子类,我们可以这样写:
class Fruits
{
public:
virtual void getName()
{
printf("I am Fruits\n");
}
};
class Apple:public Fruits
{
public:
void getName()
{
printf("I am Apple\n");
}
};
class Pear:public Fruits
{
public:
void getName()
{
printf("I am Pear\n");
}
};
水果类创建好了之后,接下来就是创建工厂类了,工厂类的主要职责是根据客户需求,生产出相应的水果,代码如下:
class Factory
{
public:
Fruits* productionFruits (string name)
{
Fruits* product = NULL;
switch(name)
{
case "Apple":
{
product = new Apple();
break;
}
case "Pear":
{
product = new Apple();
break;
}
}
return product;
}
};
工厂类创建好了之后,就可以给客户提供水果了
//客户端代码
int main ()
{
Factory fctObj;
Fruits* usrNeed = NULL;
usrNeed = fctObj.productionFruits("Apple");
usrNeed -> getName();
usrNeed = fctObj.productionFruits("Pear");
usrNeed -> getName();
return 0;
}
如果,客户这时候想吃香蕉了,该怎么办?只要生成一个叫banana的类,该类与Apple和Pear一样也是继承字Fruits类:
class Banana:public Fruits
{
public:
void getName()
{
printf("I am Banana\n");
}
};
然后让工厂类能够生产香蕉就可以了:
class Factory
{
public:
Fruits* productionFruits (string name)
{
Fruits* product = NULL;
switch(name)
{
case "Apple":
{
product = new Apple();
break;
}
case "Pear":
{
product = new Apple();
break;
}
//添加生产香蕉的代码
case "Banana":
{
product = new Banana();
break;
}
}
return product;
}
};
//客户端代码
int main ()
{
Factory fctObj;
Fruits* usrNeed = NULL;
//客户想要香蕉
usrNeed = fctObj.productionFruits("Banana");
usrNeed -> getName();
return 0;
}
现在回过头来看看工厂模式到底有什么好处?
隔绝了客户端与业务层的代码,并且降低了业务层相关类的耦合度,这样以后如果代码要扩展或修改代码,只要添加相应的类或在相应的类添加或修改相应的代码即可,不会影响其他的代码。