如何让单个接口返回不同的数据类型? [英] How To Have A Single Interface Return Different Data Types?

查看:129
本文介绍了如何让单个接口返回不同的数据类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

简而言之,我想使用单一界面 IProducer 创建一个对象 IProduct IProduct 会有不同的组件,具体取决于创建它的接口。 IProduct 类将被 IConsumer 接口使用。应该使用 IConsumer 类(我不想自己做类型检查)基于 IProduct的导出类型

In a nutshell, I want to use a single interface, IProducer, to create an object, IProduct. IProduct will have different components depending on which interface created it. The IProduct class will then be used by the IConsumer interface. The correct IConsumer class should be used (I do not want to do type checking myself) based on the derived type of IProduct.

我本质上想使用Strategy模式(单个接口后面的不同行为),但是增加了返回特定于派生接口的对象的能力。我想遵守开放/关闭原则,并且在添加更多功能时不修改任何这些现有的类。

I would essentially like to use the Strategy pattern (different behaviors behind a single interface), but with the added ability to return an object specific to the derived interface used. I want to abide by the Open/Close principle and not alter any of these existing classes when more functionality is added.

我想完成这样的事情(我'确定语法在某个地方是错误的,但是与我在一起):

I would like to accomplish something like this (I'm sure the syntax is wrong somewhere but bear with me):

class IProduct {
    public:
        int intData;
};

class ProductA : public IProduct {
    public:
        float floatData;
};

class ProductB : public IProduct {
    public:
        bool boolData;
};

class IProducer {
  public:
    virtual IProduct* produce(void) = 0;
};

class ProducerA : public IProducer {
  public:
    IProduct* produce(void) {
        return new ProductA;
    }
};

class ProducerB : public IProducer {
  public:
    IProduct* produce(void) {
        return new ProductB;
    }
};

class IConsumer {
    public:
        virtual void consume(IProduct* prod) = 0;
};

class ConsumerA : public IConsumer {
    public:
        void consume(IProduct* prod) {
        //I want to access the float!
    }
};

class ConsumerB : public IConsumer {
    public:
        void consume(IProduct* prod) {
        //I want to access the bool!
    }
};

void main() {

    IProducer* producer = ProducerFactory::create("ProducerA");

    IProduct* product = producer->produce();

    IConsumer* consumer = ConsumerFactory::create("ConsumerA");

    consumer->consume(product); //I would like the correct consumer to be used here to deal with the ProductA class
}

如果你认为有一个更好的方式去这个我是耳朵。感谢您的帮助!

If you think there is a better way to go about this I'm all ears. Thanks for your help!

推荐答案

这不是完整的解决方案(也许只是一个好奇心),但你可以随时做跟踪的类型,并使用桥接模板调用将产品分发给正确的消费者。

This is not the full solution (and maybe just a curiosity) but you can always do the tracking of types at compile time and use a bridging templated call to dispatch a product to the correct consumer.

#include <iostream>

template <class T>
class IProduct {
public:
  virtual ~IProduct() {}

  int intData;

  typedef T consumer;
};

class ConsumerA;

class ProductA : public IProduct<ConsumerA> {
public:
  float floatData;
};

class ConsumerB;

class ProductB : public IProduct<ConsumerB> {
public:
  bool boolData;
};

template <class P, class C>
void apply(P* product, C* consumer) {
  dynamic_cast<typename P::consumer*>(consumer)->consume(product);
}

template <class T>
class IConsumer {
public:
  virtual void consume(IProduct<T>* prod) = 0;
};

class ConsumerA : public IConsumer<ConsumerA> {
public:
  void consume(IProduct<ConsumerA>* prod) {
    //I want to access the float!
    std::cout << "ConsumerA" << std::endl;
    std::cout << dynamic_cast<ProductA*>(prod)->floatData << std::endl;
  }
};

class ConsumerB : public IConsumer<ConsumerB> {
public:
  void consume(IProduct<ConsumerB>* prod) {
    //I want to access the bool!
    std::cout << "ConsumerB" << std::endl;
    std::cout << dynamic_cast<ProductB*>(prod)->boolData << std::endl;
  }
};

int main(int argc, char* argv[]) {
  auto p_a = new ProductA;
  auto c_a = new ConsumerA;

  apply(p_a, c_a);

  auto p_b = new ProductB;
  auto c_b = new ConsumerB;

  apply(p_b, c_b);

  return 0;
}

这篇关于如何让单个接口返回不同的数据类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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