Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Wozu sind Attribute gut ? (https://www.delphipraxis.net/175701-wozu-sind-attribute-gut.html)

OlafSt 10. Jul 2013 22:09

Delphi-Version: XE2

Wozu sind Attribute gut ?
 
Hallo Freunde,

beim Studium der Sprach-Eigenschaften von Delphi bin ich über die Annotations (Attribute) gestolpert. Das sind diese Dinger hier:

Delphi-Quellcode:
type
   TMyAttr = class
      FData: string;
   constructor Create(AData: string);
   //Implementierung des constructors schenken wir uns mal

type
   TMyClass = class
   [MyAttr('Hallo da draussen')]
   constructor Create;
end;
Ich frage mich, welchen ernsthaften Nutzen ein solches Konstrukt wohl haben mag - zumal der Zugriff auf diese Attribute nicht gerade simpel ist. Wer kann mir da auf die Sprünge helfen ?

Union 10. Jul 2013 22:29

AW: Wozu sind Attribute gut ?
 
Um Eigenschaften abfragen zu können. Ich vermute es handelt sich um die Vorarbeiten zu den unsäglichen Livebindings. Ansonsten ist aber der Zugriff über z.b. TRttiContext.GetTypes.GetMethods.GetAttributes doch trivial.

Uwe Raabe 10. Jul 2013 22:59

AW: Wozu sind Attribute gut ?
 
Beispielsweise verwendet DataSnap die Attribute um Zugriffsberechtigungen auf Klassen bzw. Methoden-Ebene zu implementieren. Ich wüsste nicht, wie man das eleganter im Code unterbringen sollte. Es ist fast so, als ob man public/private zur Laufzeit einstellen kann.

jaenicke 11. Jul 2013 05:36

AW: Wozu sind Attribute gut ?
 
Man kann damit auch sehr elegant z.B. Konfigurationsklassen erstellen, die über die Informationen in den Attributen mit Daten gefüttert werden. Sprich man kann darüber dann das Mapping zur Konfiguration definieren, also wo der Wert in der Konfiguration steht.

Zitat:

Zitat von Union (Beitrag 1221405)
Um Eigenschaften abfragen zu können. Ich vermute es handelt sich um die Vorarbeiten zu den unsäglichen Livebindings.

Das wäre schön gewesen, aber leider wurden die LiveBindings viel zu oberflächlich in Delphi integriert, zumindest anfangs. Bei XE4 z.B. habe ich mir die zwar noch nicht angeschaut, aber wenn es da eine größere Änderung in der Implementierung an sich gegeben hätte, hätte ich das vermutlich mitbekommen. Dass sich da einiges getan hat, habe ich schon gesehen, aber soweit ich weiß alles nur was die Verwendung angeht, nicht die Umsetzung.

Der schöne Günther 11. Jul 2013 09:04

AW: Wozu sind Attribute gut ?
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1221409)
Beispielsweise verwendet DataSnap die Attribute um Zugriffsberechtigungen auf Klassen bzw. Methoden-Ebene zu implementieren.

Zitat:

Zitat von jaenicke (Beitrag 1221414)
Mapping zur Konfiguration definieren, also wo der Wert in der Konfiguration steht.

Attribute stehen bislang auch auf meiner Liste "Wie funktioniert das in Delphi?", das ist, was ich spontan geraten hätte bzw. wofür ich es versucht hätte einzusetzen: O/R-Mapping. Einmal eine Serialisierungsmethode gebaut die alle Properties durchgeht, und nur welche mit einem bestimmten Attribut werden persistiert, vorher verändert, mit anderen verknüpft, was auch immer. Das könnte man ja alles darüber steuern....

Patito 11. Jul 2013 09:34

AW: Wozu sind Attribute gut ?
 
Zitat:

Zitat von OlafSt (Beitrag 1221404)
Hallo Freunde,
Ich frage mich, welchen ernsthaften Nutzen ein solches Konstrukt wohl haben mag - zumal der Zugriff auf diese Attribute nicht gerade simpel ist. Wer kann mir da auf die Sprünge helfen ?

Der Sinn von Attributen in Programmiersprachen ist eigentlich der, dass der Compiler schon zur Compilezeit Methoden zusammenstückeln kann (mache etwas für alle Felder mit Atribut X, ...). Dadurch kann man dann eine Menge Schreibarbeit und Checks zur Laufzeit sparen. So wie das von Embarcadero aber implementiert ist, sind das aber nur Konstanten/Variablen, die etwas "anders" sind.

Für ORMs sind die Dinger soweit ich sehe unbrauchbar, da die ganzen Checks für die Attribute zur Laufzeit geschehen. Das macht das ganze dann deutlich langsamer, als wenn man das gleich richtig ausprogrammiert. Die Attribute sparen so nur in eher exotischen Fällen ein wenig Schreibarbeit (auf Kosten der Geschwindigkeit).

Die Syntax ist auch eher fragwürdig. Wenn man sich mit Delphi auskennt würde man eigentlich erwarten, dass sich das Attribut in deinem Beispiel (wie bei Interface-GUIDs) auf class bezieht.

Der Hauptnutzen von Attributen ist wohl (für Embarcadero) der, dass man damit Konstrukte in die Sprache bekommt, die dann mit anderen Compilern nicht mehr gehen (Vendor lock-in). Technisch sind die Attribute so wie sie jetzt sind eher nicht sinnvoll.

OlafSt 11. Jul 2013 10:52

AW: Wozu sind Attribute gut ?
 
Ich verstehe den möglichen Sinn hinter solchen Attributen. Augenscheinlich aber ist die Delphi-Implementierung nur eine Art "Vorstufe", die richtige, vollumfängliche kommt dann mit XE5 oder XE6 :-D

Danke für die Antworten, wieder was dazu gelernt - und das nach 30 Jahren als Programmierer 8-)

Phoenix 12. Jul 2013 06:38

AW: Wozu sind Attribute gut ?
 
Zitat:

Zitat von Patito (Beitrag 1221433)
Der Sinn von Attributen in Programmiersprachen ist eigentlich der, dass der Compiler schon zur Compilezeit Methoden zusammenstückeln kann (mache etwas für alle Felder mit Atribut X, ...). Dadurch kann man dann eine Menge Schreibarbeit und Checks zur Laufzeit sparen. So wie das von Embarcadero aber implementiert ist, sind das aber nur Konstanten/Variablen, die etwas "anders" sind.

Dafür sind wie wenigstens Attribute gedacht.

Zitat:

Zitat von Patito (Beitrag 1221433)
Für ORMs sind die Dinger soweit ich sehe unbrauchbar, da die ganzen Checks für die Attribute zur Laufzeit geschehen. Das macht das ganze dann deutlich langsamer, als wenn man das gleich richtig ausprogrammiert. Die Attribute sparen so nur in eher exotischen Fällen ein wenig Schreibarbeit (auf Kosten der Geschwindigkeit).

Quatsch. Genau für sowas sind Attribute da. Attribute sollen auf Typen Meta-Informationen bereitstellen die dann später dynamisch zur Laufzeit ausgewertet können - und zwar ohne jeden Typen explizit imstanziieren zu müssen. Die alte Methode wäre, ein Flagging Interface zu verwenden (reine Attributpräsenz auf einer Klasse) und wenn man zusätzliche Informationen über Members bräuchte müsste man eine Instanz erzeugen und über die Methoden / Properties des Interfaces (die man jedes mal implementieren müsste) diese Informationen abzufragen.

Der Zugriff auf Attribute ist auch nicht wirklich langsam. Klar muss die runtime ein wenig suchen und laden, aber das macht man ja nicht permanent sondern genau ein einziges mal und cached die Informationen wenn man sie später nochmal braucht in Memory. Und zwar dort, wo sie gebraucht werden.


Zitat:

Zitat von Patito (Beitrag 1221433)
Die Syntax ist auch eher fragwürdig. Wenn man sich mit Delphi auskennt würde man eigentlich erwarten, dass sich das Attribut in deinem Beispiel (wie bei Interface-GUIDs) auf class bezieht.

Nein? Die Syntax ist genau so wie man sie von Java und .NET-Sprachen seit Jahren kennt. Attribut über das zu annotierende Element, in eckigen Klammern. That's it. Keine Magic.

Zitat:

Zitat von Patito (Beitrag 1221433)
Der Hauptnutzen von Attributen ist wohl (für Embarcadero) der, dass man damit Konstrukte in die Sprache bekommt, die dann mit anderen Compilern nicht mehr gehen (Vendor lock-in). Technisch sind die Attribute so wie sie jetzt sind eher nicht sinnvoll.

Entweder hast Du den Sinn und Nutzen von Attributen an sich wirklich nicht verstanden, oder Du willst nur Trollen. Nach diesem letzten Absatz würde ich tatsächlich eher auf letzteres schliessen.

Alle anderen modernen typisierten Sprachen haben Attribute um es den Entwicklern zu erlauben eigene Meta-Informationen auf Typen und Member zu legen. Um damit dynamisch Dinge zu bauen die ohne solche Informationen nicht möglich wären. Ein Vendor Lock-In ist bei Delphi im übrigen gar nicht möglich. Delphi ist keine Standardisierte Sprache und reines Pascal ist das schon lange nicht mehr. Delphi an sich ist ein einziger Vendor-Lock-In. Und FreePascal als einzige einigermaßen kompatible Alternative sieht auch schon länger Attribute vor (auch wenn sie noch nicht fertig implementiert sind, oder sind die inzwischen schon drin? Mein Stand hier ist ein halbes Jahr alt).

Der schöne Günther 12. Jul 2013 08:35

AW: Wozu sind Attribute gut ?
 
Ich sitze mit großen Augen still in der Ecke und lausche. Vielen Dank für weiteres Material, interessantes Thema! :thumb:

Patito 12. Jul 2013 12:43

AW: Wozu sind Attribute gut ?
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1221545)
Ich sitze mit großen Augen still in der Ecke und lausche. Vielen Dank für weiteres Material, interessantes Thema! :thumb:

Nunja, sonderlich viel Material wird es da nicht mehr geben
1) Für die von Dir genannten Anwendungsfälle ORM/Serialisierung ist es eben etwas ungeschickt die
Methode jedes mal zur Laufzeit zusammenzustückeln. Wenn man das ganze gleich richtig macht ist man
eben gleich eine Größenordnung schneller. Attribute sparen da eben nur etwas Tipparbeit (für Code,
den man gerade beim solchen Anwendungsfällen eh vollautomatisch erzeugen kann).

2) Die Syntax ist eben Java/C# und passt nicht ganz zu Pascal.

3) Man hat für den Code nicht mehr sonderlich viele Compiler zur Auswahl.

jfheins 12. Jul 2013 12:55

AW: Wozu sind Attribute gut ?
 
Ich kann hier mal ein Beispiel von mir zeigen:
Code:
    public enum COMM_Command : byte
    {
        #region Paste Bereich

        [CommandInfo(Category.General, "Ping ausführen", PrimaryName = "")]
        PING = 0,
        [CommandInfo(Category.Response, "ACK", PrimaryName = "")]
        NACK = 2,
        [CommandInfo(Category.GetVariable, "Status", Conversion = CommType.Status)]
        REQ_STATE = 6,
        [CommandInfo(Category.GetVariable, "Zyklen")]
        REQ_CYCLES = 7,
        [CommandInfo(Category.GetVariable, "Motor (Promille)", Unit = "‰")]
        REQ_MOTOR_PROMILLE = 8,
        [CommandInfo(Category.GetVariable, "Bremse (Promille)", Unit = "‰")]
        REQ_BRAKE_STATE = 10,
        [CommandInfo(Category.GetSensor, "Encoder (Gegenrad)", Unit = "U/min")]
        REQ_ENCODER_MOTORWELLE = 12,
        [CommandInfo(Category.GetSensor, "Gefahrene Strecke", Unit = "m", Conversion = CommType.thousands)]
        REQ_DRIVEN_DISTANCE = 14,
        [CommandInfo(Category.GetSensor, "Bandsensor (binär)", Unit = "bool")]
        REQ_ROPE_SENSOR_STATE = 16,
        [CommandInfo(Category.GetSensor, "Temperatur", SecondaryName = "Sensor", Unit = "°C")]
        RES_TEMPERATURE = 81,
// ...
        [CommandInfo(Category.SetVariable, "Status", Conversion = CommType.Status)]
        SET_STATE = 135,
        [CommandInfo(Category.SetVariable, "Motor (Promille)", Unit = "‰")]
        SET_MOTOR_PROMILLE = 136,
        [CommandInfo(Category.SetVariable, "Bremse (Promille)", Unit = "‰")]
        SET_BRAKE_PROMILLE = 137,
// ...
        [CommandInfo(Category.Command, "Start", PrimaryName = "")]
        CMD_START = 200,
Das ist jetzt nur ein kleiner Ausschnitt des enum.

Die Attribute ermöglichen mir hier eine GUI ohne Wasserfallertige Fallunterscheidungen. Es gibt eine Combobox wo man die Kategorie auswählen kann ("Variable setzen", "Befehl senden"), die zweite Combobox enthält dann die möglichen Aktionen. Und wenn ein Wert dazu gehört, erscheint darunter eine Textbox.

Das ganze hätte sich auch mit einer Command-Klasse lösen lassen - diese Art hat aber den Vorteil dass der struct (der ein feld mit dem enum enthält) einfach in ein Bytearray konvertiert werden kann. Das ganze kommuniziert nämlich über einen COM-Port mit einem Mikrocontroller. Außerdem ist es einfacher, den enum in den beiden Codebasen gleich zu halten. (Der ganze Inhalt des enums wird inzwischen mit einer Excel-Tabelle generiert - so als Dokumentation)

Die Sache mit den Attributen hat in meinen Augen noch den zusätzlichen Vorteil, dass die Infos im Code "nah beisammen" sind. Fügt man ein Element ohne Attribut hinzu, fällt das sofort auf. (Die Regelmäßigkeit ist unterbrochen) Würde ich die Daten separat in einem Dictionary<COMM_Command, Attribute> ablegen, dann fällt das nicht so flott auf.

Lemmy 12. Jul 2013 13:06

AW: Wozu sind Attribute gut ?
 
Zitat:

Zitat von Patito (Beitrag 1221577)

1) Für die von Dir genannten Anwendungsfälle ORM/Serialisierung ist es eben etwas ungeschickt die
Methode jedes mal zur Laufzeit zusammenzustückeln. Wenn man das ganze gleich richtig macht ist man
eben gleich eine Größenordnung schneller. Attribute sparen da eben nur etwas Tipparbeit (für Code,
den man gerade beim solchen Anwendungsfällen eh vollautomatisch erzeugen kann).

ich persönlich finde, dass die Attribute im Bereich ORM verdammt viel Tipparbeit sparen. z.b. im Bereich der Wertüberprüfung. Da reicht mir dann eine generische Methode die alle Attribute prüft. Und den Wertbereich kann ich direkt beim Property erfassen, dokumentieren und nicht erst im Setter. Wo ich evtl. die Prüfung gar nicht haben will (z.B. beim Laden eines Projektes) und diese wieder kompliziert ausschalten muss.

weiterhin geht es weniger um "Methoden zur Laufzeit zusammenstückeln" sondern eher generische/parametrisierte Methoden zu haben, die mit den Attributen arbeiten, ohne dass ich gleich jedes Property einer Klasse selbst zu einer Klasse erheben muss (was durchaus interessant sein kann, aber manchmal halt nicht machbar ist).

und wegen

Zitat:

Zitat von Patito (Beitrag 1221577)
3) Man hat für den Code nicht mehr sonderlich viele Compiler zur Auswahl.

selten so gelacht. wie viele Compiler kennst Du denn, die VCL-Code compilieren können? Das ist ja wohl DAS Vendor lock-in schlecht hin....



Grüße

OlafSt 15. Jul 2013 14:36

AW: Wozu sind Attribute gut ?
 
Ob man wohl ein simples Beispiel zeigen könnte, die mir Deppen den Nutzen klar aufzeigen ? Die Sache mit dem ENUM weiter oben z.B. ist spannend - es fehlt aber der Fitzel Programmcode, der mir sagt: Jo, det isses. Was ORM ist, ist mir auch ein Rätsel, mag aber daran liegen, das ich nicht studiert hab sondern nur 30 Jahre Praxiserfahrung in den Knochen... ;)

mkinzler 15. Jul 2013 14:39

AW: Wozu sind Attribute gut ?
 
ORM = Object Relational Mapping

http://de.wikipedia.org/wiki/Objektr...nale_Abbildung

Sherlock 18. Jul 2013 12:48

AW: Wozu sind Attribute gut ?
 
Zitat:

Zitat von OlafSt (Beitrag 1221698)
Ob man wohl ein simples Beispiel zeigen könnte, die mir Deppen den Nutzen klar aufzeigen ? Die Sache mit dem ENUM weiter oben z.B. ist spannend - es fehlt aber der Fitzel Programmcode, der mir sagt: Jo, det isses. Was ORM ist, ist mir auch ein Rätsel, mag aber daran liegen, das ich nicht studiert hab sondern nur 30 Jahre Praxiserfahrung in den Knochen... ;)

Ich schließe mich da mal an. Der Enum Ausschnitt sieht ja erstmal recht "übersichtlich" aus. Eine (beispielhafte) Verwendung des ganzen wäre das Sahnehäubchen.

Sherlock

Union 18. Jul 2013 13:12

AW: Wozu sind Attribute gut ?
 
Hier ist ein schönes Beispiel.

Furtbichler 18. Jul 2013 13:34

AW: Wozu sind Attribute gut ?
 
Übrigens kann man die Geschichte mit den Attributen auch ganz schön übertreiben. Wenn ich mehr Attribute als Methoden habe, wird es für mich fragwürdig, diese in dieser Fülle einzusetzen.

Im Vordergrund sollte übrigens nicht die Ersparnis von Tipparbeit stehen, sondern die Lesbarkeit des Codes. Hier können Attribute -eben weil sie kurz und knackig sind- wirklich dazu beitragen, das der Code lesbarer wird (Stichwort 'ORM').

Ich persönlich finde das gezeigte Beispiel mit den Enums auf den ersten Blick übrigens schlecht lesbar.

Das Beispiel von Union (bzw. sein Link) ist schon schön, verstößt aber (ein wenig) gegen das Prinzip 'Information Hiding', wobei man anmerken muss, das es keinen anderen sinnvollen Platz für Attribute als im Interface-Abschnitt einer Klassendefinition gibt.

Ich persöhnlich gehe mit diesen Dingen eher konservativ um, denn da werkelt für mich zu viel unsichtbarer Code im Hintergrund. Wenn die Aussage hinter einem Attribut nicht klar ist, ist es deplaziert.

jfheins 18. Jul 2013 21:46

AW: Wozu sind Attribute gut ?
 
Tja, also ich kann gerne mal die Verwendung des enums demonstrieren.

Vorab: Alle Codeschnipsel sind auch auf pastebin zu finden, Code-Highlighting ist ja manchmal schon ganz nett.

Ich hole zuerst mal etwas aus:

Wie oben angedeutet, befinden sich auf dem Formular zwei Comboboxen. Die erste ist für die Kategorie, die zweite für den Typ.

Zu jedem Tupel kann es 1..3 Befehle (enumwerte) geben. So hätte zum Beispiel {"Variable setzen", "Status"} folgende enumwerte zugeordnet:
REQ_STATE = 6, // Status soll abgefragt werden (REQ=Request)
RES_STATE = 70, // Rückmeldung (RES=Response)
SET_STATE = 135, // Status soll gesetzt werden
das Tupel {"Befehl", "Notaus"} hat hingegen nur:
CMD_NOTAUS = 205, // Ein Befehl hat keine zusätzlichen Daten und es kommen auch keine Daten zurück.

Die Kategorie ist übrigens ebenfalls ein enum:
Code:
    public enum Category
    {
        [Description("Allgemein")]
        General,
        [Description("Sensor auslesen")]
        GetSensor,
        [Description("Variable auslesen")]
        GetVariable,
        [Description("Konstante auslesen")]
        GetConstant,
        [Description("Variable setzen")]
        SetVariable,
        [Description("Konstante setzen")]
        SetConstant,
        Response,
        [Description("Befehl")]
        Command
    }
Erläuterung:
Allgemein => Was woanders nicht reinpasste (=PING und Rohdaten verschicken)
Sensor auslesen => Sensoren können abgefragt, aber nicht gesetzt werden
Variablen können ausgelesen und gesetzt werden, ändern sich aber auch mit der Zeit
Konstante => Kann ausgelesen und gesetzt werden, beim Lesen kommt immer der zuletzt geschriebene Wert zurück
Befehle transportieren keine Daten. Der Empfang wird mit einem ACK bestätigt.

Netter Effekt: Die eine Combobox, die die Kategorien enthält, wird mit den Attributen gefüttert. Response steht also im enum drin, aber nicht in der Auswahlliste.

=============================
Nun zur eigentlichen Verwendung: Die Attribute können ja nur mittels Reflection ausgelesen werden. Dazu habe ich eine nette Erweiterungsmethode gebastelt. Nur so geht das typeof(...).ToList das eine Liste mit den passenden Attributwerten zurückgibt.

Der Eventhandler für doe Änderung der Kategorie schaut so aus:
Code:
        private void category_cb_SelectedIndexChanged(object sender, EventArgs e)
        {
            var selected = type_cb.SelectedItem; // Ausgewählten Wert merken

            Category cat = (Category)category_cb.SelectedValue; // Ausgewählte Kategorie
           
// Meine Erweiterungsmethode. Hier steht "Liefere mir bitte anhand des enums 'COMM_Command' eine Liste mit Tupeln {enumwert, Displayname}, bei denen die Kategorie gleich cat ist"
             List<KeyValuePair<Enum, string>> list = typeof(COMM_Command).ToList<CommandInfoAttribute>(x => x.Category == cat, x => x.DisplayName);
// Die Liste dann natürlich gleich in die zweite Combobox schieben
            type_cb.DataSource = list;

// Und falls vorher ein bestimmter Wert ausgewählt war, diesen nach Möglichkeit wieder auswählen.
            if (selected != null)
            {
                string text = ((KeyValuePair<Enum, string>)selected).Value;
                var item = list.FirstOrDefault(x => x.Value == text);
                if (item.Value != null)
                    type_cb.SelectedValue = item.Key;
            }
        }
Ich hoffe die Kommentare machen das Vorgehen deutlich. Hier dann noch der Handler für die Änderung des Typs:
Code:
        private void type_cb_SelectedIndexChanged(object sender, EventArgs e)
        {
            // Einheiten herausfinden
            string name = type_cb.Text;
             List<KeyValuePair<Enum, string>> list = typeof(COMM_Command).ToList<CommandInfoAttribute>(x => x.DisplayName == name, x => x.Unit);

            unit_lbl.Visible = list.Count == 1;
            unit_cb.Visible = list.Count != 1;

// Falls ein Wert geschickt werden soll, bitte die Einheit neben dem Editfeld anzeigen
            // Bei einer Einheit Label benutzen, sonst Combobox
            unit_lbl.Text = list[0].Value;
            if (list.Count > 1)
            {
                unit_cb.DisplayMember = "Value";
                unit_cb.ValueMember = "Key";
                unit_cb.DataSource = list;
            }
// Mit getEnumValue() bekomme ich den enumwert, der durch die aktuelle Auswahl genriert wird.
            CommandInfoAttribute attrib = getEnumValue().GetInfo();

            unit_lbl.Visible = list.Count == 1 && attrib.NeedsPrimaryValue();
            unit_cb.Visible = list.Count != 1 && attrib.NeedsPrimaryValue();

            // Sekundärwert Beschreibung zuweisen und ggf. sichtbar machen
            value2_lbl.Text = attrib.SecondaryName + ":";
            value2_lbl.Visible = attrib.NeedsSecondaryValue();
            value2_txt.Visible = attrib.NeedsSecondaryValue();

            // Bei Auslesen-Befehlen die Werteeingabe verstecken
            value_lbl.Text = attrib.PrimaryName + ":";
            value_lbl.Visible = attrib.NeedsPrimaryValue();
            value_txt.Visible = attrib.NeedsPrimaryValue();
            value_txt.Clear();
        }

        // Welcher Befehl entspricht den aktuellen GUI Einstellungen?
        private COMM_Command getEnumValue()
        {
            var unit = unit_lbl.Visible ? unit_lbl.Text : unit_cb.Text; // Einheit bestimmen
            var enumvalue = typeof(COMM_Command).ToList<CommandInfoAttribute>(x =>
                x.Category == (Category)category_cb.SelectedValue
                && x.DisplayName == type_cb.Text
                && (!x.NeedsPrimaryValue() || x.Unit == unit), x => "").First();
            return (COMM_Command)enumvalue.Key;
        }
Soo, falls ihr das jetzt bis hier durchhabt: Danke dass ihr das gelesen habt :-) Und falls euch jetzt eine bessere Lösung einfällt, nur zu - es hieß nämlich eh "Sag mal, diese Befehle und so, könnte man dafür nicht ne xml Datei machen?"

Das ganze ist natürlich nicht in einer Datei. Falls ihr euch den Code im natürlichen Habitat anschauen wollt, habe ich euch noch eine zip Datei angehängt, in der die meisten Funktionen drin sind. Darin ist auch noch ein bisschen zu sehen, wie das ganze benutzt wird.

Zitat:

Ich persönlich finde das gezeigte Beispiel mit den Enums auf den ersten Blick übrigens schlecht lesbar.
Nicht dass ich jetzt meine Arbeit abwälzen will, aber mich würden andere Ansätz schon interessieren. Der einzige Ansatz auf einem Ähnlichen Abstraktionsniveau war wie folgt: Einen normalen Enum basteln. Danach ein Dictionary<COMM_Command, CCinfo> anlegen. In einem langen Methode dann 212 mal sowas:
Code:
dict.Add(COMM_Command.REQ_APPROACH_BOTTOM_DIST, new CCinfo(Category.GetConstant, "Annäherungsdistanz (unten)") { Unit = "m", Conversion = CommType.thousands });
Hat mich nicht so begeistert :|

Furtbichler 19. Jul 2013 04:50

AW: Wozu sind Attribute gut ?
 
Zitat:

Zitat von jfheins (Beitrag 1221984)
Nicht dass ich jetzt meine Arbeit abwälzen will, aber mich würden andere Ansätz schon interessieren.

Darstellung ('Description' Attribut) als Attribut, Parametrierung als Klasse. Zugriff auf die Parameter über eine Dictionary (wie Du schon angedeutet hast).

Vorteil: Skalierbar, d.h. die Parameterklasse kann wachsen, ohne das die Lesbarkeit leidet. Bei der Verwendung von Attributen ist das nicht gegeben, denn irgendwann kleben u.U. über jedem Enum-Wert mehrere Duzend Attribute.

Die Initialisierung des Lookups erfolgt z.B. im statischen Konstruktor. Per Codefolding ist das dann unsichtbar und interessiert eh keine Sau. Die Übersichtlichkeit ist genauso 'toll' wie bei der Verwendung der Attribute.

Letztendlich nimmt sich das nicht viel, aber die Dictionary-Lösung ist erstens ein allgemeingültiges Pattern und zweitens eben (ich wiederhole mich) skalierbar.

Vorteile bei der ausschließlichen Verwendung von Attributen sehe ich nicht.

Ergo (meine Punktezählung)... 2:0 für die altbackene Lösung. Für mich zählt kompakter Code nicht (mehr). Lesbarkeit ist alles.

Frage: Wie lokalisierst (d.h. übersetzt ggfs in andere Sprachen) Du eigentlich die 'Description'-Attribute?

Ach, und zum Code: Wieso verwendest Du keine Viewmodels? (Teeren und Federn sollte man dich ;-) )

jaenicke 19. Jul 2013 08:38

AW: Wozu sind Attribute gut ?
 
Zitat:

Zitat von Furtbichler (Beitrag 1221995)
Vorteile bei der ausschließlichen Verwendung von Attributen sehe ich nicht.

Die gibt es aber. Attribute haben allgemein den Vorteil, dass sie direkt an den entsprechenden Codeteilen stehen. Wenn man nun dort etwas ändert, sieht man auch sofort, dass das auch geändert werden muss. Insbesondere fällt es sofort auf, wenn das Attribut bei einem neuen Element fehlt bzw. man kann es beim Initialisieren der Daten auch über die RTTI direkt prüfen.

Solange man nur alleine an einem Projekt arbeitet, fällt das nicht so sehr ins Gewicht, da man sich selbst eher dran erinnert, "dass da ja noch was war", aber wenn auch andere daran arbeiten, wissen diejenigen das schlicht nicht immer.

An solchen Stellen dann immer entsprechende Kommentare anzubringen ist zwar möglich, aber auch keine schöne Lösung. Da finde ich es wie auch bei Funktions- und Variablennamen besser, wenn man nur wenige Kommentare braucht, weil man schon aus einem Codeausschnitt alles schnell herauslesen kann.

Medium 19. Jul 2013 09:23

AW: Wozu sind Attribute gut ?
 
Ich dagegen bin dazu übergegangen fast alles was ich an Combobox-Einträgen so brauche über meine Datenbanken "zusammenzuqueryn", dank glaube ich ganz netter Strukturen geht das sogar mit einer Standardfunktion. Erleichtert allen voran auch das Übersetzen ohne Neucompilieren. Macht aber auch nur wirklich Sinn, wenn die DB entweder eh grbraucht würde, oder embedded ist. Ich versuche so viel Daten und deren Abhängigkeiten voneinander in die DB zu gießen, und im Programm dann nur noch mittels Kreuztabellen die Dinge zu verknüpfen. Dabei ist auch praktisch, dass ich Änderungen in gewissem Umfang machen kann, und der Kunde muss nichtmals sein Programm neu starten um diese nutzen zu können.

Uwe Raabe 19. Jul 2013 14:07

AW: Wozu sind Attribute gut ?
 
Zitat:

Zitat von Medium (Beitrag 1222018)
Ich dagegen bin dazu übergegangen fast alles was ich an Combobox-Einträgen so brauche über meine Datenbanken "zusammenzuqueryn", dank glaube ich ganz netter Strukturen geht das sogar mit einer Standardfunktion. Erleichtert allen voran auch das Übersetzen ohne Neucompilieren. Macht aber auch nur wirklich Sinn, wenn die DB entweder eh grbraucht würde, oder embedded ist. Ich versuche so viel Daten und deren Abhängigkeiten voneinander in die DB zu gießen, und im Programm dann nur noch mittels Kreuztabellen die Dinge zu verknüpfen. Dabei ist auch praktisch, dass ich Änderungen in gewissem Umfang machen kann, und der Kunde muss nichtmals sein Programm neu starten um diese nutzen zu können.

Ich weiß nicht, ob ich das so machen würde. Stimmt nicht - ich weiß, daß ich es garantiert nichts so machen würde. Genauso hat das mal vor Jahren ein frisch gebackener Diplom-Informatiker realisiert - auch mit dem Hinweis der leichten Anpassbarkeit der Texte an andere Sprachen. Problematisch wurde es allerdings, als die Anzahl der Optionen in einer neuen Programmversion erhöht wurde und dies in jeder Kundendatenbank von Hand nachgetragen werden musste. Das automatische Ergänzen war auch keine wirkliche Erleichterung und hat den Code unnötig verkompliziert. Richtig böse wird es aber dann, wenn sich die Bedeutung bestehender Einträge ändert und die vorhandenen Texte in den Kundendaten angepasst werden müssen.

Übersetzungen gehören m.E. nicht in die Datenbank - zumindest nicht in die mit den Arbeitsdaten.

Medium 19. Jul 2013 14:17

AW: Wozu sind Attribute gut ?
 
Da kommt es vermutlich auch wieder ein wenig auf die Art der Daten an. Bei uns sind das oftmals Dinge wie Rezeptbetrieb in einer intustriellen Produktionsanlage. Wenn dort z.B. ein Rezept ausgewählt wird, soll per Combobox ein Zielmischer wählbar sein. Ich habe alle Quellbehälter und Zielmischer in meiner DB, sowie deren Inhalte. Zudem eine Kreuztabelle, die mir sagt welche Quellen auf welche Ziele fahren können. Dann steht im Rezept, welche Rohstoffe nötig sind. Aus diesen Infos kann ich dann eine Liste der Zielmischer erzeugen, die von allen Quellen, die die nötigen Stoffe beinhalten erreicht werden können. Alle Behälterdaten inkl. ihrer Namen stehen auch in der DB, so dass ich meine Combobox damit gleich befülle. (Und den Index in die Objects-Property.)

Baut der Kunde dann mal einen neuen Behälter dazu, muss ich zur EInbindung in den Vollautomatikbetrieb einfach nur den neuen Tank in die Behältertabelle packen, und in der Kreuztabelle mit seinen Zielen verbinden. Und schon ist die neue Komponente "on the fly" voll einsatzfähig. Unsere Programme sind halt auch kundenspezifisch, und der Kundenstamm besteht eher aus wenigen großen als vielen kleinen. Dadurch fällt das "Breiten-Update-Problem" quasi weg. (Man hätte dieses aber auch bei in-code Daten, da muss dann eben überall das Programm getauscht werden, statt die DB angepasst.)

Bleibt am Ende fast wieder nur: Es kommt halt immer darauf an, wofür man die Dinge genau einsetzt :)

Edit: Jetzt erst deinen letzten Satz gesehen, wodurch mir klarer wurde, wo du das Problem siehst. Ich habe es in einem Fall so gelöst, dass ich die Übersetzungen in eine separate Tabelle mit Fremdschlüssel und Tabellenname gepackt habe. War im Programm dann eine andere Sprache gewählt, wurden die Texte aus der jeweiligen Übersetzungstabelle geholt. Zugegeben: Das war an ein bestehendes Projekt "angebaut", und ginge vermutlich besser wenn man es von Anfang an voll integriert. Bei Übersetzungen statischer Texte in der GUI, also Dingen, die nichts mit den Arbeitsdaten zu tun haben, nutzen wir ein 3rd Party Tool.

Furtbichler 19. Jul 2013 16:40

AW: Wozu sind Attribute gut ?
 
Zitat:

Zitat von jaenicke (Beitrag 1222006)
Zitat:

Zitat von Furtbichler (Beitrag 1221995)
Vorteile bei der ausschließlichen Verwendung von Attributen sehe ich nicht.

Die gibt es aber. Attribute haben allgemein den Vorteil,..

Absolut, ich meinte auch "ausschließlich", d.h. alles immer nur noch mit Attributen zu machen.

Bezüglich der Übersetzungen/Lokalisierung neige ich zu einer wie auch immer gearteten Standard-Lösung, die bei Delphi eher in Richtung "kommerziell und ausgereift" tendiert. Mir sind DBs am liebsten, da sie auf einfache Weise das Paradigma des zentralen Zugriffs umsetzen. Netzdateien gingen auch, aber wo kein Netz ist, bleibt nur eine DB.

Insider2004 20. Jul 2013 14:59

AW: Wozu sind Attribute gut ?
 
Ja die guten alten Attribute. Eingekauft von .net, java und sonstigen Meta-Sprachen. Passen leider überhaupt nicht zu Pascal, weil sie schlichtweg nicht nötig sind. Zinnen und Balkönchen am Delphi-Schloss. Wenn ihr richtige Software Engineers werden wollt, dann ignoriert Attribute einfach.

jaenicke 20. Jul 2013 16:33

AW: Wozu sind Attribute gut ?
 
Zitat:

Zitat von Insider2004 (Beitrag 1222132)
Passen leider überhaupt nicht zu Pascal, weil sie schlichtweg nicht nötig sind. Zinnen und Balkönchen am Delphi-Schloss. Wenn ihr richtige Software Engineers werden wollt, dann ignoriert Attribute einfach.

Stimmt und überhaupt, Codeeinrückung ist doch auch schlichtweg nicht nötig. Zinnen und Balkönchen am Quelltext. Und überhaupt, warum überhaupt mehrere Units, warum nicht gleich alles in einer, ist doch viel besser, alles andere ist doch gar nicht nötig, das wäre doch viel übersichtlicher. :roll:

mkinzler 20. Jul 2013 17:02

AW: Wozu sind Attribute gut ?
 
Wahre Profis proggen eh in Maschinencode, denn schon (Makro-)Assembler verwässern den Code. :stupid:

Furtbichler 21. Jul 2013 07:10

AW: Wozu sind Attribute gut ?
 
Na, vielleicht meinte der Insider2004 nur, das man erst das Handwerkszeug lernen sollte, bevor man mit dem Ausschmücken anfängt. Hier isses aber nun einmal so, das Attribute nur ein weiteres Werkzeug zur Modellierung der Lösung sind. Klar sollte man damit nicht anfangen, wenn man die ersten 'Hello World'-Programme schreibt, aber wenn Attribute überflüssig sind, dann sind es Klassen auch.

Allerdings...
Zitat:

Zitat von Insider2004 (Beitrag 1222132)
Eingekauft von .net, java und sonstigen Meta-Sprachen.

Was sind Meta-Sprachen?
Zitat:

Wenn ihr richtige Software Engineers werden wollt, dann ignoriert Attribute einfach.
Das ist die schmerzhafteste Aussage des Jahres. :wall:

Uwe Raabe 21. Jul 2013 08:02

AW: Wozu sind Attribute gut ?
 
Zitat:

Zitat von Furtbichler (Beitrag 1222174)
Zitat:

Wenn ihr richtige Software Engineers werden wollt, dann ignoriert Attribute einfach.
Das ist die schmerzhafteste Aussage des Jahres. :wall:

Delphi-Quellcode:
TDelphiPraxis.OnComment(Comment: TComment);
begin
  if Comment.Sender = 'Insider2004' then
    Comment.Text := '';
end;

Furtbichler 21. Jul 2013 08:15

AW: Wozu sind Attribute gut ?
 
Si.

Phoenix 21. Jul 2013 09:47

AW: Wozu sind Attribute gut ?
 
Please, don't feed the Troll.

squetk 22. Jul 2013 08:31

AW: Wozu sind Attribute gut ?
 
Zitat:

ich weiß, daß ich es garantiert nichts so machen würde.
Zitat:

dies in jeder Kundendatenbank von Hand nachgetragen werden musste.
Textinformationen gehören definitiv in eine Datenbank, genau dafür ist sie da. Und die beschriebenen Probleme bei Felderweiterungen etc. stellen sich bei der Nutzung eines guten ORM überhaupt nicht.

Elvis 22. Jul 2013 10:25

AW: Wozu sind Attribute gut ?
 
Zitat:

Zitat von squetk (Beitrag 1222225)
Zitat:

ich weiß, daß ich es garantiert nichts so machen würde.
Zitat:

dies in jeder Kundendatenbank von Hand nachgetragen werden musste.
Textinformationen gehören definitiv in eine Datenbank, genau dafür ist sie da. Und die beschriebenen Probleme bei Felderweiterungen etc. stellen sich bei der Nutzung eines guten ORM überhaupt nicht.

Hmm...
Ich finde für solche Infos sind Resources immer noch ideal, weil parallel zur DB versionierbar. Man kann mit 2 Versionen der Software auf der gleichen DB arbeiten ohne, dass man Side effects für dogmatischen Käse riskiert. Schlimm genug wenn man in den Situationen Side effects für tatsächlich sinnvolle Dinge bekommt.
Und sorry, aber Command Labels etc. in einer DB zu halten ist Käse.
Wenn man die von einem Release zum anderen wirklich umbenennen will, dann werden halt die ResX angepasst.

Phoenix 22. Jul 2013 10:36

AW: Wozu sind Attribute gut ?
 
Zitat:

Zitat von Elvis (Beitrag 1222234)
Ich finde für solche Infos sind Resources immer noch ideal, weil parallel zur DB versionierbar. Man kann mit 2 Versionen der Software auf der gleichen DB arbeiten ohne, dass man Side effects für dogmatischen Käse riskiert.

Grundsätzlich korrekt. Außer natürlich, der Kunde will translations für sich angepasst haben.

Wir haben die Translations tatsächlich auch in der Datenbank. Und wir haben pro Version Updatescripte, die geänderte Translations anpassen, sofern sie noch den Originalwert haben.

Ist zwar was mühsam, aber funktioniert.

Elvis 22. Jul 2013 11:35

AW: Wozu sind Attribute gut ?
 
Warum nicht einfach Resource DLLs mit liefern? Gerade in .Net ist das doch sehr einfach.
aber das wird OT.

Zum Thema:
Attribute sind Metadaten direkt am zu beschreibenden Code-Element. (Eigenschaft, Typ, Methode, ...)
Das heißt, man kann die Mittel der Sprache/Runtime um zusätzliche Punkte erweitern, ohne dass es zu fremdartig wirkt.

AOP-Frameworks können Attribute nutzen um sehr einfach die zu erweiternden Teile zu finden. Derjenige, der den Code liest, kann aber auch sehr einfach sehen was passiert. (Solange diese Attribute sinnvolle Namen und Parameter haben)

Ich selbst habe einen Build Task für C# geschrieben, mit dem man ein exaktes Gegenstück zu DllImport bekommt.
Da es sich in der Bedienung und Benennung eng an das vom Framework gestellte DllImport hält, fällt es eigentlich gar nicht als etwas "fremdes" auf.

PostSharp nutzt Attribute um Aspekte an bestimmte Code-Elemente zu binden. Auch das ist IMO sehr leserlich und verständlich.

Lustigerweise finde ich es gerade bei ORMs ziemlich daneben. Da Attribute-basierte Mappings nicht beim Kunden vom Kunden oder einem Consultant angepasst werden können. Aber ich bin wohl einer der ganz wenigen, die Mapping by Code nur während der ersten Entwicklungsphasen einsetzen...

Da Delphi Maschinen-Code erzeugt sind die wirklich mächtigen Use-Cases sicherlich so sau schwer zu implementieren, dass man es besser sein lässt.
Aber nicht alle Metadaten werden zum Verändern des Kompilats benötigt. ;-)

squetk 22. Jul 2013 13:34

AW: Wozu sind Attribute gut ?
 
Zitat:

Ich finde für solche Infos sind Resources immer noch ideal, weil parallel zur DB versionierbar.
Zitat:

Warum nicht einfach Resource DLLs mit liefern?
Weil ich mich damit zu sehr in Abhängigkeiten begebe.
Clients meiner Anwendung sollen in Zukunft nicht mehr zwangsläufig unter Windows laufen.
Und Begrifflichkeiten kann dann der (autorisierte) Kunde bequem anpassen.

Attribute sind Konstrukte für den Entwickler.
Ich müsste das Programm neu kompilieren, falls dem Kunden eine Beschreibung nicht passt, die ich in einem Attribut hinterlegt hab.

Uwe Raabe 22. Jul 2013 13:50

AW: Wozu sind Attribute gut ?
 
Zitat:

Zitat von squetk (Beitrag 1222225)
Textinformationen gehören definitiv in eine Datenbank, genau dafür ist sie da. Und die beschriebenen Probleme bei Felderweiterungen etc. stellen sich bei der Nutzung eines guten ORM überhaupt nicht.

Wenn es sich bei diesen "Textinformationen" z.B. um die Liste der verfügbaren Maschinen beim Kunden handelt, stimme ich dir zu. Wenn es aber um die passende Übersetzung des Labels "Stückzahl" geht, hat das nur in Ausnahmefällen was in der (Kunden-)Datenbank verloren (nur meine Meinung). Ach ja, ein ORM nutzt wohl auch nicht jeder - von einem guten ganz abgesehen. Das sollte aber jetzt nicht in einen Glaubenskrieg ausarten.

Es könnte sich als etwas schwierig erweisen, die Screenshots für die Dokumentation zu machen, wenn der Kunde quasi die gesamten Beschriftungen eines Forms verändern kann. Womöglich ergeben sich dabei ganz andere Bedeutungen und das Programm tut nicht mehr das, was man erwarten würde.

Ich stelle damit nicht grundsätzlich die Speicherung von Übersetzungen in einer Datenbank in Frage, wenn das verwendete Übersetzungs-Framework dies so realisiert.

Aber ich glaube wir schweifen ab.

Elvis 22. Jul 2013 13:56

AW: Wozu sind Attribute gut ?
 
Zitat:

Zitat von squetk (Beitrag 1222272)
Attribute sind Konstrukte für den Entwickler.
Ich müsste das Programm neu kompilieren, falls dem Kunden eine Beschreibung nicht passt, die ich in einem Attribut hinterlegt hab.

War so nicht gemeint. (Also Attribut-basiert) Ich weiß nicht, ob man in Delphi Ressource-Strings in Attributen nutzen kann, würde es aber annehmen.
Dann würde man die App nicht neu kompilieren müssen. Einfach eine Ressource-GUI geschnappt und die Texte anpassen.
Sicherlich wären Dinge, die eigentlich konfigurierbar sein sollten, aber trotzdem in ein Attribut gesteckt wurden, zu den Dingen für die Attribute eben nicht gut sind. IMO gehören viele ORM-bezogene Dinge dazu. (Also die Teile, die das Mapping zum phys. DB-Modell darstellen)

Bei P. denke ich, dass sie an solche Dinge wie effizientes Caching der Texte gedacht haben.
Das vergisst man bei diesen Texten-in-DB-Lösungen gerne: Die App darf sich jetzt einen Wolf abfragen nur um ein paar Texte darstellen zu können.

Der schöne Günther 22. Jul 2013 14:17

AW: Wozu sind Attribute gut ?
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1222273)
Es könnte sich als etwas schwierig erweisen, die Screenshots für die Dokumentation zu machen, wenn der Kunde quasi die gesamten Beschriftungen eines Forms verändern kann. Womöglich ergeben sich dabei ganz andere Bedeutungen und das Programm tut nicht mehr das, was man erwarten würde.

Vor dem Problem stehe ich auch bald, danke schonmal für den Warnhinweis :), spontan hätte ich das Problem nicht gesehen (dafür schon jetzt jede Menge andere :roteyes:).

squetk 22. Jul 2013 14:26

AW: Wozu sind Attribute gut ?
 
Zitat:

hat das nur in Ausnahmefällen was in der (Kunden-)Datenbank verloren
Ich denke, wenn ich es auf "kundenspezifische Begrifflichkeiten" einschränke, kommen wir auf einen Nenner. Den Ok-Button würde ich mir auch nur ungern umbenennen lassen :-D
Aber auf diese Art ist z.B. bei uns auch der Support in der Lage, ohne Programmierung eine Anwendung auf einen Kunden anzupassen.
Zitat:

Die App darf sich jetzt einen Wolf abfragen nur um ein paar Texte darstellen zu können.
Natürlich werden diese Art Informationen gecached - auch das sollte ein gutes O/R-Mapping leisten.

Aber wir schweifen tatsächlich ab. Die Quintessenz meiner Meinung ist dass Attribute nur Deklarationsinformationen darstellen sollten und keine Begrifflichkeiten, mit denen der Anwender hantiert.


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:33 Uhr.
Seite 1 von 2  1 2      

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