实现抽象工厂模式的最佳方法 [英] Best method to implement an abstract factory pattern

查看:69
本文介绍了实现抽象工厂模式的最佳方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下代码:

  #include< stdio.h> 


// ===========================


class Shape {
public:
virtual〜Shape(){};

virtual void process()= 0;
};

类三角形:public Shape {
public:
virtual void process()override {
printf(BBB\\\
);
}
};


// ===========================


/ * option 1 * /
class TriangleProducer {
public:
Triangle factory(){
return Triangle {};
}
};



/ * option 2 * /
class PtrShapeProducer {
public:
Shape * factory(){
return new Triangle {};
}
};



/ * option 3 * /
class PimplShape:public Shape {
Shape * sh;
public:
PimplShape(Shape * sh):sh(sh){
}

virtual〜PimplShape()override {
delete sh;
}

virtual void process()override {
sh-> process();
}
};

class PimplShapeProducer {
public:

PimplShape factory(){
return new Triangle {};
}
};


// ===========================


int main(){
TriangleProducer f1;
Triangle tri = f1.factory();
tri.process();



PtrShapeProducer f2;
形状& sh = * f2.factory();
sh.process();
delete& sh;



PtrShapeProducer f3;
PimplShape psh = f3.factory();
psh.process();



return 0;
}

选项1



这很好,但它并没有真正实现多态性。返回类型是已知的,您必须匹配它。可以添加 auto 而不是 Triangle ,但这不会更改任何东西,除了更容易重构。



选项2



这是Java和PHP的工作原理。但我理解,原始指针是不可取的在C + +。可以添加 std :: unique_ptr ,但是除非缺少 delete 语句。 p>

选项3



这是某人以前在这里提议的 - 没有原始指针,没有删除。



选项4 (此处未实现) )



使用const引用 - 但是它们是const并且不改变factory返回类型。我认为,这更像是变化,它不是真正的选择。



我缺少任何其他选项?

也将是最好的选择

解决方案

我认为最常用的现代C ++方法是你提到的但忽略。返回 std :: unique_ptr< Shape>



它是安全的,明确表示所有权,支持多态性

 类ShapeFactory {
public:
std :: unique_ptr< Shape> create(){
return std :: make_unique< Triangle>();
}
};

但我不想声称这是最好的方法。



选项3中的 PimplShape 实际上非常类似于 unique_ptr 只是较少通用或测试。


Consider following code:

#include <stdio.h>


// =============================


class Shape{
public:
    virtual ~Shape(){};

    virtual void process() = 0;
};

class Triangle : public Shape{
public:
    virtual void process() override {
        printf("BBB\n");
    }
};


// =============================


/* option 1 */
class TriangleProducer{
public:
    Triangle factory(){
        return Triangle {};
    }
};



/* option 2 */
class PtrShapeProducer{
public:
    Shape *factory(){
        return new Triangle {};
    }
};



/* option 3 */
class PimplShape : public Shape{
    Shape *sh;
public:
    PimplShape(Shape *sh) : sh(sh){
    }

    virtual ~PimplShape() override{
        delete sh;
    }

    virtual void process() override {
        sh->process();
    }
};

class PimplShapeProducer{
public:

    PimplShape factory(){
        return new Triangle {};
    }
};


// =============================


int main(){
    TriangleProducer f1;
    Triangle tri = f1.factory();
    tri.process();



    PtrShapeProducer f2;
    Shape & sh = *f2.factory();
    sh.process();
    delete & sh;



    PtrShapeProducer f3;
    PimplShape psh = f3.factory();
    psh.process();



    return 0;
}

OPTION 1

It is nice, but it does not really achieve polymorphism. Return type is known and you must match it. One may add auto instead of Triangle, but this not change anything except easier refactoring.

OPTION 2

This is how Java and PHP is doing it. But I understood that "raw" pointers are not desirable in C++. One may add std::unique_ptr, but once again this does not change anything, except missing delete statement.

OPTION 3

This is what someone propose here some time ago - works nice, no "raw" pointers, no delete. But it is so much code, and way too complicated - seems fancy way, but not the correct one.

OPTION 4 (not implemented here)

Playing with const references - however they are const and it does not change the "factory" return type. I think, this is more like variation, it is not real option.

Any other option I am missing?
Also what would be best option to go?

解决方案

I think the most idiomatic modern C++ method is the one you mention in passing but ignore. Return a std::unique_ptr<Shape>.

It is safe, clearly expresses ownership, supports polymorphism and doesn't need much code.

class ShapeFactory {
public:
  std::unique_ptr<Shape> create(){
    return std::make_unique<Triangle>();
  }
};

But I wouldn't want to claim it was the "best" method.

Your PimplShape in option 3 is actually very similar to a unique_ptr just less generic or tested.

这篇关于实现抽象工厂模式的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆