工厂设计模式提供了一个共同的接口来指向新创建的对象,避免用new创建对象。
优点:
1、一个调用者想创建一个对象,只要知道其名称就可以了。
2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
3、屏蔽产品的具体实现,调用者只关心产品的接口。
一. 简单工厂模式
每新增一个产品,就要修改工厂类,本质还是用new创建对象。
//Java中可以用接口来实现这个过程,以下是Java代码:
interface Fruit {
public void eat();
}
class Apple implements Fruit {
public void eat(){
System.out.println("吃苹果");
}
}
class Orange implements Fruit {
public void eat(){
System.out.println("吃橘子");
}
}
class Factory {
public static Fruit getInstance(String className){
if("apple".equalsIgnoreCase(className)){
return new Apple();
}
if("orange".equalsIgnoreCase(className)){
return new Orange();
}
return null;
}
}
public class TestDemo{
public static void main(String[] args){
Fruit f = Factory.getInstance("apple");
f.eat();
f = Factory.getInstance("orange");
f.eat();
}
}
//C++代码如下:
//基类中有纯虚函数,使其成为抽象类,抽象类是无法建立对象的,只作为基类提供公共的接口
enum FRUIT_TYPE{APPLE,ORANGE};
class Fruit{
public:
virtual void eat()= 0;
};
class Apple: public Fruit{
public:
void eat(){printf("吃苹果\n");}
};
class Orange: public Fruit{
public:
void eat(){printf("吃橘子\n");}
};
class Factory{
public:
Fruit* getInstance(FRUIT_TYPE fruit)
{
if(fruit == APPLE)
{
return new Apple();
}
if(fruit == ORANGE)
{
return new Orange();
}
return NULL;
}
};
二. 工厂模式
简单工厂模式的缺点:每次添加一个产品子类都必须在工厂类中添加一个判断分支,那么工厂类的代码就要不断修改。
反射的本质:通过类的名字得到对应类型的对象。
因为用了new创建对象,可扩展性很差。需要用反射中的class.forName().newInstance()实例化类。
修改代码如下:
class Factory {
public static Fruit getInstance(String className){
try{
return (Fruit)Class.forName(className).newInstance();
}catch(Exception e){
return null;
}
}
}
public class TestDemo{
public static void main(String[] args){
Fruit f = Factory.getInstance("com.zhb.factory.Apple");
f.eat();
f = Factory.getInstance("com.zhb.factory.Orange");
f.eat();
}
}
在C++中没有反射的概念,所以无法通过类名创建对象实例,但是简单工厂的模式,每新增一个产品都要修改Factory的代码,违反了开放-封闭原则:软件实体(类、模块、函数)可以扩展,但是不可修改。
所以应该定义一个用于创建对象的接口,让子类决定实例化哪一个类。说白了,就是先创建一个工厂基类,然后有几种产品,就继承基类,创建几个工厂。
代码如下:Fruit类及其子类的代码不变。
class Factory{
public:
virtual Fruit* getInstance() = 0;
};
class FactoryApple:public Factory{
public:
Fruit* getInstance(){return new Apple();}
};
class FactoryOrange:public Factory{
public:
Fruit* getInstance(){return new Orange();}
};
//主函数调用
FactoryApple factory1;
Fruit* fruit = factory1.getInstance();
fruit->eat();
FactoryOrange factory2;
fruit = factory2.getInstance();
fruit->eat();