Laden...

Aufgemerkt, warum OOP?

Erstellt von Kostas vor 18 Jahren Letzter Beitrag vor 18 Jahren 10.995 Views
K
Kostas Themenstarter:in
597 Beiträge seit 2005
vor 18 Jahren
Aufgemerkt, warum OOP?

Hallo Zusammen,

ich weis, darüber gibt es tonnenweise Berichte im Forum
und sonst wo.
Aber ich konnte noch nicht richtig erkennen wann es
sinnvoll ist eine App komplett in Objekte zu packen.

Ich hoffe das jetzt ein Leser dabei ist der OOP verinnerlicht hat
und mir den nötigen kick geben kann.

Eine meiner Anwendungen ist eine Win32 Datenbank-Anwendung
unter Delphi welche aus 178 Tabellen und 1291 Feldern besteht. (Stand Heute)

Wenn ich mir vorstelle das alles in Klassen zu packen
und für jedes Feld ein Geter uns Seter zu definieren, wird mir
ganz Übel. Noch zudem ist mir nicht klar wie die Bindung an die
unzähligen Textboxes, Checkboxes, Grids u.s.w. durchgeführt wird
wenn die Daten in Objeke liegen und nicht in DataSets.

Verwende ich typisierte Datesets, hätte ich zwar immer noch
deutlich mehr Aufwand gegenüber Delphi, aber das könnte man
verkraften.

Es ist doch so, das je mehr Code von mir selbst geschrieben wird
desto mehr Fehler sind enthalten. Das dürfte das Gegenargument
zu OO sein. Da wird immer damit geworben das der Code
übersichtlicher und leichter wartbar bleibt. Alleine schon die Tipparbeit
würde das in meinem Projekt widerlegt.

Ich glaube jedoch Unrecht zu haben, resultierend durch meine Unwissenheit.
Leider kann ich den Nutzen von OOP NOCH nicht erkennen.
Durch C# habe ich jetzt die einmalige Chance, weil Neubeginn,
mich im OOP zu beschäftigen, und das will ich auch ernsthaft tun.

Gruß Kostas

P
939 Beiträge seit 2003
vor 18 Jahren

Es gibt Vorteile, aber auch Nachteile, OOP macht nicht immer Sinn. Wenn es beispielsweise wenig Logik und wenig Datenstruktur, dafür aber viele Daten gibt und es auf Geschwindigkeit ankommt, ist Objekt-Orientierung fehl am Platz. Das trifft z.B. auf Datenbank-Massendaten, DSP oder Shader-Programmierung zu.

In deiner Anwendung scheint mir Objektorientierung jedoch hilfreich zu sein, da es eine komplexe Datenstruktur gibt.

Bei OOP geht es ganz allgemein um die Abbildung eines Teils der realen Welt auf Klassen - auf ein sogenanntes Objektmodell. Das Objektmodell ist unabhängig von der Art der Anwendung (Web, Gui, Konsole ...) konzipiert, in der es verwendet wird. Es enthält nur Daten und definiert Operationen auf diesen. Das ganze sollte modular gehalten sein. D.h. das Objektmodell braucht nicht zu wissen, dass es in einer Datenbank gespeichert wird, es gibt einen Datenbank-Service, dem man es übergeben kann. Genauso wenig muss es wissen, dass es eine GUI gibt, die es anzeigt oder eine Druck-Komponente, die es formatiert und ausdruckt, - einen Web-Server, einen Berichtsgenerator usw. Da das Objektmodell so einfach und allgemein gehalten ist. Insbesondere, da es nicht innerhalb der GUI-Klassen implementiert ist, können leicht neue Services hinzuimplementiert werden und es kann in anderen Umgebungen verwendet werden, Ausdrucken per Kommandozeile beispielsweise.

Deine Anwendung liesse sich sauber trennen in App.exe, Core.dll, Gui.dll, und Db.ll. App.exe kennt alle drei Dlls. Core.dll mit dem Objektmodell kennt nur sich selbst. Gui.dll kennt u.U. Core.dll (obwohl es auch möglich ist, die Gui unabhängig vom Objektmodell zu implementieren). Und Db.dll kennt Core.dll.

So stehen einem alle Möglichkeiten offen. Wie schon oben geschrieben, kann man nun Core.dll und Db.dll nehmen, um Webseiten zu rendern oder auszudrucken. Genauso gut ist es auch möglich, Db.dll durch eine WebService.dll ersetzen, um Objektmodell-Daten bei einem WebService anzufordern.

Aber Flexibität und Modularität muss man sich meistens mit mehr Code erkaufen, das stimmt schon. Durch die einfachere, aufgeräumte Schnittstelle und durch die leichtere Wiederverwendbarkeit sollte im Endeffekt der aber Aufwand sinken, hoffentlich.

Gruss
Pulpapex

-
885 Beiträge seit 2004
vor 18 Jahren

Pulpapex ich habe eine annähernd ähnliche Frage und bin mir nicht sicher ob ich einen neuen Thread aufmachen soll. Ich poste es mal hier:

Dieses Prinzip mit "App.exe, Core.dll, Gui.dll, und Db.dll" hört sich interessant an. Mich würde interessieren, wie ich die Dlls untereinander (so wie von dir beschrieben) "bekannt" mache, damit ich auf dessen Methode zugreifen kann. Das Ganze hat den Hintergrund, dass ich gerade dabei bin mein Projekt umzustrukturieren und ich genau dieses Prinzip anwenden wollte. Mein Freund erzählte mir etwas von "Interfaces"?! Naja auf jeden Fall würde es mich brennend interessieren, wo es darüber Infos gibt.

P.S.: Bei Codeproject blieb meine Suche erfolglos, warscheinlich aber nur, weil ich falsch gesucht habe.

3.728 Beiträge seit 2005
vor 18 Jahren
Wann Objekte

Für Datenbankprojekte wie Deins mit über 170 Tabellen halte ich es für Schwachsinn alles in Objekt zu packen. Objekte sind ressourcenfressend und unflexibel aber auch typsicher und komfortabel. Eine Anwendung wie Word oder Photoshop braucht ein Objektmodell. Bei solchen Anwendungen ist das super. Bei datenbankgestützten Geschäftsanwendungen bringt es aus meiner Sicht mehr Nachteile als Vorteile.

Es muss nur ein neues Feld in einer der Tabellen hinzukommen, schon ist die Hölle los mit Objekten. Neue Getter und Setter müssen eingefügt werden , alles neu übersetzen und je nach Architektur auf dem Anwendungsserver bzw. sämtlichen Clients neu deployen. Oft ein ganzer Tag Arbeit, nur weil ein zusätzliches Bemerkungsfeld eingefügt werden muss.

Besser sind statuslose Geschäftskomponenten, die sämtliche Geschäftslogik kapseln. Die laufen hervorragend auf einem Applikationsserver (z.B. Enterprise Services). Für den Datentransport DataTables/DataSets (keine typisierten DataSets). Wenn eine Komponente über die Firewall hinweg kommunizieren muss, verpasst man ihr per Klick im COM+ Katalog eine SOAP-Webservice Schnittstelle. Die Anwendung besteht letztendlich aus vielen kleinen unabhängigen Komponenten, die über definierte Schnittstellen miteinander kommunizieren. Ab besten die Komponenten sind nicht über Verweise fest verdrahtet, sondern über ein Microkernel Framework. Jede Komponente kapselt Geschäftslogik zu einem bestimmten Thema (z.B. Adressverwaltung). Die GUI ist auch aus Komponenten zusammengesetzt (Ein Control das z.B. Verkaufspreise auflistet wird an vielen Stellen in der GUI gebraucht). Man erstellt sich einen Baukasten aus Komponenten für Datenzugriff, Geschäftslogik, Authentifizierung/Sicherheit und Anzeige.

Mit diesem Modell habe ich sehr gute Erfahrungen gemacht.

K
Kostas Themenstarter:in
597 Beiträge seit 2005
vor 18 Jahren

Hallo Rainbird,

wenn ich Dich richtig verstanden habe, würdest Du den weg ohne typisierte Datasetzt
gehen. Rechnet sich den dieser mehraufwand?
Und wie schätzt Du den Nutzen von OR-Mappern wie z.B.: NDO
bei etwas grösseren Projekten ein?

Gruß Kostas

S
8.746 Beiträge seit 2005
vor 18 Jahren

Objektorientierung ist eine Methode des kleinen und mittleren Maßstabes. OO ist keine Alternative zu Komponenten oder SOA, sondern ist ein Mittel diese umzusetzen.

Ob es lohnt, den Bruch zwischen der OO- und der relationaler Sicht über einen O/R-Mapper bzw. per Hand zu schliessen, hängt doch stark von Einzelfall ab. M.E. lohnt es immer dann, wenn das reine Daten-Retrieval nur einen kleinen Teil der Datenlogik ausmacht. Wer einfach nur simple Abfragen visualisieren muss, der ist mit einem relationalen Ansatz (DataSets) gut bedient. Ich persönlich empfinde das Arbeiten mit Objeken deutlich komfortabler (mit den damit verbundenen Produktivitätsgewinnen). Unterm Strich muss es sich aber rechnen.

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo -acid-,

Pulpapex ich habe eine annähernd ähnliche Frage und bin mir nicht sicher ob ich einen neuen Thread aufmachen soll.

die Frage ist schon ziemlich Off-topic. Deshalb nur kurz: du brauchst keine Interfaces. Du musst nur in dem Projekt, wo du Klassen aus einer DLL benutzen willst, diese DLL als Referenz hinzufügen. Gibt schon mehrere Threads zu dem Thema.

herbivore

7 Beiträge seit 2005
vor 18 Jahren

Und dennoch stimme ich der Antwort von Pulaplex vollkommen zu. Natürlich muß man abwägen ob es sich lohnt ein OO-Modell zu konzipieren, denn es verbrauch viel Zeit diese Modelle zu entwerfen und zu konstruieren. Aber auf der anderen Seite gibt es viele Tools die einem die Arbeit damit erleichten, und in großen Projekten kann man klare Schnittstellen definieren.

Hab ich nun ein Programmierteam und definiere feste Schnittstellen, so hab ich die Möglichkeit um diese Schnittstellen herum ein Konstrukt zu erstellen was leicht skalierbar, wartbar und verständlich ist.

Letzendlich bestimmt die Erfahrung des Programmierers welches Modell er vorzieht und wie die Qualität des Modells ist.

Ich bin eher jemand der sehr viele kleine Anwendungen schreibt, und zudem auch noch im Lernstadium ist, aber ich habe schon viele klare Vorteile in der OO-Programmierung kennengelernt.

Nur um einige kleine Beispiele zu nennen, bastele ich an einem Blog der auf SQL mit PHP basiert. Dort habe ich durch OO die Möglichkeit sehr einfach Inhaltsobjekte zu erzeugen und kann das ganze Projekt wunderbar skalieren. Die SQL abfragen sind gekapselt und der eigentliche Content, ist in Klassen verpackt die überhaupt nicht interessiert wo sie nun dargestellt werden.

Ein anderes Projekt ist ein Disassembler für S7. Dort hab ich mir ein Inteface definiert und verschiedene OPCODE-Klassen die alle von diesem Interface erben. so habe ich die Möglichkeit auf einfachste Weise meine OPCODE-Klassen zu erweitern ohne das ich alles auseinanderreißen muß.

Letzendlich kommt es allerdings auch auf das Projekt an. Manchmal lohnt sich OO-Programmierung einfach nicht. Siehe Schnittstellenporogrammierung.

4.506 Beiträge seit 2004
vor 18 Jahren

Hallo zusammen!

Mal OOP hin, oder her, genauso ob Mehraufwand, oder nicht.

Es gibt Vor- und Nachteile.

Aber was ich persönlich finde, ist es so abstrakt wie möglich zu gestalten. Also wenn z.B. eine neue DB-Spalte hinzukommt, dann sollte so weit wie möglich alles automatisiert sein, dass das in das Konzept mit integriert wird.

Also z.B. die ganze Arbeit im OOP-Modell, mit dem Get und Set sollte automatisch generiert werden, und bestenfalls automatisch kompiliert und dynamisch eingebunden werden können.

Dann ist es nur noch eine Frage der Rechnerperformance und Speicherbelegung, welches Modell man nun wählt. Aber es ist keine Frage mehr wie viel Aufwand hat der Programmierer damit.

Ich weiß, dass es wunschdenken ist, so etwas in der realen Welt zu produzieren, denn es steht immer der Chef hintendran und sorgt dafür, dass man schnell und nicht super zu dem Ziel kommt.

Was will ich damit sagen:
Für Kostas ist es einmal wirklich mehr Aufwand das ganze zu konzipieren. Aber danach sollten Modifikationen und Erweiterungen möglichst automatisiert mitintegriert werden können. (wenn man es "richtig" macht)

Ciao
Norman-Timo

A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”

3.728 Beiträge seit 2005
vor 18 Jahren
Datenabfragen

Ich halte von OR-Mappern bei größeren datenbankbasierten Projekten in den meisten Fällen nichts. Es kommt dabei stark auf die Art des Datenzugriffs an. Dinge wie Summenbildung etc. sind bei Objekten mit verhältnismäßig hohem Aufwand möglich.

Außerdem kann dem Applikationsserver bei vielen gleichzeitigen Benutzern schnell der Hauptspeicher ausgehen, wenn er alles in Objektmodelle einpacken muss.

Der Aufwand bei nicht typisierten DataSets (Ich arbeite nur auf dem Client mit DataSets , die Geschäftslogik arbeitet meistens nur mit DataTables) hält sich gering, wenn man sich eine gute Datenzugriffskomponente schreibt.

S
8.746 Beiträge seit 2005
vor 18 Jahren

Bei großen Anwendungen sollte man das Deplyoment und Migrationsproblem wirklich nicht unterschätzen. Genau hier kann die strenge Typisisierung zur Falle werden, da das Ausrollen von Client und Server zur gleichen Zeit zur Pflicht wird. Hier bieten sich untypisierte Verfahren wirklich an, egal ob DataSet oder XML. Das gilt aber wirklich nur für die Schicht, die Client und Server verbindet. Auf dem Server selbst kann voll typisiert gearbeitet werden ohne daraus einen Nachteil zu generieren.

Was aus meiner Sicht selten Sinn macht, ist das Verkapseln eines relationalen Modells mit ein paar Objekten. Wenn man mit OO auf der Datenhaltungsschicht arbeitet, dann nur mit einem OO-Modell als Ausgangsbasis. Gerade bei komplexen Beziehungsstrukturen wird das zur einer Arbeitsersparnis, weil O/R-Mapper die DB-Schemata oft fehlerfreier und besser erzeugen, als das die meisten Leute per Hand können. Auch das dröge Erstellen von Beziehungstaballen wird einem abgenommen.

S
1.047 Beiträge seit 2005
vor 18 Jahren

zwar nicht direkt zum thema, aber nochmal zu dem oo und datenbanken:

gibts irgendwo eine richtige gute datenbankanwendung mit sourcecode die man mal als grundlagen nehmen kann zum veranschaulichen "so macht man das" im bezug auf schichtentrennung, datenbankzugriff usw.?

ich les immer nur die theoretischen sachen, von wegen dal und so, aber nie eine richtige beispielanwendung bzw code... 😕

S
8.746 Beiträge seit 2005
vor 18 Jahren

Schau mal bei MS unter dem Stichwort DAL rein.

3.728 Beiträge seit 2005
vor 18 Jahren
Gral

Es gibt keinen Heiligen Gral!

Man kann nicht sagen: "So macht man das und fertig!".

Beispielanwendungen können immer nur einzlne Konzepte verständlich machen. Und hätte man wirklich so eine komplette große Referenzanwendung, dann wäre man viele Monate damit beschäftigt, erstmal den Code richtig zu verstehen (Warum hat der das an der Stelle jetzt so gemacht und nicht so ...).

Anwendungen wachsen aus Anforderungen. Anforderungen ändern sich, deshalb ändern sich auch Anwendungen.

S
1.047 Beiträge seit 2005
vor 18 Jahren

Original von Rainbird
Es gibt keinen Heiligen Gral!

Man kann nicht sagen: "So macht man das und fertig!".

Beispielanwendungen können immer nur einzlne Konzepte verständlich machen. Und hätte man wirklich so eine komplette große Referenzanwendung, dann wäre man viele Monate damit beschäftigt, erstmal den Code richtig zu verstehen (Warum hat der das an der Stelle jetzt so gemacht und nicht so ...).

Anwendungen wachsen aus Anforderungen. Anforderungen ändern sich, deshalb ändern sich auch Anwendungen. ok, geb ich dir recht
vielleicht hab ich mich auch falsch ausgedrückt...

glaub ich programmier mir mal was zusamen und frag dann nach eurer meinung dazu... dann gibts auch eine diskussionsgrundlage und man kann mal die verschiedenen ansichten sich anschauen 🙂

K
Kostas Themenstarter:in
597 Beiträge seit 2005
vor 18 Jahren

Hallo zusammen,

Ich sympadisiere mit dem Microkernel Framework denn dadurch
Zwinge ich mich automatisch dazu Schnittstellen bereit zu stellen.
Aber auch mit typisierte Datasets um möglichst vielle Fehlerqullen
Zu umgehen.

Leider ist beides vereint nach meinem Wissensstand nicht moglich.
Oder vieleicht doch irgendwie?

Typisierte Datasets sich aber auch nützlich

Ich meiner Microkernel Klasse habe ich eine Methode:



public void ReadWithPK(enumTbl id, DataSet ds, int PKID)
{
	IPK pk = null;
	switch (id)
	{
		case enumTbl.Beleg: pk = new CBelege(); break;
        case enumTbl.BelegPos: pk = new CBelegPos(); break;
    }

	pk.getPK(ds, PKID);

}


Mit nur ein paar solche Methoden im Microkernel komme ich
an sämtliche Daten auch bei hunderte von Tabellen.
Eigentlich eine tolle Sache. Setzt allerdings ein DataSet voraus
welches als Parameter übergeben wird. Und somit nicht typisierte Datasets.

Gibt es irgend eine Technik um ein typisiertes Dataset übergebern zu können?

Gruß Kostas

S
8.746 Beiträge seit 2005
vor 18 Jahren

Sagt mal, wer hat eigentlich diesen komischen Begriff "microkernel framework" geprägt? Was soll denn das aussagen? Offenbar wird "microkernel" synonym zu "Inversion of control" gebraucht.

Aber was zum Geier hat das mit Microkernels zu tun, die ja nun eine völlig andere Bedeutung in der IT haben?

K
Kostas Themenstarter:in
597 Beiträge seit 2005
vor 18 Jahren

Sorry Svenson wenn ich was durcheinander gebracht habe.
Meine aussagen, kommentare und insbesondere der Code hat
den Anfänger-Status.

Sorry nochmal.

Gruß Kostas

P.S. Was versteht man bitte unter "microkernel framework"
in knappen Worten.

S
8.746 Beiträge seit 2005
vor 18 Jahren

Nee, macht ja nix. War ein willkommener Aufhänger, weil mir das in letzter Zeit schon ein paar mal über den Weg gelaufen ist. Wenn man mal danach googelt, bekommt man erstaunlich wenige Hits. Die Beziehung wurde mir nur durch den Artikel in der DOTNET.PRO klar, sowie durch einen Link, indem Spring als ein solches Framework bezeichnet wurde.

Im Prinzip ist die Bedeutung auch ableitbar: Solche Frameworks stellen ja auf eine gewisse Art und Weise den Infrastruktur-Kern der Anwendung dar, weil sie die Komponenten verbinden.

Mich interessiert aber primär, woher der Begriff stammt und wer ihn geprägt hat, und wo die Abgrenzungen zu IoC zu sehen ist (IoC = Konzept, Microkernel framework = Umsetzung?).

3.728 Beiträge seit 2005
vor 18 Jahren
Os

Ich glaube der Begriff kommt aus der Betriebssystem Entwicklung.

http://de.wikipedia.org/wiki/Microkernel

S
8.746 Beiträge seit 2005
vor 18 Jahren

Ja, paßt natürlich weil Microkernel-BS - ebenso wie IoC-Frameworks - die BS- (bzw. Applikations-) Komponenten erst zur Laufzeit binden und nicht zu einem monolithischen Kern compiliert sind.

432 Beiträge seit 2005
vor 18 Jahren

hi kostas,

ich habe zwei projekte deiner dimension, die ich in den nächsten monaten von access frontend auf c# portieren werde. die daten liegen auf einem sql server 2000. als ich mit c# angefangen habe, waren meine fragen im grunde die gleichen wie deine; ich habe mich für nachstehendes konzept entschieden und fahre damit gut, daher hier in kürze die architektur:
1.ich packe ca. 60-80 % der geschäftslogik in stored procedures, udf´s und trigger (das habe ich schon immer so gemacht, auch mit dem access frontend) 1.eine selbstgeschriebene singleton wrapper klasse übernimmt meine aufrufe von SP´s und UDF´s, in dem sinne, dass ich mich bei aufruf nicht mehr um die namen der parameter kümmern muss 1.Der wrapper ist der einzige kerl in meiner anwendung, der ein dataset kennt und das ist untypisiert; für meine projekte habe ich nämlich keinen grund gefunden, jemals ein typisiertes DataSet zu verwenden (vielleicht kann mir jemand hier mal einen nennen...?) 1.mein desktop ist eine leere hülle, die alle datenansichten nur aus DLL´s lädt 1.jede datenansicht ist eine DLL; der verbleibende teil evtl. geschäftslogik kommt hier zum liegen und alle DLL´s benutzen den singleton wrapper

was mich hierhin gebracht hat, war folgender ansatz:
Änderungen am Datenmodell betreffen immer einen teil der GUI, weil felder auch gefüllt/gepflegt werden wollen. habe ich jetzt also eine änderung, passe ich nur die zuständige DLL an, kompiliere sie und liefere sie neu aus.
die anwendung muss nicht angefasst werden. selbst wenn ganze tabellen und geschäftsprozesse dazukommen, weil alle dll´s namentlich in einer eigenen tabelle der DB registriert sind. die anwendung lädt eben einfach alles bei bedarf.

hth, ron

**PS zu deinem beispielcode **(public void ReadWithPK(enumTbl id...)...):
etwas ähnliches habe ich auch gemacht, allerdings ebenfalls auf SP Basis. in meinen datenbanken heissen ALLE primary keys grundsätzlich [RecordID].
Mit folgender SP kann ich jetzt beispielsweise in jeder tabelle einen gewünschten datensatz löschen:

CREATE PROCEDURE udp_d_Record @tableName varchar(40), @recordID int
AS
declare @sql varchar(400)
@sql = 'DELETE FROM [' + @tableName + '] where RecordID = ' + convert(varchar, @recordID)
exec @sql

PS 2: ellinas isse?

K
Kostas Themenstarter:in
597 Beiträge seit 2005
vor 18 Jahren

Hi citizen.ron,

erstmal Herzlichen Dank für die ausführliche Antwort die ich mit Begeisterung
konsumiert habe. (Konsumiert, welch ein tolles "altes", neues Wort. Ist in
meinen Vokabular erst seit C# und ADO.NET neu gefestigt worden)
Unter Delphi habe ich alle anderen Ausgelacht die DLL ohne Ende erzeugt
haben. Alle meine Anwendung bestehen aus einer Prg.Exe, Prg.Ini und das
Datenbank file. Über eine hochkomplexe XCopy Installation war auch jede
Anwendung installiert. Zumindest ein paar Krokodilstränen fliesen schon.

Ich Sache Stored Procedures, trigger und udfs habe ich auch sehr gerne
eingesetzt jedoch nicht in so einem Umfang wie Du weil ich mich mit Delphi
sehr wohl gefühlt habe. Eine Sache der Bequemlichkeit würde ich sagen.
Wenn es jedoch aus performace gründen gefordert war, habe ich es gerne gemacht.
Unbedingt in der DB habe ich Dinge abgelegt die außerordentlich wichtig waren
wie z.B.: den Lagerbestand zu aktualisieren wenn eine Warenbewegung
stattgefunden hat. All diese essentiellen Dinge gehörten meiner Meinung nach
in der DB.

Dein Vorgehen klingt sehr interessant, jede Datensicht in einer DLL zu packen.
Doch warum würde ich gerne wissen? Ich würde es verstehen wenn ein Job
es ist Module zu schreiben welche selbstständig leben können, um eben schnell
mehrere Anwendungen zusammen zu stecken. In meiner Vergangenheit gab
es sicherlich parallelen aber noch kein einziges mal die Anforderung ein
Modul 1:1 zu übernehmen.
Ein Beispiel: in jeder Anwendung gibt es eine Adressmodul. Ich habe einen
Kunden der braucht nur die Anschrift und sonst nix. Ein anderer benötigt
Ansprechpartner, verwaltet Beziehungen wie Mutter-/Tochter-Geselschaften,
und ein anderer Arbeit International. Dieser wiederum möchte das Adresseform
an die landesübliche Darstellungsform vor sich sehen. Eine Griechische 🙂
Anschrift unterscheidet sich von der Deutschen. Ich habe lieber jedes mal das
"Rad" neu erfunden weil ich dadurch auch nur wirklich die benötigten
Informationen im Datenmodel hatte. Die Anwendung war dadurch sehr leicht
zu pflegen. Die App.Exe selbst war natürlich auch in jede Menge Forms
aufgeteilt und jede davon hatte auch in eigen Regie die Persistenz gewahrt.
Bei bedarf, konnte ich auch jedes Form aus fremden Projekten in das
aktuelle kopieren.

Typisiere Dataseds würde ich gerne aus zwei Gründen verwenden:

  1. Tippfehler bei Tabellennamen und Felder werden zur Designzeit
    erkannt und nicht erst zur Laufzeit.
  2. Die Datenbindung zur Textboxes, Checkboxes, ebenso die einzelnen Felder
    in den Grids können bequem ausgewählt werden ohne Code schreiben
    zu müssen. Denn jede verdammte Codezeile kann Fehler beinhalten.

Wie ist es eigentlich bei DLLs, wenn ein User die Anwendung gestartet hat,
sind doch die benutzte Dlls offen und können nicht ersetzt werden.
Das würde bedeuten, um DLLs zu ersetzen muss die Anwendung von
allen Usern beendet werden. Somit dürfte es eigentlich egal sein ob eine
DLL ersetze oder gleich die komplette App.EXE.
Auch bei der App.Exe wird die Exe nicht komplett in den Speicher geladen
sondern nur die Pages die benötigt werden.

Die Sache mit der Delete SP ist echt Super. Ich habe bis jetzt nur mit
Interbase bzw Firebird gearbeitet. Da ist es nicht möglich innerhalb einer
SP den Tabellennamen Variabel zu halten.

PS2: jasu Ellada!!!

Gruß Kostas

Ich werde Dir eine persönliche Nachricht schreiben um in Kontakt zu kommen.

N
4.644 Beiträge seit 2004
vor 18 Jahren

Gewisse Sachen in dlls auszulagern macht Sinn, wenn man Sachen verteilen ( Server ) , wiederverwenden will. Allerdings bekommt man immernoch sehr starke statische Abhängigkeiten. Aus der Sicht der Erweiterbarkeit sind Interfaces die beste Variante. Damit kannst Du eine AddIn fähige App bauen. Stichwort Microkernel -> Forumsuche. Stell Dir vor Deine App. App.exe ( alles ein Guss ) läuft und Du willst diese erweitern. Was dann? Code integrieren -> neu übersetzen!? Das kannst Du mit dem Interface-Konzept umgehen, ungefähr wie das Windows OS. Das ist auch erweiterbar ohne Neuübersetzung ( Treiberinstallation ) .

432 Beiträge seit 2005
vor 18 Jahren

yassu kostas, guten morgen alle anderen!

hier noch eine ergänzung zu meiner architektur:
die dll´s sind alle implementierungen des gleichen interfaces, in meinem fall eine ICRMView. Hierdurch trage ich dem von vielen hier propagierten "Microkernel" insofern rechnung, als ich mit interfaces arbeite. ich habe allerdings auf eine "factory-dll" verzichtet, die selbst wieder nur die instanzen erstellt. meine GUI, sprich: desktopformular, weiss, dass alle DLL´s ICRMView-Implementierungen sind.

Wie ist es eigentlich bei DLLs, wenn ein User die Anwendung gestartet hat,
sind doch die benutzte Dlls offen und ...

Die dll´s sind alle lokal installiert und werden per publishing verteilt. eine dll ist daher immer nur einmal geladen. minimum-versionsanforderungen lassen sich über die funktionalität des frameworks lösen.

Typisiere Dataseds würde ich gerne aus zwei Gründen verwenden:

  1. Tippfehler...

Nicht grund genug ! 😜

  1. Die Datenbindung zur Textboxes, Checkboxes, ebenso die einzelnen Felder in den Grids...

Das grid (in .net 2.0 jedenfalls) ermittelt die spaltenstruktur automatisch. sollten gggf. spalten der gesamtstruktur einer abfrage/tabelle nicht sichtbar sein, lässt sich das wiederum über einen mechanismus (z.B. in meinem fall des View-interfaces und des sql wrappers) lösen.

steuerelemente der detailansichten müssen auch nicht über code angebunden werden, denn die databindings-properties (in vs 2005) erwarten nicht, dass die datenanbindung zur entwurfszeit tatsächlich vorliegt, d.h. ich kann ein control durchaus auf [myDataset].[MyTable].[myColumn] verweisen, ohne dass es das zur entwurfszeit schon gäbe. das control interessiert sich im schlimmsten fall ja nur für die BindingSource, und die kann ich zur laufzeit ja immer noch auf die richtige zieltabelle im untypisierten dataset umbiegen, kostet nen einzeiler =)

...Datensicht in einer DLL zu packen. Doch warum würde ich gerne wissen? ...

die vorteile sind bei der größenordnung deser projekte einerseits eine schrittweise modulare inbetriebnahme, weil ich nach und nach (z.b. abteilungsweise) prozesse automatisieren und die zugehörigen module ausliefern kann ohne die installation auch nur anzufassen; neue dlls werden in einer tabelle der DB eingetragen und sind dann verfügbar. aus dem gleichen grund erziele ich eine bessere wartbarkeit.

hth, ron

195 Beiträge seit 2004
vor 18 Jahren

Original von Rainbird
Besser sind statuslose Geschäftskomponenten, die sämtliche Geschäftslogik kapseln...

Blöde Frage, aber:

Was genau versteht man in diesem Zusammenhang unter "statuslose Geschäftskomponenten"?

Umwege erhöhen die Ortskenntnis.

S
8.746 Beiträge seit 2005
vor 18 Jahren

Eine statuslose Komponente antwortet auf einen Methodenaufruf (mit den gleichen Parametern) immer mit dem gleichen Ergebnis.

Zustandsbehaftung erschwert sowohl Implementierung (Stichwort Persistenz) als auch Test. Der Verzicht auf Zustände führt - wenn überhaupt möglich - zu stabilerem Code.

Zudem skalieren solche Systeme optimal, weil man mehrere identische Instanzen erzeugen kann. D.h. man kann problemlos die Rechenleistung durch weitere Server erhöhen.

In J2EE findet man dieses Pattern in Form von Session-Beans.

195 Beiträge seit 2004
vor 18 Jahren

Original von svenson
Der Verzicht auf Zustände

Ich hab vielleicht ein besonders großes Brett vorm Kopf, aber ich versteh immer noch nicht, um welche Zustände es gehen soll X(

Hast Du ev. ein Beispiel?

Umwege erhöhen die Ortskenntnis.

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo Bini,

es geht um den Zustand des Objekts, also um die Summe seiner Felder.

Hier ein Beispiel:

zustandsbehaftet:


public int Wert
{
   get { return _iWert; }
   set { _iWert = value; }
}
private int _iWert;

zustandslos:


public int Wert
{
   get { return 5; }
}

herbivore

195 Beiträge seit 2004
vor 18 Jahren

Original von citizen.ron
weil alle dll´s namentlich in einer eigenen tabelle der DB registriert sind. die anwendung lädt eben einfach alles bei bedarf

hi ron,

ich hab ungefähr das gleiche Problem wie kostas, deshalb finde ich Deinen Ansatz auch sehr interessant.

Meine Fragen:

  1. Was ist an einem typisierten Dataset schlecht?
  2. Kannst Du Deine DLL-Registrierung in der DB noch ein bißchen ausführlicher beschreiben, ich kann mir noch nicht recht vorstellen, wie das funktioniert. In der DB stehen nur die Namen der DLLs?

Umwege erhöhen die Ortskenntnis.

195 Beiträge seit 2004
vor 18 Jahren

Original von herbivore
Hallo Bini,
es geht um den Zustand des Objekts, also um die Summe seiner Felder.
Hier ein Beispiel:
...

Danke Herbivore, daß Du Dir die Mühe machst.

Allerdings bin ich jetzt noch nicht viel schlauer schäm. Wozu sollen denn Klassen gut sein, die keine Werte haben?

Oder kommt das bei mir einfach nicht vor, daß ich es noch nie vermißt habe??? grübel

Zum Hintergrund: Meine Software (also die, die ich betreue), dient im Wesentlichen dazu, die Daten der Datenbank zu präsentieren und für Änderungen und Auswertungen zur Verfügung zu stellen. Also wohl nichts ungewöhnliches.

Für eine tiefergehende Erklärung oder einen Link oder auch nur ein Stichwort, mit dem man besser googlen kann als mit "statuslos" und "zustandslos" wäre ich dankbar.

Umwege erhöhen die Ortskenntnis.

3.728 Beiträge seit 2005
vor 18 Jahren
Zustand

Der Zustand oder Status oder Clientstatus oder Sitzungsstatus (Im wesentlichen bedeuten diese Begriffe alle das selbe) ist ganz einfach erklärt. Stell Dir eine Anwendung vor, die es ermöglicht Angebote zu erfassen. In ein Formular gibt der Benutzer Adresse und Positionen des Angebots ein. Irgendwo müssen diese Daten gehalten werden. Du wirst jetzt sagen: In einer Datenbank natürlich!

Dorthin kommen die Daten aber erst später. Der Benutzer ist ja gerade noch dabei das Angebot einzugeben. Niemand würde ein unvollständiges Angebot in der Datenbank speichern. Also liegen die Daten solange in Variablen (z.B. in einem DataSet) im Hauptspeicher. Das ist der Clientstatus! Der Clientstatus beschreibt den Zustand/Status der momentanen Sitzung eines Benutzers.

In meinem Beispiel liegt der Clientstatus in einer Windows Forms Anwendung auf dem Client. Es gibt aber auch Leute, die den Status auf einen Applikationsserver legen oder sogar auf eine Datenbank (serverseitige Cursor). Das beduetet Du erzeugst z.B. über .NET Remoting ein Objekt auf dem Appserver und setzt eine Eigenschaft. Wenn Du das nächstemal über .NET Remoting die Eigenschaft abfragst, hat sie noch den selben wert. Das Objekt mit seinen Eigenschaften verbraucht natürlich Ressourcen (z.B. Hauptspeicher) auf dem Appserver. Bei 5 gleichzeitigen Benutzern fällt das noch nicht so ins Gewicht, aber bei 200 Benutzern, die alle auf dem Appserver arbeiten, wird plötzlich alles zähflüssig langsam. Der Appserver hat keinen Speicher mehr frei.

Wenn die Objekte auf dem Appserver statuslos sind, halten sie keine Daten über mehrere Funktionsaufrufe hinweg. Bei Verwendung von SingleCall (.NET Remoting) bzw. JustInTimeActivation (Enterprise Services) wird ein Objekt nach dem Methodenaufruf vom Client sofort wieder zerstört. Diese Vorgehensweise entlastet den Appserver.

Es gibt allerdings Fälle, bei denen statuswahrende Objekte sinnvoll sind. Wenn z.B. sich schnell ändernde Daten (wie Aktienkurse) vielen Benutzern gleichzeitig zu verfügung gestellt werden sollen. Oder wenn die Erzeugung eines Objekt "teuer" ist. Das wäre z.B. der Fall wenn ein Objekt eine Verbindung zu einem Großrechner oder zu diversen Applikationen (z.B. DATEV) aufbauen muss.

Zusammenfassung:

Statuslose Objekte halten keine Daten über mehrere Funktionsaufrufe. Deshalb werden auch keine Eigenschaften implementiert(Wäre ja sinnlos). Statuslose Objekte sind "Wegwerfartikel". Sie leben nur so lange wie nötig.

Statuswahrende Objekte halten Daten über mehrere Funktionsaufrufe hinweg. Sie leben meistens wesentlich länger als ihre statuslosen Kollegen. Die Lebensdauer wird oft über Leases definiert oder direkt vom Client bestimmt.

Beispiel für eine statuslose Angebotskomponente mit Enterprise Services:


[JustInTimeActivation]
public class OfferManager : ServicedComponent
{
    [AutoComplete]
    public DataTable GetOffer(Guid offerID)
    {
        // ...
    {

    [AutoComplete]
    public DataTable GetCustomerOffers(Guid customerID)
    {
        // ..
    }

    [AutoComplete]
    public decimal CalcOfferTotal(DataTable offer,int index)
    {
        // ...
    }

    [AutoComplete]
    public void SaveOffers(DataTable offers)
    {
        // ...
    }

    // usw ...

}

3.728 Beiträge seit 2005
vor 18 Jahren

Original von Bini
Meine Fragen:

  1. Was ist an einem typisierten Dataset schlecht?

Wenn Du z.B. eine Spalte in einer Tabelle zufügst, musst Du Dein typisiertes DataSet auch ändern. Ich hasse es alles an tausend Stellen zu ändern.

Außerdem muss die Schnittstelle des typisierten DataSets auf beiden Seiten (Geschäftsobjekt und Client) bekannt sein. Das bedeutet, dass typisierte DataSets in separaten Assemblies definiert werden müssen (Verweischaos! Ich hab eh schon genug Verweise in den einzelnen DLLs). Diese müssen auf dem Appserver bereitgestellt und an alle Clients verteilt werden. Wenn sich da was ändert hast Du einen großen logistischen Aufwand, bis alle Clients wieder korrekt funktionieren.

Ich arbeite nur für den Clientstatus mit DataSets (weil ich da oft mehrere Tabellen gleichzeitig bearbeiten muss). Meine Geschäftskomponenten geben immer nur DataTables zurück. DataSets sind als Container für ein "SELECT * FROM Offer WHERE OfferID=@offerID" einfach nicht sinnvoll.

195 Beiträge seit 2004
vor 18 Jahren

Hallo Rainbird,

danke für die ausführliche Erklärung. Vom Prinzip her ist es mir jetzt schon klar.

Meine Daten liegen in einem Riesen-Dataset. Dieses ist allen Forms bekannt. Ich habe nur ungefähr 10 Nutzer, die haben alle die exe, welche direkt auf die zentrale DB zugreift.

Mit dem ganzen Konzept bin ich nicht sehr glücklich - unter anderem wegen starker Perfomanceproblem - und versuche jetzt, mir soviel konzeptionelles Wissen anzueignen, daß ich das Ganze umstrukturieren kann. Als Einzelkämpfer kann ich mich mit niemandem beraten und muß deshalb hier alle meine (dummen 😉 ) Fragen loswerden.

An welcher Stelle meiner Anwendung wären denn statuslose Objekte nützlich? Da bin ich immer noch ratlos. Wie gesagt, Prinzip und theoretischer Nutzen ist mir (nun) klar, aber die praktische Bedeutung nicht. Oder wird das erst sinnig, wenn ich meine Anwendung aufteilen würde in serverseitige und clientseitige Komponenten? Erstere würden dann z.B. auf dem DB-Rechner laufen?

So viele Fragen noch. Ich komme so langsam voran seufz

Umwege erhöhen die Ortskenntnis.

432 Beiträge seit 2005
vor 18 Jahren

hallo bini

warum typisierte datasets "schlecht" sind, hat bini ja schon hinreichend erklärt... 😉

Kannst Du Deine DLL-Registrierung in der DB noch ein bißchen ausführlicher beschreiben, ich kann mir noch nicht recht vorstellen, wie das funktioniert. In der DB stehen nur die Namen der DLLs?

nun, ich habe letztlich alle dll´s in einer tabellenspalte namentlich genannt, ausserdem die klasse, die innerhalb der dll die implementierung eines interfaces darstellt. auf diese weise kann sich die anwendung darauf verlassen, dass die instanz des objekts garantiert eine implementierung sagen wir des interface "IAnsicht" ist.

der pfad der dlls wird über config-datei oder registry gesteuert und da liegen die dll´s dann physisch drin.

darüberhinaus steuern weitere tabellen, welche dll für welchen benutzer zugänglich ist, ggf. seine weiteren rechte daran, natürlich kann man auch noch hinterlegen, ob sie seitens des kunden lizenziert ist usw.

nachstehend ein bissi code der klasse, die für das laden und anzeigen der dll aus den angaben der tabelle verantwortlich ist:


  
      private IAnsicht PlugIn;      // Variable, die eine Instanz der in der DLL definierten Klasse aufnimmt

  // View ist die Klasse, die für das Laden der DLL aus der Tabelle zuständig ist
  // In ihrem Konstruktor erhält sie den für sie zuständigen Datensatz aus der Tabelle.
  // Der Pfad der DLLs wird über config-Datei oder registry gesteuert und kommt ebenfalls von aussen
      public View(DataRow record, string libPath, Panel targetPanel)
      {
         viewRecord  = record;
         assembly    = null;
         PlugIn      = null;
         form        = null;
         DLLPath     = libPath;
         viewPanel   = targetPanel;
         _Label            = viewRecord["Label"].ToString();
         _Action           = (eViewAction)viewRecord["Action"];
         assemblyFileName  = viewRecord["AssemblyFileName"].ToString();
         plugInClassName   = viewRecord["ClassName"].ToString();
         _IndexKey         = viewRecord["ControlName"].ToString();
         _Flags            = (eViewFlags)viewRecord["Flags"];
         if (viewRecord["Picture"] != DBNull.Value) try
         {
            MemoryStream mStream = new MemoryStream((Byte[])@viewRecord["Picture"]);  
            _Picture = new Bitmap(mStream, true);
            mStream.Close();
         }
         catch (Exception exception)
         {
            Messenger.Process(exception, "Error reading image stream of view '" + _Label + "':");
         }
      }

      private bool LoadAssembly()
      {//Load the assembly
         bool result = false;

         try
         {
            if (assembly == null) assembly = Assembly.LoadFrom(DLLPath + assemblyFileName + ".dll");
            Messenger.Process("Loaded assembly file " + assembly.FullName);
            if (PlugIn   == null) PlugIn   = (IAnsicht )assembly.CreateInstance(plugInClassName);
            Messenger.Process("Instantiated class " + plugInClassName);
            result = (PlugIn != null);
         }
         catch {}
         return result;
      }

      public Form ShowWindow(Form parentForm)
      {
         Form result = null;
         if (LoadAssembly()) 
         {
            IAnsicht childWindow = (IAnsicht)assembly.CreateInstance(plugInClassName);
            childWindow.ShowWindow(parentForm);
         }
         return result;
      }

hth, ron

3.728 Beiträge seit 2005
vor 18 Jahren

Original von Bini
An welcher Stelle meiner Anwendung wären denn statuslose Objekte nützlich? Da bin ich immer noch ratlos. Wie gesagt, Prinzip und theoretischer Nutzen ist mir (nun) klar, aber die praktische Bedeutung nicht. Oder wird das erst sinnig, wenn ich meine Anwendung aufteilen würde in serverseitige und clientseitige Komponenten? Erstere würden dann z.B. auf dem DB-Rechner laufen?

So viele Fragen noch. Ich komme so langsam voran seufz

Bau Deine Anwendung so, als hättest Du einen Applikationsserver. Die Geschäftskomponenten werden eh in DLLs untergebracht. Es sprincht nichts dagegen diese DLLs direkt in der EXE-Anwendung einzubinden (Wenn man keinen AppServer hat). Wenn die Anwendung größer wird, kannst Du sie dann ohne viel Aufwand auf verschiede Prozesse/PCs verteilen (Einfach die Geschäftskomponenten in einem .NET Remoting Host auf einem dedizierten PC bereitstellen).

Halte nur in Deiner EXE-Anwendung einen Clientstatus! Die Geschäftskomponenten sollten statuslos sein.

Geschwindigkeitsprobleme im Bezug auf die Datenbank haben oft folgende Ursachen:*Es wurden keine Indizes auf Such-Tabellenfelder gesetzt (Am besten den Indexerstellungsassistenten von SQL Server benutzen! Das kann die Geschwindigkeit VERVIELFACHEN!) *DB-Verbindungen werden durchgehend offen gehalten (Vielleicht sogar mehrere pro Client) *Listen (z.B. DataGrid) werden beim laden eines Formular mit ganzen Tabellen befüllt (SELECT * FROM Table); Während der Entwicklung mit 5 Dummy-Datensätzen geht das noch sehr flott, aber im produktiveinsatz kann man Kaffee trinken gehen *Bei komplexen Abfragen/Berechnungen werden keine Gespeicherten Prozeduren verwendet, obwohl diese um einiges schneller sind

Der erste Punkt der Liste ist am wichtigsten. Dabei sollte man wissen, dass ein Index nur dann sinnvoll ist, wenn er alle Suchfelder in Kombination enthält. Wenn ich also z.B. nach Kunden-Nr und Erfassungsdatum suche sollte ein Index angelegt werden, die diese (und nur diese) beiden Felder enthält.

195 Beiträge seit 2004
vor 18 Jahren

Hallo Ron,
Hallo Rainbird,

danke nochmal für die Erklärungen. Ich muß mir das alles noch genauer anschauen, habe aber momentan nicht so viel Zeit dafür, wie ich gerne hätte.

Ich hab jetzt auch noch einige interessante Artikel gefunden, die mich hoffentlich mit dem ganzen Thema ein Stück voranbringen.

@Rainbird
Indices sind vorhanden, allerdings gehe ich davon aus, daß ich hier noch mal kontrollieren muß, ob die ausreichend und sinnvoll sind. Verbindungen werden nicht offengelassen, die Daten wandern per Datareader in das Dataset und damit ist gut.
Die Statements sind allerdings teilweise recht komplex und damit eben nicht die schnellsten. Laut Anweisung der Geschäftsführung vor drei Jahren sollten aber KEINE DB-internen Prozeduren verwendet werden... 😜 Wahrscheinlich wollte man sich einen Wechsel der DB offenhalten, was aber ohnehin nicht mehr zur Diskussion steht. Datagrids werden nicht verwendet.

@Ron
Deinen Beispielcode werde ich in meine private Wissensbank aufnehmen 🙂
Ich werde mich aber wohl doch erst mal auf andere Baustellen konzentrieren.
Ich habe jetzt schon viele Ideen gesammelt, was in meiner Anwendung verbessert werden soll / kann, aber als eine-Frau-Team sind meine Möglichkeiten zeitlich einfach stark beschränkt.
Ist gar nicht so einfach, den roten Faden nicht zu verlieren 8o

Wenn ich ein einigermaßen klares Konzept vor Augen habe, werde ich das sicher hier vorstellen 😉

Umwege erhöhen die Ortskenntnis.