本文适合新手和小白
目录
1、Factory Method
(1)意图
定一个用于创建对象的接口,让子类决定实例化哪一个内,Factory Method使一个类的实例化延迟到子类。。
(2)结构
其中:
Prouduct定义工厂方法所创建的对象的接口;
ConcreteProuduct实现Prouduct类型的接口;
Creator声明工厂方法,该方法返回一个Prouduct类型对象。Creator也可以定义工厂方法的默认实现,它返回一个默认的ConcreteProuduct对象,可以调用工厂方法以创建一个Product对象;
ConcreteCreator重新定义方法以返回一个ConcreteProuduct势力
(3)适用性
当一个类不知道打所必须创建的对象的类的时候。
当一个类希望由它的子类制定它所创建的对象的时候
当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望哪一个帮助子类时代里这一信息局部化的时候
2、根据UML编写代码
通过对UML类图的观察,图中有2种关系一个是泛化关系,另一个是实现关系
(1)泛化关系
根据教材366页的解释。泛化是一种特殊/一般的关系,特殊元素(子元素)的对象可替代一般元的对象。用这种方法子元素共享了父元素的结构和行为。我们可以理解为父类和子类利用多态特诊完成我们需要的操作,本例子中ConcreteCreator与Creator就是子与父的关系,中间的箭头由子类指向父类。
先别管程序要实现什么,我们先根据UML图中的泛化关系把代码写出来
#include<iostream>
using namespace std;
class Product{//抽象产品,实现一个创建对象的接口
public:
virtual ~Product(){};//确保析构函数
};
class ConcreteProudct_1:public Product{//具体产品,为Product实现一个接口
public:
ConcreteProudct_1(){}
~ConcreteProudct_1(){};
};
class Creator{//抽象生产工厂,返回一个Product类型对象
public:
virtual Product *FactoryMethod()=0;
void AnOperation(){
};
virtual ~Creator(){};
};
class ConcreateCreator_1:public Creator{//具体的生产工厂1返回一个具体产品
public:
Product *FactoryMethod(){
return new ConcreteProudct_1();//返回产品1
};
~ConcreateCreator_1(){};
};
int main(){
}
(2)实现关系
根据教材描述,实现是类元之间的语义关系,其中一个类元指定由另一个类元保证执行的契约。在两种情况下会使用实现关系,一种是在接口和实现他们的类和构件之间,另一种是在用例和实现他们之间的协作上。教科书的描写真的是晦涩难懂,其实就是实现类与接口之间的关系,关系如下:
既然 ConcreteCreator中的方法是通过 ConcreteProudct_1来实现的 那么我们增加实现方法show
class Product{//抽象产品,实现一个创建对象的接口
public:
virtual void show()=0;//增加方法
virtual ~Product(){};//确保析构函数
};
class ConcreteProudct_1:public Product{//具体产品,为Product实现一个接口
public:
ConcreteProudct_1(){}
void show(){//增加的实现方法
cout<<"我是工厂1,生存产品1"<<endl;
};
~ConcreteProudct_1(){};
};
(3)泛化与实现的组合使用
在实际UML图中,这两者关系一定是结合使用的,我们用最好理解的例子来举例,鸽子是鸟类中这个大家族一个种类,鸽子是鸟类的子类,因为她是鸟类所以理论上具备飞翔能力,那么鸽子也应该有,这是继承(泛化)关系。鸟类要挥舞翅膀利用空气动力学实现飞翔这是实现关系,假如我们把鸽子换企鹅,实现方法飞这个方法就会变成,企鹅挥舞翅膀利用空气动力学想飞,但是不满足飞翔相关条件不能飞了,比如长得太胖。这样的UML图画出来大致如下:
本UML中 ConcreteCreator 的Factory Method方法,将通过ConcreteProuduct这个类来具体实现具体的在代码实现中展示。
3、代码实现
#include<iostream>
using namespace std;
class Product{//抽象产品,实现一个创建对象的接口
public:
virtual void show()=0;
virtual ~Product(){};//确保析构函数
};
class ConcreteProudct_1:public Product{//具体产品,为Product实现一个接口
public:
ConcreteProudct_1(){}
void show(){
cout<<"我是工厂1,生存产品1"<<endl;
};
~ConcreteProudct_1(){};
};
class ConcreteProudct_2:public Product{//具体产品,为Product实现一个接口
public:
ConcreteProudct_2(){}
void show(){
cout<<"我是工厂2,生存产品2"<<endl;
};
~ConcreteProudct_2(){};
};
class Creator{//抽象生产工厂,返回一个Product类型对象
public:
virtual Product *FactoryMethod()=0;
void AnOperation(){
cout<<"这里可以实现一些通用的方法"<<endl;
};
virtual ~Creator(){};
};
class ConcreateCreator_1:public Creator{//具体的生产工厂1返回一个具体产品
public:
Product *FactoryMethod(){
return new ConcreteProudct_1();//返回产品1
};
~ConcreateCreator_1(){};
};
class ConcreateCreator_2:public Creator{//具体的生产工厂返回一个具体产品
public:
Product *FactoryMethod(){
return new ConcreteProudct_2();//返回产品2
};
~ConcreateCreator_2(){};
};
int main(){
Creator *a=new ConcreateCreator_2();//父类指向子类的指针,利用隐藏的this指针实现多态,实例化一个具体生产工厂1或者工厂2,本例子用的是工厂2
a->AnOperation();
Product *b=a->FactoryMethod();//父类指向子类的指针,返回一个具体的产品
b->show();
delete a;
a=NULL;
delete b;
b=NULL;
return 0;
}