Laden...

Trennung von Awendungslogik und Optik

Erstellt von Pedro_15 vor 18 Jahren Letzter Beitrag vor 18 Jahren 14.883 Views
P
Pedro_15 Themenstarter:in
375 Beiträge seit 2005
vor 18 Jahren
Trennung von Awendungslogik und Optik

Hallo Ihr,

wie ihr seht bin ich neu hier.
Ich möchte mit einigen Leuten ein relativ grosses Software Projekt starten.

Wir habe einige Programmiererfahrung aus dem Studium und aus einigen Projekten (Java, PHP und einwenig C#), leider noch keine bei der Trennung von View und Modell.

Und dazu habe ich auch gleich die Frage, wie kann ich Anwendungslogilk (Modell) und die Optik (View) trennen.

Es soll möglichst eine genaue Trennung geben, denn es ist geplant mehrere Frontends zu Programmieren (WindowsForm, WEB).

Beispiel:
Die Anwendung ermittel aus einem Verzeichnis alle Dateien. Sie sollen jetzt in WindowsForm in Treeview angezeigt werden oder im Web in einer Tabelle.
Beim Anklicken des Treevieweintrages oder des Tabelleneintrages soll eine Funktion (die selbe natürlich) aufgerufen werden.

Ich glaube, wenn ich das umsetzen kann, dann bin ich im Verständnis einwenig weiter.

MVC und den Webcast von Microsoft habe ich mir schon angeschaut, aber so richtig weiter bin ich damit auch nicht gekommen. Könnt Ihr mir sagen, ob das mit MVC das richtige ist und mir sagen, wie und womit ich mich am besten einarbeiten kann und vielleicht behilflich sein das obige Beispiel zu lösen.

Vielen Dank für die Hilfe.

Pedro

432 Beiträge seit 2005
vor 18 Jahren

hi pedro,

da c# eine voll objektorientierte sprache ist, ergibt sich eigentlich schon fast für jedes projekt zwangsläufig eine trennung von logik und optik.

um bei deinem beispiel zu bleiben, würde die funktion, die auf der ausgewählten datei oder dem ausgewählten ordner ausgeführt werden soll, ohnehin in einer eigenen klasse implementiert sein:

public class myFileHandler
{
   public int DoSomething(myFileInfo fileInfo)
   {
      // Implementierung
   }
}

Diese Klasse kannst du dann in alle oberflächen einbinden. darüberhinaus könntest du sie sogar in eine eigene dll kompilieren und dynamisch aus den oberflächen heraus laden.
hierzu haben wir gerade einen interessanten aktuellen thread:
extrem dynamische bindung über variable klassennamen?

viel erfolg

ron

S
8.746 Beiträge seit 2005
vor 18 Jahren

MVC ist nur "ein" Pattern um die Trennung zu erreichen ((es heisst übrigens Layout und nicht Optik, obwohl Optik irgendwie lustig ist... 🙂 ). Es gilt im allgemeinen als schwergewichtig. Zudem nimmt .NET mit seinen Events Teile des MVC-Pattern bereits vorweg.

Der Unterschied beim Windows.Form-Ansatz zu MVC besteht darin, dass der Controller Teil der Form-Klasse, also des Views ist (Events-Implementierung).

In normalen Windows-Anwendungen ist das eigentlich ausreichend. Wenn verschiedene Frontends (Web und Forms) bedient werden müssen, eher nicht.

Entscheidend ist also die saubere Trennung der Modells vom Rest. Wie man das macht, siehst du hier:

http://www.codeproject.com/csharp/model_view_controller.asp?df=100&forumid=3987&exp=0&select=331412

Kurz gesagt geht es darum, dass Modell und der Rest nur via Events kommunizieren. Der direkte Zugriff auf das Datenobjekt ist tabu. Datenobjekte müssen quasi ihre Veränderung über einen Event in das GUI spiegln. .NET fährt einen leicht modifizierten Ansatz namens DataBinding. Hier werkeln ähnliche Mechanismen, die Codetrennung ist aber.... nunja.... nicht existent, bzw. man muss sie selbst erreichen.

Von MS gibts einen Applikation-Block von für das "große" MVC:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/uip.asp?_r=1

P
Pedro_15 Themenstarter:in
375 Beiträge seit 2005
vor 18 Jahren

Danke für die schnellen Antworten.

@citizen.ron

Eigene Klasse für den FileHandler ist klar, aber wie wird z.b. die Treeview gefüllt (Kommunikation Layout-Modell).

In der Klasse FileHandler mit treeview.add, das kann ja nicht der richtige weg sein.

In der Layoutklasse fileHandler.getFileList() und diese dann an den Treeview übergeben und dann in Schleife Adden, schein mir auch nicht die Richtige Wahl zu sein.

@svenson
Aber MVC ist der richtige Weg oder?

S
8.746 Beiträge seit 2005
vor 18 Jahren

Ob MVC der richtige Weg ist, kann man nur im Einzelfall sagen. MVC ist extrem geschwätzig, es produzierte enorme Mengen an Klassen. Das ist per se ein Nachteil, wiel die Komplexität damit steigt.

Wenn nicht wirklich die Anforderung auf dem Tisch liegt, die Business-Logic an verschiedenen Frontend-Typen (Forms und ASP) anzuknüppern, dann würde ich den leichtgewichtigen Ansatz i.d.R. bevorzugen (Codeprojekt-Artikel). Bei dir scheint die Lage anders zu sein, deswegen würde ich mir den MS-App-Block näher zu Gemüte führen.

In jedem Fall ist die "Trennung" richtig, weil es die Software änderbar hält.

432 Beiträge seit 2005
vor 18 Jahren

In der Klasse FileHandler mit treeview.add, das kann ja nicht der richtige weg sein.

doch, auf eine bestimmte weise schon, denn es gibt in .net (2.0) ohnehin keine filetreeview, die müsstest du sowieso programmieren oder einkaufen.

die einbindung in deine oberfläche könnte also geschehen über:

FolderPanel.Controls.Add(myFileHandler.GetTree());

mit FolderPanel als Panel deiner Oberfläche, in der die TreeView zu liegen kommt.

Die Methode myFileHandler.GetTree() liefert als Rückgabewert eine TreeView, deren Knoten du tatsächlich innerhalb der Klasse aufbaust.
Vielleicht erbst du deine Klasse sogar von TreeView.

ich selbst habe zum beispiel einige erbende klassen von TreeNode geschrieben, weil ich outlook attribute und funktionen in den knoten selbst legen wollte; oder ich habe von TreeNode geerbt, um mit sql datenbank objekten rumzuwerkeln und attribute der datenbankobjekte in den knoten mit "hineinlegen" wollte.

das hat den vorteil, dass bei knotenauswahl durch den benutzer auch gleich alle für mich wichtigen attribute "ausgewählt" werden.

die klasse TreeView (oder ihre nachkommen) lassen ja durchaus zu, dass du den nodes nachkommen eines TreeNode unterjubelst.

bringt dich das auf ideen? 😉

P
Pedro_15 Themenstarter:in
375 Beiträge seit 2005
vor 18 Jahren

Die Methode myFileHandler.GetTree() liefert als Rückgabewert eine TreeView, deren Knoten du tatsächlich innerhalb der Klasse aufbaust.

Das ist doch das was ich die ganze Zeit mache, aber damit ist die Bindung der FileHandler Klasse mit dem Layout da und die will ich ja gerade vermeiden.

Ich kann myFileHandler.GetTree() nur aufrufen, wenn ich ein Treeview brauche und muss für die Tabellenausgabe in einer Zweiten Methode zur Verfügung stellen.

Ich denke, wenn ich das richtig verstanden habe, muss ein Event "neues File" in FileHandler ausgelöst werden und das Layout darauf reagieren.

Ist das so richtig?

Pedro

432 Beiträge seit 2005
vor 18 Jahren

du kannst natürlich auch allgemeiner eine methode GetViewObject() mit rückgabewert object implementieren und es dir in der oberfläche beim hinzufügen des controls egal sein lassen, ob es jetzt eine tabelle war oder ein treeview oder eine kaffeemaschine...

der andere ansatz ist wie du sagst, mehrere methoden für verschiedene bedürfnisse bereitzustellen; das ist doch legitim und durchaus üblich. nicht jeder benutzer einer klasse muss ja auch alle funktionen der klasse nutzen. die eine oberfläche braucht die einen, die andere die anderen methoden und ausserdem gibt es noch eine schnittmenge.

oder störst du dich daran, dass deine FileHandler Klasse mit using nun auf so "optische" sachen wie ein treeview verweisen muss?

ist doch egal, das .net framework muss auf dem zielrechner eh vorhanden sein, also kann man ja auch benutzen, was man braucht.
die saubere trennung ist doch trotzdem da, solange du nicht umgekehrt jetzt in der filehandler klasse auf funktionen der oberfläche zugreifen willst.

432 Beiträge seit 2005
vor 18 Jahren

da ich letztlich gerade am gleichen thema sitze, setz ich grad nochmal einen drauf:

wenn die filehandler klasse die treeview baut, kann sie ja auch den eventhandler dafür selbst bereitstellen:

treeView.AfterSelect += new TreeViewEventHandler(this.eh_TreeView_AfterSelect);

damit sieht der benutzer zwar die treeview in seiner "oberfläche", geliefert wird sie ihm aber aus der klasse FileHandler, die hier jetzt auch das Ereignis des Auswählens eines Knotens abarbeitet...

P
Pedro_15 Themenstarter:in
375 Beiträge seit 2005
vor 18 Jahren

Ich weiss nicht. Ich bin mir wirlich unsicher.

Das ist genau mein Problem, ich weiss nicht, ob das in Ordnung ist.

Das MVC Beispiel zeigt ein anderen Weg und alle Methoden für die Unterschiedlichen Oberflächen doppelt zu schreiben, finde ich eigentlich nicht toll.

Ich weiss auch nicht, ob der Eventansatz der Richtige ist.

Ich hoffe, ihr könnt mir Helfen einwenig Licht ins dunkel zubringen.

Pedro

P
Pedro_15 Themenstarter:in
375 Beiträge seit 2005
vor 18 Jahren

wenn die filehandler klasse die treeview baut, kann sie ja auch den eventhandler dafür selbst bereitstellen:

Das finde ich wiederspricht ja nun völlig der Kapselung von View und Modell.

75 Beiträge seit 2005
vor 18 Jahren
Model View Controller

Hi,

doch doch, wenn Du alles Sauber wie im Model View Controler
Pattern implementierst. Dann kannst Du Chefe irgendwann
sagen, warum bringen wir nicht auch ne PDA Version raus
und brauchst dafür nur noch einen neuen PDA View zu
implementieren. Immer schön alles was mit Anwendungslogik
zu tun bloss nicht in die Gui bauen. Tu Dir denn gefallen
und starte einfach gleich nach diesem Prinzip, es ist einfacher
als später irgendwann da ein Wochenende zu sitzen und alles
umzuschreiben und zu denken ach hätte ich doch 😉

Gruss
LarsLovesDotNet

Alles was man sich vorstellen kann,kann man auch programmieren.

AODL- An OpenDocument LibraryAODL
WWW: www.OpenDocument4all.com

P
Pedro_15 Themenstarter:in
375 Beiträge seit 2005
vor 18 Jahren

@LarsLovesDotNet

Stimme dir voll und ganz zu. Deswegen dieses Thema vor dem Start.

Aber die Frage ist, wie setze ich das um.

Pedro

P
Pedro_15 Themenstarter:in
375 Beiträge seit 2005
vor 18 Jahren

Ich denke, wenn ich das richtig verstanden habe, muss ein Event "neues File" in MyFileHandler ausgelöst werden und das Layout darauf reagieren.

Könnt Ihr mir das bestätigen oder liege ich da völlig falsch.

Ist es richtig, dass zwischen Layout und Modell mit Events kommuniziert wird, wenn man ein strickte Trennung zwischen Modell und View bauen will?

Habt Ihr ein Code BeispielP

Danke!

Pedro

A
452 Beiträge seit 2005
vor 18 Jahren

wenn du eine strikte trennung von model und view hast dann hast du aber kein mvc pattern mehr 😉

ich habe es mir so eingerichtet, dass ich ein interface erstellt habe von dem alle meine viewst abgeleitet werden. das interface implementiert dann noch das model und das control. so bekommen alle views von dem model und dem control etwas mit aber zumindes das model kennt die views und das control nicht.

bei mir reagiert dann noch das control auf die events der form und gibt dann änderungen an die views weiter (bzw an das interface)
das heisst dass bei mir form und control recht nah zusammenarbeiten. vllt habe ich hier aber auch geschlampt... ich hoffe nicht Oo

Signatur:
Die Signatur wird unter Ihren Beiträgen dargestellt.

😁 😮 ?( 8) 😭 8o :] 🙁 =) X( 🙂 😜 😉 :rolleyes: 👶 :evil: 👅
Smilies find ich doof =]

P
Pedro_15 Themenstarter:in
375 Beiträge seit 2005
vor 18 Jahren
Nicht unbedingt MVC

Es muss nicht unbedingt MVC sein.
Die Trennung, die Modullarisierung und die Wiederverwendbarkeit ist wichtig.

Ich möchte vermeiden das ich bei der Anforderung die View auszutauschen mich vercode.

Pedro

A
452 Beiträge seit 2005
vor 18 Jahren

also ich denke da ist schon die möglichkeit ein interface zu benutzen, ganz nett 😉

du erstellst ein interface, dass alle methoden beinhaltet die deine views auch beinhalten, zB fuelleView. (wenn du zB einmal eine listviewansicht und einmal eine textboxansicht hast)

die methoden schreibst du dann ja in den einzelnen views selbst aus.
dann greifst du nur noch mit dem controller auf das interface zu und lässt somit die views alleine stehn. die views selbst können sich dann noch die daten aus dem model holen, die sie grad benötigen.

Signatur:
Die Signatur wird unter Ihren Beiträgen dargestellt.

😁 😮 ?( 8) 😭 8o :] 🙁 =) X( 🙂 😜 😉 :rolleyes: 👶 :evil: 👅
Smilies find ich doof =]

P
Pedro_15 Themenstarter:in
375 Beiträge seit 2005
vor 18 Jahren

Ich wollte mal das MVC Beispiel von http://www.codeproject.com/csharp/model_view_controller.asp?df=100&forumid=3987&exp=0&select=331412 probieren.

Leider kann ich das Beispiel so nicht erstellen.

public delegate void BookPriceChangedHandler(objectsender,
			BookPriceChangedEventArgs e);
        
// declare the bookpricechanged event using the bookpricechangeddelegate
public event BookPriceChangedHandlerBookPriceChanged;

Fehlermeldung:
D:\eigene dateien\Visual Studio Projects\MVC\Book.cs(11): Erkennungszeichen erwartet.
D:\eigene dateien\Visual Studio Projects\MVC\Book.cs(15): Ungültiger Token ';' in Klasse, Struktur oder Schnittstellenmemberdeklaration

Kann mir jemand helfen?

Pedro

PS: Ich benutze VS2003.

A
452 Beiträge seit 2005
vor 18 Jahren

kann es sein dass es object sender heissen muss und nicht objectsender?

Signatur:
Die Signatur wird unter Ihren Beiträgen dargestellt.

😁 😮 ?( 8) 😭 8o :] 🙁 =) X( 🙂 😜 😉 :rolleyes: 👶 :evil: 👅
Smilies find ich doof =]

P
Pedro_15 Themenstarter:in
375 Beiträge seit 2005
vor 18 Jahren

Danke völlig richtig , im Beispielcode fehlen einige Leerzeichen.

Danke Pedro

3.728 Beiträge seit 2005
vor 18 Jahren
Model

Bei verteilten Anwendungen sollte das Model nicht die Geschäftslogik enthalten, sondern nur den temporären Clientstatus verwalten. Geschäftsregeln sollten in separaten statuslosen Komponenten untergebracht werden (Statuslose Komponenten skalieren besser als statuswahrende Komponenten). Das Model delegiert Anfragen an diese Geschäftskomponenten. Wichtig ist, dass der komplette Clientstatus (z.B. ein DataSet, mit dem der Benutzer über ein DataGrid arbeitet) im Model verwaltet wird. Außerdem sollte NUR das Model auf Geschäftskomponenten zugreifen. Controller und Views kennen nur das Model als Informationsquelle und führen Aktionen auch nur über das Model aus und nie direkt.

Bei Webclients muss man vorsichtig sein, wenn man ein Model verwendet, welches auch für Forms-Clients eingesetzt wird. Bei Forms-Clients wird der Clientstatus auf dem Computer des Anwenders verwaltet. Bei Webanwendungen muss der Clientstatus auf dem Webserver gehalten werden. Das kann bei vielen gleichzeitigen Benutzern sehr viele Ressourcen des Webservers verschlingen (Bei 100 Benutzern bedeutet das 100 Model-Objekte im Hauptspeicher!). Bei Webanwendungen geht man deshalb so sparsam wie möglich mit dem Clientstatus (auch Sitzungsstatus genannt) um. Da die Konzepte von Forms- und Webanwendungen so verschieden sind, ist es eine Herausforderung ein universelles Model zu entwerfen.

B
50 Beiträge seit 2005
vor 18 Jahren

Hi,

ich finde diesen Thread sehr interessant und ich habe mich in letzter Zeit auch ein wenig mit MVC beschäftigt. Mir ist es wichtig dass der grafische Code komplett vom logischem Code getrennt ist. Deswegen lasse ich kein View auf ein Model direkt zugreifen.. aber im MVC Pattern ist das ja so festgelegt oder? Ich kann aber nicht wirklich verstehen wieso.

Also meine Vorgehensweise:
View<-----Controller------>Model

Die View kommuniziert mit dem Controller übrigens auch nur über Events. Der Controller ist immer an ein View angepasst. Und der Controller hat zugriff auf das Model. Aber wie gesagt, das View greift nie direkt auf das Model zu.

Beispiele:
* Der Controller ruft eine Funktion aus dem Model auf. Diese Funktion schlägt fehl. Der Controller ruft eine Funktion aus der View auf, die eine MessageBox zeigt mit dem Fehler.
* Das View fügt einen neuen Kunden in einen TreeView hinzu. Das View führt nun einen Event aus, der Controller fängt dieses Event ab und fügt den Kunden in das Model hinzu.

So, was haltet ihr davon? Gibt es dabei gravierende Nachteile?

3.728 Beiträge seit 2005
vor 18 Jahren
Passives Modell

Du hast das passive Modell verwendet. Dabei reden die Views nur über den Controller mit dem Model. Da die Methodenaufrufe und Events des Models über den Controller durchgeschleift werden müssen, ist es viel mehr Aufwand.

Wenn Du einfach nur eine komplexe Windows Forms Anwendung strukturiert und erweiterbar haben willst, lohnt sich dieser Aufwand nicht.

Wenn Du aber den Clientstatus (oder auch Sitzungsstatus) völlig unabhängig kapseln willst (weil z.B. Web oder Mobile Clients mit dem selben Model arbeiten sollen) solltest Du es sogar unbedingt so machen. Für jede Anzeigetechnologie hast Du dann einen eigenen Controller. Der jeweilige Controller schirmt das Model von den Eigenheiten der jeweiligen Anzeigetechnologie ab.

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo zusammen,

ich habe nicht den ganzen Thread verfolgt und beziehe mich nur auf die letzten beiden Beiträge.

Das das Modell von dem View entkoppelt werden sollte, ist klar, damit man ein View durch ein anderes ersetzen kann, ohne das Modell anpassen zu müssen. Das ist aber schon der Fall, wenn das View das Modell kennt/benutzt, aber nicht umgekehrt. Aber warum man durch View<-----Controller------>Model eine bessere Entkoppelung erreichen sollte, ist mir völlig unklar. Ich sehe da nur Nachteile.

herbivore

PS: @Bakunin, vielleicht kannst du mal ein kleines Codebeispiel bringen, aus denen man je eine MVC-Klasse, deren Methoden und den von dir beschriebenen Ablauf sehen kann.

B
50 Beiträge seit 2005
vor 18 Jahren

Hallo herbivore,

ich beschäftige mich damit wie gesagt erst seit kurzem. Ich habe es eigentlich so gemacht, damit eine komplette Trennung zwischen View und Model entsteht. Also das View kennt nicht das Model und das Model kennt nicht das View. Der Controller ist also die Schnittstelle zwischen den beiden. Wenn sich jetzt etwas im Model ändert, muss der Controller angepasst werden, aber nicht das View. Das View greift immer noch auf die gleiche Schnittstelle im Controller zu.

@Rainbird
Danke für die Erklärung.

Ob es so eben Vorteile hat und Nachteile hat wollte ich ja fragen. Ich habe es wie gesagt so strukturiert um eine komplette Trennung der Logik mit dem Layout zu erreichen.

Also hier ein kleines Bsp wie es so funktioniert:



//VIEW
		//============================DELEGATES===========================
		public delegate void closeWindow();
		public delegate void loadMainConfig();
		
		//============================DELEGATE EVENTS=====================
		public event closeWindow onClose;
		public event loadMainConfig onLoadMainConfig;
	
		public ConfigurationView (){
		}
		
		public void show(){			
			Application.Init ();

			Glade.XML gxml = new Glade.XML (null, "gui.glade", "frm_Configuration", null);
			gxml.Autoconnect (this);
                        //(.....) 
			Application.Run ();
		}
		
		public void close(){
			Application.Quit();
			if(this.onClose != null)	this.onClose();
		}
		
		public void showErrorMessage(string Message){
                //(...)
		}
		
		public bool showQuestionDialog(string Message){
                //(...)
		}
		
		public string showFileChooser(string Message){
                //(...)
		}
		
		//============================GLADE EVENTS===================================
		private void onFrmConfigurationDeleteEvent (object sender, DeleteEventArgs a){
			this.close();
			a.RetVal = true;
		}
		
		private void onDruidPageMainConfigPrepare(object sender, EventArgs e){
			if(this.onLoadMainConfig != null)	this.onLoadMainConfig();
		}


//Controller


		private ConfigurationController(){
		}
	
		public static ConfigurationController getConfigurationController(string MainConfigFile){
			ConfigurationController oCC = new ConfigurationController();
			
			oCC.m_MainConfigFile = MainConfigFile;
			oCC.m_ConfigView = new ConfigurationView();
			
			oCC.m_ConfigView.onClose += new WikiDoc.IO.GUI.Views.ConfigurationView.closeWindow(oCC.onClose);
			oCC.m_ConfigView.onLoadMainConfig += new WikiDoc.IO.GUI.Views.ConfigurationView.loadMainConfig(oCC.onLoadMainConfig);
			
			return oCC;
		}
	
		public void show(){
			this.m_ConfigView.show();
		}
		
		public void close(){
			if(this.onCloseView != null)	this.onCloseView();
		}
		
	//============================EVENTS===================================
		
		private void onClose(){
			this.close();
		}

		private void onLoadMainConfig(){			
				//(....)
				//Show the main config
				this.m_ConfigView.Server = this.m_MainConfig.DatabaseServer;
				this.m_ConfigView.User = this.m_MainConfig.DatabaseUser;
				this.m_ConfigView.Password = this.m_MainConfig.DatabasePassword;
				this.m_ConfigView.Database = this.m_MainConfig.DatabaseName;
				this.m_ConfigView.TagFile = this.m_MainConfig.TagConfigFilePath;
				this.m_ConfigView.LogFile = this.m_MainConfig.LogFilePath;
			}
		}


Der Code ist natürlich stark gekürzt (Fehler einfach übersehen). Hoffentlich es ist jetzt ein wenig klarer. Achja damit keine all zu große Verwirrung entsteht, dass ganze ist unter mono geschrieben und es ist eine Glade# Anwendung.+

Ok, und der "bessere" Ansatz wäre also (außer es tritt der Fall ein wie Rainbird erklärt hat), wenn das View auch direkt auf das Model zugreifen kann? Aber ist es dann immer noch eine strikte Trennung zwischen Layout und Logik? Also wenn die View Komponente direkt auf das Model zugreifen kann? Und was für eine Rolle spielt dann überhaupt der Controller?

Hier wäre ich auch um ein Code Bsp. erfreut 🙂. Außer ich habe zuviele Links übersehen.

Bakunin

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo Bakunin,

eine komplette Trennung von Model und Oberfläche (ich schreibe jetzt extra nicht View) ist nicht möglich. Irgendwer muss auf das Modell zugereifen, ob das der Controller oder das View ist, macht ja (bezogen auf diese Zugriffe) nicht mehr oder weniger Aufwand. Da nun aber Änderungen im Modell immer auf das View durchschlagen können (ein Modellobjekt bekommt eine neue Eigenschaft, die angezeigt werden soll), ist die Entkoppelung durch den Controller nie wirklich vollständig. Ich sehe den Controller in deiner Variante nur als (sorry) lästige, Aufwand produzierende und unnötige Zwischenschicht. Nochmal sorry für das harte Urteil, aber ich wollte klar machen, dass keine Vorteile und nur Nachteile darin sehe.

Aber ist es dann immer noch eine strikte Trennung zwischen Layout und Logik? Also wenn die View Komponente direkt auf das Model zugreifen kann?

Ja, wichtig ist, dass das Modell nichts von dem View weiß und keine Anhängigkeiten dazu hat. Das ist aber auch schon der Fall, wenn die View-Klassen die Modell-Klassen kennen/benutzen, aber nicht umgegekehrt.

Und was für eine Rolle spielt dann überhaupt der Controller?

Nach meinem Verständnis ist der Controller der Input-Teil (Keyboard, Mouse, ButtonClick, MenuClick, ...) und das View der Output-Teil (Anzeige/Visualisierung der Daten) der Oberfläche. Bei einer Windows-Forms-Anwendung geht das Hand in Hand. Eine ListBox ist View in soweit, dass es die Daten anzeigt und Controler in soweit, als dass man z.B. durch einen Doppelklick eine Aktion auslösen kann. Im Prinzip gehört ist schon die Selektion von Einträgen zum Controller.

View und Controller liegen als m.E. nebeneinander auf einer Ebene und sind gleichwertige Seiten der gleichen Medaille. In der reinen Lehre Ich würde View und Controller also nebeneineinder zeichnen und über dem Modell (ein Pfeil von V zu M und einer von C zu M). Für die Praxis würde ich nur zwei Kästen zeichnen, einen Kasten VC über einem Kasten M (mit einem Pfeil von VC zu M).

herbivore

B
50 Beiträge seit 2005
vor 18 Jahren

Hi herbivore,

ich habe kein Problem wenn jemand Kritik übt, also musst du dich nicht entschuldigen. Ich wollte ja wissen was daran gut oder schlecht ist, oder ob es gänzlich "falsch" ist.

Ich kann im Moment gerade schlecht mehr schreiben, ich werde später noch ein paar Fragen zu deinem Post stellen.

Bis später
Bakunin

B
50 Beiträge seit 2005
vor 18 Jahren

So, jetzt die richtige Antwort.
Also würdest du das so machen: (onDruidPageMainConfigPrepare Funktion)



//VIEW
//============================DELEGATES===========================
		//public delegate void closeWindow();
		//public delegate void loadMainConfig();
		
		//============================DELEGATE EVENTS=====================
		//public event closeWindow onClose;
		//public event loadMainConfig onLoadMainConfig;
	
		public ConfigurationView (){
		}
		
		public void show(){			
			Application.Init ();

			Glade.XML gxml = new Glade.XML (null, "gui.glade", "frm_Configuration", null);
			gxml.Autoconnect (this);
                        //(.....) 
			Application.Run ();
		}
		
		public void close(){
			Application.Quit();
			//if(this.onClose != null)	this.onClose();
		}
		
		public void showErrorMessage(string Message){
                //(...)
		}
		
		public bool showQuestionDialog(string Message){
                //(...)
		}
		
		public string showFileChooser(string Message){
                //(...)
		}
		
		//============================GLADE EVENTS===================================
		private void onFrmConfigurationDeleteEvent (object sender, DeleteEventArgs a){
			this.close();
			a.RetVal = true;
		}
		
		private void onDruidPageMainConfigPrepare(object sender, EventArgs e){
			//if(this.onLoadMainConfig != null)	this.onLoadMainConfig();
            //-----------ÄNDERUNG-------------- (m_MainConfig Variable existiert noch nicht, ist jetzt nur mal zur Veranschaulichung)

			//Show the main config
			this.Server = this.m_MainConfig.DatabaseServer;
			this.User = this.m_MainConfig.DatabaseUser;
			this.Password = this.m_MainConfig.DatabasePassword;
			this.Database = this.m_MainConfig.DatabaseName;
			this.TagFile = this.m_MainConfig.TagConfigFilePath;
			this.LogFile = this.m_MainConfig.LogFilePath;
		}

Somit befindet sich der Code, der vorher im Controller abgearbeitet wurde nun im Layoutcode (also nicht View, da ja View und Controller hier vereint sind... wenn ich dich richtig verstanden habe).

Bakunin.

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo Bakunin,

leider habe ich schon den Code oben nicht so richtig geblickt. Aber wenn ich den alten und den neuen Code nebeneinander lege, finde ich zumindest nichts, was dagegen spricht, dass du es richtig verstanden hast. 🙂

herbivore

B
50 Beiträge seit 2005
vor 18 Jahren

Hi herbivore,

Dann ist ja alles gut 😉. Aber damit du weißt was sich konkret geändert hat:

Der Inhalt der Funktion onLoadMainConfig aus dem Controller, wurde direkt in das "View" übernommen. In diese Funktion onDruidPageMainConfigPrepare.

Bakunin

P
Pedro_15 Themenstarter:in
375 Beiträge seit 2005
vor 18 Jahren
Noch einmal...

Hallo,

das ist ja alles so spannend.
Ich muss aber noch etwas Fragen.

Anwendung:

  1. Erzeugen von Objekten in Modell - und von Abhängige Objekten
  2. Übergabe der Objecte an View und Erstellung des Treeviews.
  3. Bei Klick auf Treenode soll eine Methode von den Übergebenen Objecten aufgeufen werden und das Ergebnis in eine Textbox geschrieben werden.
  4. Es soll möglich sein Treenodes zu löschen.

Jetzt meine Fragen:

  1. Wie kann ich eine Abhängige Struktur so wie ein Treeview im Modell abbilden?
    Ich kann ja im Modell kein Treeview benutzen, da wir das ja trennen wollen und es geht ja auch nicht das Treeview Objekt aus das der View zu benutzen als Datenhalter.
    Object1
    ---> Object1.1
    ---> Object1.2
    Object2
    ---> Object2

  2. Wie kann ich vom Treenode Object auf das Object im Modell verweisen ,damit ich das Ergbnis bekomme und in ein Textfeld schreiben kann.
    Ein Löschen von Treenodes ist möglich, dann muss auch die Referenze im Modell gelöscht werden.

Ich hoffe, ihr könnt mir da nochmal Helfen.

Danke für die Hilfe!

Pedro

A
452 Beiträge seit 2005
vor 18 Jahren

zu 1. wenn du weisst wie viele subknoten du haben wirst, dann schreib dir eine collection, die knoten und subknoten sammeln kann kann.

zu 2. treeview1.SelectedNode. wenn du ein node ausgesucht hast musst du nur noch die view ansprechen. deine textbox wird bestimmt nichts anderes sein als eine weitere view. deshalb rate ich auch eine allgemeine view zu schreiben, die alle methoden oder eigenschaften deiner speziellen views besitzt.

dann musst du im controller nur noch die allgemeine view aufrufen und sagen was gemacht werden soll 🙂

Signatur:
Die Signatur wird unter Ihren Beiträgen dargestellt.

😁 😮 ?( 8) 😭 8o :] 🙁 =) X( 🙂 😜 😉 :rolleyes: 👶 :evil: 👅
Smilies find ich doof =]

P
Pedro_15 Themenstarter:in
375 Beiträge seit 2005
vor 18 Jahren

zu 1.
Die anzahl ist fliessend...

zu 2.
Die frage war, wie ich wieder zum Modell komme und das Ergebnis wieder in die View zurück schreibe.

Danke Pedro

A
452 Beiträge seit 2005
vor 18 Jahren

zum model kommst du indem du der view sagst 'hole mir die daten aus dem model'. <- model instanzieren/eigenschaft erstellen.

  1. Bei Klick auf Treenode soll eine Methode von den Übergebenen Objecten aufgeufen werden und das Ergebnis in eine Textbox geschrieben werden.

so wie ichs beschrieben hab...

Signatur:
Die Signatur wird unter Ihren Beiträgen dargestellt.

😁 😮 ?( 8) 😭 8o :] 🙁 =) X( 🙂 😜 😉 :rolleyes: 👶 :evil: 👅
Smilies find ich doof =]

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo Pedro_15,

Wie kann ich eine Abhängige Struktur so wie ein Treeview im Modell abbilden?

ich vermute mal, du meinst mit abhängige Struktur einfach einen Baum, aus dem die Abhängigkeiten zwischen den Modellobjekten hervorgeht.

Es gibt zwei Möglichkeiten. Entweder du schreibst dir eine eigene Knoten-Klasse und ordnest jedem Knoten ein Modellobjekt zu, also z.B.


class Knoten
{
   private List<Knoten> listknKinder;
   private Modellobjekt mobjTag;
   //...
}

oder du packst die Baumstruktur gleich in die Modellobjekte, z.B.


class Modellobjekt
{
   private List<Modellobjekt> listknKinder;
   //...
}

Unter .NET 1.1 musst du List<...> durch ArrayList ersetzen.

Wie kann ich vom Treenode Object auf das Object im Modell verweisen

Ein TreeNode hat eine Tag-Eigenschaft, in der du dir das zugehörige Modellobjekt merken kannst.

herbivore