工厂模式
工厂模式即建立创建对象的工厂,实现创建者和调用者分离。
-
简单工厂模式:该模式对对象创建管理方式最为简单,因为他简单的对不同类对象的创建进行了一层薄薄的封装。该模式通过向工厂传递类型来指定要创建的对象。
-
工厂方法模式:将生成具体产品的任务分发给具体的产品工厂。
-
抽象工厂模式:通过在AbstractFactory中增加创建产品的接口,并在具体子工厂中实现新加产品的创建。
简单工厂模式
下面通过手机生产的过程进行理解:
#include <stdio.h>
typedef enum productType
{
xiaomi,
iphone,
huawei
}PRODUCTTYPE;
class Phone
{
public:
virtual void MakePhone() = 0;
};
class MI : public Phone
{
public:
void MakePhone()
{
printf("make xiaomi phone\n");
}
};
class IPHONE : public Phone
{
public:
void MakePhone()
{
printf("make iphone phone\n");
}
};
class HUAWEI : public Phone
{
public:
void MakePhone()
{
printf("make huawei phone\n");
}
};
class SimpleFactory
{
public:
Phone *createPhone(PRODUCTTYPE type)
{
switch (type)
{
case xiaomi:
return new MI();
case iphone:
return new IPHONE();
case huawei:
return new HUAWEI();
default:
return NULL;
}
}
};
int main()
{
SimpleFactory *factory = new SimpleFactory();
Phone *phone1 = factory->createPhone(huawei);
if (phone1 != NULL)
phone1->MakePhone();
Phone *phone2 = factory->createPhone(xiaomi);
if (phone2 != NULL)
phone2->MakePhone();
Phone *phone3 = factory->createPhone(iphone);
if (phone3 != NULL)
phone3->MakePhone();
delete phone1;
phone1 = NULL;
delete phone2;
phone2 = NULL;
delete phone3;
phone3 = NULL;
return 0;
}
工厂方法模式
简单工厂模式例子中,已经可以生产xiaomi,iphone和huawei三类产品。此时需要添加oppo产品。那么此时需要在产品枚举中添加新的产品类型,然后修改factory中的switch语句。这种改动量比较大,大工程中易产生错误,这种扩展方式是很糟糕的。并且由于对原始代码进行了修改,那么原来的测试工作就无效了,需要进行新的全覆盖测试。
工厂方法模式是在简单工厂模式的基础上,对工厂添加了一个抽象层。将工厂共同的动作抽象出来,而具体的实现由子类本身去实现,让子类决定生产什么样的产品。
应用场景
工厂方法模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中。核心工厂不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。
1、设计初期,就考虑到产品在后期进行扩展的情况下,可以使用工厂方法模式。
2、产品结构复杂的请情况下,可以使用工厂方法模式。
设计模式在详细设计时就需要进行定夺,需要权衡很多方面的因素,不能为了使用而使用。
#include <stdio.h>
class Phone
{
public:
virtual void MakePhone() = 0;
};
class MI : public Phone
{
public:
void MakePhone()
{
printf("xiaomi phone\n");
}
};
class HUAWEI : public Phone
{
public:
void MakePhone()
{
printf("huawei phone\n");
}
};
class Factory
{
public:
virtual Phone *CreatePhone() = 0;
};
class MIFactory : public Factory
{
public:
Phone *CreatePhone()
{
return new MI();
}
};
class HUAWEIFactory : public Factory
{
public:
Phone *CreatePhone()
{
return new HUAWEI();
}
};
void main()
{
Factory *MIfactory = new MIFactory();
Phone *mi = MIfactory->CreatePhone();
mi->MakePhone();
Factory *HWfactory = new HUAWEIFactory();
Phone *huawei = HWfactory->CreatePhone();
huawei->MakePhone();
if (MIfactory)
{
delete MIfactory;
MIfactory = NULL;
}
if (mi)
{
delete mi;
mi = NULL;
}
if (HWfactory)
{
delete HWfactory;
HWfactory = NULL;
}
if (huawei)
{
delete huawei;
huawei = NULL;
}
}
抽象工厂模式
工厂方法模式,后期产品会越来越多,建立的工厂也会越来越多,工厂进行了增长,工厂变得凌乱而难于管理;由于工厂方法模式创建的对象都是继承于phone的,所以工厂方法模式中,每个工厂只能创建单一种类的产品,当需要生产一种全新的产品时(不继承自phone),工厂方法则心有余而力不足。
举个例子方理解:
一个显示器电路板厂商,旗下的显示器电路板种类有液晶和非液晶的;这个时候厂商建造两个工厂,A工厂负责生产液晶电路板;B工厂负责生产非液晶电路板;工厂一直这样运行着。但是有一天经理发现这届生产显示器的其他部分也能挣钱,所以,决定在建立两个厂C和D,C负责生产液晶显示其余部件;D负责生产非液晶显示器的其余部件。此时,旁边的参谋提出我们只需要在原有的A和B厂添加一条负责液晶和非液晶显示器其余部件的生产线。这样做只需要对原有的厂房进行扩大,而不需要增加新的厂房,一方面,方便管理;另一方面,生产液晶和非液晶显示器的技术人员对液晶显示器和液晶显示器的其他部件生产具有指导作用。
在软件的开过程中,工厂A和B就是工厂方法模式;再建立C和D,就是重复工厂方法模式,只是生产的产品不一样。这样做增加成本。在面向对象中,很注重对象的维护和管理,对象越多,就越难维护,成本也会增加。
抽象工厂模式,就好比是两个工厂方法模式的叠加。抽象工厂创建的是一系列相关的对象,其中创建的实现其实就是采用的工厂方法模式。在工厂factory中的每一个方法,就好比是一条生产线,而生产线实际需要生产什么养的产品,这是由factory1和factory2去决定的,这样便延迟了具体子类的实例化;同时集中化了生产线的管理,节省了资源的浪费。
使用场合:
工厂方法模式适用于产品种类结构单一的场合,为一类产品提供创建的接口;而抽象工厂方法适用于产品种类结构的场合,主要用于创建一组(有多个种类)相关的产品,为他们提供创建的接口;就是当具有多个抽象角色时,抽象工厂便可以排上用场。
#include <stdio.h>
class MI
{
public:
virtual void MakePhone() = 0;
};
class RedMI : public MI
{
public:
void MakePhone()
{
printf("redmi phone\n");
}
};
class MIPro : public MI
{
public:
void MakePhone()
{
printf("MIPro phone\n");
}
};
class HUAWEI
{
public:
virtual void MakePhone() = 0;
};
class Mate20 : public HUAWEI
{
public:
void MakePhone()
{
printf("Mate20 Phone\n");
}
};
class P30 : public HUAWEI
{
public:
void MakePhone()
{
printf("P30 phone\n");
}
};
class Factory
{
public:
virtual MI* CreateMIPhone() = 0;
virtual HUAWEI* CreateHWPhone() = 0;
};
class Factory1 : public Factory
{
public:
MI* CreateMIPhone()
{
return new RedMI();
}
HUAWEI* CreateHWPhone()
{
return new Mate20();
}
};
class Factory2 : public Factory
{
public:
MI* CreateMIPhone()
{
return new MIPro();
}
HUAWEI* CreateHWPhone()
{
return new P30();
}
};
void main()
{
Factory *factoryObj1 = new Factory1();
MI *mi1 = factoryObj1->CreateMIPhone();
HUAWEI *hw1 = factoryObj1->CreateHWPhone();
mi1->MakePhone();
hw1->MakePhone();
Factory *factoryObj2 = new Factory2();
MI *mi2 = factoryObj2->CreateMIPhone();
HUAWEI *hw2 = factoryObj2->CreateHWPhone();
mi2->MakePhone();
hw2->MakePhone();
if (factoryObj1)
{
delete factoryObj1;
factoryObj1 = NULL;
}
if (factoryObj2)
{
delete factoryObj2;
factoryObj2 = NULL;
}
if (mi1)
{
delete mi1;
mi1 = NULL;
}
if (mi2)
{
delete mi2;
mi2 = NULL;
}
if (hw1)
{
delete hw1;
hw1 = NULL;
}
if (hw2)
{
delete hw2;
hw2 = NULL;
}
}