前言
三大工厂模式链接
本文不会就基本概念做介绍,着重分析 使用模板和使用继承实现工厂模式的优缺点。
初学者区分不出工厂方法和抽象工厂,实际上两者没有什么必然界限,工厂方法是抽象工厂的一个特殊情况(抽象工厂对外接口只有一个时,即为工厂方法)
前置类和函数
辅助类
Robot类
class Robot
{
public:
virtual void ShowType() = 0;
virtual ~Robot() = default;
};
class DancerRobot : public Robot
{
public:
virtual void ShowType()
{
Mylog("Dancerobot type");
}
};
class WorkerRobot : public Robot
{
public:
virtual void ShowType()
{
Mylog("WorkerRobot type");
}
};
RobotCharge类
class Charger
{
public:
virtual void ShowType() = 0;
virtual ~Charger() = default;
};
class DancerRobotCharger : public Charger
{
public:
virtual void ShowType()
{
Mylog("DancerRobotCharger type");
}
};
class WorkerRobotCharge : public Charger
{
public:
virtual void ShowType()
{
Mylog("WorkerRobotCharger type");
}
};
prinln
void Mylog()
{
std::cout << std::endl;
};
template <typename T, typename... Rest>
void Mylog(T arg, Rest... rest)
{
std::cout << arg << " ";
Mylog(rest...);
};
工厂方法模式
println类
继承实现工厂方法模式
// 工厂基类
class RobotFactory
{
public:
virtual Robot *Create() = 0;
virtual ~RobotFactory() = default;
};
class DancerRobotFactry : public RobotFactory
{
public:
virtual DancerRobot *Create()
{
return new DancerRobot();
};
};
class WorkerRobotFactry : public RobotFactory
{
public:
virtual WorkerRobot *Create()
{
return new WorkerRobot();
};
};
泛型实现
template <typename Robot>
class RobotFactory1
{
public:
Robot *Create()
{
return new Robot();
}
};
测试demo
class FactoryTest
{
public:
FactoryTest() = delete;
~FactoryTest() = delete;
public:
static void Test()
{
{
//继承实现工厂方法
RobotFactory *factory = new DancerRobotFactry();
Robot *robot = factory->Create();
robot->ShowType();
}
{
// 泛型实现工厂方法
auto factory = new RobotFactory1<WorkerRobot>();
Robot *robot = factory->Create();
robot->ShowType();
}
}
};
结论
对比上面的实现我们很明显发现使用模板实现精简的多,而且我们可以直接从传入模板的类型即可判断处该factory是什么工厂;而使用继承实现,如果该robot类对应的factory命名不规范,我们无法直接更具factory类名判断出其create的robot类型。
抽象工厂模式
继承实现
继承实现不上代码了,在抽象类RobotFactory中添加一个新的接口CreateCharger用于创建RobotCharger。因此其所有子类都需要添加CreateCharger接口。
泛型实现
template <typename Robot, typename RobotCharger>
class RobotFactory1
{
public:
Robot *Create()
{
return new Robot();
}
RobotCharger* CreateCharger(){
return new RobotCharger();
}
};
结论
对比上面继承实现我们发现,当使用泛型实现抽象工厂时,我们添加或删除其他类型创建方法时很简单;但使用继承,当我们修改接口类时,需要修改所有子类的接口相比而言比较麻烦。