B.3: View (Ansicht auf das Model und Update der Sicht)#

Die Ansicht (View) repräsentiert die Darstellung / Benutzeroberfläche einer Anwendung. Es zeigt dem/der Benutzer:in die Daten aus dem Modell an und ermöglicht ihm die Interaktion mit der Anwendung. Änderungen am Modell werden meist über ein Observer-Pattern auf dem Modell wahrgenommen und dann in der Ansicht entsprechend aktualisiert und angepasst dargestellt.

In dem umzusetzenden Beispiel nutzen wir als erstes einmal ebenso das Terminal (genau wie für den Controller).

Grundlegende Struktur#

#ifndef VIEW_TERMINAL_H_
#define VIEW_TERMINAL_H_

#include "observer.h"
#include "model_ngram_chatbot.h"
#include "control_chatbot.h" 
#include <iostream>
#include <string>

// Simple view class for realizing the view in the terminal.
// You should first have looked at the observer and observable mechanism (observer.h).
// The View is realizing a receiver for updates. This means it will get notified 
// that something changed in the model (when notifyUpdate has been added in the model)
// - but only that something changed.
// The View has to implement what to do with this and how to represent this:
// - the update function is automatically triggered and inside it
//      the change has to be handled.
class ViewTerminal : public Observer {
private:
    ChatBotModel& model;  // Reference to the model to observe and interact with
    ChatBotController& controller; // Reference to the controller to delegate commands

public:
    // Constructor requires a reference to the model
    ViewTerminal(ChatBotModel& modelRef, ChatBotController& controllerRef);

    // TODO 1: The View is the point of interaction with the user and 
    // we move the main loop into this run method. 
    // Refactor your code again ...
    // Function to start the interaction loop
    void run();

    //TODO 2 a): Implement the update function - how to display to the user in the view
    // the change.
    // TODO 2 b): In the model class (the Observable) add the notifyUpdate to trigger
    //      this update using the observer mechanism.
    // Overriding the update function from Observer
    virtual void update() override;
};

#endif // VIEW_TERMINAL_H_
#include "view_terminal.h"

// Constructor implementation
ViewTerminal::ViewTerminal(ChatBotModel& modelRef, ChatBotController& controllerRef) : model(modelRef), controller(controllerRef) {
    model.addObserver(this);  // Registering this view as an observer to the model
}

// TODO 1: The View is the point of interaction with the user and 
// we move the main / control loop into this run method. 
// Refactor your code again ...
// Function to start the interaction loop
// Interaction loop for the terminal view
void ViewTerminal::run() {
    std::string input;
    std::cout << "Welcome to the n-gram Chat Bot. Type 'generate' to create a sentence, or 'exit' to quit." << std::endl;

    while (true) {
        ...
        break;
        ...
    }
}

//TODO 2 a): Implement the update function - how to display to the user in the view
// the change.
// Afterwards = TODO 2 b): In the model class (the Observable) add the notifyUpdate to trigger
//      this update using the observer mechanism.
// Implementation of the update method from Observer
void ViewTerminal::update() {
    // Output the latest data from the model
    std::cout << "Model updated. Current word: " << TODO GET CURRENT STATE OF MODEL << std::endl;
}

Anweisungen

  • Machen sie sich zuerst mit dem Observer und Observable Mechanismus vertraut (in observ.h und observer.cpp):

    • Observable: Schauen sie sich einmal im Model an, wie dies abgeleitet wird von Observable und welche Folgen das hat.

    • Observer: Wechseln sie dann zu der View Klasse als Observer. Der Observer-Observable Mechanismus sorgt dafür, dass der Observer informiert wird, wenn sich Änderungen im Model (als Observable) ergeben.

  • Die View dient als Schnittstelle zum Benutzer – hier sollen Interaktionen ausgelöst werden und dann über den Controller weitergegeben werden. Daher wird auch (in dieser Art der Strukturierung) vereinfachend die Hauptschleife nun in den View verschoben (aus dem Controller). Refaktorisieren sie diesen Teil erneut, diesmal in die run Methode in dem View.

  • Implementieren sie im View die update Methode, die automatisch ausgelöst wird, wenn im Model eine Änderung den Observable-Mechanismus aktiviert hat. Der View ist hierin dafür zuständig, sich die entsprechenden Informationen aus dem Model zu besorgen.

  • Zuletzt müssen sie genau dies im Model noch vorsehen: die notifyUpdate Methode dort einsetzen an den Stellen, in denen sich im Modell etwas grundlegend ändert, was im View angezeigt werden soll.

Ergebnis, Fragen#

  • Prüfen sie einmal ihr Verständnis des Ablaufs und gehen das main Programm durch.

  • Welche Rolle hat der Observer?

  • Wie könnte der View verbessert werden oder ein anderer View aussehen?

  • Welche Eigenschaften sollten dabei erhalten bleiben und welche könnten abgeändert werden?