设计模式(3)工厂方法模式

奉上原文链接 https://blog.csdn.net/sinat_21107433/article/details/102616501

工厂方法模式思路

简单工厂设计模式的思路,决定了每次新增一种具体的产品时,就需要更改工厂内部的产品构成。因为开闭原则,决定了对外开放接口,对内封闭的思路,工厂方法设计模式,不在使用工厂类统一创建所有的具体产品,不同工厂针对不同的产品,新增产品时,需要同时新增对应的工厂。

工厂方法模式:定义一个用于创建对象的接口,但是让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。

工厂方法模式结构

从上述工厂方法模式的介绍中,可以看出此种模式由以下几个主要成员组成:

  • 抽象工厂(AbstractFactory):所有生产具体产品的工厂类的基类,提供工厂类的公共方法;
  • 具体工厂(ConcreteFactory):生产具体的产品
  • 抽象产品(AbstractProduct):所有产品的基类,提供产品类的公共方法
  • 具体产品(ConcreteProduct):具体的产品类

在这里插入图片描述

工厂方法模式实例

需求
需求
需求
客户
篮球工厂
篮球
足球工厂
足球
排球工厂
排球

对应的UML图如下:
在这里插入图片描述
factorymethod.h

#include <iostream>
#include <string.h>

using namespace std;

//抽象产品类AbstractProduct
class AbstractSportProduct
{
    
    
public:
  AbstractSportProduct() {
    
    }
  //抽象方法:
  void printName(){
    
    };
  void play(){
    
    };
};

//具体产品类Basketball
class Basketball : public AbstractSportProduct
{
    
    
public:
  Basketball()
  {
    
    
    printName();
    play();
  }
  //具体实现方法
  void printName()
  {
    
    
    cout << "Get Basketball\n";
  }
  void play()
  {
    
    
    cout << "Play Basketball\n\n";
  }
};

//具体产品类Football
class Football : public AbstractSportProduct
{
    
    
public:
  Football()
  {
    
    
    printName();
    play();
  }
  //具体实现方法
  void printName()
  {
    
    
    cout << "Get Football\n";
  }
  void play()
  {
    
    
    cout << "Play Football\n\n";
  }
};

//具体产品类Volleyball
class Volleyball : public AbstractSportProduct
{
    
    
public:
  Volleyball()
  {
    
    
    printName();
    play();
  }
  //具体实现方法
  void printName()
  {
    
    
    cout << "Get Volleyball\n";
  }
  void play()
  {
    
    
    cout << "Play Volleyball\n\n";
  }
};

//抽象工厂类
class AbstractFactory
{
    
    
public:
  virtual AbstractSportProduct *getSportProduct() = 0;
};

//具体工厂类BasketballFactory
class BasketballFactory : public AbstractFactory
{
    
    
public:
  BasketballFactory()
  {
    
    
    cout << "BasketballFactory\n";
  }
  AbstractSportProduct *getSportProduct()
  {
    
    
    cout << "Basketball";
    return new Basketball();
  }
};

//具体工厂类FootballFactory
class FootballFactory : public AbstractFactory
{
    
    
public:
  FootballFactory()
  {
    
    
    cout << "FootballFactory\n";
  }
  AbstractSportProduct *getSportProduct()
  {
    
    
    cout << "Football";
    return new Football();
  }
};

//具体工厂类VolleyballFactory
class VolleyballFactory : public AbstractFactory
{
    
    
public:
  VolleyballFactory()
  {
    
    
    cout <<  "VolleyballFactory\n";
  }
  AbstractSportProduct *getSportProduct()
  {
    
    
    cout << "Valleyball";
    return new Volleyball();
  }
};

factorymethod.cpp

#include <iostream>
#include "factorymethod.h"

using namespace std;

int main()
{
    
    
	cout << "工厂方法模式\n\n";
	
	//定义工厂类对象和产品类对象
	AbstractFactory *fac = NULL;
	AbstractSportProduct *product = NULL;

	fac = new BasketballFactory();
	product = fac->getSportProduct();
	if (fac)
	{
    
    
		delete fac;
	}
	if (product) {
    
    
		delete product;
	}

	fac = new FootballFactory();
	product = fac->getSportProduct();
	if (fac)
	{
    
    
		delete fac;
	}
	if (product) {
    
    
		delete product;
	}

	fac = new VolleyballFactory();
	product = fac->getSportProduct();	
	if (fac)
	{
    
    
		delete fac;
	}
	if (product) {
    
    
		delete product;
	}

	return 0;
}

工厂方法模式总结

综上,可以看出,如果想玩一中体育运动,需要对应的增加一个工厂即可。由此,相对于简单工厂模式,工厂方法模式更符合开闭原则。

优点:

  1. 工厂方法用于创建客户所需产品,同时向客户隐藏某个具体产品类将被实例化的细节,用户只需关心所需产品对应的工厂;
  2. 工厂自主决定创建何种产品,并且创建过程封装在具体工厂对象内部,多态性设计是工厂方法模式的关键;
    新加入产品时,无需修改原有代码,增强了系统的可扩展性,符合开闭原则。

缺点:

  1. 添加新产品时需要同时添加新的产品工厂,系统中类的数量成对增加,增加了系统的复杂度,更多的类需要编译和运行,增加了系统的额外开销;
  2. 工厂和产品都引入了抽象层,客户端代码中均使用的抽象层(AbstractFactory和AbstractSportProduct ),增加了系统的抽象层次和理解难度。

适用环境:

  • 客户端不需要知道它所需要创建的对象的类;
  • 抽象工厂类通过其子类来指定创建哪个对象(运用多态性设计和里氏代换原则)

猜你喜欢

转载自blog.csdn.net/qq_24649627/article/details/115008349