![]() |
C/S mit Objekten - Grundsatzfrage
Liste der Anhänge anzeigen (Anzahl: 1)
Ich habe mal ansatzweise überlegt, wie so eine Anwendung strukturiert wird.
Also ich würde mir das wie in der Skizze vorstellen: Im Server gibt es eine Factory, die auf Anfrage Businessobjekte erzeugt bzw. heraus gibt. Z.B. die Schüler, Lehrer, Klassen und Zimmer einer Schule. Bei der Anfrage kann die ID des gewünschten Objektes übergeben werden. Sonst kann auch ein neues Objekt erzeugt werden. Die Factory bleigt Eigentümer der Objekte und gibt die nach einiger Zeit und vollem Puffer wieder frei. Intern werden die Daten über einen ORM aus einer Datenbank geholt. Die gesamte Geschäftslogik läuft in den Objekten, die die Factory erzeugt. Greift ein Objekt auf ein anderes zu, holt es sich entsprechend auch über die (eigene) Factory. In den Clients gibt es auch eine Factory, die eine bestimmte Menge an Objekten puffern kann und die ggf. wieder verwirft. Allerdings holt diese die Daten über ein Protokoll vom Server. Die GUI-Controls holen sich die Daten aus den Eigenschaften der Objekte, die die Factory bereit stellt. An der Stelle fällt mir ein, dass das neue LiveBinding dafür nicht taugen wird, da die GUI-Controls jeweils eine ObjektId (z.B. PersonId) und die Factory kennen, bei Bedarf von der Factory ein entsprechendes Objekt abrufen und sich dann selbst an die gewünschte Objekteigenschaft (z.B. Person.FirstName) binden müssen. Insofern wird hier das Konzept meiner bisherigen odControls in ähnlicher Form sinnvoller sein als das (durchaus interessante) LiveBinding. Die Clients müssten beauftragt werden, sich neu zu zeichnen, wenn im Server Änderungen erfolgen. Objekte haben einen Zeitstempel, in dem die letzte Änderung gespeichert wird (Uhrzeit auf dem Server). Wenn das lientobjekt den gleichen Zeitstempel hat muss das Objekt nicht neu zum Client übertragen werden. Ebenso müssen die Clients Datenänderungen natürlich an den Server schicken. Bis hierher ist mir alles so ziemlich klar und klingt machbar. Hoffe, dass Ihr mir das nicht alles um die Ohren haut... Z.B. eine Namensänderung einer Person lässt sich so recht leicht syncronisieren. Wie geht man aber mit komplexen Methodenaufrufen um, die die Geschäftslogik betreffen? Z.B. könnte es eine Methode geben TStudent.MoveToClass(Class: TClass) geben. Diese Aktion kann ja nicht im Client durchgeführt werden. Wie gibt man diese denn an den Server weiter? Als Zeichenkette, die der Server dann wieder (per RTTI?) als Objektmethode ausführt? Dann müsste aber u.U. auch wieder ein Result an den Client geschickt werden (für eine sinnvolle Reaktion der GUI und Focusänderung)!? Dann müssten die Objekte jeweils wissen, ob sie sich im Server oder Client befinden. Im Client könnten die Methoden "normal" arbeiten und im Client müssten sie eine Anweisung an den Server schicken. Gibt es irgendwo Informationen, wie solche Anwendungen arbeiten? |
AW: C/S mit Objekten - Grundsatzfrage
Zitat:
Ich bin ein großer Fan des "Service Layers" - der Client spricht mit einem zustandslosen Service Layer, das ist eine Art Interface bei dem der Client die komplexeren Aktionen wie MoveToClass als Remote Procedure Call ausführt. Auch "Remote Facade" und "Data Transfer Object" sind wichtige Patterns. Ich setze diese Patterns in Java Enterprise Edition Anwendungen an. Geht aber analog auch mit Delphi. Zwischen den Schichten wie Webanwendung (serverseitig) und Enterprise JavaBean (auch im Server) werden dann Data Transfer Objekte über eine "Facade" ausgetauscht. |
AW: C/S mit Objekten - Grundsatzfrage
Liste der Anhänge anzeigen (Anzahl: 1)
Michael, danke für den Tipp. Das Buch habe ich heute (in deutsch) bestellt und darf vor dem Kauf auch nochmal rein schauen.
Aber mal noch eine grundsätzliche Frage zur Realisierung über DataSnap. Ich würde in meinem Client ein Panel verwenden, das (wie im Bild) einen Schüler darstellt. Durch Doppelkick soll eine Funktion Student.SwipNames(Age:Integer):Boolean aufgerufen werden, die den Vornamen und Nachnamen vertauscht und ein Alter zuweist (auch wenn das natürlich recht sinnfrei ist). Implementiert wäre das etwa so:
Delphi-Quellcode:
In einer Desktopanwendung würde PanelStudent, wenn es das Student-Objekt kennt ja einfach die Methode aufrufen und gut ist.
function TStudent.SwipNames(Age_:Integer): Boolean;
var S: String; begin S := FirstName; FirstName := LastName; LastName := S; Result := (Age <> Age_); Age := Age_; end; Über DataSnap würde ja eine Persistentklasse registriert (hier mal TSchool), die im Client und Server bekannt ist. Jetzt kann der Client Methoden von TSchool ausführen, die DataSnap zum Server weiter leitet. Von TStudent direkt können aber keine Methoden ausgeführt werden - oder? Also müsste man eine neue Funktion TSchool.Student_SwipNames(Student: TStudent; Age_:Integer): Boolean bzw. TSchool.Student_SwipNames(StudentId: Integer; Age_:Integer): Boolean einführen, der das Student-Objekt oder dessen Id übergeben wird und die dann die eigentliche Funktion ausführt. Richtig? Das PanelStudent dürfte dann beim Doppelklick nicht die StudentObjekt-Methode ausführen, sondern die School-Methode auf dem Server starten. Aber es dürfte keine Methode eines im Client instanziierten Student-Objektes ausgeführt werden. Das StudentObjekt müsste sich also unterschiedlich verhalten, je nachdem ob es im Client oder auf dem Server instanziiert wurde. Oder gibt man an den Client nur reine Datenobjekte ohne jede Geschäftslogik? Ich komme da zu keinem Schluss... :duck: Funktioniert das so? Bzw. wo liege ich daneben? Wie kommt das Result zurück zum Client? Wie sieht ein Setter (z.B. set_FirstName) eines TStudent-Objektes im Client aus? Dort klassisch Value an FFirstName zuzuweisen macht ja keinen Sinn... Gibt es dazu Infos? (Sonst finde ich Demos und Erklärungen zu DataSets, die für meinen Anwendungsfall ja nicht passen.) |
AW: C/S mit Objekten - Grundsatzfrage
Also auch bei einer Desktop-Anwendung würde ich dem Model keine weiterführende Funktionalität zuweisen, sondern dieses eben auch an eine Methode einer Verwaltungsklasse übergeben.
Diese Verwaltungsklasse ist bei C/S aber nur eine Durchreiche an den Server und die Bearbeitung findet dort statt. Also statt
Delphi-Quellcode:
nehme ich lieber
TStudent.SaveTo(WhereEver);
TStudent.SwipNames(AAge : integer)
Delphi-Quellcode:
TSchoolManager.Save( ASchoolSubject : TSchoolSubject );
TSchoolManager.SwipNames( APersonSubject : TPersonSubject; AAge : Integer );
Delphi-Quellcode:
Warum?
TSchoolSubject = class
... end; TPersonSubject = class(TSchoolSubject) ... end; TStudent = class( TPersonSubject ) ... end; Der Manager weiß, ob und wenn ja wohin und wie er speichern soll. |
AW: C/S mit Objekten - Grundsatzfrage
Ok, in dem Zusammenhang klingt das plausibel. Aber die Möglichkeiten der OOP werden dadurch ja eigentlich nicht ausgeschöpft bzw. zu Gunsten anderer Aspekte zurückgefahren.
Kannst Du mal noch andeuten, wie Du dann
Delphi-Quellcode:
implementierst?
TSchoolManager.Save( ASchoolSubject : TSchoolSubject );
TSchoolManager.SwipNames( APersonSubject : TPersonSubject; AAge : Integer ); Würdest Du dann die entsprechende Ausführung letztlich doch in den übergebenen Objekten
Delphi-Quellcode:
(sofern kein Serialisierer eingesetzt würde) und
ASchoolSubject.Save
Delphi-Quellcode:
vornehmen oder die Objekte lediglich wie Records ohne Funktionalität behandeln?
APersonSubject.SwipNames(AAge)
Wenn die Funktionalität in den Objekten steckt, müsste aber sicher gestellt sein, dass diese auf den Clients (dort können die Objekte ja auch instantiiert werden) nicht ausgeführt wird (z.B. durch eine Reaktion auf einen bestimmten Wert in einem Setter). Vielleicht wäre es ja daher doch nicht so verkehrt, die Daten zwischen Server und Client als DataSets zu übertragen und nur auf dem Server mit Business-OOP zu arbeiten? Oder man erstellt reine Datenklassen, die man im Client verwendet und für den Server um die Businesslogic erweitert. Aber dann passt das mit der Übertragung nicht zusammen. Und selbst wenn man in einem Setter ggf. den Value korrigieren würde, wäre das ja schon eine Art Businesslogic!? Ach Mann - ich koche mir lieber erst mal noch einen Kakao... :gruebel: |
AW: C/S mit Objekten - Grundsatzfrage
Liste der Anhänge anzeigen (Anzahl: 1)
Im Anhang mal ein Mini-Beispiel (nur Source) mit der Speicherung in einem FlatFile.
Für alle anderen Speicherorte/-ziele (DB,XML,etc.) einfach einen entsprechende Handler schreiben. Das Model und der Manager bleiben davon unberührt ... und das ist auch gut so. Besondere Beachtung bitte der Klasse TVisitor schenken, die habe ich dem Uwe gRaabet :mrgreen: |
AW: C/S mit Objekten - Grundsatzfrage
Ok, vielen Dank für die Mühe!
Ich hoffe, dass ich Dich nicht nicht überstrapaziere - oder dass ich mich jedenfalls mal irgendwann revangieren kann! :wink: Also implementierst Du Deine Objekte als reine Datenspeicher ohne jegliche Funktionalität, die statt dessen komplett im Manager und den dazu gehörigen Klassen untergebracht wird. Der Einfachheit halber denke ich mir die Visitor und den Writer mal weg. Dann werden die Objekte an an den Manager übergeben, der die Eigenschaften der Objekte irgendwo speichert. Ok. Für die Serverseite ist das für mich soweit verständlich. Aber wie wird im Client auf Änderungen reagiert? Z.B. soll ein Edit an PersonWithId1.FirstName gebunden werden. Jeder Tastendruck soll den Personennamen an den Server übertragen und dort in der Datenschicht ändern. Mit DataBinding sehe ich da keine Möglichkeit. Es gibt ja kein Personenobjekt auf dem Client, an das sich das Edit binden kann. Das Edit müsste dazu eine Id (1), den gewünschten PropertyNamen ("FirstName") und den ClientManager kennen um bei diesem Manager ein entsprechendes Objekt abzufordern, an das es sich dann binden kann. Ein Standardedit kann das aber ja nicht. Somit müsste alternativ die GUI (z.B. in Form.Show) die Daten vom Server holen und das Edit händisch an die Daten kleben. Und Glue Code will man ja nicht mehr. :stupid: Jetzt wird es noch schwieriger... Änderungen im Edit werden nun an das Personenobjekt im Client geschickt, welches die Änderung brav in FFirstName vermerkt. Dadurch geht aber doch keine Meldung an den Server!? Statt dessen müsste doch (soweit ich das bisher durchschaue) das Edit im OnChange etwa folgendes veranlassen:
Delphi-Quellcode:
Datasnap schickt den Auftrag dann an den Server, der dann die Änderung vornimmt.
ClientManager.SetFirstName(PersonWithId1, EditFirstName.Text);
Für jede Klasse und jede Eigenschaft müsste der Manager eine entsprechende Methode bereit halten. Ist das so? Ich hoffe nicht! |
AW: C/S mit Objekten - Grundsatzfrage
Äh, nee, da hast du das Konzept noch nicht verstanden :)
Das alles ist so für den Client. Auf dem Server könnten die Daten völlig anders abgelegt sein.. Der Manager nimmt die Objekte entgegen und übergibt diese an die Datenschicht. Was diese Datenschicht damit macht ist der GUI, dem Objekt und sogar dem Manager sowas von egal. In diesem Beispiel werden die Daten in eine Textdatei gepackt. Aber wo wäre das Problem, hier etwas zu haben, was die Daten in einen Stream packt und an einen Server sendet. Oder eine email schreibt - gut das ist sinnlos, aber möglich und es würde sich keiner der restlichen Beteiligten daran stören. Warum auch, der Manager hat den Wunsch der Speicherung durchgereicht und die Datenschicht meldet zurück "ist erledigt" Jetzt wird natürlich implizit auch erwartet, dass der Wunsch des Ladens ebenso wieder erfüllt wird. Frage an den Manager, der an die Datenschicht und die muss jetzt zusehen, wie sie da rankommt. Aber jetzt mal im Ernst, warum sollte jeder Tastendruck an den Server geschickt werden? Die Oberfläche (z.B. ein Edit) bekommt einen Wert aus einem Objekt geliefert (DataBinding). Dieser kann jetzt verändert werden. Wenn alle Änderungen erfolgt sind, dann gibt es eine Entscheidung, diese Daten zu speichern. Also die Daten von der Oberfläche in das Objekt (DataBinding) und jetzt das Objekt an den Manager. Der Rest ist wie gehabt. Für eine Validierung der Daten macht es durchaus Sinn, diese vom Manager überprüfen zu lassen. Die Vorgehensweise ist die gleiche wie beim Speichern, nur dass dem Manager mitgeteilt wird, diese zu prüfen und eben nicht zu speichern. Wo die Validierung erfolgt (im Client, ein Teil auf dem Client und ein Teil auf dem Server oder ausschließlich auf dem Server) ist dem Objekt und der GUI wieder sowas von egal. Hauptsache es wurde geprüft und man bekommt zurück ob das ok ist oder wo die Fehler sind. Achja, die Frage wer holt denn jetzt die Daten? Es wird eine Entscheidung getroffen, einen TStudent mit der ID 5 zu bearbeiten (Doppelklick auf ein Listenelement einer ListView) Instanz vom Manager laden lassen EditFormular aufrufen und Instanz übergeben DataBinding übergibt die Daten an die GUI Jetzt darf getippt werden bis zum OK (oder Abbruch) DataBinding übergibt die GUI Daten an das Objekt EditFormular wird geschlossen Instanz an den Manager übertragen zum Speichern fertisch |
AW: C/S mit Objekten - Grundsatzfrage
Dann haben wir uns falsch verstanden (oder zumindest ich Dich).
Ich bin ursprünglich von einem Thin Client ausgegangen, der nur der Darstellung und Eingabe von Daten dient. Die gesamte Geschäftslogik soll im Server laufen (der evtl. einen ORM nutzt und darüber ggf. auf einen DB-Server zugreift - genau so gut könnten die Objekte des Servers aber auch persistent im Speicher gehalten werden - das würde für die Clients absolut keinen Unterschied machen). Die Clients müssen sich nur die Daten (Objekte) abholen, die sie gerade anzeigen müssen. Alles andere interessiert sie nicht. (Der Manager kümmert sich allerdings um eine Zwischenpufferung der Objekten und verwirft sie nach einiger Zeit wieder wenn sie nicht benötigt werden.) Ich will dann auch nicht ein bestimmtes Objekt (z.B. Person) händisch abrufen und beim Öffnen eines Bearbeitungsformulars mit der GUI verdrahten, sondern die GUI-Controls sollen das selbständig erledigen. Nach meinen Vorstellungen erhält das Formular einen Controller, dem eine ObjektId zugewiesen werden kann. Daraufhin öffnet er das Formular, auf dem er sich befindet und gibt die Id an alle enthaltenen GUI-Controls des Formulars weiter. Edit1.MyPropName wurde bereits zur Designtime 'FirstName' zugewiesen und Edit2.MyPropName entsprechend 'LastName'. Die Edits holen jetzt von globalen Manager das Objekt mit der betreffenden Id und binden sich (selbständig) an dessen Propertys "FirstName" bzw. "LastName". Verschachtelungen sind in diesem Szenario auch möglich. Hat z.B. eine Person ein Unterobjekt "Adress" und dieses die Eigenschaften "City" und "Street" können z.B. zwei Labels die MyPropNames "Adress.City" und "Adress.Street" zugewiesen werden. Über RTTI wird die Zuweisung dann aufgelöst und die beiden Labels an die entsprechenden Eigenschaften des Unterobjektes "Adress" gebunden. So würde ich mir das wünschen und so nutze ich das bereits in einer Desktopanwendung (jedoch noch nicht als C/S). Ob nun jeder Tastendruck zum Server gehen soll, darüber kann man natürlich unterschiedlicher Auffassung sein. Ich würde aber dahin tendieren. Spätestens mit Verlassen eines Edit-Feldes oder nach einer Eingabepause sollte eine Syncronisation erfolgen. Ändere ich im Objekt den PersonX.FirstName wird ja damit erst mal noch nichts an den Server geschickt und nichts validiert. Grundsätzlich könnte aber im Setter jeder Eigenschaft (TPerson.set_FirstName, TPerson.set_FirstName usw.) geprüft werden, ob sich das Objekt im Server oder im Client befindet (z.B. ob ein TClientManager existiert) und im letzteren Fall das Objekt zur Übertragung an den Server anmelden (Warteschlange) oder es auch sofort vom Server validieren lassen. Im Client will ich letztlich nur die Controls platzieren und die Eigenschaftsnamen zuweisen. Per Code muss dann nur die GUI-Logik geschrieben werden. Die GUI muss nichts von den Objekten wissen. Ein Framework beschafft im Hintergrund die Datenobjekte und bindet sie per RTTI an die GUI-Controls (sofern ein entsprechendes Objekt gefunden wurde und die in "MyPropName" angegebene Eigenschaft existiert - sonst wird das Control gecleart). Die BusinessLogic soll m.E. komplett im Server laufen. Der Client braucht demzufolge auch gar keine geschäftsfähigen Objekte sondern letztlich einfach nur die Daten. Die Frage ist für mich allerdings, wie man die Businesskommunikation zwischen Client und Server abwickelt, die über reine Datenänderungen hinaus gehen. Dieses Problem löst ja offenbar DataSnap, jedoch ist mir das alles zu komlex, als dass ich da einen Einstieg finde. Ein paar frühe Demovideos sahen ganz interessant aus. Das aktuelle erschlägt mich aber ziemlich. Sir, bei Deiner Zusammenfassung kann ich auch nicht komplett folgen, Sir (jedenfalls nicht in der Reihenfolge): - Instanz vom Manager laden lassen ok - EditFormular aufrufen und Instanz übergeben ok - DataBinding übergibt die Daten an die GUI Hier musst Du die Datenbindung von Hand vornehmen, oder? Entweder kannst Du klassisch Edit1.Text:=Person.FirstName vornehmen oder Du musst in ähnlicher Weise ein LiveBinding (im Quelltext) vornehmen. - Jetzt darf getippt werden bis zum OK (oder Abbruch) ok - DataBinding übergibt die GUI Daten an das Objekt Das ist missverständlich. Die Daten WURDEN bereits per LiveBinding in das Objekt geschrieben oder im anderen Fall musst Du wieder Person.FirstName:=Edit1.Text zuweisen. - EditFormular wird geschlossen Und hier muss entschieden werden, ob die neuen Daten des Objektes gespeichert (also an den Server geschickt) werden sollen (ggf. mit vorheriger Validierung) oder nicht. Dein Szenario würde ich letztlich nicht einmal als wirkliche C/S-Anwendung, sondern eher als Datenbankanwendung bezeichnen wollen (Ich biete Dir bereits hier eine Friedenspfeife an! :stupid:). Die Clients sind eigenständige Programme, die ihre Daten an einer zentralen Stelle speichern und gemeinsam darauf zugreifen. Das macht jede Datenbankanwendung so, nur dass Du die Daten in Objekten weiter verarbeitest. Oder lehne ich mich da zu weit aus dem Fenster? Oder ist es einfach schon wieder zu spät für mich? Nachti! |
AW: C/S mit Objekten - Grundsatzfrage
Zitat:
Insbesondere zum Beispiel die Validierung. Wenn ich auch nur anfange falsche Usereingaben zu machen, dann soll mich die GUI *sofort* darüber informieren - und nicht erst, wenn ich nach der Mittagspause zurück komme und auf 'speichern' drücke - und dann das ganze erst zum Server geht und dort erst validiert wird. Die Idee mit 'die Anwendung geht sofort zum Server' kannst Du unmittelbar verwerfen. Das Skaliert nicht. Der Server müsste für jeden Client ein eigenes Datenuniversum vorhalten (was ist, wenn ein User nahezu alle Daten verändert, aber nie auf Speichern klickt?). Was ist, wenn die Netzwerkverbindung ausfällt? Das ganze ist nur für extrem beschränkte Anwendungsfälle möglich, und jede kleine Anforderung die es erfordert, aus dieser 'Immer da, unendlich bandbreite, kurze Roundtrips, genug Serverkapazität'-Komfortzone auszubrechen ist mit Deiner Architektur nicht abbildbar und erfordert unmengen an Aufwand. Und natürlich kannst Du die Validierung auch nicht komplett auf den Client verschieben. Der Server kann sich niemals sicher sein, dass ein 'korrekter' Client mit ihm spricht und ihm bereits validierte Daten liefert. Er muss die Validierung zwangsläufig nochmal durchführen. Es hätte ja jemand die Kommunikation abhören können und der schickt nun gefälschte Anfragen. Rockford Lhotka hat in seinem Buch 'Expert C# 2008 Business Objects' ( ![]() Die Idee ist es, eine verteilte Anwendung so aufzuteilen, dass es egal ist, wo welche Schicht läuft. Das heisst in dem konkreten Fall einer klassischen 3-tier Anwendung (DB, Appserver & Client) läuft die absolut identische Businesslogik *sowohl* auf dem Server als auch auf dem Client. Nur so kann eine gescheite, sofortige Reaktion auf die Usereingabe erfolgen und der Server sicher sein, dass valide Daten vorliegen. Du hast aber durch diese Architektur auch sofort die Möglichkeit, dass der Appserver weggelassen wird und Du, nur durch umkonfigurieren und ausrollen einer zusätzlichen dll (die die Datenzugriffsschicht enthält) aus der 3- eine 2-Schicht Anwendung zu machen (das klassische Client/Server Modell: Client-Anwendung gegen Datenbank-Server). Aber im Prinzip versuchst Du hier |
AW: C/S mit Objekten - Grundsatzfrage
@Phoenix
Das sind interessante Ideen, aber die Umsetzung halte ich doch für recht aufwändig. Was soll man hier unter Business Logik verstehen? Ein Server ist ein Server ist ein Server. Dient z.B. dazu, referenzielle Integrität sicherzustellen. Überhaupt ist er dazu da, sämtliche Fehleingaben abzuwehren. Ein dummer Client, ohne jegliche Eingabekontrolle, sollte es nicht schaffen, Fehleingaben durchzudrücken. Wie soll sich bspw. ein intelligenter Client als Server verhalten, ohne selbst ein komplettes Datenbank-Replikat zu halten, was ja die Validierungsgrundlage ist? Business Logik lebt doch im gesamten Datenkontext, idR. ein Mehrbenutzersystem, das nicht selten auch automatisiert Daten aus 3. System verarbeitet, wie und auch warum sollte auf einer solchen Basis eine Business Operation im Client ablaufen? In vielen Fällen mag das Sinn machen, aber als pauschales Konzept scheint mir das nicht sehr sinnvoll. |
AW: C/S mit Objekten - Grundsatzfrage
Zitat:
Heutzutage geht die Entwicklung sehr Stark in Richtung 'disconnected processing'. Ein gewisses Subset des Datenuniversums (meist Stammdaten + relevante Bewegungsdaten) exisitiert auf mehreren Devices, die ohne permanente Verbindung zum 'Backend' autark arbeiten - und sich dann in mehr oder weniger regelmäßigen Abständen synchronisieren. Ggf. laufen auch immer nur Teilbereiche einer Anwendung auf diese Art (z.B. Live-Auswertungen für das Management auf Tablets). Das Problem ist hierbei, das solche Anforderungen nie von vorneherein auf der Spezifikation stehen, sondern erst später dazu kommen. Eine vernünftige Architektur sollte in der Lage sein, solche Szenarien relativ einfach zu ermöglichen - eine schlechte Architektur erschwert bzw. verhindert solche späteren Anpassungen. |
AW: C/S mit Objekten - Grundsatzfrage
@Phoenix :thumb:
Das gesamte Konstrukt ist Client/Server und nicht weil ich 2 Programme an 2 verschiedenen Orten habe. Die GUI (Client) spricht mit dem Objekt und dem Manager (Server) Der Manager (Client) spricht mit dem DatenLayer (Server) Der DatenLayer (Client) spricht mit dem Betriebssystem um die Daten zu speichern (Server) Der Clou an der Sache ist, dass der Client nicht wissen muss, wie die Verarbeitung im Server umgesetzt ist. Jeder Server kann auch ein Client eines anderen Servers sein und ist dann eigentlich nur eine Leitstelle. Dem Client davor ist das aber herzlich egal. Und wenn alles in eine Anwendung gegossen wird (weil rein Single-User-Betrieb) dann ist das bei der Umsetzung immer noch C/S |
AW: C/S mit Objekten - Grundsatzfrage
Ich habe mir "Pattern für Enterprise Application-Architekturen" gekauft. Jetzt suche ich noch jemanden, die mir Abends immer vorlesen kann. :stupid:
Das Buch behandelt schon die richtigen Themen, ich bin jedoch noch bei der Einleitung. Also mal sehen, was die Zeit bringt. Der Argumentation der geteilten Datenhaltung mag ich mich eher nicht anschließen. Sinnvoll ist das sicher dann, wenn regional unterschiedliche Daten interesssant sind, die irgendwann in einer zentralen Datenbasis zusammengeführt werden. Wenn aber mehrere Firmenmitarbeiter mit exakt den gleichen Daten arbeiten müssen, dann würde ich das nicht zweckmäßig finden. Aber danke für die Beteiligung. Ich werde mal mit einem kleinen Testprojekt herum spielen... |
AW: C/S mit Objekten - Grundsatzfrage
Wer mag, schaue mal hier:
![]() |
AW: C/S mit Objekten - Grundsatzfrage
Zitat:
|
AW: C/S mit Objekten - Grundsatzfrage
Nee, bin schwer erkältet und kann momentan nicht einladen ;-)
Habs mal auf "nicht gelistet" gestellt... |
AW: C/S mit Objekten - Grundsatzfrage
Hallo André,
wie verhält sich Dein Beispiel wenn mehrere Client gleichzeitig Änderungen vornehmen ... |
AW: C/S mit Objekten - Grundsatzfrage
Das gäbe natürlich Probleme. Die letzte Änderung würde sich durchsetzen.
Man kann/müsste sich hier überlegen, wie man eine Art abgespeckte Transaktionsverwaltung regeln könnte. Zumindest müsste es eine Sperre für bestimmte Konflikte geben. Im Moment wollte ich erst mal an die gezeigte Stelle kommen und das hat ganz gut funktioniert. Die gesamte Projektlogik läuft im "SchoolManager" und die GUI im Client bekommt zur Designtime oder Laufzeit lediglich eine ObjektId und ggf. ObjektyProperty zugewiesen. Eine 08/15-Datenbankanwendung soll mein Ansatz nicht ersetzen, ich möchte aber z.B. mein Turnierprojekt gern auf C/S umstellen und suche dafür Möglichkeiten. Ich habe auch schon einen DB-Einsatz getestet aber das hat nicht wirklich funktioniert. Dafür die die Projektstruktur einfach zu komplex und variabel. Daher will ich mit Objekten arbeiten. Auch die GUI soll die Daten in "Objekten" präsentieren, so dass der User die Spieler, Spiele, Felder usw. anfassen und verschieben kann. Grids will ich vermeiden und deshalb ist auch DataBinding und DataSnap nichts passendes für mich. Die Arbeitsweise, in den Client-Controls letztlich nur die PropertyNames einzutragen und den Rest dem Framework (sind hier letztlich nur 2 Units und die Controls) zu überlassen, hat sich für mich jedenfalls in meinem bisherigen Projekt schon sehr bewährt. Die GUI-Controls fordern (wenn sie sich zeichnen müssen) eigenständig die benötigten Objekte bei ClientManager ab. Der ClientManager holt die Objekte vom Server. Falls von dort neuere Daten kommen, weist er das Control (bzw. dessen Controller) an, sich nochmal mit den neuen Daten zu zeichnen. Natürlich fehlt da noch jede Menge (auch eine Eingabevalidierung), aber ich wollte Euch dennoch mal das erste Ergebnis zeigen und Eure Einschätzungen dazu hören. |
AW: C/S mit Objekten - Grundsatzfrage
Ich habe das Gefühl, dass du dich da etwas verrant hast.
Änderungen an Objekten sollten nur dann an den Server und dann an die Clients gesendet werden, wenn die Daten konsistent sind. Du schickst aber jede Teiländerung an die Clients, die ja noch während der Änderung in sich falsch sein kann. Somit bekommt ein Client Daten zu sehen, die unsinnig sein können. Was DataBinding zwangsweise mit Grids zu schaffen hat, ist mir auch schleierhaft. Nachvollziehen kann ich den Wunsch der Push-Funktion an alle Clients, wenn sich Daten geändert haben. Nehmen wir die Schule als Beispiel: Ein Schüler soll von Klasse A in Klasse B verlegt werden. Somit habe ich Änderungen an 3 Objekten. Aber erst wenn alle 3 Objekte im Server abgelegt sind, dann haben alle Clients Zugriff auf konsistente Daten (Transaktion) und sollten dann informiert werden und nicht früher. Sind die Daten bei Client A und B in Bearbeitung, dann ist es zudem sehr verwirrend für die Anwender, wenn sich wie durch Geisterhand die Daten verändern. Dieses Kollisions-Management (gleichzeitige Änderung von mehreren Stellen am gleichen Datensatz) kann man unterschiedlich implementieren mit mehr oder weniger Aufwand:
|
AW: C/S mit Objekten - Grundsatzfrage
Mein Video zeigt den aktuellen Stand und die grundsätzliche Arbeitsweise.
Ich möchte die Objekte (Daten und BL) auf dem Server haben und die Clients (GUI) mit möglichst geringem händischen Aufwand an diese Objekte "binden". Ich möchte nicht "Person(1)" abrufen, und die Edits mit dessen Eigenschaften verdrahten. Ich möchte nur sagen, was die Controls anzeigen sollen, die Daten sollen sie sich selbst beschaffen. Wenn man LiveBinding oder DSharp nutzt, muss man doch vom Server bestimmte Objekte oder Datensätze abrufen und kann dann die GUI anweisen, diese darzustellen. Das möchte ich aber gern automatisieren. Ich möchte normalerweise auch keine Tabellendaten in Gittern oder Daten grundsätzlich in Edits darstellen. Eine Person soll ein Objekt sein, das alle Informationen kapselt und das als Einheit verwendet werden kann. Das wird doch mit DataSnap und DataBinding schwierig - oder? Jedenfalls müsste man dann die SubControls händisch mit den untergeordneten Datenobjekten verdrahten. Werden einige GUI-Controls gezeichnet sorgen sie auch dafür, dass sie die richtigen Daten erhalten. Es ist dafür kein Quelltext im Client notwendig (sondern nur ein Eintrag in "Edit.ssfCtrl.PropName"). Darauf kam es mir an. Die GUI kann dann (z.B. bei Mengendarstellungen) dynamisch GUI-Controls erzeugen und denen die passende ObjektId zuweisen. Mehr ist nicht notwendig. Auf diese Weise kann der Datenbestand dynamisch abgebildet werden. Client-Objekte (die Daten-Kopien der BL-Objekte enthalten), die gerade nirgends angezeigt werden (z.B. weil ein Formular geschlossen wurde) können wieder verworfen werden. Wird das Formular geöffnet, werden sie einfach neu abgerufen. Also nur die Daten, die angezeigt werden, sind dem Client bekannt. Dass es eine Konfliktbehandlung geben muss ist klar. (Ich habe ja bisher lediglich versucht, die Datenübertragung und Datenbindung zu realisieren.) Auch wenn es nicht ganz so einfach wird: Der ClientManager kann ja grundsätzlich angewiesen werden, mit der Speicherung der Datenänderungen zum Server zu warten bis - eine Validierung der Änderungen erfolgt ist (dazu müsste allerdings auch beim Server angefragt werden) und/oder - der User "Ok" drückt. Wie gesagt, mir ging es erst mal vorrangig um die Datenübertragung und Datenbindung. |
AW: C/S mit Objekten - Grundsatzfrage
Zitat:
Delphi-Quellcode:
procedure TSchoolManager.SwipNames( ASchoolSubjectID : TSchoolSubjectID; AAge : Integer );
anstatt dem Service ein "komplettes" Objekt zu übergeben, was unter Umständen wiederum Unterobjekte / Listen von Objekten enthält, würde nur seine ID benutzt (die ein einfaches Integer Feld, eine GUID oder auch eine aus mehreren Elementen zusammengesetzte Struktur sein kann). Diese wird serialisiert an den Server gesendet, der dann die gewünschte Operation mit dem Objekt ausführt. Auftretende Fehler würde ich per (serialisierter) Exception an den Client zurücksenden. Bei einer serviceorientierten Architektur wäre der Service, der den TSchoolManager implementiert, komplett zustandslos, das bedeutet das die Anwendungslogik im Client liegt. |
AW: C/S mit Objekten - Grundsatzfrage
Dass über das Protokoll eine ObjektId übertragen wird ist schon klar.
Ich meinte mit meiner Frage, ob Du dann die Ausführung im Objekt "TPerson.SwipNames(...)" durchführen würdest (also Objekte auch Businessfunktionalitäten ausführen können) oder ob Du das grundsätzlich vermeiden (und nur vom Manager aus, also von außen, den Tausch der Werte des Objektes vornehmen) würdest. Inzwischen hat sich die Frage für mich aber erübrigt, da in meinem aktuellen Test im Client kein TPerson-Objekt erzeugt wird sondern lediglich TClientDataObjekte, die als Datenspeicher dienen. Realisiert wird das über eine StringList und dessen Names und Values.
Delphi-Quellcode:
Der Client und die ClientDataObjekte wissen somit nichts von den eigentlichen Geschäftsobjekten (abgesehen davon, dass man noch so eine Art ClassName zuweisen kann, den der Client bei Bedarf interpretieren kann).
TClientDataObject = class(TComponent)
private FId: TssfId; FTS: TDateTime; FSL: TStringList; FLTS: TDateTime; public constructor Create(Owner: TComponent); override; destructor Destroy; override; published property Id: TssfId read FId write FId; property TS: TDateTime read FTS write FTS; property SL: TStringList read FSL write FSL; property LTS: TDateTime read FLTS; end; Es ist somit möglich, die Businessobjekte mit einer vollständigen Funktionalität auszustatten, ohne dass dies auf dem Client störend sein könnte. Auf dem Client müsste lediglich die GUI-Logik laufen, die ggf. beim Server die benötigten Informationen abholt. |
AW: C/S mit Objekten - Grundsatzfrage
Zitat:
Komplex wird es dann wenn ein Businessobjekt auch Objekt-Properties haben kann, wie Person.Adresse - wie soll das Adress-Objekt auf den Client abgebildet und angesprochen werden? |
AW: C/S mit Objekten - Grundsatzfrage
Mal in´s Unreine:
Es gibt ein Datenobjekt 1, das Personendaten enthält:
Code:
und
Objekt1
#Id=1 #TS=Uhrzeit der letzten Änderung #ClassName=Person (Für Interpretationen auf dem Client) FirstName=André LastName=Stahl Adress=2 (Id)
Code:
(wobei die ID´s GUID´s o.ä. sind)
Objekt2
#Id=2 #TS=Uhrzeit der letzten Änderung #ClassName=Adress (Für Interpretationen auf dem Client) Country=Halle Street=Pekinger Str Wenn ein Edit Id=1 und PropName='FirstName' zugewiesen bekommt, holt es sich vom Manager Objekt1 und nutzt (wenn vorhanden) dessen Eigenschaft FirstName. Ein anderes Edit soll Id=2 und PropName='Street' verwenden. Das macht dann keinen Unterschied und es ist egal, welche Businessobjekte da letztlich representiert werden. Ein drittes Edit kann aber auch einfach PropName='Adress.Country' zugewiesen bekommen. Wenn es z.B. in einem Bearbeitungsformular für eine Person liegt würde das Formular die PersonenId erhalten und diese an alle untergeordneten Controls weiter geben. Das Country-Edit würde zunächst nun das Objekt1 beim Manager abrufen, wobei der auf Grund des Punktes in PropertyName noch prüft ob Objekt1.Adress eine gültige Id enthält und dann statt dem Objekt1 eben das Objekt2 zurück gibt und dessen Eigenschaft "Country" weiter verwendet wird. Intern gibt es daher tatsächlich die Eigenschaften: - Id - PropName - usedId - usedPropName Der Manager kümmert sich also sebständig um die Auflösung von Unterobjekten. |
AW: C/S mit Objekten - Grundsatzfrage
Nur mal so eine Grundfrage, wie das bei der Tuniersoftware gedacht ist. Wo liegen dann Client und Server? Auf verschiedenen Computern? Was ist, wenn dann mal keine Verbindung besteht? Kann der Client dann allein weiter machen oder muss das Tunier ausfallen?
Frage nur so aus Neugier, da ich am WE mein Patenkind auf einem Tischtennistunier besucht habe und da war auch irgendeine Software am laufen. Da wurden immer wieder Paarungen ausgedruckt und an auf die vorhandenen "Platten" verteilt. Die Eingetragenen Ergebnisse mussten dann ruckzuck an den Mann mit dem Notebook gegeben werden, der das dann eingetragen hat, woraus sich dann wieder neue Paarungen ergaben, usw. Hinterher müssen diese Daten wohl auch auf einer speziellen Webseite des Verbandes hochgeladen werden für sowas wie die Gesamt-Rang-Liste. |
AW: C/S mit Objekten - Grundsatzfrage
Guter Einwurf!
Mein Sohn spielt in einem Fussballclub welcher dieses Jahr das erste Mal das Dorfturnier durchgeführt hat. Der Club hat dann auch so ne Software gekauft (nicht von Stahli). Das war eine einzige Katastrophe. Denn es sollte doch zumindest möglich sein auf den verschiedenen Plätzen die Ergebnisse einzutragen (clients). Und dann von mir aus via Lan oder Datei oder weiss der Geier irgendwie mit dem Server zu synchronisieren. Aber auch hier wurden dann Zettel ausgedruckt zur Zentrale gerannt, dort wieder abgeschrieben... Kann ja wohl nicht wahr sein? |
AW: C/S mit Objekten - Grundsatzfrage
@Jumpy
Meine aktuelle Turniersoftware [SchleichWerbung], die übrigens auch und gerade für Tischtennis sehr geeignet ist :wink:[/SchleichWerbung] hat zwar bereits eine Trennung von GUI und BL, ermöglicht jedoch nicht den Zugriff mehrer Clients auf die Daten. GUI und Objekte müssen derzeit in der selben Anwendung existieren. Innerhalb der Anwendung funktionieren die Objekte allerdings schon autark. Die Objekte benötigen also keinen Zugang zur GUI und die GUI auch keinen (direkten) Zugang zu den Objekten. Die Vermittlung übernimmt eine Zwischenschicht. Die Programmlogik wird also niemals irgendwo nachsehen, ob im FormularXy.CheckBoxZ.Checked gesetzt ist. Die Programmlogik weiß nicht einmal welche Formulare das gibt und ob überhaupt eine GUI existiert. An dieser Grundlage soll sich auch nichts ändern. Jedoch soll es möglich sein, mehrere Clients (auch auf verschiedenen PC´s) mit den Daten zu bedienen. Im Server soll der gesamte Turnierzustand verwaltet werden. Die Clients können dann auf den Server zugreifen, die Daten abrufen und Änderungen initiieren. Der Server kann dann (das wird der Regelfall sein) mit einem (Haupt-)Client auf einem PC laufen, so dass ein Netzwerkausfall unschädlich wäre, während weitere Clients über ein Netzwerk zugreifen könnten. Es wäre aber auch ein emebeded Server möglich, so dass Client und Server in einer Anwendung laufen und somit der Server nur genutzt wird um eine eindeutige Trennung zwischen GUI und BL zu gewährleisten und ggf. später doch externe Clients anzubinden. Also für den Anwender müsste sich grundsätzlich nichts ändern, außer dass man Alternativen für weitere Clients erhält. @taveuni Mein Programm unterstützt auch Mannschaftssportarten wie Fußball. Aber ich bin erhrlich gesagt nicht so recht überzeugt, dass man dafür eine Software benötigt. Ein Spiel läuft 2 Stunden. Dann kann man das Ergebnis per Handy durchgeben und erhält von mir aus per Mail einen aktuellen Zwischenstand. Alternativ wäre eine Website denkbar, in der nach Anmeldung die Punkte eingetragen werden könnten. Vielleicht habe ich auch falsche Vorstellungen von dem Turnier, aber irgendwie erschließt sich mir der Nutzen einer netzwerkbasierten Software nicht recht dafür. Wenn mein Projekt sich wie erhofft weiter entwickelt, dann würde es eine solches Turnier aber unterstützen (jedenfalls wenn ein Netzwerk vorhanden wäre - wie das über Internet ginge, kann ich derzeit nicht beurteilen). Im Gegensatz zu Mannschaftssportarten ist der Verwaltungsaufwand bei Tischtennis, Badminton usw. sehr viel höher, da die Platten oder Felder sehr viel stärker frequentiert werden und da die Teilnehmer in einem Turnier oft in unterschiedlicher Weise und mit unterschiedlichen Partnern spielen müssen. Es herrscht also ein ziemliches Durcheinander, das ohne Software kaum sinnvoll zu beherrschen ist. Wird ein Feld frei, muss die Turnierleitung entscheiden, wen sie als nächstes aufruft. Es müssen alle noch zu absolvierenden Spiele gepüft werden, ob alle beteiligtenj Spieler gerade verfügbar sind und wann sie zuletzt gespielt haben. Dann spielt aber auch der bisherige Turnierverlauf und die Zeitplanung für die Entscheidung noch eine Rolle. Beim Fußball ist das alles natürlich deutlich einfacher. Aber da spielt man ja auch sowiso nur mit dem Fuß. :mrgreen: |
AW: C/S mit Objekten - Grundsatzfrage
Also bei unserem Dorfturnier (und wir sind eine kleine Gemeinde) welche einmal im Jahr stattfindet war es dieses Jahr so:
- 135 Mannschaften - Mannschaften in 5-er Gruppen (Durchschnitt) round robin. - 3 Fussballplätze - Spieldauer Junioren 2x6 Minuten, Erwachsene 2x10 Minuten. - Achtelfinals, Viertelfinals, Halbfinals, Final. - Pause zwischen den Spielen 30 Sekunden. Das alles in 2 Tagen! Also auch hier ist viel Dynamik in der Luft. Wenn die Gruppenspiele dem Ende entgegen gehen wollen/müssen die Mannschaften ziemlich kurzfristig wissen wo und wann das nächste Spiel gegen welchen Gegner usw. Viele "Veranstalter" (Vereine) versuchen das mit Excel und Makros irgendwie hinzukriegen. Ich träume von einer (verteilten) Software welche das verwaltet. Spielausfälle usw. automatisch verarbeitet. Zwischenranglisten und Spielpläne dynamisch (Webserver) zur Verfügung stellt usw. Also los ans Werk! Sonst setz ich mich selbst mal dran :x |
AW: C/S mit Objekten - Grundsatzfrage
Aha, also fast Badminton mit rundem Ball und Fuß... ;-)
Vorschlag: Ihr könnt Euch ja mal mein (aktuelles) Programm ansehen, ob das grundsätzlich nützlich wäre. Mannschaftssportarten kann es ja auch verwalten. Wenn Du mir per pn Deine Mailadresse schreibst, schicke ich Dir auch gern eine Testlizenz, damit Du alle Möglichkeiten nutzen und Turniere speichern kannst. Eine verteilte Anwendung habe ich im Moment noch nicht, will das ja aber mal in Angriff nehmen (incl. einer Überarbeitung der gesamten Objektverwaltung). |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:06 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz