Фабричный шаблон на Arduino

Я хочу создать шаблон фабрики для определения того, какой из N объектов подключен к моему порту Serial. Предполагая, что каждый объект имеет уникальный ответ на входной поток "Какая это тема?", как мне заставить мой класс ScienceFactory создать мои подклассы Science?

ПРАВКА 2 Для ясности,

  • Arduino отправляет запрос идентификации на устройство.
  • Устройство отвечаетстрокой идентификации
  • Arduino получает строку идентификации
  • Arduino создает правильный Science Child

Рассмотрев различные примеры, мне удалось получить следующий скелет кода:

class ScienceFactoy
{
    public:
      enum Subject {Biology, Chemistry, Physics};
      enum Subject Topic;
      bool GetTopic();
};

bool ScienceFactoy::GetTopic()
{
    Serial.println("What Topic is this?");
    /*The Device will respond with "Biology", "Chemestry" or "Physics"
    over Serial*/

    Topic=Biology;
      /*Instead of writing the Serial.read() logic, 
      let's pretend the device is a Biology device*/

    if(Topic==Biology)
    {
        //Создать класс биологии
        return true;
    }
    if(Topic==Chemistry)
    {
        //Создать класс по химии
        return true;
    }
    if(Topic==Physics)
    {
        //Создать класс по физике
        return true;
    }
    else
    {
        return false;
    }
}

class Science
{
    public:
      enum Subject {Biology, Chemistry, Physics};
      enum Subject Topic;
      //bool takeAttendance()
      //виртуальная пустота TestStudents();
      //виртуальный void PopQuiz();
      virtual void Free() = 0;
};

class Biology : public Science
{
    public:
    Biology(){Serial.println("Ready For Bio");}
      //bool DissectFrogs(){}
};

class Chemistry : public Science
{
    public:
    Chemistry(){Serial.println("Ready For Chem");}
      //boolСмешанныеХимическиеВещества(){}
};

class Physics : public Science
{
    public:
    Physics(){Serial.println("Ready For Physics");}
      //boolOpticsLab(){}
};

Science ConnectedClass;

void setup() {
  Serial.begin(9600);
  ScienceFactory ClassAtSerialPort; /*(Something happens that redefines 
  ClassAtSerialPort to be the correct class)*/
  /*SerialOut "Ready For Bio\n" should happen here*/
  ConnectedClass=ClassAtSerialPort;

}

void loop() {
  if(ConnectedClass.Topic==Biology){DissectFrogs();};

}

Однако я не знаю, что делать дальше, так как мой код специфичен для Arduino. (Изменить код так, чтобы он компилировался)

, 👍-1


1 ответ


Лучший ответ:

2

Это не простое решение из-за структуры ваших классов Factory и Science.

Ваш класс Science должен содержать фактический экземпляр самого себя для использования, когда цикл хочет вызвать потомков. Этот экземпляр будет называться 'device' в моем примере.

class Science
{
    public:
      enum Subject {Biology, Chemistry, Physics};
      enum Subject Topic;
      //bool takeAttendance()
      //virtual void TestStudents();
      //virtual void PopQuiz();
      virtual void Free() = 0;
      Science* device;
};

В вашем вызове GetTopic() вам затем нужно создать экземпляр фактического дочернего класса

if(Topic==Biology)
{
    //Создать класс биологии
    device = new Biology(); // с соответствующими параметрами
    return true;
}

Затем в вашей настройке() вам придется использовать класс, который был создан

ConnectedClass=ClassAtSerialPort.device;

Таким образом, в коде loop() вы вызываете метод, специфичный для устройства.

void loop() {
  if(ConnectedClass.Topic==Biology){connectedClass.doScience();};

}

В вашем подходе есть проблема, которую вам все еще нужно решить. Опора на полиморфизм, как правило, делается путем создания общего метода в родителе, который переопределяют все дочерние классы (например, doScience()), и каждый дочерний класс делает то, что уместно. У вас могут быть методы, специфичные для класса, но тогда вам, скорее всего, сначала нужно будет привести устройство к определенному классу.

,