amiga-news DEUTSCHE VERSION
.
Links| Forums| Comments| Report news
.
Chat| Polls| Newsticker| Archive
.

amiga-news.de Forum > Programmierung > Strukturen, was passiert wenn... [ - Search - New posts - Register - Login - ]

1 -2- [ - Post reply - ]

2005-12-09, 21:28 h

Reth
Posts: 1858
User
@Holger:

Danke, hab aber auch Informatik studiert (hoffentlich blamier ich mich jetzt nicht), drum schreckt mich Skriptmäßiges nicht so schnell.

Von Bruce Eckel hab ich Thinking in C++ und Thinking in Java hier daheim ,dazu noch den C++ Primer in der 5. Edition.

Da schlag ich immer gern nach, hat gute Beispiele usw. Allerdings designmäßig hab ich bisher noch kein Buch gefunden (bin die obigen 3 aber auch noch nicht durchgegangen, hab mit dem Thinking in C++ angefangen was durchlesen anbelangt, im Primer schlag ich gern nach, dort gibt es jede Menge guter Beispiele!).

Design Pattern sind mir auch nicht fremd, obwohl ich bisher bewusst nur sehr wenige verwendet habe und mich auch noch nicht tiefer damit befasst habe (also was es z.B. alles für welche gibt usw.).

Ciao

[ Dieser Beitrag wurde von Reth am 09.12.2005 um 21:29 Uhr editiert. ]

[ - Answer - Quote - Direct link - ]

2005-12-11, 14:24 h

Holger
Posts: 8116
User
Zitat:
Original von Reth:
Danke, hab aber auch Informatik studiert (hoffentlich blamier ich mich jetzt nicht), drum schreckt mich Skriptmäßiges nicht so schnell.

Ging weniger um die Skriptform, sondern darum, daß es thematisch den Softwareengeneering-Vorlesungen gleicht, die ich auch kenne, die einem Studenten wie ein großes Theorie-Bla-Bla vorkommen, dem man allenfalls in 1000-Mannentwicklerteams mit großem Wasserkopf wiederbegegnet.
Den praktischen Nutzen für einen selbst findet man dann meist erst außerhalb des Studiums. Deshalb habe ich mehr Praxisbezug empfohlen.
Zitat:
Design Pattern sind mir auch nicht fremd, obwohl ich bisher bewusst nur sehr wenige verwendet habe und mich auch noch nicht tiefer damit befasst habe (also was es z.B. alles für welche gibt usw.).

Das ist der Punkt. Es ist wichtig, ein Bewußtsein dafür zu entwickeln. Du benutzt mit Sicherheit schon jeder Menge Patterns in der Praxis. Sie zu erkennen und durch andere zu ergänzen, hilft einem beim Programmieren gewaltig.
Deshalb hilft es auch nicht, einfach nur ein Buch durchzuackern, und sich zu merken, welche es gibt. Wenn Du eigene Erfahrungen in dem Buch wiedererkennst, wird der Knoten platzen. Nicht jedes Pattern ist wirklich nützlich. Aber die Herangehensweise an die Probleme, die Denkweise beim Programmieren machts.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Answer - Quote - Direct link - ]

2005-12-11, 23:15 h

whose
Posts: 2156
User
@Holger:

Könntest Du evtl. mal ein Beispiel aus der Praxis hinreichend genau skizzieren? Mich interessiert das Thema Design Patterns auch, allerdings habe ich davon recht wenig mit auf den Weg bekommen zu meiner Zeit. OOP gehe ich bis heute noch aus dem Weg, wenn möglich, aber sicher wird irgendwann der Punkt kommen, wo ich es gebrauchen muß. Sicherlich habe ich Patterns auch schon unbewußt angewandt, aber nützlicher sind sie bestimmt, wenn man sie bewußt anwendet. Ich denke mal, ein Beispiel aus der Praxis hilft da enorm beim Verständnis.

Grüße



--
---

:boing: µA1 PPC 750GX-800
:boing: A4000 PPC 604e-233

[ - Answer - Quote - Direct link - ]

2005-12-12, 09:42 h

Mad_Dog
Posts: 1944
User
Mag schon sein, daß das genannte Skript etwas allgemein gehalten ist, aber immerhin geht es auf wichtige Themen wie z.B. Realtime-Systeme usw. ein. Einige Dinge, die dort besprochen werden, dürften auch dem geübten Hobby-Programmierer klar sein. Z.B. :

- Sorge dafür, daß Module möglichst wiederverwendbar sind
- Sorge dafür, daß einzelne Module so wenig wie möglich voneinander abhängig sind
- Vermeide unnötiges Herumkopieren von Daten
- Black Box Prinzip
- "Teile und herrsche"
- Vermeide lange Parameterlisten in Funktionen
- Verwende so wenig globale Variablen wie möglich
- Vermeide jede Art von "Spagetticode"
- fertige eine gute Dokumentation an (dieser Teil wird von vielen unterschätzt)
- Verwende die Mittel, die die jeweilige Sprache bietet sinnvoll (z.B. OOP, Kapselung, Vererbung usw.)

Übrigens geht Bjarne Stroustrup (der Erfinder von C++) in seinem Buch "Die C++ Programmiersprache" auch in einigen Kapiteln auf Design Aspekte ein. Teilweise schreibt er auch Dinge, die Insider aus "Peopleware" kennen (Faktor Mensch in der DV Entwicklung).
--

http://www.norman-interactive.com

[ - Answer - Quote - Direct link - ]

2005-12-12, 13:44 h

Holger
Posts: 8116
User
Zitat:
Original von whose:
@Holger:

Könntest Du evtl. mal ein Beispiel aus der Praxis hinreichend genau skizzieren? Mich interessiert das Thema Design Patterns auch, allerdings habe ich davon recht wenig mit auf den Weg bekommen zu meiner Zeit. OOP gehe ich bis heute noch aus dem Weg, wenn möglich, aber sicher wird irgendwann der Punkt kommen, wo ich es gebrauchen muß.


Das ist keine Frage von OOP oder nicht OOP. OOP ist auch nur die konsequente Zusammenfassung der Programmiertechniken, die sich auch vor der Erfindung von OOP als die effektivsten herausgestellt hatten. Es ist nicht, wie manch einer glaubt, eine radikal andere Art der Softwareentwicklung, im Gegenteil.

Mal ein simples Beispiel, das Pattern "Factory Method". Es besteht darin, Objekte statt mittels new-Operator direkt anzulegen, über einen Methodenaufruf, der diesen Vorgang kapselt, zu erzeugen. Damit erreicht man eine Entkopplung von dem konkreten Typen des erzeugten Objekts.
Kann man 1:1 auch auf nicht-OOP Programmiersprachen übertragen. Vor AmigaOS3.0 war es nicht möglich, Grafikkarten transparent in das System einzubinden, weil es u.a. unmöglich war, Grafikkarten-BitMaps anzulegen. Erst die Einführung der Factory-Funktion AllocBitMap, die wahlweise native- oder Grafikkarten-BitMaps zurückliefern kann, macht dies möglich. Strukturen, die von der Anwendung quasi "von Hand" angelegt werden, wie z.B. RastPort, können nicht erweitert werden.
Das entspricht auch dem allgemeineren Muster der zusätzlichen Indirektion, Factory ist eine konkretere Anwendung.

Als Anregung zum selber raussuchen: viele Amiga-Libraries entsprechen mehr oder weniger dem Facade Pattern.

Die commodities.library ist eine praktische Anwendung des Observer Patterns.

usw

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Answer - Quote - Direct link - ]

2005-12-12, 15:37 h

whose
Posts: 2156
User
@Holger:

Danke Dir für die Beispiele, die Du genannt hast. Im Gegensatz zu trockenen Scripten, die ich zu dem Thema vorgeworfen bekommen habe, kann man sich doch an solchen Beispielen viel besser in die Materie reindenken und sich selbst während des Designprozesses entsprechend beobachten :)

Zitat:
Original von Holger:

Das ist keine Frage von OOP oder nicht OOP. OOP ist auch nur die konsequente Zusammenfassung der Programmiertechniken, die sich auch vor der Erfindung von OOP als die effektivsten herausgestellt hatten. Es ist nicht, wie manch einer glaubt, eine radikal andere Art der Softwareentwicklung, im Gegenteil.


Das war mir schon klar. Als in einer Vorlesung einmal der Satz fiel: "Design patterns versprechen zwar, die Denkweise in der Entwicklung von Computersoftware zu verändern, aber in Wirklichkeit tun sie es bereits seit Jahrzehnten völlig unbemerkt", wußte ich schon, daß ich (und viele, viele andere Softwareentwickler) diese Methodik bereits anwende. Leider blieb es zu meiner Zeit bei dem Satz und praxisnahe Beispiele zum Thema bekam man auch auf Nachfrage einfach nicht vermittelt. Es blieb bei der grauen Theorie, die Du ein paar Postings vorher schon an dem Script, auf das MadDog verwies, kritisiert hast.

Zitat:
Mal ein simples Beispiel, das Pattern "Factory Method". Es besteht darin, Objekte statt mittels new-Operator direkt anzulegen, über einen Methodenaufruf, der diesen Vorgang kapselt, zu erzeugen. Damit erreicht man eine Entkopplung von dem konkreten Typen des erzeugten Objekts.
Kann man 1:1 auch auf nicht-OOP Programmiersprachen übertragen. Vor AmigaOS3.0 war es nicht möglich, Grafikkarten transparent in das System einzubinden, weil es u.a. unmöglich war, Grafikkarten-BitMaps anzulegen. Erst die Einführung der Factory-Funktion AllocBitMap, die wahlweise native- oder Grafikkarten-BitMaps zurückliefern kann, macht dies möglich. Strukturen, die von der Anwendung quasi "von Hand" angelegt werden, wie z.B. RastPort, können nicht erweitert werden.
Das entspricht auch dem allgemeineren Muster der zusätzlichen Indirektion, Factory ist eine konkretere Anwendung.

Als Anregung zum selber raussuchen: viele Amiga-Libraries entsprechen mehr oder weniger dem Facade Pattern.

Die commodities.library ist eine praktische Anwendung des Observer Patterns.

usw


Danke Dir nochmal. Auf die Idee, diverse OS-Bibliotheken mal im Licht von Design Patterns zu betrachten, bin ich nie gekommen. Das hole ich jetzt mal gründlich nach.

Grüße

--
---

:boing: µA1 PPC 750GX-800
:boing: A4000 PPC 604e-233

[ - Answer - Quote - Direct link - ]

2005-12-13, 08:53 h

Reth
Posts: 1858
User
@whose:

Hi, sorry wollte Dir auf Deine Frage auch schon lang antworten:

Wenn Du z.B. mit Intuition arbeitest und Messages empfängst und auswertest, verwendest Du damit automatisch das Observer-Pattern.

[ - Answer - Quote - Direct link - ]

2005-12-14, 13:03 h

Reth
Posts: 1858
User
Zitat:
Original von Holger:
Du denkst zu sehr in den alten AmigaOS-Strukturen, mit denen man sich eigentlich lieber nicht beschäftigen sollte. Was zeichnet denn in der Praxis z.B. einen Button aus? Einen Label-String und/oder ein Icon und im Falle des Label-Strings evtl. ein markierter Buchstabe für den Short-Cut. Dimension und Position sind Sache des Layouts, interessiert mich als Anwendungsprogrammierer überhaupt nicht und Flags bei einem Button? Kenne ich keine. Sicher, in den Gadget-Strukturen gibt es allgemeine Flags für Intuition, aber der Wert ist für jeden Button identisch.
Rahmen und Füllfarbe sollten nur im absoluten Ausnahmefall von denen einer normalen Buttons abweichen...
Ähnliches bei einer Checkbox, gleiche Attribute, plus einem boolschen Selected-Attribut.

Versuch Dich an der Praxis desjenigen, der die Komponenten hinterher benutzt zu orientieren. Was braucht er wirklich:
Button erzeugen, Text/Icon setzen
eindeutige ID zuordnen für die auszuführende Aktion, übersetzte String im locale-catalog, Hilfethemen.

Ein Gadget besteht von der Logik her wirklich aus fast nichts. Seiner Identität, Position in der Gadget-Hierarchie, den View-Optionen und dem Datenmodell.
Man beachte, daß mehrere Gagdets sich ein View-Setup und/oder ein Datenmodell teilen können. Im Gadget direkt sind nur die nicht gemeinsam nutzbaren Eigenschaften enthalten.


Hm, jetzt ist bei mir ein erstes Knötchen geplatzt.
Wenn ich Buttons etc. vom Layout entkopple, dann mache ich in diesen Klassen nur noch die eigentliche Funktionalität und beim einhängen der Buttons etc. in die Layoutklasse werden dann die Gadgets, MUI- bzw. ReAction-Komponenten angelegt.

In so nem Fall könnte man auch ne andere Philosophie verfolgen als z.B . in Java wo das Layout einer Komponente gesetzt wird:
Man könnte in so nem Fall nen unabhängigen LayoutManager machen, dem dann das Fenster ebenfalls als Komponenten übergeben wird und im LayoutManager wird dann erst die Amiga-API gerufen und das Fenster erzeugt.
Müsste man aber in jedem Fall ersteinmal komplett durchdenken und die Vor- und Nachteile aufzeichnen.

Für meinen momentanen Bedarf ist das alles erst einmal viel zu viel Aufwand (obwohl man ja nen Simplen FixedLayoutManager schreiben kann, der Elemente an feste Koordinaten setzt und dazu dann Buttons und was man sonst noch so braucht - die Integration von Menüs wäre so auch möglich), werd mal meine Wrapper schreiben und Dir dann schicken.
Wenns mich zu sehr packt, dann probier ich evtl. doch noch den Ansatz mit der Trennung von Buttonfunktionalität und Design mit Hilfe eines solchen simplen LayoutManagers, letzterer wird dann aber in das Fensterobjekt gesetzt bzw. ist dort immer vorhanden, wenn kein anderes Layout gesetzt wird.
Die Ereignisverarbeitung (Messages) dachte ich mir entweder an die Komponenten zu hängen (also wie nen Listener pro Button), oder in die Komponenten zu integrieren (ein Button weiss, wenn er gedrückt wird) oder nach Art getrennt ins Fenster zu hängen (z.B. so ne Art Listener für Mausereignisse, einen für Buttonereignisse etc.).

Ciao

[ - Answer - Quote - Direct link - ]

2005-12-14, 15:54 h

Holger
Posts: 8116
User
Zitat:
Original von Reth:
Hm, jetzt ist bei mir ein erstes Knötchen geplatzt.
Wenn ich Buttons etc. vom Layout entkopple, dann mache ich in diesen Klassen nur noch die eigentliche Funktionalität und beim einhängen der Buttons etc. in die Layoutklasse werden dann die Gadgets, MUI- bzw. ReAction-Komponenten angelegt.

In so nem Fall könnte man auch ne andere Philosophie verfolgen als z.B . in Java wo das Layout einer Komponente gesetzt wird:

Na, so viel anders sind die systemabhängigen peers ja auch nicht. Im Falle des reinen AWTs werden preferred sizes von den peers bestimmt, im Falle von Swing übernimmt das jewelige Look&Feel diese Aufgaben.

Diese Trennung ist aber weit weniger wichtig für die Anwendungsentwicklung als die konsequenten Benutzung des MVC-Patterns.

Zum Beispiel:
code:
import java.awt.event.ActionEvent;
import javax.swing.*;

public class Example
{
  public static void main(String[] args)
  {
    final JFrame frame=new JFrame("test");
    Action quit=new AbstractAction("Quit")
    {
      { putValue(SHORT_DESCRIPTION, "Quit application"); }
      public void actionPerformed(ActionEvent e)
      {
        if(JOptionPane.showConfirmDialog(frame, "Really Quit?", "Quit",
           JOptionPane.YES_NO_OPTION)==JOptionPane.OK_OPTION)
          System.exit(0);
      }
    };
    frame.setContentPane(new JButton(quit));
    JMenuBar b=new JMenuBar();
    frame.setJMenuBar(b);
    b.add(new JMenu("Application")).add(quit);
    frame.pack();
    frame.show();
  }
}

Ein Objekt wie die Action kann ich im GUI belibig oft einbinden, im Gegensatz zu einer Component, die nur genau einmal auftauchen darf. Die Action bestimmt die wichtigen Eigenschaften, wie Label und Beschreibung, sowie den eigentlichen auszuführenden Code, den man natürlich nur einmal schreiben möchte. Und dabei ist es sogar egal, ob ich diese als MenuItem oder Button einbinde.
Interessant hierbei auch die Anzahl der Properties, die ich tatsächlich bei den Gadgets anfasse, im Falle des Button gar keine, im Falle des MenuItems lasse ich mir das zugehörige Objekt noch nicht einmal zurückgeben, weil ich es nicht brauche, und JMenu es implizit anlegt.
Zitat:
Für meinen momentanen Bedarf ist das alles erst einmal viel zu viel Aufwand (obwohl man ja nen Simplen FixedLayoutManager schreiben kann, der Elemente an feste Koordinaten setzt und dazu dann Buttons und was man sonst noch so braucht ...
Die einfachsten LayoutManager, die trotzdem 80% aller Anwendungsfälle abdecken, sind immer noch die, die wahlweise horizontal oder vertikal in einer Linie anordnen. Durch Verschachtelung solcher Layouts kann man eine Menge erreichen. Nahezu alle UI-System bieten so etwas an, manche bieten nur das.
Und man kommt damit sehr weit.
Zitat:
Wenns mich zu sehr packt, dann probier ich evtl. doch noch den Ansatz mit der Trennung von Buttonfunktionalität und Design mit Hilfe eines solchen simplen LayoutManagers, letzterer wird dann aber in das Fensterobjekt gesetzt bzw. ist dort immer vorhanden, wenn kein anderes Layout gesetzt wird.
Layout sollte schon eine Container-Eigenschaft sein, nur so kannst Du durch Kombination einfacher Algorithmen auch komplexe Layout-Aufgaben lösen. Für die Trennung der Funktionalität beschäftige Dich lieber mit dem MVC- oder vergleichbaren Patterns (siehe oben).
Dann hast Du auch einen Ansatzpunkt für die Ereignisverarbeitung.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ Dieser Beitrag wurde von Holger am 14.12.2005 um 15:54 Uhr editiert. ]

[ - Answer - Quote - Direct link - ]

2005-12-15, 13:37 h

Reth
Posts: 1858
User
@Holger:

Gutes Beispiel.
In diesem ist der Controller aber mit dem Model verbunden, was ja auch Sinn macht. Leider kann man an die Action keinen ActionListener hängen, dieser wäre dann ein getrennter Kontroller, wodurch man hier ein bisschen zu fest gebunden ist für meinen Geschmack. Aber es gibt da ja noch andere Möglichkeiten (z.B. eigene Actionklasse, die alle eingehangenen ActionListener bedient).

In meinem Fall dachte ich an einen recht einfachen Ansatz, da ich ja wie gesagt kein komplettes Framework für das Amiga-API schreiben will und mich primär die Ereignisse innerhalb eines Fensters interessieren.

Daher die Idee, einem Fenster verschiedene Beobachter anzugeben: Einen für die Mausaktionen, einen für Menüaktionen, einen für Gadgets etc.
Ich weiss, dass das keine MVC-Trennung ist, entspricht aber den häufigsten Aktivitäten, die man in einer Fensteranwendung haben kann.

Ein striktes MVC zu implementieren finde ich nicht ganz so gelungen wie der Ansatz in Java, wo der Controller ans Model gehangen werden kann (Listener).
Dadurch verliert man zwar ein bisschen die Möglichkeit, einen Controller für unterschiedliche Models zu verwenden (nur wenn das Interface nicht stimmt, ansonsten kann ich den Controller überall einhängen), aber dazu fällt mir so schnell auch kein gutes Bsp. ein.


Ciao

[ - Answer - Quote - Direct link - ]

2005-12-15, 15:06 h

Holger
Posts: 8116
User
Zitat:
Original von Reth:
In meinem Fall dachte ich an einen recht einfachen Ansatz, da ich ja wie gesagt kein komplettes Framework für das Amiga-API schreiben will und mich primär die Ereignisse innerhalb eines Fensters interessieren.

Innerhalb eines Fensters? Eigentlich treten diese Ereignisse außerhalb des Computers auf. Das Fenster ist stellt eine von Dir willkürlich gewählte Resource.
Zitat:
Daher die Idee, einem Fenster verschiedene Beobachter anzugeben: Einen für die Mausaktionen, einen für Menüaktionen, einen für Gadgets etc.
Ich weiss, dass das keine MVC-Trennung ist, entspricht aber den häufigsten Aktivitäten, die man in einer Fensteranwendung haben kann.

Aber was macht man denn typischerweise mit solchen Events? Du versuchst herauszufinden, welcher Button/Menüpunkt betroffen ist, und ordnest ihm die zugehörige Aktion zu. Das kann über IDs und ellenlangen Switch-Statements oder halt über Pointer auf die zugehörige Aktion machen.
Mehrere Beobachter an ein Fenster zu hängen, die dann jeder für sich herausfinden müssen, ob das jeweilige Event für sie relevant ist, sind nicht nur umständlich zu programmieren, sondern auch Resourcenverschwendung. Intuition teilt Dir bereits mit, welches Gadget betroffen ist, das Gadget bietet mit dem UserData-Eintrag bereit eine Möglichkeit der Zuordnung zum zughörigen Anwendungobjekt, warum willst Du diese Möglichkeiten nicht nutzen?
Mehrere Beobachter für ein- und dieselbe Funktion sind eher die Ausnahme.
Zitat:
Ein striktes MVC zu implementieren finde ich nicht ganz so gelungen wie der Ansatz in Java, wo der Controller ans Model gehangen werden kann (Listener).
Dadurch verliert man zwar ein bisschen die Möglichkeit, einen Controller für unterschiedliche Models zu verwenden (nur wenn das Interface nicht stimmt, ansonsten kann ich den Controller überall einhängen), aber dazu fällt mir so schnell auch kein gutes Bsp. ein.

Ich glaube, ich sagte schon, daß ich den Ansatz von Swing für brauchbar halte, toll finde ich ihn nicht. Diese Divergenz der unterschiedlichen Interfaces halte ich auch nicht für sinnvoll. Listen und Tabellen muß man nicht als völlig unterschiedliche Strukturen ansehen, Listen und Bäume ebenfalls nicht.
Die Implementation der Dateiauswahldialoge zeigt, wie umständlich die Handhabung durch diese Design-Schwäche werden kann.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ Dieser Beitrag wurde von Holger am 15.12.2005 um 15:10 Uhr editiert. ]

[ - Answer - Quote - Direct link - ]

2005-12-15, 16:26 h

Reth
Posts: 1858
User
Hi Holger,

[quote]
Original von Holger:
Zitat:
Aber was macht man denn typischerweise mit solchen Events? Du versuchst herauszufinden, welcher Button/Menüpunkt betroffen ist, und ordnest ihm die zugehörige Aktion zu. Das kann über IDs und ellenlangen Switch-Statements oder halt über Pointer auf die zugehörige Aktion machen.
Mehrere Beobachter an ein Fenster zu hängen, die dann jeder für sich herausfinden müssen, ob das jeweilige Event für sie relevant ist, sind nicht nur umständlich zu programmieren, sondern auch Resourcenverschwendung. Intuition teilt Dir bereits mit, welches Gadget betroffen ist, das Gadget bietet mit dem UserData-Eintrag bereit eine Möglichkeit der Zuordnung zum zughörigen Anwendungobjekt, warum willst Du diese Möglichkeiten nicht nutzen?
Mehrere Beobachter für ein- und dieselbe Funktion sind eher die Ausnahme.


Aber die Auswertung welches Gadget betroffen ist, musst Du mit Hilfe von Switches oder ähnlichem irgendwo vornehmen, hatte nicht vor die doppelt zu machen (falls Du das dachtest).
Irgendwie musst man ja den Pointer für die Aktion identifizieren, der betroffen ist.
Oder wie willst Du sonst nen Controller für ein Gadget informieren?
Läuft das über die UserData? Wie siehts da mit der Parametrisierung aus (muss mich noch mal in die AmigaLiteratur vergraben)?

[ - Answer - Quote - Direct link - ]

2005-12-15, 16:57 h

Holger
Posts: 8116
User
Zitat:
Original von Reth:
Hi Holger,

Irgendwie musst man ja den Pointer für die Aktion identifizieren, der betroffen ist.
Oder wie willst Du sonst nen Controller für ein Gadget informieren?
Läuft das über die UserData? Wie siehts da mit der Parametrisierung aus (muss mich noch mal in die AmigaLiteratur vergraben)?


Ich hab das jetzt auch nicht im Kopf. Bin davon ausgegangen, daß es wie üblich ein ULONG oder APTR ist, also in jedem Fall ein 32 Bit-Wert, den man zur freien Verfügung hat, also auch zum Speichern eines Pointers benutzen kann.
Der kann dann auf ein ButtonModel oder eine Action zeigen. Es muß natürlich konsequent eingehalten werden, daß alle UserData-Inhalte immer auf eine Implementierung/Unterklasse davon zeigen, da man ja um einen cast an dieser Stelle nicht herum kommt.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Answer - Quote - Direct link - ]

2005-12-16, 09:01 h

Reth
Posts: 1858
User
@Holger:

Hm, bin mir nicht ganz sicher, ist glaub ein UWORD.

Also ist es so, wie ich für mich schon vermutet hatte, dass beim Aufruf des Pointers in UserData von einer einheitlichen Schnittstelle (zuminest bei Gadgets) ausgegangen wird. Wenn man keine ganz einheitliche Schnittstelle machen will, muss man dann ja ne Unterscheidung zw. z.B. Menüs und Gadgets machen.

Ciao

[ - Answer - Quote - Direct link - ]

2005-12-18, 00:20 h

Holger
Posts: 8116
User
Zitat:
Original von Reth:
Hm, bin mir nicht ganz sicher, ist glaub ein UWORD.

gg_UserData ist ein APTR.
Zitat:
Also ist es so, wie ich für mich schon vermutet hatte, dass beim Aufruf des Pointers in UserData von einer einheitlichen Schnittstelle (zuminest bei Gadgets) ausgegangen wird.
Wenn Du nicht noch irgendwo eine codierte Zusatzinformation darüber, was für ein Typ hinter dem pointer steckt, speichern willst, mußt Du wohl eine gemeinsame Schnittstelle finden. Beliebige pointer plus die Zusatzinformation stellen letztendlich auch eine einheitliche Schnittstelle dar, nur eine kompliziertere.
Also in jedem Fall wirst Du eine wie auch immer geartete einheitliche Schnittstelle haben.
Zitat:
Wenn man keine ganz einheitliche Schnittstelle machen will, muss man dann ja ne Unterscheidung zw. z.B. Menüs und Gadgets machen.
Intuition liefert Dir erstmal prinzipiell unterschiedliche Message-Typen, anhand derer Du also unterscheiden kannst. Allerdings empfielt sich hier eine Abstraktion, genau daraus gewinnt man ja letztendlich die Vorteile der OOP.
Allerdings mußt Du Dir bei Menüstrukturen noch etwas einfallen lassen, da gibts nämlich keinen UserData-Pointer.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Answer - Quote - Direct link - ]

2005-12-28, 22:09 h

Reth
Posts: 1858
User
@Holger:

Danke nochmals.

Hoffe, Du und alle anderen hatten ein schönes Weihnachtsfest!

Jetzt hab ich nochmal ne Frage:

Nachdem ich nun auf den eher MVC-lastigen Ansatz gewechselt hab, stellt sich mir das Problem, dass ich meinem Fenster ja nun Buttons etc. hinzufügen will (habs jetzt mal ohne Layoutmanager).

Dabei soll diese Methode des Fensters die GadgetStruktur füllen und sich das Gadget einhängen.
Nun verhält sich aber ein TextButton ja anders als ein ImageButton!

Gibts da ne Möglichkeit mit Templates zu arbeiten, oder sollte man für jeden Buttontyp ne Conviniencemethode schreiben, oder RuntimeTypeChecking betreiben (letzteres ist ja der imperformanteste Ansatz)?

Ciao

[ - Answer - Quote - Direct link - ]

2005-12-29, 15:42 h

Holger
Posts: 8116
User
Zitat:
Original von Reth:
Nachdem ich nun auf den eher MVC-lastigen Ansatz gewechselt hab, stellt sich mir das Problem, dass ich meinem Fenster ja nun Buttons etc. hinzufügen will (habs jetzt mal ohne Layoutmanager).

Dabei soll diese Methode des Fensters die GadgetStruktur füllen und sich das Gadget einhängen.
Nun verhält sich aber ein TextButton ja anders als ein ImageButton!

Das ist ein deutlicher Hinweis darauf, daß die Methoden des Fensters der falsche Platz sind, um diese Funktionalität zu implementieren.
Das hieße ja dann, das die Einführung neuer Gadgetklassen eine Änderung der Fensterimplementation erfordert. Genau das soll aber OOP verhindern.
Zitat:
Gibts da ne Möglichkeit mit Templates zu arbeiten, oder sollte man für jeden Buttontyp ne Conviniencemethode schreiben, oder RuntimeTypeChecking betreiben (letzteres ist ja der imperformanteste Ansatz)?

Entweder Du verschiebst die Funktionalität des Umwandelns in Standard-Gadgetstrukturen in die Buttons, etc. Oder Du verlagerst diese Funktionalität in eine dritte Klasse. Letzteres ist die sauberste Methode.
Solche Operationen können auch vom Compiler transparent eingefügt werden, d.h. die Benutzung bleibt unkompliziert.

class Fenster
{
...
public:
void add(StandardGadget g);
}

class MyButton
{
//optional: friend MyButton
}

class MyButtonStandardGadgetFactory
{
public:
MyButtonStandardGadgetFactory(MyButton b);
operator StandardGadget();
}

// ...

MyButton example;
Fenster fenster;
fenster.add(example);

So in etwa.

mfg

PS: Hoffe natürlich auch, daß Du (und alle anderen) ein schönes Fest hatten!

[ - Answer - Quote - Direct link - ]

2005-12-29, 16:12 h

Holger
Posts: 8116
User
@Reth:
Vielleicht solltest Du doch mal Deine sourcen schicken, damit ich mir auch eine Vorstellung davon machen kann.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Answer - Quote - Direct link - ]

2005-12-29, 21:32 h

Reth
Posts: 1858
User
Zitat:
Original von Holger:
Entweder Du verschiebst die Funktionalität des Umwandelns in Standard-Gadgetstrukturen in die Buttons, etc. Oder Du verlagerst diese Funktionalität in eine dritte Klasse. Letzteres ist die sauberste Methode.
Solche Operationen können auch vom Compiler transparent eingefügt werden, d.h. die Benutzung bleibt unkompliziert.

class Fenster
{
...
public:
void add(StandardGadget g);
}

class MyButton
{
//optional: friend MyButton
}

class MyButtonStandardGadgetFactory
{
public:
MyButtonStandardGadgetFactory(MyButton b);
operator StandardGadget();
}

// ...

MyButton example;
Fenster fenster;
fenster.add(example);

So in etwa.

mfg

PS: Hoffe natürlich auch, daß Du (und alle anderen) ein schönes Fest hatten!


Hm, mein erster Ansatz war der, dass die Gadgetklassen ihre Strukturen selbst erzeugen und Window eine Friendklasse ist, damit die Strukturen nur über private Methoden zugreifbar sind.
Nun habe ich es ohne die Strukturen in den Gadgetklassen probiert, bis zu diesem Punkt.

Bei dem Ansatz mit der Factoryklasse braucht diese aber doch auch pro Gadgettyp ne eigene Methode oder ne RuntimeTypeChecking-Variante, oder!?
Geht das nicht irgendwie dynamischer (ohne RTTC) via Templates o.ä.?

Die Sourcen kann ich Dir gern mal zukommen lassen, wird wohl aber erst nächstes Jahr!

Auch PS: Danke schön, das Weihnachtsfest war schön!

Ciao

[ - Answer - Quote - Direct link - ]

2005-12-30, 15:32 h

Holger
Posts: 8116
User
Zitat:
Original von Reth:
Bei dem Ansatz mit der Factoryklasse braucht diese aber doch auch pro Gadgettyp ne eigene Methode oder ne RuntimeTypeChecking-Variante, oder!?

Nein, Du benutzt eine Factory pro Gadgettyp. Bestehende Klassen werden für die Integration neuer Typen nicht angefaßt. Darum geht es bei dieser Vorgehensweise.
Zitat:
Geht das nicht irgendwie dynamischer (ohne RTTC) via Templates o.ä.?
Also entweder Runtime oder Compile-Time. Die obige Variante wird zur compile-time aufgelöst, aber Du mußt keine existierende Klasse verändern, um neue Features hinzuzufügen. Mehr kannst Du nicht verlangen.
Das funktioniert auch, wenn Du an eine schon übersetzte Fensterklasse bindest. Nur die neue Gadgetklasse und die neue Factory müssen übersetzt werden, da die Schnittstelle die einheitliche Gadgetstruktur ist. Sauberer geht's nicht; auch späte Bindung könnte da keinen weiteren Vorteil herausarbeiten.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Answer - Quote - Direct link - ]


1 -2- [ - Post reply - ]


amiga-news.de Forum > Programmierung > Strukturen, was passiert wenn... [ - Search - New posts - Register - Login - ]


.
Masthead | Privacy policy | Netiquette | Advertising | Contact
Copyright © 1998-2024 by amiga-news.de - all rights reserved.
.