一、简单工厂,工厂模式,抽象工厂

为什么?

统一管理对象的创建过程式分为多种

工厂模式说起来很虚的感觉,如果构造函数很简单, 直接就可以new出来。那还需要工厂模式做什么?
设计模式嘛,就是要将简单的东西标准化,用统一的模式或者方式去做某件事情,包括创建对象。更重要的是设计模式一直在强调解耦。怎么解耦?通常的方法就是中间加一层——抽象层,高层抽象,底层抽象都向这个中间层靠。
那换句话说,其实是在“封装”代码。将一些常用,会用到的代码进一步封装。
所以会看到,我就简单的new一个对象怎么就要额外的添加那么多个类啊。
因为啊,以后底层的类可能要更改,底层类的构造函数可能要更改,如果使用了工厂模式,那么只需要改这一个抽象层就行了,不用在所有代码里挨个找。

简单工厂模式

这种模式不是标准的23中模式之一。因为它不符合开闭原则。当类新加子类的时候,需要修改代码。

简单工厂模式,统一的返回某个基类的子类实例。

UML

简单工厂模式

代码

//抽象层
class AbCar
{
public:
  virtual  void run()=0;
};

//各个子类
class BWM:public:AbCar
{
public:
  virtual void run()
  {
    //dosomething
  };
};

class QQ:public:AbCar
{
public:
  virtual void run()
  {
    //dosomething
  };
};

//创建工厂
class CarFactory
{
public:
  AbCar create(string type)
  {
    if(type=="BMW")
    {
      return new BWM;
    }elseif(type=="QQ")
      {
        return new QQ;
      }
  }else{
    return nullptr;
  }
}

如果有新加入的子类,那么就要修改CreateCar,这不符合开闭原则。
但这是最近单的一类。用起来也很方便。

工厂模式

为了解决简单工厂模式不符合开闭原则的问题,出现了工厂模式。
工厂模式符合开闭原则。但是,引入了新的类,每一个实例类对应一个创建类。实例类共同继承一个抽象类,创建类共同继承另一个抽象类。两个抽象类之间有依赖关系。
使用时,要创建那个实例类,先创建对应的创建类。

UML

工厂模式

代码

//实例类的共同抽象类
class AbCar
{
public:
  virtual void run()=0;
};

//具体的实例类
class BMW:public:AbCar
{
public:
  virtual viod run()
  {
  }
private:
  int engine;
};

//具体的实例类
class QQ:public:AbCar
{
public:
  virtual viod run()
  {
  }
private:
  int engine;
}

//创建类共同继承的虚类
class AbCarFactory
{
public:
  virtual AbCar *create()=0
}

//具体的创建类
class BMWFactory:public AbCarFactory
{
public:
  virtual AbCar *create()
  {
    return new BMW;
  }
}

//具体的创建类
class QQFactory:public AbCarFactory
{
public:
  virtual AbCar *create()
  {
    return new QQ;
  }
}

//使用
int main()
{
  AbCarFactory *factory=new QQFactory;
  AbCar *qq=factory->create();
  delete factory;
  factory=nullptr;
  //。。。
  return 0;
}

在UML图的中间两层,可以无限的加新的类,新的类型的汽车。
可以看出来,其实更加复杂了有没有。但是如果以后car这个类的constructor变化了,那么只需要修改对应的创建类即可。也就是又“封装了一层”。

抽象工厂模式

工厂模式有个缺点,就是一种创建类只能创建一种实例类的实例。
所以,抽象工厂组合了工厂模式和简单工厂模式。
也是因为这样,所以抽象工厂模式也是不符合开闭原则的。

将同一种类型的创建类合并,一个创建类中放多个createType()函数,每一种type对应返回一种实例类。

UML

抽象工厂模式

代码

//实例类的共同抽象类
class AbCar
{
public:
  virtual void run()=0;
};

//具体的实例类
class BMW01:public:AbCar
{
public:
  virtual viod run()
  {
  }
private:
  int engine;
};

//具体的实例类
class BMW01:public:AbCar
{
public:
  virtual viod run()
  {
  }
private:
  int engine;
}

//创建类共同继承的虚类
class AbCarFactory
{
public:
  virtual AbCar *create()=0
}

//具体的创建类
class BMWFactory:public AbCarFactory
{
public:
  virtual AbCar *createBMW01()
  {
    return new BMW01;
  }
  virtual AbCar *createBMW02()
  {
    return new BMW02;
  }
}

//使用
int main()
{
  AbCarFactory *factory=new BMWFactory;
  AbCar *bmw=factory->createBMW01();
  delete factory;
  factory=nullptr;
  //。。。
  return 0;
}

创建类的抽象类的纯虚函数,在其子类中并没有什么作用,如果两个创建类中能创建的类型并没有共同的特点那?如果两个创建类能够创建的实例并不相同那?
那创建类的基类的纯虚函数,就是个摆设,或者是多余。并不符合借口隔离的原则。

所以我觉得这个抽象工厂模式的应用范围,真是窄。

总结

用的多的应该还是工厂模式。
简单工厂模式弊端大。需要按照参数类型进行创建。扩展不方便,
抽象工厂模式,对于一类产品的扩展和简单工厂模式一样,如果一个创建类要拓展一种创建类型,那么就要添加一个成员函数。如果使用基类继承过来的,那么基类也要加一个。而其他继承这个基类的子类,也新添加了一个类型吗?并不见得。

所以抽象工厂模式,应该应用在大型的,可能持久不变的项目中。

工厂模式更加接地气儿。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容