MVC Pattern für Roboterbewegungen mit 3 Klassen



  • Hallo zusammen,
    ich programmiere aktuell eine Simulation für einen Roboterarm, der rechts, links, auf und zu bewegt werden kann.
    Ich teste die Verwendung des MCV-Patterns.
    Mein Code funktioniert, allerdings bin ich auf der Suche nach einer besseren Lösung.

    Ich würde gerne die 3 Objekte für View, Controller und Model in der Main erzeugen lassen und dann mit einem Zeiger oder Konstruktor auf die erzeugten Objekte zeigen lassen. So wie ich es hier gemacht habe werden mehr Objekte (3 in der Main und nochmal 2 im Controller) erzeugt als ich benötige. Hat jemand eine Idee, wie ich das besser programmieren kann? Ich hatte versucht einen Zeiger zu erzeugen und dann in der Klasse Controller zu verarbeiten aber das klappt leider nicht.. Danke euch schon mal, ich freu mich auf eure Antworten 🙂

    #include <stdio.h>
    #include <iostream>
    #include <limits>
    using namespace std;
    //Darstellung der Ausgabe
    class view{	
    //class controller;
    private: 	
    	public:
    		int AusgabeZu(int aktPos){
    			switch(aktPos){
    			//ZU	
    			case 1: cout  << "o\n"<<"|\\ \n"<< "| \\ \n"<<"|  \\ \n"<< "---\n" << endl; break;
    			case 2: cout  << "o----\n"<<"| \n"<< "|  \n"<<"|  \n"<< "---\n" << endl; break;
    			case 3: cout << "   / \n"<< "  /\n"<<" /\n"<<"o\n"<<"| \n"<< "|  \n"<<"|  \n"<< "---\n" << endl; break;
    			case 4: cout << "|\n"<< "| \n"<< "|\n"<<"o\n"<<"| \n"<< "|  \n"<<"|  \n"<< "---\n" << endl; break;
    			case 5: cout << "\\ \n"<< " \\ \n"<<"  \\ \n"<<"   o\n"<<"   | \n"<< "   |  \n"<<"   |  \n"<< "  ---\n" << endl; break;
    			case 6: cout << "----o\n"<<"    | \n"<< "    |  \n"<<"    |  \n"<< "   ---\n" << endl; break;
    			case 7: cout << "   o \n" <<"  /| \n" <<  " / | \n" << "/  |\n"<< "  ---\n" << endl; break;	
    			} 	
    		}
    		int AusgabeAuf(int aktPos){
    			switch(aktPos){
    			//AUF
    			case 1: cout  << "o\n"<<"|\\ \n"<< "| \\ \n"<<"| |\\ \n"<< "---\n" << endl; break;
    			case 2: cout  << "o---<\n"<<"| \n"<< "|  \n"<<"|  \n"<< "---\n" << endl; break;
    			case 3: cout  << "   |_ \n"<< "  /\n"<<" /\n"<<"o\n"<<"| \n"<< "|  \n"<<"|  \n"<< "---\n" << endl; break;
    			case 4: cout  << "V\n"<< "| \n"<< "|\n"<<"o\n"<<"| \n"<< "|  \n"<<"|  \n"<< "---\n" << endl; break;
    			case 5: cout  << "_| \n"<< " \\ \n"<<"  \\ \n"<<"   o\n"<<"   | \n"<< "   |  \n"<<"   |  \n"<< "  ---\n" << endl; break;
    			case 6: cout  << ">---o\n"<<"    | \n"<< "    |  \n"<<"    |  \n"<< "   ---\n" << endl; break;
    			case 7: cout  << "   o \n" <<"  /| \n" <<  " / | \n" << "/| |\n"<< "  ---\n" << endl; break;
    			} 		
    		}
    };
    // Daten und Berechnungen
    class model{
    	//view view1;	
    	public:
    	//Einlesen der Bewegungsdaten
    	int inputMove(int calc, int greiferZustand, int moveInput){		
    		if (moveInput==2){
    			//Berechnung calc
    			if (calc < 7 && calc >=1){
    				calc = calc+1;	
    			}
    			else {
    			 calc = 1;
    			}
    		}
    		else if (moveInput==1){
    			if (calc <= 7 && calc > 1){
    				calc = calc-1;	
    			}
    			else {
    			 calc = 7;
    			}
    		}
    		return calc;
    	}
    };
    //Steuerung und Benutzereingaben
    class controller{
    	private:
    		model model1;
    		view view1;
    	public:
    	int input (){
    		int greiferZustand = 1, test =7;
    		cout<< "Startposition: " << endl;
    		view1.AusgabeAuf(test);
    		while (true){
    			//Eingabe Controller
    			int moveInput=move();
    			if (moveInput ==3){
    				greiferZustand = 1;
    				//Folgeposition Ausgabe View
    				view1.AusgabeAuf(test);		
    				test = model1.inputMove(test,greiferZustand, moveInput);
    			}
    			else if (moveInput == 4){
    				greiferZustand = 0;	
    				//Folgeposition Ausgabe View
    				view1.AusgabeZu(test);
    				test = model1.inputMove(test,greiferZustand, moveInput);
    			}
    			else{
    				test = model1.inputMove(test,greiferZustand, moveInput);
    				cout << "aktuelle Position: " << test<< endl;
    			//Folgeposition Ausgabe View
    				if (greiferZustand == 0){
    					view1.AusgabeZu(test);
    				}
    				if (greiferZustand == 1){
    					view1.AusgabeAuf(test);	
    				}
    			}	
    		}	
    	}	
    	int move(){
    		float moveInput=0;	
    				cout << "Bitte Bewessgunsssg eingeben: [1]=Rechts, [2]=Links, [3]=Greifer Auf, [4]=Greifer Zu: ";
     
      if (cin >> moveInput && (moveInput ==1 || moveInput == 2 || moveInput == 3 ||moveInput ==4)) {
      		// hat geklappt => raus aus der schleife, Rückgabe Inputwert
      		return moveInput;	
      } else if (!cin.bad() && !cin.eof()) {
        	cerr << "Sie haben eine ungueltige Zahl eingegeben! Versuchen Sie es erneut.\n";
        	cin.clear(); // Fehlerzustand zurücksetzen
        	cin.ignore(std::numeric_limits<streamsize>::max(),'\n'); 
        	move();
      }
    }
    };	
    //Main ruft nur den Controller auf
    int main(int argc, char** argv) {
    	//Erstellen Objekt controller,class controller;
    	controller controller1;
    	model model1;
    	view view1;
    	controller1.input();
    }
    
    

    Schönen Feiertag 🙂



  • Du solltest die Model und View Objekte dem Controller in dessen Konstruktor als Zeiger übergeben:

    model model1;
    view view1;
    controller controller1(&model1, &view1);
    

    Falls die View auch noch das Model kennen soll, dann entsprechend:

    view view1(&model1);
    

    Und in den Klassen dann jeweils diese Zeiger als Member halten, welche dann vom Konstruktor initialisiert werden:

    class controller
    {
    private:
    	model* _model;
    	view* _view;
    public:
    	controller(model* m, view *v)
    	 : _model(m), _view(v)
    	{
    	}
    
    	// ...
    }
    

    Die Abhängigkeiten sollten niemals umgekehrt sein (wie teilweise in deinem auskommentierten Code, also Model sollte weder View noch Controller kennen, noch die View den Controller), s.a. Model View Controller (MVC-Pattern).



  • Hallo Th69,

    vielen Dank für deine Antwort 🙂
    ich habe deine Tipps soweit ich es verstanden habe eingefügt.
    Jetzt bekomme ich leider die Fehler, die ich schon die ganze Zeit bekomme:
    view1 und model1 was not declared in this scope z.B in Zeile 72, d.h. ja, dass die Klasse Controller nicht auf die Zeiger zugreifen kann oder muss ich bei der Konstruktorinitialisierung noch etwas hinzufügen?

    Vielen Dank nochmal für deine Mühe 🙂
    Die auskommentierten Aufrufe habe ich entfernt, hatte das so in meiner ersten Variante drin stehen.

    #include <stdio.h>
    #include <iostream>
    #include <limits>
    using namespace std;
    //Darstellung der Ausgabe
    class view{
    	public:
    		int AusgabeZu(int aktPos){
    			switch(aktPos){
    			//ZU
    			case 1: cout  << "o\n"<<"|\\ \n"<< "| \\ \n"<<"|  \\ \n"<< "---\n" << endl; break;
    			case 2: cout  << "o----\n"<<"| \n"<< "|  \n"<<"|  \n"<< "---\n" << endl; break;
    			case 3: cout << "   / \n"<< "  /\n"<<" /\n"<<"o\n"<<"| \n"<< "|  \n"<<"|  \n"<< "---\n" << endl; break;
    			case 4: cout << "|\n"<< "| \n"<< "|\n"<<"o\n"<<"| \n"<< "|  \n"<<"|  \n"<< "---\n" << endl; break;
    			case 5: cout << "\\ \n"<< " \\ \n"<<"  \\ \n"<<"   o\n"<<"   | \n"<< "   |  \n"<<"   |  \n"<< "  ---\n" << endl; break;
    			case 6: cout << "----o\n"<<"    | \n"<< "    |  \n"<<"    |  \n"<< "   ---\n" << endl; break;
    			case 7: cout << "   o \n" <<"  /| \n" <<  " / | \n" << "/  |\n"<< "  ---\n" << endl; break;
    			}
    		}
    		int AusgabeAuf(int aktPos){
    			switch(aktPos){
    			//AUF
    			case 1: cout  << "o\n"<<"|\\ \n"<< "| \\ \n"<<"| |\\ \n"<< "---\n" << endl; break;
    			case 2: cout  << "o---<\n"<<"| \n"<< "|  \n"<<"|  \n"<< "---\n" << endl; break;
    			case 3: cout  << "   |_ \n"<< "  /\n"<<" /\n"<<"o\n"<<"| \n"<< "|  \n"<<"|  \n"<< "---\n" << endl; break;
    			case 4: cout  << "V\n"<< "| \n"<< "|\n"<<"o\n"<<"| \n"<< "|  \n"<<"|  \n"<< "---\n" << endl; break;
    			case 5: cout  << "_| \n"<< " \\ \n"<<"  \\ \n"<<"   o\n"<<"   | \n"<< "   |  \n"<<"   |  \n"<< "  ---\n" << endl; break;
    			case 6: cout  << ">---o\n"<<"    | \n"<< "    |  \n"<<"    |  \n"<< "   ---\n" << endl; break;
    			case 7: cout  << "   o \n" <<"  /| \n" <<  " / | \n" << "/| |\n"<< "  ---\n" << endl; break;
    			}
    		}
    };
    // Daten und Berechnungen
    class model{
    	public:
    	//Einlesen der Bewegungsdaten
    	int inputMove(int calc, int greiferZustand, int moveInput){
    		if (moveInput==2){
    			//Berechnung calc
    			if (calc < 7 && calc >=1){
    				calc = calc+1;
    			}
    			else {
    			 calc = 1;
    			}
    		}
    		else if (moveInput==1){
    			if (calc <= 7 && calc > 1){
    				calc = calc-1;
    			}
    			else {
    			 calc = 7;
    			}
    		}
    		return calc;
    	}
    };
    //Steuerung und Benutzereingaben
    class controller{
        private:
            model* _model1;
            view* _view1;
        public:
            // Konstruktor
            controller(model* m, view *v)
            : _model1(m), _view1(v)
            {
            }
    	int input (){
    		int greiferZustand = 1, test =7;
    		cout<< "Startposition: " << endl;
    		view1.AusgabeAuf(test);
    		while (true){
    			//Eingabe Controller
    			int moveInput=move();
    			if (moveInput ==3){
    				greiferZustand = 1;
    				//Folgeposition Ausgabe View
    				view1.AusgabeAuf(test);
    				test = model1.inputMove(test,greiferZustand, moveInput);
    			}
    			else if (moveInput == 4){
    				greiferZustand = 0;
    				//Folgeposition Ausgabe View
    				view1.AusgabeZu(test);
    				test = model1.inputMove(test,greiferZustand, moveInput);
    			}
    			else{
    				test = model1.inputMove(test,greiferZustand, moveInput);
    				cout << "aktuelle Position: " << test<< endl;
    			//Folgeposition Ausgabe View
    				if (greiferZustand == 0){
    					view1.AusgabeZu(test);
    				}
    				if (greiferZustand == 1){
    					view1.AusgabeAuf(test);
    				}
    			}
    		}
    	}
    	int move(){
    		float moveInput=0;
    				cout << "Bitte Bewessgunsssg eingeben: [1]=Rechts, [2]=Links, [3]=Greifer Auf, [4]=Greifer Zu: ";
    
      if (cin >> moveInput && (moveInput ==1 || moveInput == 2 || moveInput == 3 ||moveInput ==4)) {
      		// hat geklappt => raus aus der schleife, Rückgabe Inputwert
      		return moveInput;
      } else if (!cin.bad() && !cin.eof()) {
        	cerr << "Sie haben eine ungueltige Zahl eingegeben! Versuchen Sie es erneut.\n";
        	cin.clear(); // Fehlerzustand zurücksetzen
        	cin.ignore(std::numeric_limits<streamsize>::max(),'\n');
        	move();
      }
    }
    };
    //Main ruft nur den Controller auf
    int main(int argc, char** argv) {
    	//Erstellen Objekt controller1, model1, view1
    	model model1;
        view view1;
        //Beziehung zwischen Controller und Model und View
        //Übergabe von Zeiger Model1 und View1 in Konstruktor von Controller1
        controller controller1(&model1, &view1);
    	controller1.input();
    }
    
    


  • Du mußt dann natürlich auf die Member _view1 und _model1 zugreifen (die 1 im Namen finde ich irritierend - als ob es davon mehrere in der Klasse gäbe):

    _view1->AusgabeAuf(test); // -> (statt . ) wegen Zeigerzugriff
    

Log in to reply