简单工厂模式–》工厂模式—》抽象工厂模式
文章目录
- 简单工厂模式定义:
- 各个角色
- 1. 抽象产品类
- 2. 具体产品类:
- 3. 工厂类:简单工厂模式的核心。
- 客户端
- 设计图表
- 未使用简单工厂模式:
- 出现的问题:
- 使用简单工厂模式:
- 抽象产品类
- 具体产品类
- 静态工厂方法
- 总结:
- 优点:
- 缺点:
- 使用场景:
- 改进:
简单工厂模式定义:
简单工厂模式:定义一个工厂类,它可以根据参数的不同返回不同的实例,被创建的实例通常都有共同的父类,因为在简单工厂模式中用于创建实例的方法是今天方法,因此简单工厂模式也称为静态工厂模式,它属于类创建型模式。
1.要点
当你需要什么,只需要传入一个正确的参数,就可以获取所需要的对象,而无需知道细节,简单工厂的结构模式比较简单,其核心就是工厂类的设计。
各个角色
1.Factory(工厂角色):工厂角色即工厂类,它是简单工厂模式的核心,负责实现创建所有产品实例的内部逻辑,工厂类可以被外界直接调用,创建所需的产品对象,
(在工厂中提供静态的工厂方法factory(),它的返回类型为抽象产品类型Product。)
2.Product(抽象产品角色):它是工厂类所创建的所有对象的父类,封装了各种产品对象的公有方法,它的引入提高了系统的灵活性,是的工厂类只需要定义一种通用的工厂方法,因为所有擦黄建德具体铲平都是它的子类对象。
3.ConcreteProduct(具体产品角色):简单工厂模式的创建目标,所有被创建的对象都充当这个角色的具体类的实例,每个具体产品角色都继承了抽象产品角色,需要实现的抽象产品中声明的抽象方法。
代码实现 :
1. 抽象产品类
在使用简单工厂模式时,首先需要对产品进行重构,不能设计一个包罗万象的产品类,而根据实际情况设计一个铲平层次结构,将所有产品公共的代码移到抽象产品类,并在抽象产品类中声明一些抽象方法,以供不同的具体产品来实现,如下:
class Product
{
//所有产品类的公共业务方法
}
public:
void methodSame()
{
//公共方法的实现。
}
//声明抽象业务方法
virtual void methoddiff() = 0;
};
2. 具体产品类:
实现抽象类中的抽象方法。
class ConcreateProductA:public Product
{
//实现业务
public:
void methodiff()
{
//业务方法的具体实现。
}
};
class ConcreateProductB:public Product
{
//实现业务
public:
void methodiff()
{
//业务方法的具体实现。
}
};
3. 工厂类:简单工厂模式的核心。
提供的工厂方法必须是,静态方法>
功能:通过客户端传入的参数,选择创建不同的对象。
class Factory
{
public:
static Product * getProduct(string src)
{
Product *product = NULL;
if(src = "B")
{
product = new ConcreteProductA();
//初始化 product
}
else if(src = B)
{
product = new ConcreteProductB();
//初始化产品
}
return product;
}
};
客户端
int main()
{
Profuct *product = nullptr;
//通过工厂创建产品对象
product = Factory::getProduct("A");
product -> methodSame();
product->methodDiff();
}
设计图表
未使用简单工厂模式:
class Chart
{
private:
string type; // 图表类型
public:
Chart(const string& t) : type(t)
{
if (type == "histogram") {
// 初始化柱状图
}
else if (type == "pie") {
// 初始化饼状图
}
else if (type == "line") {
// 初始化折线图
}
}
void display()
{
if (type == "histogram") {
// 显示柱状图
}
else if (type == "pie") {
// 显示饼状图
}
else if (type == "line") {
// 显示折线图
}
}
};
出现的问题:
- 在Chart类中包含很多"if…else"代码块,整个类的代码相当冗长;如果需求大,代码会越长,阅读难度和维护难度越大;而且大量条件语句会影响系统的性能。
- Chart类的职责过重,违反了“单一职责原则”,不利于类的重用和维护。
- 当需要增加新类型的图表时,必须修改chart类的源代码,违反了“开闭原则”。
- 客户端只能通过new关键字来直接创建Chart类对象,4.类与客户端类的耦合度较高,对象的创建和使用无法分离。
使用简单工厂模式:
抽象产品类
class Chart
{
public:
virtual void display() = 0;
};
具体产品类
//具体产品类
class histogram : public Chart
{
public:
histogram()
{
cout << "创建柱状图" << endl;
}
void display()
{
cout << "显示柱状图" << endl;
}
};
class Linechart : public Chart
{
public:
Linechart()
{
cout << "创建线形图" << endl;
}
void display()
{
cout << "显示线形图" << endl;
}
};
静态工厂方法
1. 没有this指针,不依赖于对象,只能访问静态成员。
2. 可以直接根据类来调用。因为它的功能就是创建对象。
class Factory
{
public:
//静态工厂方法
//没有this指针,不依赖于对象,只能访问静态成员。
//可以直接根据类来调用。因为它的功能就是创建对象。
static Chart *getFactory(string src)
{
Chart * chart = NULL;
if (src == "histogram")
{
chart = new histogram();
cout << "初始化柱状图" << endl;
}
else if (src == "line")
{
chart = new Linechart();
cout << "初始化线形图" << endl;
}
return chart;
}
};
int main()
{
Chart *fa = NULL;
//通过静态工厂方法创建具体产品类对象
fa = Factory::getFactory("line");
fa->display();
}
结果:
总结:
在简单工厂模式下,客户端通过工厂类创建了一个产品类的实例,而无需直接使用new关键字来创建对象。
优点:
1.工厂类包含必要的逻辑判断,可以再什么时候创建哪一个产品的实例。客户端就不需要做这些了。
2.客户端无需知道具体产品类的类名,只需要直到具体产品类对应的参数,对于一些复杂的类名,免去了使用者去记忆。
3.引入配置文件,可以在不修改任何客户端代码的情况下更换合增加新的具体产品类,提高了系统的灵活性。
缺点:
1.工厂类集中类所有产品的创建逻辑,职责过重。
2.使用简单工厂模式势必增加系统中累的个数。增加了系统的复杂度。
3.系统扩展困难,因为每添加一个具体的产品类,势必要修改工厂类。产品太多,更难维护,
4.简单工厂模式使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。
使用场景:
1.工厂类负责创建的对象少。
2.客户端只知道传入工厂类的参数,对如何创建不关注,
改进:
class Chart
{
public:
virtual void display() = 0;
static Chart *getFactory(const string &src);
};
static Chart *Chart::getFactory(const string &src)
{
Chart * chart = NULL;
if (src == "histogram")
{
chart = new histogram();
cout << "初始化柱状图" << endl;
}
else if (src == "line")
{
chart = new Linechart();
cout << "初始化线形图" << endl;
}
return chart;
}
还可以使用Json,通过修改配置文件来创建不同的对象。