Factory Method - 工厂方法模式

来源:互联网 发布:网络连接受限制怎么办 编辑:程序博客网 时间:2024/05/22 16:05
定义
定义一个用于创建对象的接口,让子类决定具体实例化哪一个类,把一个类的实例化延迟到子类。

案例
现在有两种男人:程序员和其他男人,为了延续下一代,每个男人都需要找寻一个女人,但是每个男人都有每个男人的要求,有的要漂亮的,有的要有内涵的,有的要技术好的。这各种各样的女人就像一些列的产品,从Girl延伸出来的(Gril not woman),比如ThinGril、FatGirl。程序员都喜欢性感的Gril,所以创建Girl对象的时候都是new一个ThinGril,而其他的男人都喜欢FatGirl,就得到如下类图:


从上图可以看出每一个男人只能选择一个女人,因为这是受法律保护的。
从类图不难得到一下代码:
  1. class Man {
  2. public:
  3. virtual Gril* createGirlFriend() = 0;
  4. }
  5. class Programmer : public Man {
  6. public:
  7. virtual Gril* createGrilGriend() {
  8. return new ThinGirl();
  9. }
  10. }
  11. class OtherMan: public Man {
  12. public:
  13. virtual Gril* createGrilGriend() {
  14. return new FatGirl();
  15. }
  16. }
  17. Man* man = new Programmer();
  18. Girl* girl = man->createGrilFriend();
注意工厂方法有两种不同的情况:
  1. Man是一个抽象类,不提供工厂方法的实现。
  2. Man提供工厂方法的实现。
而且创建产品对象的时候还可以提供参数的形式来实例化对象:
  1. class Man {
  2. public:
  3. virtual Gril* createGirlFriend(string hobby) {
  4. if (hobby == "Normal")
  5. return ThinGirl();
  6. else
  7. return FatGirl();
  8. }
  9. }
  10. class OtherMan: public Man {
  11. public:
  12. virtual Gril* createGrilGriend(string hobby) {
  13. // anyway
  14. return new FatGirl();
  15. }
  16. }
  17. Man* man = new Programmer();
  18. Girl* girl = man->createGrilFriend();
从代码里可以看出其他的男人都有自己的路要走,不接受建议。
工厂方法还可以通过模版方法来避免创建子类:
  1. class Man {
  2. public:
  3. virtual Gril* createGirlFriend() = 0;
  4. }
  5. template <typename TheGirl>
  6. class OtherMan: public Man {
  7. public:
  8. virtual Gril* createGrilGriend() {
  9. return new TheGirl();
  10. }
  11. }
  12. Man* man = new NormalMan<BeautifulGirl>();
  13. Girl* girl = man->createGrilFriend();
适用性
  • 当一个类不知道它要具体创建什么产品类对象的时候。
  • 当一个类希望由它的子类来创建产品类对象。
  • 当一个类把创建产品类对象委托给自己的子类,而被委托的这一子类就是需要创建对象的代理者,和它息息相关。
相关模式
工厂方法模式:一个抽象工厂类派生多个具体工厂类,一个抽象产品类派生多个具体产品类。每个男人一个女人(一夫一妻)。
抽象工厂模式:一个抽象工厂类派生多个具体工厂类。多个抽象产品类派生多个具体产品类。每个男人多个女人(多妻制)。
0 0