Фабричный шаблон на 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

Обсуждение

похоже, это не связано с Arduino... поясните, пожалуйста, если Arduino отправляет сообщение «Какая это тема?» на последовательный порт, какое устройство получает строку и действует с ней так, как вы описываете?, @jsotola

Обновлено для ясности: указанный код выполняется на Arduino, который отвечает за выдачу соответствующих команд дочернему устройству Science., @ATE-ENGE

Arduino не имеет возможности компилировать код во время выполнения, @jsotola

Думаю, мне не нужно компилировать код во время выполнения, мне просто нужно знать, как читать Serial, чтобы определить, нужно ли инициализировать класс Biology или Chem. Всё должно быть уже скомпилировано., @ATE-ENGE

Извините, я выражаюсь непонятно... Мой вопрос таков: «Как заставить Factory Class создать экземпляр Class A или Class B на основе информации, которую конструктор Factory Class получает от Serial?», @ATE-ENGE

Что вы уже пробовали для исследования класса Serial или для кодирования последовательного приёма? Какую скорость передачи данных вы используете и т.д., @Kelly S. French


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()), и каждый дочерний класс делает то, что уместно. У вас могут быть методы, специфичные для класса, но тогда вам, скорее всего, сначала нужно будет привести устройство к определенному классу.

,