工厂模式:(最终目的是生成对象)
1.简单工厂模式
2.工厂方法模式
3.抽象工厂模式
举个例子来说明(吃苹果):
(1)对于普通的情况来说,我们要走路,买苹果,洗苹果,最后可以吃到苹果。
(2)但是对于工厂模式来说,我们可以雇人(第三方)去做走路、买苹果、洗苹果这一系列的才操作,那么就不需要自己去做,自己只要做吃苹果这个目的就可以了,不必去关心苹果的来源。
所以说只要告诉工厂,我们需要做什么就可以了,不用关心对象的生成,这就是工厂模式的优势之处。
1.简单工厂模式
#include <iostream>
#include <string>
class Fruit
{
public:
Fruit(std::string name):mname(name){}
virtual void option() = 0;
protected:
std::string mname;
};
class Apple : public Fruit
{
public:
Apple(std::string name):Fruit(name){}
void option()
{
std::cout << "this is an Apple!" << std::endl;
}
};
class Banana : public Fruit
{
public:
Banana(std::string name):Fruit(name){}
void option()
{
std::cout << "this is an Banana!" << std::endl;
}
};
class Factory
{
public:
Fruit* createFactory(int flag)
{
switch (flag)
{
case 1:
return new Apple("apple");
break;
case 2:
return new Banana("banana");
break;
default:
std::cout << "no product!" << std::endl;
return nullptr;
break;
}
}
};
int main()
{
Factory f;
Fruit* pf = f.createFactory(2);
pf->option();
return 0;
}
此时无论是苹果还是香蕉都是从同一个工厂中产出的。 那么如果此时还需要添加一条梨的产线,应该怎么办呢?
我们需要添加一个类:
class Pear : public Fruit
{
public:
Pear(std::string name):Fruit(name){}
void option()
{
std::cout << "this is an Pear!" << std::endl;
}
};
并且要添加工厂模式中的内容:
class Factory
{
public:
Fruit* createFactory(int flag)
{
switch (flag)
{
case 1:
return new Apple("apple");
break;
case 2:
return new Banana("banana");
break;
case 3:
return new Pear("Pear");
break;
default:
std::cout << "no product!" << std::endl;
return nullptr;
break;
}
}
};
我们可以看到,如果要是添加一条生产线会很麻烦,不灵活,要频繁的修改工厂的代码,这就违背了面向对象中的开放-封闭原则:
(1)开放原则
新版本可以沿用旧版本的代码
(2)封闭原则
不能修改旧版本的代码
基于此,就提出了第二种的工厂模式:
2.工厂方法模式
一个工厂生产一种产品,即有一个工厂只生产苹果,另外一个工厂只生产香蕉,如果再想生产梨,则需要再开发一个工厂,这个时候就不会影响到其他的工厂及其产品,所以此时应该将工厂写成基类。
class Fruit
{
public:
Fruit(std::string name):mname(name){}
virtual void option() = 0;
protected:
std::string mname;
};
class Apple : public Fruit
{
public:
Apple(std::string name):Fruit(name){}
void option()
{
std::cout << "this is an Apple!" << std::endl;
}
};
class Banana : public Fruit
{
public:
Banana(std::string name):Fruit(name){}
void option()
{
std::cout << "this is an Banana!" << std::endl;
}
};
class Factory
{
public:
Factory(std::string name):mname(name){}
//创建不同功能的工厂
virtual Fruit* createFruit() = 0;
protected:
std::string mname;
};
//苹果工厂
class Factory_1 : public Factory
{
public:
Factory_1(std::string name):Factory(name){}
Fruit* createFruit()
{
return new Apple("Apple");
}
};
//香蕉工厂
class Factory_2 : public Factory
{
public:
Factory_2(std::string name):Factory(name){}
Fruit* createFruit()
{
return new Banana("Banana");
}
};
int main()
{
Factory* pf = new Factory_1("f1");
Fruit* ppf = pf->createFruit();
ppf->option();
return 0;
}
如果此时再想加梨的生产线的时候,我们只需要添加一个生产梨的工厂就可以了:
class Pear : public Fruit
{
public:
Pear(std::string name):Fruit(name){}
void option()
{
std::cout << "this is an Pear!" << std::endl;
}
};
class Factory_3 : public Factory
{
public:
Factory_3(std::string name):Factory(name){}
Fruit* createFruit()
{
return new Pear("Pear");
}
};
这样的话就可以解决开放-封闭原则的问题啦。
3.抽象工厂模式
如果此时我们需要生产一台电脑C,需要配件A、B来组成:
A1和A2、B1和B2是属于同一种配件,只是大小不同,那么A1和A2、B1和B2属于同一族,A1和B1之间具有强相关性。所以我们这样设计才可以体现出强相关性,因为只有编号对应才可以组成相应的电脑。
//生产A部件
class A
{
public:
A(std::string name):mname(name){}
virtual void option() = 0;
protected:
std::string mname;
};
class A_1 : public A
{
public:
A_1(std::string name):A(name){}
void option()
{
std::cout << "this is A1" << std::endl;
}
};
class A_2 : public A
{
public:
A_2(std::string name):A(name){}
void option()
{
std::cout << "this is A2" << std::endl;
}
};
//生产B部件
class B
{
public:
B(std::string name):mname(name){}
virtual void option() = 0;
protected:
std::string mname;
};
class B_1 : public B
{
public:
B_1(std::string name):B(name){}
void option()
{
std::cout << "this is B1" << std::endl;
}
};
class B_2 : public B
{
public:
B_2(std::string name):B(name){}
void option()
{
std::cout << "this is B2" << std::endl;
}
};
class AbstractFactory
{
public:
AbstractFactory(std::string name):mname(name){}
virtual A* createA() = 0;
virtual B* createB() = 0;
protected:
std::string mname;
};
//创建编号为1的部件
class AF1 : public AbstractFactory
{
public:
AF1(std::string name):AbstractFactory(name){}
A* createA()
{
return new A_1("a1");
}
B* createB()
{
return new B_1("b1");
}
};
//创建编号为2的部件
class AF2 : public AbstractFactory
{
public:
AF2(std::string name):AbstractFactory(name){}
A* createA()
{
return new A_2("a2");
}
B* createB()
{
return new B_2("b2");
}
};
int main()
{
AbstractFactory* apf = new AF2("af2");
A* pa = apf->createA();
B* pb = apf->createB();
pa->option();
pb->option();
return 0;
}
总结:
1.简单工厂模式–规模固定,产品不容易发生变动
就是将生产交给一个工厂,再有生产线进来的时候也是交给这个工厂,违背了开放-封闭原则。
2.工厂方法模式–规模不固定,产品容易发生变动
解决开放-封闭原则,灵活性更大,一种产品对应一个工厂,可以理解成一对一的情况
3.抽象工厂模式
对于一件东西的不同组成部分,体现的主要是这些步骤之间的关联,那么才使用抽象工厂模式