工厂模式分为三种:
1、简单工厂模式
所有的产品由一个工厂生产
就是工厂产产品,一个工厂可以产多种产品
工厂模式属于创建型模式,是C++中最常见的设计模式之一。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。下面我会具体分析工厂模式各个方面。
例如:
一号产品产苹果
二号产品产香蕉
class Fruit
{
public:
Fruit(std::string nm) :name(nm){}
virtual void operation() = 0;
protected:
std::string name;
};
class Apple : public Fruit
{
public:
Apple(std::string name) :Fruit(name){}
void operation()
{
std::cout << "this is an apple!" << std::endl;
}
};
class Banana : public Fruit
{
public:
Banana(std::string name) :Fruit(name){}
void operation()
{
std::cout << "this is an banana!" << std::endl;
}
};
这样设计的主要缺点,就是要增加其它的水果类型时,就需要增加新的工厂类。这就违反了开放封闭原则:软件实体(类、模块、函数)可以扩展,但是不可修改。于是,工厂方法模式出现了。
2、工厂方法模式:所谓工厂方法模式,是指定义一个用于创建对象的接口,让子类决定实例化哪一个类。使一个类的实例化延迟到其子类。
一个工厂只生产一个产品
工厂方法模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。
工厂方法模型适应的场景:
在设计的初期,就考虑到产品在后期会进行扩展的情况下,可以使用工厂方法模式;
产品结构较复杂的情况下,可以使用工厂方法模式;
由于使用设计模式是在详细设计时,就需要进行定夺的,所以,需要权衡多方面的因素,而不能为了使用设计模式而使用设计模式。
class Factory
{
public:
Factory(std::string nm) :name(nm){}
virtual Fruit* createFruit() = 0;
protected:
std::string name;
};
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");
}
};
class Pear :public Fruit
{
public:
Pear(std::string name) :Fruit(name){}
void operation()
{
std::cout << "this is a pear!" << std::endl;
}
};
class Factory_3 :public Factory
{
public:
Factory_3(std::string name) :Factory(name){}
Fruit* createFruit()
{
return new Pear("pear");
}
};
class Factory
{
public:
Fruit* createFruit(int flag)
{
switch (flag)
{
case 1:
return new Apple("apple");
break;
case 2:
return new Banana("banana");
break;
default:
std::cout << "this factory can not create this fruit!" << std::endl;
break;
}
}
};
int main()
{
Factory* pf = new Factory_3("f3");
Fruit* pfr = pf->createFruit();
pfr->operation();
return 0;
}
3、抽象工厂模式
抽象工厂模式(Abstract Factory Pattern)是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。
一个工厂生产一类产品
优缺点:
优点:
封装了产品的创建,使得不需要知道具体是哪种产品,只需要知道是哪个工厂即可。
可以支持不同类型的产品,使得模式灵活性更强。
可以非常方便的使用一族中的不同类型的产品。
缺点:
结构过于臃肿,如果产品类型较多或产品族较多,会非常难于管理。
每次如果添加一组产品,那么所有的工厂类都必须添加一个方法,这样违背了开放-封闭原则。所以一般适用于产品组合产品族变化不大的情况。
适用场景
在不必指定产品的具体的情况下,创建多个产品族中的产品对象。
class B
{
public:
B(std::string nm) :name(nm){}
virtual void operation() = 0;
protected:
std::string name;
};
class B1 : public B
{
public:
B1(std::string nm) :B(nm){}
void operation()
{
std::cout << "this is B1 " << std::endl;
}
};
class B2 : public B
{
public:
B2(std::string nm) :B(nm){}
void operation()
{
std::cout << "this is B2 " << std::endl;
}
};
class C
{
public:
C(std::string nm) :name(nm){}
virtual void operation() = 0;
protected:
std::string name;
};
class C1 : public C
{
public:
C1(std::string nm) :C(nm){}
void operation()
{
std::cout << "this is C1 " << std::endl;
}
};
class C2 : public C
{
public:
C2(std::string nm) :C(nm){}
void operation()
{
std::cout << "this is C2 " << std::endl;
}
};
class Factory_A
{
public:
Factory_A(std::string nm) :name(nm){}
virtual B* createB() = 0;
virtual C* createC() = 0;
protected:
std::string name;
};
class Factory_A1 :public Factory_A
{
public:
Factory_A1(std::string name) :Factory_A(name){}
B* createB()
{
return new B1("b1");
}
C* createC()
{
return new C1("c1");
}
};
class Factory_A2 :public Factory_A
{
public:
Factory_A2(std::string name) :Factory_A(name){}
B* createB()
{
return new B2("b2");
}
C* createC()
{
return new C2("c2");
}
};